linux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: linux

To: linux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: linux
From: ralf@linux-mips.org
Date: Fri, 29 Apr 2005 12:15:31 +0100
Reply-to: linux-mips@linux-mips.org
Sender: linux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    linux
Changes by:     ralf@ftp.linux-mips.org 05/04/29 12:15:24

Modified files:
        .              : CREDITS MAINTAINERS Makefile 
        Documentation  : DMA-mapping.txt feature-removal-schedule.txt 
        Documentation/aoe: mkdevs.sh mkshelf.sh udev-install.sh 
        Documentation/driver-model: bus.txt driver.txt 
        Documentation/infiniband: ipoib.txt 
        Documentation/power: video.txt 
        Documentation/scsi: scsi_mid_low_api.txt 
        arch/arm/kernel: process.c sys_arm.c traps.c 
        arch/arm/lib   : changebit.S clearbit.S setbit.S testchangebit.S 
                         testclearbit.S testsetbit.S 
        arch/arm/mach-footbridge: dc21285-timer.c 
        arch/arm/mach-ixp4xx: Kconfig 
        arch/arm/mach-sa1100: h3600.c 
        arch/arm/mm    : fault.c init.c 
        arch/arm26/kernel: sys_arm.c 
        arch/i386/kernel: Makefile apic.c efi.c entry.S i8259.c 
                          io_apic.c nmi.c process.c signal.c smpboot.c 
                          time.c vsyscall.lds.S 
        arch/i386/kernel/acpi: boot.c 
        arch/i386/kernel/cpu: amd.c common.c intel.c proc.c 
        arch/i386/kernel/cpu/mtrr: generic.c main.c 
        arch/i386/mach-voyager: voyager_thread.c 
        arch/i386/mm   : hugetlbpage.c pgtable.c 
        arch/i386/oprofile: nmi_int.c 
        arch/i386/pci  : irq.c 
        arch/ia64/mm   : hugetlbpage.c 
        arch/m68k      : defconfig 
        arch/m68k/configs: amiga_defconfig apollo_defconfig 
                           atari_defconfig bvme6000_defconfig 
                           hp300_defconfig mac_defconfig 
                           mvme147_defconfig mvme16x_defconfig 
                           q40_defconfig sun3_defconfig sun3x_defconfig 
        arch/mips      : defconfig 
        arch/mips/configs: atlas_defconfig capcella_defconfig 
                           cobalt_defconfig db1000_defconfig 
                           db1100_defconfig db1500_defconfig 
                           db1550_defconfig ddb5476_defconfig 
                           ddb5477_defconfig decstation_defconfig 
                           e55_defconfig ev64120_defconfig 
                           ev96100_defconfig ip22_defconfig 
                           ip27_defconfig ip32_defconfig 
                           it8172_defconfig ivr_defconfig 
                           jaguar-atx_defconfig jmr3927_defconfig 
                           lasat200_defconfig malta_defconfig 
                           mpc30x_defconfig ocelot_3_defconfig 
                           ocelot_c_defconfig ocelot_defconfig 
                           ocelot_g_defconfig osprey_defconfig 
                           pb1100_defconfig pb1500_defconfig 
                           pb1550_defconfig rm200_defconfig 
                           sb1250-swarm_defconfig sead_defconfig 
                           tb0226_defconfig tb0229_defconfig 
                           workpad_defconfig yosemite_defconfig 
        arch/parisc/lib: iomap.c 
        arch/ppc       : Kconfig 
        arch/ppc/boot/simple: Makefile 
        arch/ppc/kernel: head_fsl_booke.S signal.c time.c traps.c 
        arch/ppc/mm    : pgtable.c 
        arch/ppc/platforms: chrp_time.c gemini_setup.c pmac_cache.S 
                            pmac_cpufreq.c pmac_feature.c pmac_smp.c 
                            prep_pci.c 
        arch/ppc/syslib: m8xx_wdt.c open_pic.c open_pic_defs.h 
                         ppc4xx_pic.c ppc85xx_common.c 
        arch/ppc64     : Kconfig 
        arch/ppc64/kernel: head.S maple_setup.c of_device.c 
                           pSeries_setup.c pci.c pmac_feature.c 
                           ppc_ksyms.c prom.c traps.c vdso.c 
        arch/ppc64/mm  : hugetlbpage.c init.c 
        arch/sh/kernel/cpu: bus.c 
        arch/sparc/kernel: ptrace.c 
        arch/sparc64/kernel: ptrace.c signal32.c sys_sparc32.c systbls.S 
        arch/sparc64/mm: init.c 
        arch/um/include: choose-mode.h 
        arch/x86_64/ia32: ia32_binfmt.c syscall32.c vsyscall-sigreturn.S 
        arch/x86_64/kernel: aperture.c apic.c e820.c entry.S genapic.c 
                            head.S i8259.c io_apic.c mce.c nmi.c 
                            ptrace.c setup.c signal.c smp.c smpboot.c 
                            time.c traps.c 
        arch/x86_64/mm : fault.c init.c 
        crypto         : deflate.c 
        drivers/base   : class.c core.c firmware_class.c platform.c 
                         sys.c 
        drivers/block  : Kconfig ll_rw_blk.c scsi_ioctl.c 
        drivers/block/aoe: aoe.h aoeblk.c aoecmd.c aoedev.c aoenet.c 
        drivers/char   : mmtimer.c random.c s3c2410-rtc.c sonypi.c 
        drivers/char/agp: efficeon-agp.c uninorth-agp.c 
        drivers/char/drm: r128_state.c 
        drivers/char/tpm: tpm.c tpm.h 
        drivers/i2c/busses: Kconfig i2c-i801.c 
        drivers/i2c/chips: it87.c via686a.c 
        drivers/ide/legacy: hd.c 
        drivers/ide/pci: piix.c sc1200.c 
        drivers/infiniband/core: agent.c fmr_pool.c mad.c mad_priv.h 
                                 user_mad.c 
        drivers/infiniband/hw/mthca: mthca_av.c mthca_cmd.c mthca_cmd.h 
                                     mthca_cq.c mthca_dev.h 
                                     mthca_doorbell.h mthca_eq.c 
                                     mthca_main.c mthca_memfree.c 
                                     mthca_memfree.h mthca_mr.c 
                                     mthca_profile.c mthca_profile.h 
                                     mthca_provider.c mthca_provider.h 
                                     mthca_qp.c mthca_reset.c 
        drivers/infiniband/ulp/ipoib: ipoib_fs.c ipoib_ib.c ipoib_main.c 
                                      ipoib_multicast.c 
        drivers/macintosh: macio_asic.c mediabay.c via-pmu.c 
        drivers/md     : md.c 
        drivers/media/dvb/cinergyT2: cinergyT2.c 
        drivers/media/video: bttv-cards.c meye.c msp3400.c tda9887.c 
                             tuner-core.c 
        drivers/message/fusion: mptbase.c mptbase.h mptscsih.c 
        drivers/message/i2o: i2o_config.c 
        drivers/mmc    : mmc.c mmci.c pxamci.c wbsd.c 
        drivers/mtd/maps: sa1100-flash.c 
        drivers/net    : 8139cp.c Kconfig bmac.c mv643xx_eth.c 
                         pci-skeleton.c r8169.c smc91x.c typhoon.c 
        drivers/net/irda: Kconfig sa1100_ir.c stir4200.c vlsi_ir.c 
        drivers/net/tulip: de2104x.c winbond-840.c xircom_tulip_cb.c 
        drivers/net/wireless: airo.c airport.c orinoco_pci.c 
        drivers/net/wireless/prism54: islpci_hotplug.c 
        drivers/pci    : quirks.c 
        drivers/pci/hotplug: pciehp_core.c 
        drivers/pci/pcie: portdrv.h portdrv_bus.c portdrv_core.c 
                          portdrv_pci.c 
        drivers/pcmcia : au1000_generic.c hd64465_ss.c m32r_cfc.c 
                         m32r_pcc.c pxa2xx_base.c sa1100_generic.c 
                         sa1111_generic.c 
        drivers/pnp/pnpbios: core.c 
        drivers/s390/scsi: zfcp_aux.c zfcp_def.h zfcp_erp.c zfcp_fsf.c 
                           zfcp_fsf.h zfcp_sysfs_adapter.c 
        drivers/scsi   : 53c700.c 53c700.h 53c7xx.c BusLogic.c Kconfig 
                         Makefile NCR5380.c NCR_D700.c advansys.c 
                         aha152x.c ahci.c aic7xxx_old.c ata_piix.c 
                         atari_NCR5380.c constants.c cpqfcTSinit.c 
                         cpqfcTSworker.c gdth.c gdth.h ips.c lasi700.c 
                         libata-scsi.c mesh.c ncr53c8xx.c nsp32.c 
                         pci2000.c qlogicfc.c qlogicisp.c scsi.c scsi.h 
                         scsi_error.c scsi_ioctl.c scsi_lib.c 
                         scsi_priv.h scsi_scan.c scsi_sysfs.c seagate.c 
                         sg.c sim710.c sun3_NCR5380.c ultrastor.c 
        drivers/scsi/aic7xxx: Kconfig.aic7xxx aic79xx_osm.c 
                              aic7xxx_osm.c aic7xxx_osm.h cam.h 
        drivers/scsi/arm: acornscsi.c fas216.c scsi.h 
        drivers/scsi/qla2xxx: Makefile qla_dbg.c qla_def.h qla_gbl.h 
                              qla_init.c qla_inline.h qla_iocb.c 
                              qla_isr.c qla_mbx.c qla_os.c qla_version.h 
        drivers/scsi/sym53c8xx_2: sym_glue.c 
        drivers/serial : 8250.c amba-pl010.c imx.c pmac_zilog.c pxa.c 
                         s3c2410.c sa1100.c serial_txx9.c 
        drivers/serial/jsm: jsm.h jsm_driver.c jsm_tty.c 
        drivers/usb/class: audio.c bluetty.c 
        drivers/usb/core: config.c devices.c devio.c file.c hcd-pci.c 
                          hcd.h hub.c inode.c message.c urb.c usb.c 
                          usb.h 
        drivers/usb/gadget: ether.c omap_udc.c rndis.c rndis.h serial.c 
        drivers/usb/host: ehci-dbg.c ehci-hcd.c ehci-mem.c ehci-sched.c 
                          ehci.h hc_crisv10.c ohci-omap.c ohci-pci.c 
                          ohci-pxa27x.c ohci-q.c ohci.h uhci-hcd.c 
        drivers/usb/image: microtek.c 
        drivers/usb/input: aiptek.c hid-core.c 
        drivers/usb/media: dabusb.c ov511.c se401.c usbvideo.c w9968cf.c 
        drivers/usb/misc: auerswald.c 
        drivers/usb/misc/sisusbvga: sisusb.c 
        drivers/usb/net: pegasus.c usbnet.c zd1201.c 
        drivers/usb/serial: belkin_sa.c cypress_m8.c digi_acceleport.c 
                            empeg.c ftdi_sio.c io_edgeport.c io_ti.c 
                            kl5kusb105.c omninet.c pl2303.c pl2303.h 
                            ti_usb_3410_5052.c visor.c visor.h 
        drivers/usb/storage: sddr55.c transport.c unusual_devs.h 
        drivers/video  : pxafb.c sa1100fb.c w100fb.c 
        drivers/video/aty: aty128fb.c radeon_pm.c 
        drivers/video/backlight: corgi_bl.c 
        drivers/video/savage: savagefb_driver.c 
        drivers/w1     : w1.c w1_smem.c 
        fs             : binfmt_elf.c buffer.c char_dev.c compat.c 
                         direct-io.c dquot.c fcntl.c quota_v2.c 
                         read_write.c 
        fs/ext2        : acl.c ext2.h inode.c super.c 
        fs/ext3        : acl.c 
        fs/jbd         : transaction.c 
        fs/nfsd        : nfs4callback.c nfs4state.c nfssvc.c 
        fs/partitions  : check.c 
        fs/proc        : base.c proc_misc.c 
        fs/sysfs       : file.c 
        include/asm-alpha: pgtable.h 
        include/asm-arm: dma-mapping.h pgtable.h ptrace.h system.h 
        include/asm-arm/arch-ebsa285: debug-macro.S 
        include/asm-arm/arch-rpc: debug-macro.S 
        include/asm-arm26: pgtable.h 
        include/asm-cris: pgtable.h 
        include/asm-frv: pgtable.h 
        include/asm-generic: iomap.h pgtable.h 
        include/asm-h8300: page.h unistd.h 
        include/asm-i386: pgtable.h processor.h smp.h suspend.h 
        include/asm-ia64: page.h pgtable.h processor.h 
        include/asm-m32r: pgtable.h 
        include/asm-m68k: pgtable.h setup.h 
        include/asm-mips: pgtable-32.h pgtable-64.h 
        include/asm-parisc: pgtable.h 
        include/asm-ppc: cputable.h dbdma.h keylargo.h macio.h mmu.h 
                         ocp.h of_device.h open_pic.h pgtable.h 
                         pmac_feature.h prom.h reg.h reg_booke.h 
        include/asm-ppc64: pgtable.h processor.h vdso.h 
        include/asm-s390: pgtable.h processor.h 
        include/asm-sh : bus-sh.h pgtable.h 
        include/asm-sh64: pgtable.h 
        include/asm-sparc: pgtable.h unistd.h 
        include/asm-sparc64: cacheflush.h compat.h pgtable.h stat.h 
                             unistd.h 
        include/asm-um : pgtable-2level.h pgtable-3level.h 
        include/asm-x86_64: bug.h cpufeature.h e820.h kdebug.h local.h 
                            msr.h pgtable.h processor.h proto.h ptrace.h 
                            smp.h unistd.h 
        include/linux  : atalk.h blkdev.h cpuset.h debugfs.h hugetlb.h 
                         ioctl32.h list.h mm.h pci.h pci_ids.h 
                         pcieport_if.h sched.h skbuff.h sysdev.h sysfs.h 
                         usb.h usb_cdc.h workqueue.h 
        include/linux/mmc: host.h 
        include/net    : dst.h 
        include/net/irda: irda_device.h 
        include/scsi   : scsi.h scsi_cmnd.h scsi_device.h scsi_host.h 
        kernel         : auditsc.c compat.c cpuset.c exit.c params.c 
                         resource.c sched.c signal.c workqueue.c 
        kernel/power   : smp.c 
        lib            : iomap.c kobject.c 
        mm             : filemap.c memory.c mincore.c mmap.c oom_kill.c 
                         vmscan.c 
        net/appletalk  : ddp.c 
        net/bridge     : br_sysfs_if.c 
        net/core       : dst.c rtnetlink.c skbuff.c sock.c 
        net/ipv4       : route.c udp.c 
        net/ipv6       : addrconf.c ip6_output.c raw.c 
        net/irda       : irda_device.c 
        scripts        : ver_linux 
        security/selinux: avc.c hooks.c nlmsgtab.c 
        security/selinux/include: av_inherit.h av_perm_to_string.h 
                                  av_permissions.h class_to_string.h 
                                  flask.h 
        sound/core     : init.c 
        sound/oss      : Kconfig cs46xx.c opl3sa2.c 
        sound/pci      : atiixp_modem.c intel8x0.c 
        sound/ppc      : beep.c pmac.c pmac.h tumbler.c 
Added files:
        Documentation  : dontdiff kref.txt 
        Documentation/aoe: todo.txt 
        Documentation/scsi: ChangeLog.lpfc lpfc.txt 
        arch/arm/lib   : bitops.h 
        arch/i386/kernel: vsyscall-note.S 
        drivers/scsi/lpfc: Makefile lpfc.h lpfc_attr.c lpfc_compat.h 
                           lpfc_crtn.h lpfc_ct.c lpfc_disc.h lpfc_els.c 
                           lpfc_hbadisc.c lpfc_hw.h lpfc_init.c 
                           lpfc_logmsg.h lpfc_mbox.c lpfc_mem.c 
                           lpfc_nportdisc.c lpfc_scsi.c lpfc_scsi.h 
                           lpfc_sli.c lpfc_sli.h lpfc_version.h 
        drivers/scsi/qla2xxx: qla_attr.c 
Removed files:
        Documentation/scsi: qla2xxx.revision.notes 
        drivers/scsi   : scsi_obsolete.h 
        drivers/scsi/qla2xxx: qla_listops.h 

Log message:
        Merge with Linux 2.6.12-rc3.

diff -urN linux/CREDITS linux/CREDITS
--- linux/CREDITS       2005/03/18 17:36:42     1.141
+++ linux/CREDITS       2005/04/29 11:14:59     1.142
@@ -1958,7 +1958,8 @@
 N: Colin Leroy
 E: colin@colino.net
 W: http://www.geekounet.org/
-D: PowerMac adt7467 fan driver
+D: PowerMac adt746x fan driver
+D: Random fixing of various drivers (macintosh, usb, sound)
 S: Toulouse
 S: France
 
@@ -3298,6 +3299,7 @@
 D: Author of job control and system call restart code
 D: Author of ramdisk device driver
 D: Author of loopback device driver
+D: Author of /dev/random driver
 S: MIT Room E40-343
 S: 1 Amherst Street
 S: Cambridge, Massachusetts 02139
diff -urN linux/MAINTAINERS linux/MAINTAINERS
--- linux/MAINTAINERS   2005/04/08 18:57:41     1.178
+++ linux/MAINTAINERS   2005/04/29 11:14:59     1.179
@@ -73,7 +73,7 @@
 3C359 NETWORK DRIVER
 P:     Mike Phillips
 M:     mikep@linuxtr.net
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 L:     linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
@@ -81,13 +81,13 @@
 3C505 NETWORK DRIVER
 P:     Philip Blundell
 M:     philb@gnu.org
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 3CR990 NETWORK DRIVER
 P:     David Dillow
 M:     dave@thedillows.org
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 3W-XXXX ATA-RAID CONTROLLER DRIVER
@@ -143,7 +143,7 @@
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 P:     Paul Gortmaker
 M:     p_gortmaker@yahoo.com
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 A2232 SERIAL BOARD DRIVER
@@ -172,14 +172,6 @@
 W:     http://www.stud.uni-karlsruhe.de/~uh1b/
 S:     Maintained
 
-ACP/MWAVE MODEM
-P:     Paul B Schroeder
-M:     paulsch@us.ibm.com
-P:     Mike Sullivan
-M:     sullivam@us.ibm.com
-W:     http://www.ibm.com/linux/ltc/
-S:     Supported
-
 AACRAID SCSI RAID DRIVER
 P:     Adaptec OEM Raid Solutions
 L:     linux-scsi@vger.kernel.org
@@ -334,7 +326,7 @@
 
 ARPD SUPPORT
 P:     Jonathan Layes
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 ASUS ACPI EXTRAS DRIVER
@@ -708,7 +700,7 @@
 
 DIGI RIGHTSWITCH NETWORK DRIVER
 P:     Rick Richardson
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 W:     http://www.digi.com
 S:     Orphaned
 
@@ -814,7 +806,7 @@
 ETHEREXPRESS-16 NETWORK DRIVER
 P:     Philip Blundell
 M:     philb@gnu.org
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 ETHERNET BRIDGE
@@ -877,7 +869,7 @@
 FRAME RELAY DLCI/FRAD (Sangoma drivers too)
 P:     Mike McLagan
 M:     mike.mclagan@linux.org
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 FREEVXFS FILESYSTEM
@@ -1217,7 +1209,7 @@
 IPX NETWORK LAYER
 P:     Arnaldo Carvalho de Melo
 M:     acme@conectiva.com.br
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 IRDA SUBSYSTEM
@@ -1594,13 +1586,13 @@
 M:     akpm@osdl.org
 P:     Jeff Garzik
 M:     jgarzik@pobox.com
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 NETWORKING [GENERAL]
 P:     Networking Team
 M:     netdev@oss.sgi.com
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 NETWORKING [IPv4/IPv6]
@@ -1636,7 +1628,7 @@
 P:     Jan-Pascal van Best and Andreas Mohr
 M:     Jan-Pascal van Best <jvbest@qv3pluto.leidenuniv.nl>
 M:     Andreas Mohr <100.30936@germany.net>
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER
@@ -1678,7 +1670,7 @@
 M:     p2@ace.ulyssis.student.kuleuven.ac.be
 P:     Mike Phillips
 M:     mikep@linuxtr.net 
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 L:     linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
@@ -1783,7 +1775,7 @@
 PCNET32 NETWORK DRIVER
 P:     Thomas Bogendörfer
 M:     tsbogend@alpha.franken.de
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 PHRAM MTD DRIVER
@@ -1795,7 +1787,7 @@
 POSIX CLOCKS and TIMERS
 P:     George Anzinger
 M:     george@mvista.com
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Supported
 
 PNP SUPPORT
@@ -1860,14 +1852,14 @@
 S:     Maintained
 
 RADEON FRAMEBUFFER DISPLAY DRIVER
-P:     Ani Joshi
-M:     ajoshi@shell.unixbox.com
+P:     Benjamin Herrenschmidt
+M:     benh@kernel.crashing.org
 L:     linux-fbdev-devel@lists.sourceforge.net
 S:     Maintained
 
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
-P:     Ani Joshi
-M:     ajoshi@shell.unixbox.com
+P:     Paul Mackerras
+M:     paulus@samba.org
 L:     linux-fbdev-devel@lists.sourceforge.net
 S:     Maintained
 
@@ -1877,6 +1869,11 @@
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+RANDOM NUMBER DRIVER
+P:     Matt Mackall
+M:     mpm@selenic.com
+S:     Maintained
+
 REAL TIME CLOCK DRIVER
 P:     Paul Gortmaker
 M:     p_gortmaker@yahoo.com
@@ -2042,7 +2039,7 @@
 P:     Daniele Venzano
 M:     venza@brownhat.org
 W:     http://www.brownhat.org/sis900.html
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 SIS FRAMEBUFFER DRIVER
@@ -2101,7 +2098,7 @@
 SONIC NETWORK DRIVER
 P:     Thomas Bogendoerfer
 M:     tsbogend@alpha.franken.de
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Maintained
 
 SONY VAIO CONTROL DEVICE DRIVER
@@ -2151,7 +2148,7 @@
 SPX NETWORK LAYER
 P:     Jay Schulist
 M:     jschlst@samba.org
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 S:     Supported
 
 SRM (Alpha) environment access
@@ -2230,7 +2227,7 @@
 TOKEN-RING NETWORK DRIVER
 P:     Mike Phillips
 M:     mikep@linuxtr.net
-L:     linux-net@vger.kernel.org
+L:     netdev@oss.sgi.com
 L:     linux-tr@linuxtr.net
 W:     http://www.linuxtr.net
 S:     Maintained
diff -urN linux/Makefile linux/Makefile
--- linux/Makefile      2005/04/08 18:57:41     1.249
+++ linux/Makefile      2005/04/29 11:14:59     1.250
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 12
-EXTRAVERSION =-rc2
+EXTRAVERSION =-rc3
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
diff -urN linux/Documentation/dontdiff linux/Documentation/dontdiff
--- linux/Documentation/dontdiff        1970/01/01 00:00:00
+++ linux/Documentation/dontdiff        2005-04-29 12:14:59.473455000 +0100     
1.1
@@ -0,0 +1,137 @@
+.*
+*~
+53c8xx_d.h*
+*.a
+aic7*reg.h*
+aic7*seq.h*
+aic7*reg_print.c*
+53c700_d.h
+aicasm
+aicdb.h*
+asm
+asm_offsets.*
+autoconf.h*
+*.aux
+bbootsect
+*.bin
+bin2c
+binkernel.spec
+BitKeeper
+bootsect
+bsetup
+btfixupprep
+build
+bvmlinux
+bzImage*
+ChangeSet
+classlist.h*
+compile.h*
+comp*.log
+config
+config-*
+config_data.h*
+conmakehash
+consolemap_deftbl.c*
+COPYING
+CREDITS
+.cscope
+*cscope*
+cscope.*
+*.out
+*.css
+CVS
+defkeymap.c*
+devlist.h*
+docproc
+dummy_sym.c*
+*.dvi
+*.eps
+filelist
+fixdep
+fore200e_mkfirm
+fore200e_pca_fw.c*
+gen-devlist
+gen_init_cpio
+gen_crc32table
+crc32table.h*
+*.cpio
+gen-kdb_cmds.c*
+gentbl
+genksyms
+*.gif
+*.gz
+*.html
+ikconfig.h*
+initramfs_list
+*.jpeg
+kconfig
+kconfig.tk
+Kerntypes
+keywords.c*
+ksym.c*
+ksym.h*
+kallsyms
+mk_elfconfig
+elfconfig.h*
+modpost
+pnmtologo
+logo_*.c
+*.log
+lex.c*
+logo_*_clut224.c
+logo_*_mono.c
+lxdialog
+make_times_h
+map
+mkdep
+*_MODULES
+MODS.txt
+modversions.h*
+Module.symvers
+*.mod.c
+*.o
+*.ko
+*.orig
+*.lst
+*.grp
+*.grep
+oui.c*
+mktables
+raid6tables.c
+raid6int*.c
+raid6altivec*.c
+wanxlfw.inc
+maui_boot.h
+pss_boot.h
+trix_boot.h
+*.pdf
+parse.c*
+parse.h*
+PENDING
+ppc_defs.h*
+promcon_tbl.c*
+*.png
+*.ps
+*.rej
+SCCS
+setup
+*.s
+*.so
+*.sgml
+sim710_d.h*
+sm_tbl*
+split-include
+System.map*
+tags
+TAGS
+*.tex
+times.h*
+tkparse
+*.ver
+version.h*
+*_vga16.c
+vmlinux
+vmlinux.lds
+vmlinux-*
+vsyscall.lds
+zImage
diff -urN linux/Documentation/kref.txt linux/Documentation/kref.txt
--- linux/Documentation/kref.txt        1970/01/01 00:00:00
+++ linux/Documentation/kref.txt        2005-04-29 12:14:59.485258000 +0100     
1.1
@@ -0,0 +1,216 @@
+
+krefs allow you to add reference counters to your objects.  If you
+have objects that are used in multiple places and passed around, and
+you don't have refcounts, your code is almost certainly broken.  If
+you want refcounts, krefs are the way to go.
+
+To use a kref, add one to your data structures like:
+
+struct my_data
+{
+       .
+       .
+       struct kref refcount;
+       .
+       .
+};
+
+The kref can occur anywhere within the data structure.
+
+You must initialize the kref after you allocate it.  To do this, call
+kref_init as so:
+
+     struct my_data *data;
+
+     data = kmalloc(sizeof(*data), GFP_KERNEL);
+     if (!data)
+            return -ENOMEM;
+     kref_init(&data->refcount);
+
+This sets the refcount in the kref to 1.
+
+Once you have an initialized kref, you must follow the following
+rules:
+
+1) If you make a non-temporary copy of a pointer, especially if
+   it can be passed to another thread of execution, you must
+   increment the refcount with kref_get() before passing it off:
+       kref_get(&data->refcount);
+   If you already have a valid pointer to a kref-ed structure (the
+   refcount cannot go to zero) you may do this without a lock.
+
+2) When you are done with a pointer, you must call kref_put():
+       kref_put(&data->refcount, data_release);
+   If this is the last reference to the pointer, the release
+   routine will be called.  If the code never tries to get
+   a valid pointer to a kref-ed structure without already
+   holding a valid pointer, it is safe to do this without
+   a lock.
+
+3) If the code attempts to gain a reference to a kref-ed structure
+   without already holding a valid pointer, it must serialize access
+   where a kref_put() cannot occur during the kref_get(), and the
+   structure must remain valid during the kref_get().
+
+For example, if you allocate some data and then pass it to another
+thread to process:
+
+void data_release(struct kref *ref)
+{
+       struct my_data *data = container_of(ref, struct my_data, refcount);
+       kfree(data);
+}
+
+void more_data_handling(void *cb_data)
+{
+       struct my_data *data = cb_data;
+       .
+       . do stuff with data here
+       .
+       kref_put(data, data_release);
+}
+
+int my_data_handler(void)
+{
+       int rv = 0;
+       struct my_data *data;
+       struct task_struct *task;
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       kref_init(&data->refcount);
+
+       kref_get(&data->refcount);
+       task = kthread_run(more_data_handling, data, "more_data_handling");
+       if (task == ERR_PTR(-ENOMEM)) {
+               rv = -ENOMEM;
+               kref_put(&data->refcount, data_release);
+               goto out;
+       }
+
+       .
+       . do stuff with data here
+       .
+ out:
+       kref_put(&data->refcount, data_release);
+       return rv;
+}
+
+This way, it doesn't matter what order the two threads handle the
+data, the kref_put() handles knowing when the data is not referenced
+any more and releasing it.  The kref_get() does not require a lock,
+since we already have a valid pointer that we own a refcount for.  The
+put needs no lock because nothing tries to get the data without
+already holding a pointer.
+
+Note that the "before" in rule 1 is very important.  You should never
+do something like:
+
+       task = kthread_run(more_data_handling, data, "more_data_handling");
+       if (task == ERR_PTR(-ENOMEM)) {
+               rv = -ENOMEM;
+               goto out;
+       } else
+               /* BAD BAD BAD - get is after the handoff */
+               kref_get(&data->refcount);
+
+Don't assume you know what you are doing and use the above construct.
+First of all, you may not know what you are doing.  Second, you may
+know what you are doing (there are some situations where locking is
+involved where the above may be legal) but someone else who doesn't
+know what they are doing may change the code or copy the code.  It's
+bad style.  Don't do it.
+
+There are some situations where you can optimize the gets and puts.
+For instance, if you are done with an object and enqueuing it for
+something else or passing it off to something else, there is no reason
+to do a get then a put:
+
+       /* Silly extra get and put */
+       kref_get(&obj->ref);
+       enqueue(obj);
+       kref_put(&obj->ref, obj_cleanup);
+
+Just do the enqueue.  A comment about this is always welcome:
+
+       enqueue(obj);
+       /* We are done with obj, so we pass our refcount off
+          to the queue.  DON'T TOUCH obj AFTER HERE! */
+
+The last rule (rule 3) is the nastiest one to handle.  Say, for
+instance, you have a list of items that are each kref-ed, and you wish
+to get the first one.  You can't just pull the first item off the list
+and kref_get() it.  That violates rule 3 because you are not already
+holding a valid pointer.  You must add locks or semaphores.  For
+instance:
+
+static DECLARE_MUTEX(sem);
+static LIST_HEAD(q);
+struct my_data
+{
+       struct kref      refcount;
+       struct list_head link;
+};
+
+static struct my_data *get_entry()
+{
+       struct my_data *entry = NULL;
+       down(&sem);
+       if (!list_empty(&q)) {
+               entry = container_of(q.next, struct my_q_entry, link);
+               kref_get(&entry->refcount);
+       }
+       up(&sem);
+       return entry;
+}
+
+static void release_entry(struct kref *ref)
+{
+       struct my_data *entry = container_of(ref, struct my_data, refcount);
+
+       list_del(&entry->link);
+       kfree(entry);
+}
+
+static void put_entry(struct my_data *entry)
+{
+       down(&sem);
+       kref_put(&entry->refcount, release_entry);
+       up(&sem);
+}
+
+The kref_put() return value is useful if you do not want to hold the
+lock during the whole release operation.  Say you didn't want to call
+kfree() with the lock held in the example above (since it is kind of
+pointless to do so).  You could use kref_put() as follows:
+
+static void release_entry(struct kref *ref)
+{
+       /* All work is done after the return from kref_put(). */
+}
+
+static void put_entry(struct my_data *entry)
+{
+       down(&sem);
+       if (kref_put(&entry->refcount, release_entry)) {
+               list_del(&entry->link);
+               up(&sem);
+               kfree(entry);
+       } else
+               up(&sem);
+}
+
+This is really more useful if you have to call other routines as part
+of the free operations that could take a long time or might claim the
+same lock.  Note that doing everything in the release routine is still
+preferred as it is a little neater.
+
+
+Corey Minyard <minyard@acm.org>
+
+A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and
+presentation on krefs, which can be found at:
+  
http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf
+and:
+  http://www.kroah.com/linux/talks/ols_2004_kref_talk/
+
diff -urN linux/Documentation/DMA-mapping.txt 
linux/Documentation/DMA-mapping.txt
--- linux/Documentation/DMA-mapping.txt 2004/08/06 00:33:21     1.24
+++ linux/Documentation/DMA-mapping.txt 2005/04/29 11:14:59     1.25
@@ -443,15 +443,9 @@
 implicitly have a direction attribute setting of
 PCI_DMA_BIDIRECTIONAL.
 
-The SCSI subsystem provides mechanisms for you to easily obtain
-the direction to use, in the SCSI command:
-
-       scsi_to_pci_dma_dir(SCSI_DIRECTION)
-
-Where SCSI_DIRECTION is obtained from the 'sc_data_direction'
-member of the SCSI command your driver is working on.  The
-mentioned interface above returns a value suitable for passing
-into the streaming DMA mapping interfaces below.
+The SCSI subsystem tells you the direction to use in the
+'sc_data_direction' member of the SCSI command your driver is
+working on.
 
 For Networking drivers, it's a rather simple affair.  For transmit
 packets, map/unmap them with the PCI_DMA_TODEVICE direction
diff -urN linux/Documentation/feature-removal-schedule.txt 
linux/Documentation/feature-removal-schedule.txt
--- linux/Documentation/feature-removal-schedule.txt    2005/04/08 18:57:46     
1.4
+++ linux/Documentation/feature-removal-schedule.txt    2005/04/29 11:14:59     
1.5
@@ -40,3 +40,11 @@
        addressabilty (by using a pfn) and supports sparc & sparc64
        iospace as part of the pfn.
 Who:   Randy Dunlap <rddunlap@osdl.org>
+
+---------------------------
+
+What:  register_ioctl32_conversion() / unregister_ioctl32_conversion()
+When:  April 2005
+Why:   Replaced by ->compat_ioctl in file_operations and other method
+       vecors.
+Who:   Andi Kleen <ak@muc.de>, Christoph Hellwig <hch@lst.de>
diff -urN linux/Documentation/aoe/todo.txt linux/Documentation/aoe/todo.txt
--- linux/Documentation/aoe/todo.txt    1970/01/01 00:00:00
+++ linux/Documentation/aoe/todo.txt    2005-04-29 12:14:59.587465000 +0100     
1.1
@@ -0,0 +1,14 @@
+There is a potential for deadlock when allocating a struct sk_buff for
+data that needs to be written out to aoe storage.  If the data is
+being written from a dirty page in order to free that page, and if
+there are no other pages available, then deadlock may occur when a
+free page is needed for the sk_buff allocation.  This situation has
+not been observed, but it would be nice to eliminate any potential for
+deadlock under memory pressure.
+
+Because ATA over Ethernet is not fragmented by the kernel's IP code,
+the destructore member of the struct sk_buff is available to the aoe
+driver.  By using a mempool for allocating all but the first few
+sk_buffs, and by registering a destructor, we should be able to
+efficiently allocate sk_buffs without introducing any potential for
+deadlock.
diff -urN linux/Documentation/aoe/mkdevs.sh linux/Documentation/aoe/mkdevs.sh
--- linux/Documentation/aoe/mkdevs.sh   2005/01/25 04:27:51     1.2
+++ linux/Documentation/aoe/mkdevs.sh   2005/04/29 11:14:59     1.3
@@ -5,6 +5,7 @@
 
 if test "$#" != "1"; then
        echo "Usage: sh `basename $0` {dir}" 1>&2
+       echo "       n_partitions=16 sh `basename $0` {dir}" 1>&2
        exit 1
 fi
 dir=$1
diff -urN linux/Documentation/aoe/mkshelf.sh linux/Documentation/aoe/mkshelf.sh
--- linux/Documentation/aoe/mkshelf.sh  2005/01/25 04:27:51     1.2
+++ linux/Documentation/aoe/mkshelf.sh  2005/04/29 11:14:59     1.3
@@ -2,6 +2,7 @@
 
 if test "$#" != "2"; then
        echo "Usage: sh `basename $0` {dir} {shelfaddress}" 1>&2
+       echo "       n_partitions=16 sh `basename $0` {dir} {shelfaddress}" 1>&2
        exit 1
 fi
 n_partitions=${n_partitions:-16}
diff -urN linux/Documentation/aoe/udev-install.sh 
linux/Documentation/aoe/udev-install.sh
--- linux/Documentation/aoe/udev-install.sh     2005/03/18 17:36:43     1.1
+++ linux/Documentation/aoe/udev-install.sh     2005/04/29 11:14:59     1.2
@@ -23,4 +23,8 @@
 # /etc/udev/rules.d
 #
 rules_d="`sed -n '/^udev_rules=/{ s!udev_rules=!!; s!\"!!g; p; }' $conf`"
-test "$rules_d" && sh -xc "cp `dirname $0`/udev.txt $rules_d/60-aoe.rules"
+if test -z "$rules_d" || test ! -d "$rules_d"; then
+       echo "$me Error: cannot find udev rules directory" 1>&2
+       exit 1
+fi
+sh -xc "cp `dirname $0`/udev.txt $rules_d/60-aoe.rules"
diff -urN linux/Documentation/driver-model/bus.txt 
linux/Documentation/driver-model/bus.txt
--- linux/Documentation/driver-model/bus.txt    2004/09/19 12:30:00     1.5
+++ linux/Documentation/driver-model/bus.txt    2005/04/29 11:14:59     1.6
@@ -18,7 +18,7 @@
        int             (*match)(struct device * dev, struct device_driver * 
drv);
        int             (*hotplug) (struct device *dev, char **envp, 
                                    int num_envp, char *buffer, int 
buffer_size);
-       int             (*suspend)(struct device * dev, u32 state);
+       int             (*suspend)(struct device * dev, pm_message_t state);
        int             (*resume)(struct device * dev);
 };
 
diff -urN linux/Documentation/driver-model/driver.txt 
linux/Documentation/driver-model/driver.txt
--- linux/Documentation/driver-model/driver.txt 2003/06/05 18:23:57     1.5
+++ linux/Documentation/driver-model/driver.txt 2005/04/29 11:14:59     1.6
@@ -16,7 +16,7 @@
         int     (*probe)        (struct device * dev);
         int     (*remove)       (struct device * dev);
 
-        int     (*suspend)      (struct device * dev, u32 state, u32 level);
+        int     (*suspend)      (struct device * dev, pm_message_t state, u32 
level);
         int     (*resume)       (struct device * dev, u32 level);
 
         void    (*release)      (struct device_driver * drv);
@@ -195,7 +195,7 @@
 If the device is still present, it should quiesce the device and place
 it into a supported low-power state.
 
-       int     (*suspend)      (struct device * dev, u32 state, u32 level);
+       int     (*suspend)      (struct device * dev, pm_message_t state, u32 
level);
 
 suspend is called to put the device in a low power state. There are
 several stages to successfully suspending a device, which is denoted in
diff -urN linux/Documentation/infiniband/ipoib.txt 
linux/Documentation/infiniband/ipoib.txt
--- linux/Documentation/infiniband/ipoib.txt    2005/01/13 14:05:16     1.1
+++ linux/Documentation/infiniband/ipoib.txt    2005/04/29 11:14:59     1.2
@@ -32,14 +32,13 @@
   mcast_debug_level to 1.  These parameters can be controlled at
   runtime through files in /sys/module/ib_ipoib/.
 
-  CONFIG_INFINIBAND_IPOIB_DEBUG also enables the "ipoib_debugfs"
+  CONFIG_INFINIBAND_IPOIB_DEBUG also enables files in the debugfs
   virtual filesystem.  By mounting this filesystem, for example with
 
-    mkdir -p /ipoib_debugfs
-    mount -t ipoib_debugfs none /ipoib_debufs
+    mount -t debugfs none /sys/kernel/debug
 
   it is possible to get statistics about multicast groups from the
-  files /ipoib_debugfs/ib0_mcg and so on.
+  files /sys/kernel/debug/ipoib/ib0_mcg and so on.
 
   The performance impact of this option is negligible, so it
   is safe to enable this option with debug_level set to 0 for normal
diff -urN linux/Documentation/power/video.txt 
linux/Documentation/power/video.txt
--- linux/Documentation/power/video.txt 2005/04/08 18:57:47     1.7
+++ linux/Documentation/power/video.txt 2005/04/29 11:14:59     1.8
@@ -32,9 +32,9 @@
   acpi_sleep=s3_bios,s3_mode is needed.
 
 (5) radeon systems, where X can soft-boot your video card. You'll need
-  new enough X, and plain text console (no vesafb or radeonfb), see
-  http://www.doesi.gmxhome.de/linux/tm800s3/s3.html. Actually you
-  should probably use vbetool (6) instead.
+  a new enough X, and a plain text console (no vesafb or radeonfb). See
+  http://www.doesi.gmxhome.de/linux/tm800s3/s3.html for more information.
+  Alternatively, you should use vbetool (6) instead.
 
 (6) other radeon systems, where vbetool is enough to bring system back
   to life. It needs text console to be working. Do vbetool vbestate
@@ -74,8 +74,9 @@
 Acer TM 803LCi                 vga=normal, vbetool (6)
 Arima W730a                    vbetool needed (6)
 Asus L2400D                     s3_mode (3)(***) (S1 also works OK)
+Asus L3350M (SiS 740)           (6)
 Asus L3800C (Radeon M7)                s3_bios (2) (S1 also works OK)
-Asus M6NE                      ??? (*)
+Asus M6887Ne                   vga=normal, s3_bios (2), use radeon driver 
instead of fglrx in x.org
 Athlon64 desktop prototype     s3_bios (2)
 Compal CL-50                   ??? (*)
 Compaq Armada E500 - P3-700     none (1) (S1 also works OK)
@@ -99,16 +100,16 @@
 IBM TP R32 / Type 2658-MMG      none (1)
 IBM TP R40 2722B3G             ??? (*)
 IBM TP R50p / Type 1832-22U     s3_bios (2)
-IBM TP R51                     ??? (*)
+IBM TP R51                     none (1)
 IBM TP T30     236681A         ??? (*)
 IBM TP T40 / Type 2373-MU4      none (1)
 IBM TP T40p                    none (1)
 IBM TP R40p                    s3_bios (2)
 IBM TP T41p                    s3_bios (2), switch to X after resume
-IBM TP T42                     ??? (*)
+IBM TP T42                     s3_bios (2)
 IBM ThinkPad T42p (2373-GTG)   s3_bios (2)
 IBM TP X20                     ??? (*)
-IBM TP X30                     ??? (*)
+IBM TP X30                     s3_bios (2)
 IBM TP X31 / Type 2672-XXH      none (1), use radeontool 
(http://fdd.com/software/radeon/) to turn off backlight.
 IBM Thinkpad X40 Type 2371-7JG  s3_bios,s3_mode (4)
 Medion MD4220                  ??? (*)
diff -urN linux/Documentation/scsi/ChangeLog.lpfc 
linux/Documentation/scsi/ChangeLog.lpfc
--- linux/Documentation/scsi/ChangeLog.lpfc     1970/01/01 00:00:00
+++ linux/Documentation/scsi/ChangeLog.lpfc     2005-04-29 12:14:59.922403000 
+0100     1.1
@@ -0,0 +1,1865 @@
+Known issues :
+       * Please read the associated RELEASE-NOTES file !!!
+       * This source release intended for upstream kernel releases only!
+
+Changes from 20050323 to 20050413
+
+       * Changed version number to 8.0.28
+       * Fixed build warning for 2.6.12-rc2 kernels: mempool_alloc now
+         requires a function which takes an unsigned int for gfp_flags.
+       * Removed pci dma sync calls to coherent/consistent pci memory.
+       * Merged patch from Christoph Hellwig <hch@lst.de>: split helpers
+         for fabric and nport logins out of lpfc_cmpl_els_flogi.
+       * Removed sysfs attributes that are used to dump the various
+         discovery lists.
+       * Fix for issue where not all luns are seen.  Search all lists
+         other than unmap list in lpfc_find_target().  Otherwise INQUIRY
+         to luns on nodes in NPR or other relevant states (PLOGI,
+         PRLI...) are errored back and scan() terminates.
+       * Removed FC_TRANSPORT_PATCHESxxx defines.  They're in 2.6.12-rc1.
+       * Compare return value of lpfc_scsi_tgt_reset against SCSI
+         midlayer codes SUCCESS/FAILED which that function returns rather
+         than SLI return code.
+       * Removed extraneous calls to lpfc_sli_next_iotag which should
+         only be called from lpfc_sli_submit_iocb.  Also make
+         lpfc_sli_next_iotag static.
+       * Added PCI ID for LP10000-S.
+       * Changes in lpfc_abort_handler(): Return SUCCESS if we did not
+         find command in both TX and TX completion queues.  Return ERROR
+         if we timed out waiting for command to complete after abort was
+         issued.
+       * Zero-out response sense length in lpfc_scsi_prep_cmnd to prevent
+         interpretation of stale sense length when the command completes
+         - was causing spurious 0710 messages.
+       * Moved clearing of host_scribble inside host_lock in IO
+         completion path.
+       * Fixed a bunch of mixed tab/space indentation.
+       * Allow hex format numbers in sysfs attribute setting.  Fix
+         application hang when invalid numbers are used in sysfs
+         settings.
+       * Removed extra iotag allocation by lpfc_abort_handler.
+       * Clear host_scribble in the scsi_cmnd structure when failing in
+         queuecommand.
+       * Changed logic at top of lpfc_abort_handler so that if the
+         command's host_scibble field is NULL, return SUCCESS because the
+         driver has already returned the command to the midlayer.
+
+Changes from 20050308 to 20050323
+
+       * Changed version number to 8.0.27
+       * Changed a few lines from patch submitted by Christoph Hellwig
+         (3/19). MAILBOX_WSIZE * (uint32_t) is replaced with an
+         equivalent MAILBOX_CMDSIZE macro.
+       * Merged patch from Christoph Hellwig (3/19): some misc patches
+         against the latest drivers:
+         - stop using volatile.  if you need special ordering use memory
+           barriers but that doesn't seem to be the case here
+         - switch lpfc_sli_pcimem_bcopy to take void * arguments.
+         - remove typecast for constants - a U postfix marks them
+           unsigned int in C
+         - add a MAILBOX_CMD_SIZE macro, as most users of
+           MAILBOX_CMD_WSIZE didn't really want the word count
+         - kill struct lpfc_scsi_dma_buf and embedded the two members
+           directly in struct lpfc_scsi_buf
+         - don't call dma_sync function on allocations from
+           pci_pool_alloc - it's only for streaming mappings (pci_map_*)
+       * Merged patch from Christoph Hellwig (3/19) - nlp_failMask isn't
+         ever used by the driver, just reported to userspace (and that in
+         a multi-value file which is against the sysfs guidelines).
+       * Change pci_module_init to pci_register_module() with appropriate
+         ifdefs.
+       * Added #include <linux/dma-mapping.h> as required by the DMA
+         32bit and 64bit defines on some archs.
+       * Merged patch from Christoph Hellwig (03/19) - fix initialization
+         order - scsi_add_host must happen last from scsi POV. Also some
+         minor style/comment fixups.
+       * Fixed use of TRANSPORT_PATCHES_V2 by changing to
+         FC_TRANSPORT_PATCHES_V2.
+
+Changes from 20050223 to 20050308
+
+       * Changed version number to 8.0.26
+       * Revise TRANSPORT_PATCHES_V2 so that lpfc_target is removed and
+         rport data is used instead. Removed device_queue_hash[].
+       * Changed RW attributes of scan_down, max_luns and fcp_bind_method
+         to R only.
+       * Fixed RSCN handling during initial link initialization.
+       * Fixed issue with receiving PLOGI handling when node is on NPR
+         list and marked for ADISC.
+       * Fixed RSCN timeout issues.
+       * Reduced severity of "SCSI layer issued abort device" message to
+         KERN_WARNING.
+       * Feedback from Christoph Hellwig (on 2/5) - In the LPFC_EVT_SCAN
+         case the caller already has the target ID handly, so pass that
+         one in evt_arg1.
+       * Fix compile warning/resultant panic in
+         lpfc_register_remote_port().
+
+Changes from 20050215 to 20050223
+
+       * Changed version number to 8.0.25
+       * Add appropriate comments to lpfc_sli.c.
+       * Use DMA_64BIT_MASK and DMA_32BIT_MASK defines instead of
+         0xffffffffffffffffULL & 0xffffffffULL respectively.  Use pci
+         equivalents instead of dma_set_mask and also modify condition
+         clause to actually exit on error condition.
+       * Restart els timeout handler only if txcmplq_cnt. On submission,
+         mod_timer the els_tmofunc.  This prevents the worker thread from
+         waking up the els_tmo handler un-necessarily.  The thread was
+         being woken up even when there were no pending els commands.
+       * Added new typedefs for abort and reset functions.
+       * Collapsed lpfc_sli_abort_iocb_xxx into a single function.
+       * Collapsed lpfc_sli_sum_iocb_xxx into a single function.
+       * Removed TXQ from all abort and reset handlers since it is never
+         used.
+       * Fixed Oops panic in 8.0.23 (reported on SourceForge).  The
+         driver was not handling LPFC_IO_POLL cases correctly in
+         fast_ring_event and was setting the tgt_reset timeout to 0 in
+         lpfc_reset_bus_handler.  This 0 timeout would not allow the FW
+         to timeout ABTS's on bad targets and allow the driver to have an
+         iocb on two lists.  Also split the lpfc_sli_ringtxcmpl_get
+         function into two routines to match the fast and slow completion
+         semantics - ELS completions worked for the wrong reasons.  Also
+         provided new log message number - had two 0326 entries.
+       * Removed unused #define LPFC_SCSI_INITIAL_BPL_SIZE.
+       * Removed unused struct lpfc_node_farp_pend definition.
+       * Removed unused #define LPFC_SLIM2_PAGE_AREA.
+       * Changed zeros used as pointers to NULL.
+       * Removed unneeded braces around single line in lpfc_do_work.
+       * Close humongous memory leak in lpfc_sli.c - driver was losing 13
+         iocbq structures per LIP.
+       * Removed last of GFP_ATOMIC allocations.
+       * Locks are not taken outside of nportdisc, hbadisc, els and most
+         of the init, sli, mbox and ct groups of functions
+       * Fix comment for lpfc_sli_iocb_cmd_type to fit within 80 columns.
+       * Replaced wait_event() with wait_event_interruptible().
+         wait_event() puts the woker thread in an UNINTERRUPTIBLE state
+         causing it to figure in load average calculations. Also add a
+         BUG_ON to the ret code of wait_event_interruptible() since the
+         premise is that the worker thread is signal-immune.
+
+Changes from 20050208 to 20050215
+
+       * Changed version number to 8.0.24
+       * Fixed a memory leak of iocbq structure.  For ELS solicited iocbs
+         sli layer now frees the response iocbs after processing it.
+       * Closed large memory leak -- we were losing 13 iocbq structures
+         per LIP.
+       * Changing EIO and ENOMEM to -EIO and -ENOMEM respectively.
+       * Cleanup of lpfc_sli_iocb_cmd_type array and typing of iocb type.
+       * Implemented Christoph Hellwig's feedback from 02/05: Remove
+         macros putLunHigh, putLunLow. Use lpfc_put_lun() inline instead.
+       * Integrated Christoph Hellwig's feedback from 02/05: Instead of
+         cpu_to_be32(), use swab16((uint16_t)lun). This is the same as
+         "swab16() on LE" and "<<16 on BE".
+       * Added updates for revised FC remote port patch (dev_loss_tmo
+         moved to rport, hostdata renamed dd_data, add fc_remote_host()
+         on shutdown).
+       * Removed unnecessary function prototype.
+       * Added code to prevent waking up worker thread after the exit of
+         worker thread.  Fixes panic seen with insmod/rmmod testing with
+         70 disks.
+       * Integrated Christoph Hellwig's patch from 1/30: Make some
+         variables/code static (namely lpfcAlpaArray and
+         process_nodev_timeout()).
+       * Integrated Christoph Hellwig's patch from 1/30: Use
+         switch...case instead of if...else if...else if while decoding
+         JDEC id.
+
+Changes from 20050201 to 20050208
+
+       * Changed version number to 8.0.23
+       * Make lpfc_work_done, lpfc_get_scsi_buf,
+         lpfc_mbx_process_link_up, lpfc_mbx_issue_link_down and
+         lpfc_sli_chipset_init static.
+       * Cleaned up references to list_head->next field in the driver.
+       * Replaced lpfc_discq_post_event with lpfc_workq_post_event.
+       * Implmented Christoph Hellwig's review from 2/5: Check for return
+         values of kmalloc.
+       * Integrated Christoph Hellwig's patch from 1/30: Protecting
+         scan_tmo and friends in !FC_TRANSPORT_PATCHES_V2 &&
+         !USE_SCAN_TARGET.
+       * Integrated Christoph Hellwig's patch from 1/30: Some fixes in
+         the evt handling area.
+       * Integrated Christoph Hellwig's patch from 1/30: Remove usage of
+         intr_inited variable. The interrupt initilization from OS side
+         now happens in lpfc_probe_one().
+       * Integrated Christoph Hellwig's patch from 1/30: remove shim
+         lpfc_alloc_transport_attr - remove shim lpfc_alloc_shost_attrs -
+         remove shim lpfc_scsi_host_init - allocate phba mem in scsi's
+         hostdata readjust code so that they are no use after free's
+         (don't use after scsi_host_put) - make lpfc_alloc_sysfs_attr
+         return errors
+       * Fixed panic in lpfc_probe_one(). Do not delete in a list
+         iterator that is not safe.
+       * Clean up fast lookup array of the fcp_ring when aborting iocbs.
+       * Following timeout handlers moved to the lpfc worker thread:
+         lpfc_disc_timeout, lpfc_els_timeout, lpfc_mbox, lpfc_fdmi_tmo,
+         lpfc_nodev_timeout, lpfc_els_retry_delay.
+       * Removed unused NLP_NS_NODE #define.
+       * Integrated Christoph Hellwig's patch from 1/30: remove unused
+         lpfc_hba_list; remove unused lpfc_rdrev_wd30; remove
+         lpfc_get_brd_no and use Linux provided IDR.
+       * Changed board reset procedure so that lpfc_sli_send_reset()
+         writes the INITFF bit and leaves lpfc_sli_brdreset() to clear
+         the bit.
+       * Removed outfcpio sysfs device attribute.
+       * VPD changes: 1) Modify driver to use the model name and
+         description from the VPD data if it exists 2) Rework use of DUMP
+         mailbox command to support HBAs with 256 bytes of SLIM.
+       * Fixed compile error for implicit definition of struct
+         scsi_target
+
+Changes from 20050124 to 20050201
+
+       * Changed version number to 8.0.22
+       * Moved discovery timeout handler to worker thread. There are
+         function calls in this function which are not safe to call from
+         HW interrupt context.
+       * Removed free_irq from the error path of HBA initialization.
+         This will fix the free of uninitialised IRQ when config_port
+         fails.
+       * Make sure function which processes unsolicited IOCBs on ELS ring
+         still is called with the lock held.
+       * Clear LA bit from work_ha when we are not supposed to handle LA.
+       * Fix double locking bug in the error handling part of
+         lpfc_mbx_cmpl_read_la.
+       * Implemented fast IOCB processing for FCP ring.
+       * Since mboxes are now unconditionally allocated outside of the
+         lock, free them in cases where they are not used.
+       * Moved out a couple of GFP_ATOMICs in lpfc_disc_timeout, to
+         before locks so that they can GFP_KERNEL instead. Also cleaned
+         up code.
+       * Collapsed interrupt handling code into one function.
+       * Removed event posting and handling of solicited and unsolicited
+         iocbs.
+       * Remove ELS ring handling leftovers from the lpfc_sli_inter().
+       * ELS ring (any slow ring) moved from the lpfc_sli_inter() into a
+         worker thread.  Link Attention, Mbox Attention, and Error
+         Attention, as well as slow rings' attention is passed to the
+         worker thread via worker thread copy of Host Attention
+         register. Corresponding events are removed from the event queue
+         handling.
+       * Add entries to hba structure to delegate some functionality from
+         the lpfc_sli_inter() to a worker thread.
+       * Reduced used of GFP_ATOMIC for memory allocations.
+       * Moved locks deeper in order to change GFP_ATOMIC to GFP_KERNEL.
+       * IOCB initialization fix for Raw IO.
+       * Removed qcmdcnt, iodonecnt, errcnt from lpfc_target and from
+         driver.
+       * Added call to lpfc_els_abort in lpfc_free_node.  Modified
+         lpfc_els_abort to reset txq and txcmplq iterator after a
+         iocb_cmpl call.
+       * Fixed a use after free issue in lpfc_init.c.
+       * Defined default mailbox completion routine and removed code in
+         the sli layer which checks the mbox_cmpl == 0 to free mail box
+         resources.
+       * In lpfc_workq_post_event, clean up comment formatting and remove
+         unneeded cast of kmalloc's return.
+       * Removed loop which calls fc_remote_port_unblock and
+         fc_remote_port_delete for every target as this same effect is
+         accomplished by the scsi_remove_host call.
+       * Minor cleanup of header files.  Stop header files including
+         other header files.  Removed sentinels which hide multiple
+         inclusions.  Removed unneeded #include directives.
+       * Fixed memory leaks in mailbox error paths.
+       * Moved lock from around of lpfc_work_done to lpfc_work_done
+         itself.
+       * Removed typedef for LPFC_WORK_EVT_t and left just struct
+         lpfc_work_evt to comply with linux_scsi review coding style.
+       * Fixed some trailing whitespaces, spaces used for indentation and
+         ill-formatting multiline comments.
+       * Bug fix for Raw IO errors.  Reuse of IOCBs now mandates setting
+         of ulpPU and fcpi_parm to avoid incorrect read check of Write IO
+         and incorrect read length.
+
+Changes from 20050110 to 20050124
+
+       * Changed version number to 8.0.21
+       * Removed unpleasant casting in the definition and use of
+         lpfc_disc_action function pointer array.
+       * Makefile cleanup.  Use ?= operator for setting default
+         KERNELVERSION and BASEINCLUDE values.  Use $(PWD) consistently.
+       * Removed call to lpfc_sli_intr from lpfc_config_port_post.  All
+         Linux systems will service hardware interrupts while bringing up
+         the driver.
+       * Christoph Hellwig change request: Reorg of contents of
+         lpfc_hbadisc.c, lpfc_scsi.h, lpfc_init.c, lpfc_sli.c,
+         lpfc_attr.c, lpfc_scsi.c.
+       * Renamed discovery thread to lpfc_worker thread.  Moved handling
+         of error attention and link attention and mbox event handler to
+         lpfc_worker thread.
+       * Removed .proc_info and .proc_name from the driver template and
+         associated code.
+       * Removed check of FC_UNLOADING flag in lpfc_queuecommand to
+         determine what result to return.
+       * Move modification of FC_UNLOADING flag under host_lock.
+       * Fix IOERR_RCV_BUFFER_WAITING handling for CT and ELS subsystem.
+       * Workaround firmware bug for IOERR_RCV_BUFFER_WAITING on ELS
+         ring.
+       * Fixed a couple lpfc_post_buffer problems in lpfc_init.c.
+       * Add missing spaces to the parameter descriptions for
+         lpfc_cr_delay, lpfc_cr_count and lpfc_discovery_threads.
+       * Lock before calling lpfc_sli_hba_down().
+       * Fix leak of "host" in the error path in the remove_one() path.
+       * Fix comment for lpfc_cr_count.  It defaults to 1.
+       * Fix issue where we are calling lpfc_disc_done() recursively from
+         lpfc_linkdown(), but list_for_each_entry_safe() is not safe for
+         such use.
+       * Bump lpfc_discovery_threads (count of outstading ELS commands in
+         discovery) to 32
+       * If the SCSI midlayer tries to recover from an error on a lun
+         while the corresponding target is in the NPR state, lpfc driver
+         will reject all the resets. This will cause the target to be
+         moved to offline state and block all the I/Os. The fix for this
+         is to delay the lun reset to a target which is not in MAPPED
+         state until the target is rediscovered or nodev timeout is
+         fired.
+
+Changes from 20041229 to 20050110
+
+       * Changed version number to 8.0.20
+       * rport fix: use new fc_remote_port_rolechg() function instead of
+         direct structure change
+       * rport fix: last null pointer check
+       * Phase II of GFP_ATOMIC effort.  Replaced iocb_mem_pool and
+         scsibuf_mem_pool with kmalloc and linked list.  Inserted list
+         operations for mempool_alloc calls.  General code cleanup.  All
+         abort and reset routines converted.  Handle_ring_event
+         converted.
+       * If the mbox_cmpl == lpfc_sli_wake_mbox_wait in
+         lpfc_sli_handle_mb_event, pmb->context1 points to a waitq. Do
+         not free the structure.
+       * rport fixes: fix for rmmod crash
+       * rport fixes: when receiving PRLI's, set node/rport role values
+       * rport fixes: fix for unload and for fabric port deletes
+       * VPD info bug fix.
+       * lpfc_linkdown() should be able to process all outstanding events
+         by calling lpfc_disc_done() even if it is called from
+         lpfc_disc_done() Moving all events from phba->dpc_disc to local
+         local_dpc_disc prevents those events from being processed.
+         Removing that queue. From now on we should not see "Illegal
+         State Transition" messages.
+       * Release host lock and enable interrupts when calling
+         del_timer_sync()
+       * All related to rports: Clean up issues with rport deletion
+         Convert to using block/unblock on list remove (was del/add)
+         Moved rport delete to freenode - so rport tracks node.
+       * rport fixes: for fport, get maxframe and class support
+         information
+       * Added use of wait_event to work with kthread interface.
+       * Ensure that scsi_transport_fc.h is always pulled in by
+         lpfc_scsiport.c
+       * In remote port changes: no longer nulling target->pnode when
+         removing from mapped list. Pnode get nulled when the node is
+         freed (after nodev tmo). This bug was causing i/o recieved in
+         the small window while the device was blocked to be errored w/
+         did_no_connect. With the fix, it returns host_busy
+         (per the pre-remote port changes).
+       * Merge in support for fc transport remote port use. This removes
+         any consistent bindings within the driver. All scanning is now
+         on a per-target basis driven by the discovery engine.
+
+Changes from 20041220 to 20041229
+
+       * Changed version number to 8.0.19
+       * Fixed bug for handling RSCN type 3.  Terminate RSCN mode
+         properly after ADISC handling completes.
+       * Add list_remove_head macro.  Macro cleans up memory allocation
+         list handling.  Also clean up lpfc_reset_bus_handler - routine
+         does not need to allocate its own scsi_cmnd and scsi_device
+         structures.
+       * Fixed potential discovery bug, nlp list corrutpion fix potential
+         memory leak
+       * Part 1 of the memory allocation rework request by linux-scsi.
+         This effort fixes the number of bdes per scsi_buf to 64, makes
+         the scatter-gather count a module parameter, builds a linked
+         list of scsi_bufs, and removes all dependencies on lpfc_mem.h.
+       * Reverted lpfc_do_dpc, probe_one, remove_one to original
+         implementation.  Too many problems (driver not completing
+         initial discovery, and IO not starting to disks).  Backs out
+         kthread patch.
+       * Fix race condition in lpfc_do_dpc.  If wake_up interrupt occurs
+         while lpfc_do_dpc is running disc_done and the dpc list is
+         empty, the latest insertion is missed and the schedule_timeout
+         does not wakeup.  The sleep interval is MAX_SCHEDULE_TIMEOUT
+         defined as ~0UL >> 1, a very large number.  Hacked it to 5*HZ
+         for now.
+       * Fixed bug introduced when discovery thread implementation was
+         moved to kthread. kthread_stop() is not able to wake up thread
+         waiting on a semaphore and "modprobe -r lpfc" is not always
+         (most of the times) able to complete. Fix is in not using
+         semaphore for the interruptable sleep.
+       * Small Makefile cleanup - Remove remnants of 2.4 vs. 2.6
+         determination.
+
+Changes from 20041213 to 20041220
+
+       * Changed version number to 8.0.18
+       * Janitorial cleanup after removal of sliinit and ringinit[] ring
+         statistic is owned by the ring and SLI stats are in sli
+         structure.
+       * Integrated patch from Christoph Hellwig <hch@lst.de> Kill
+         compile warnings on 64 bit platforms: %variables for %llx format
+         specifiers must be caste to long long because %(u)int64_t can
+         just be long on 64bit platforms.
+       * Integrated patch from Christoph Hellwig <hch@lst.de> Removes
+         dead code.
+       * Integrated patch from Christoph Hellwig <hch@lst.de>: use
+         kthread interface.
+       * Print LPFC_MODULE_DESC banner in module init routine.
+       * Removed sliinit structure and ringinit[] array.
+       * Changed log message number from 324 to 326 in lpfc_sli.c.
+       * Wait longer for commands to complete in lpfc_reset_bus_handler
+         and lpfc_reset_bus_handler.  Also use schedule_timeout() instead
+         of msleep() and add error message in lpfc_abort_handler()
+       * When setting lpfc_nodev_tmo, from dev_loss set routine, make 1
+         sec minimum value.
+       * Functions which assume lock being held were called without lock
+         and kernel complained about unlocking lock which is not locked.
+       * Added code in linkdown to unreg if we know login session will be
+         terminated.
+       * Removed automap config parameter and fixed up use_adisc logic to
+         include FCP2 devices.
+
+Changes from 20041207 to 20041213
+
+       * Changed version number to 8.0.17
+       * Fix sparse warnings by adding __iomem markers to lpfc_compat.h.
+       * Fix some sparse warnings -- 0 used as NULL pointer.
+       * Make sure there's a space between every if and it's (.
+       * Fix some overly long lines and make sure hard tabs are used for
+         indentation.
+       * Remove all trailing whitespace.
+       * Integrate Christoph Hellwig's patch for 8.0.14: if
+         pci_module_init fails we need to release the transport template.
+         (also don't print the driver name at startup, linux drivers can
+         be loaded without hardware present, and noise in the log for
+         that case is considered unpolite, better print messages only for
+         hardware actually found).
+       * Integrate Christoph Hellwig's patch for 8.0.14: Add missing
+         __iomem annotations, remove broken casts, mark functions static.
+         Only major changes is chaning of some offsets from word-based to
+         byte-based so we cans simply do void pointer arithmetics (gcc
+         extension) instead of casting to uint32_t.
+       * Integrate Christoph Hellwig's patch for 8.0.14: flag is always
+         LPFC_SLI_ABORT_IMED, aka 0 - remove dead code.
+       * Modified preprocessor #ifdef, #if, #ifndef to reflect upstream
+         kernel submission.  Clean build with make clean;make and make
+         clean;make ADVANCED=1 on SMP x86, 2.6.10-rc2 on RHEL 4 Beta
+         1. IO with a few lips and a long cable pull behaved accordingly.
+       * Implement full VPD support.
+       * Abort handler will try to wait for abort completion before
+         returning.  Fixes some panics in iocb completion code path.
+
+Changes from 20041130 to 20041207
+       
+       * Changed version number to 8.0.16
+       * Hung dt session fix.  When the midlayer calls to abort a scsi
+         command, make sure the driver does not complete post-abort
+         handler.  Just NULL the iocb_cmpl callback handler and let SLI
+         take over.
+       * Add Read check that uses SLI option to validate all READ data
+         actually received.
+
+
+Changes from 20041123 to 20041130
+
+       * Changed version number to 8.0.15
+       * Ifdef'd unused "binary" attributes by DFC_DEBUG for clean
+         compiles
+       * Stop DID_ERROR from showing up along with QUEUE_FULL set by the
+         Clarion array (SCSI error ret. val.  0x70028) There is no need
+         for driver to hard fail command which was failed by the target
+         device.
+       * Fix for Scsi device scan bug reported on SourceForge.  Driver
+         was returning a DID_ERROR in lpfc_handle_fcp_error causing
+         midlayer to mark report luns as failing even though it
+         succeeded.
+       * Don't ignore SCSI status on underrun conditions for inquiries,
+         test unit ready's, etc.  This was causing us to lose
+         reservation conflicts, etc
+
+Changes from 20041018 to 20041123
+       
+       * Changed version number to 8.0.14
+       * Added new function "iterator" lpfc_sli_next_iocb_slot() which
+         returns pointer to iocb entry at cmdidx if queue is not full.
+         It also updates next_cmdidx, and local_getidx (but not cmdidx)
+       * lpfc_sli_submit_iocb() copies next_cmdidx into cmdidx. Now it is
+         the only place were we are updating cmdidx.
+       * lpfc_sli_update_ring() is split in to two --
+         lpfc_sli_update_ring() and lpfc_sli_update_full_ring().
+       * lpfc_sli_update_ring() don't to read back correct value of
+         cmdidx.
+       * Simplified lpfc_sli_resume_iocb() and its use.
+       * New static function lpfc_sli_next_iocb(phba, pring, &piocb) to
+         iterate through commands in the TX queue and new command (at the
+         end).
+       * Reduced max_lun to 256 (due to issues reported to some arrays).
+         Fixed comment, and macro values so def=256, min=1, max=32768.
+       * Fix an obvious typo/bug: kfree was used to free lpfc_scsi_buf
+         instead of mempool_free in lpfc_scsiport.c.
+       * Suppress nodev_tmo message for FABRIC nodes.
+       * Fixed some usage of plain integer as NULL pointer.
+       * Bug fix for FLOGI cmpl, lpfc_els_chk_latt error path code
+         cleanup.
+       * Fixup lpfc_els_chk_latt() to have Fabric NPorts go thru
+         discovery state machine as well.
+       * Fixes to lpfc_els_chk_latt().
+       * Use DID not SCSI target id as a port_id and add some missing
+         locks in lpfc_fcp.c.
+       * Changed eh_abort_handler to return FAILED if command is not
+         found in driver.
+       * Fix crash: paging request at virtual address 0000000000100108 -
+         a result of removing from the txcmpl list item which was already
+         removed (100100 is a LIST_POISON1 value from the next pointer
+         and 8 is an offset of the "prev") Driver runs out of iotags and
+         does not handle that case well. The root of the proble is in the
+         initialization code in lpfc_sli.c
+       * Changes to work with proposed linux kernel patch to support
+         hotplug.
+       * Zero out seg_cnt in prep_io failure path to prevent double sg
+         unmap calls.
+       * Fix setting of upper 32 bits for Host Group Ring Pointers if in
+         SLIM. Old code was inappropriately masking off low order bits.
+       * Use scsi_[activate|deactivate]_tcq calls provided in scsi_tcq.h.
+       * Integrated patch from Christoph Hellwig (hch@lst.de): don't call
+         pci_dma_sync_* on coherent memory. pci_dma_sync_* is need and
+         must be used only with streaming dma mappings pci_map_*, not
+         coherent mappings.  Note: There are more consistent mappings
+         that are using pci_dma_sync calls. Probably these should be
+         removed as well.
+       * Modified lpfc_free_scsi_buf to accomodate all three scsi_buf
+         free types to alleviate miscellaneous panics with cable pull
+         testing.
+       * Set hotplug to default 0 and lpfc_target_remove to not remove
+         devices unless hotplug is enabled.
+       * Fixed discovery bug: plogi cmpl uses ndlp after its freed.
+       * Fixed discovery bug: rnid acc cmpl, can potentially use ndlp
+         after its freed.
+       * Modularize code path in lpfc_target_remove().
+       * Changes to support SCSI hotplug (ifdef'ed out because they need
+         kernel support USE_SCAN_TARGET requires kernel support to export
+         the interface to scsi_scan_target and to move the SCAN_WILD_CARD
+         define to a general scsi header file.  USE_RESCAN_HOST requires
+         kernel support to export an interface to scan_scsi_host() with
+         the rescan flag turned on).
+       * Removed redundant variable declaration of lpfc_linkdown_tmo.
+       * Fix for large port count remove test.
+       * Added check to see if BAR1 register is valid before using BAR1
+         register for programming config_port mail box command.
+       * Added lpfc_scsi_hotplug to enable/disable driver support of SCSI
+         hotplug.
+       * Changed lpfc_disc_neverdev() to lpfc_disc_illegal() and changed
+         lpfc_disc_nodev() to lpfc_disc_noop().  Adjusted appropriate
+         events to use these routines.
+       * Add support for SCSI device hotplug.
+       * Take dummy lpfc_target's into account for lpfc_slave_destroy().
+       * Bug fix to store WWPN / WWNN in NameServer / FDMI lpfc_nodelist
+         entries.
+       * Added slavecnt in lpfc_target for diagnostic purposes.
+       * Added lpfc_hba load/unload flags to take care of special cases
+         for add/remove device.
+       * Have target add/remove delay before scanning.
+       * Have rmmod path cleanup blocked devices before scsi_remove_host.
+       * Added a #define for msleep for 2.6.5 kernels.
+       * In reset bus handler if memory allocation fails, return FAILED
+         and not SUCCESS.
+       * Have lpfc eh handlers, bus_reset and lun_reset, wait for all
+         associated I/Os to complete before returning.
+       * Fix memset byte count in lpfc_hba_init so that
+         LP1050 would initialize correctly.
+       * Backround nodev_timeout processing to DPC This enables us to
+         unblock (stop dev_loss_tmo) when appopriate.
+       * Fix array discovery with multiple luns.  The max_luns was 0 at
+         the time the host structure was intialized.  lpfc_cfg_params
+         then set the max_luns to the correct value afterwards.
+       * Remove unused define LPFC_MAX_LUN and set the default value of
+         lpfc_max_lun parameter to 512.
+       * Reduced stack usage of lpfc_hba_init.
+       * Cleaned up the following warning generated by
+         scripts/checkincludes.pl lpfc_fcp.c: scsi/scsi_cmnd.h is
+         included more than once.
+       * Replaced "set_current_state(TASK_UNINTERRUPTIBLE);
+         schedule_timeout(timeout)" with "msleep(timeout)".
+       * Fixnode was loosing starget when rediscovered. We saw messages
+         like: lpfc 0000:04:02.0: 0:0263 Cannot block scsi target as a
+         result.  Moved starget field into struct lpfc_target which is
+         referenced from the node.
+       * Add additional SLI layer logging in lpfc_sli.c.
+       * Ignore more unexpected completions in lpfc_nportdisc.c.
+       * Can not call lpfc_target_unblock from the soft interrupt
+         context.  It seems to be not nessasery to unblock target from
+         nodev timeout.
+       * Introduce and use less lethal event handler for unexpected
+         events in lpfc_nportdisc.c.
+       * Can not call fc_target_(un)block() functions with interrupts
+         disabled in lpfc_scsiport.c.
+       * Added new configuration parameter, lpfc_max_luns range 1-32768,
+         default 32768.
+       * Allow lpfc_fcp.c to call lpfc_get_hba_sym_node_name().
+       * Increase nodev timeout from 20 seconds to 30 seconds.
+       * Replace some kfree((void*)ptr) with kfree(ptr).
+       * Make 3 functions static: lpfc_get_hba_sym_node_name,
+         lpfc_intr_prep and lpfc_setup_slim_access.  Move lpfc_intr_prep
+         and lpfc_setup_slim_access so they're defined before being used.
+       * Remove an unecessary list_del() in lpfc_hbadisc.c.
+       * Set nlp_state before calling lpfc_nlp_list() since this will
+         potentially call fc_target_unblock which may cause a race in
+         queuecommand by releasing host_lock.
+       * Since lpfc_nodev_tmo < dev_loss_tmo remove queuecommand
+         DID_BAD_TARGET return for now.
+       * Fix a problem with rcv logo.
+       * Remove unused portstatistics_t structure.
+       * Remove #if 0 and unnecessary checks in lpfc_fcp.c.
+       * Simplify lpfc_issue_lip: Extra layer of protection removed.
+       * Grab lock before calling lpfc_sli_issue_mbox(phba, pmb,
+         MBX_NOWAIT) in lpfc_sli_issue_mbox_wait().
+
+Changes from 20040920 to 20041018
+
+       * Changed version number to 8.0.13
+       * Hide some attributes using #ifndef DFC_DEBUG ... #endif.
+       * Modify Makefile to (1) make BUILD_NO_DEBUG=1 will hide some
+         (binary) attributes (2) make BUILD_FC_TRANS=0 will build driver
+         for 2.6.5 kernel with block/unblock patch.
+       * Modified #ifdef names.
+       * Added support for proposed FC transport host attributes (which
+         replaces some of the attributes we had local to the driver).
+         Removed the binary statistics sysfs attribute.
+       * Added extra ELS verbose logging for ELS responses.
+       * Added recognition for BUILD_FC_TRANS=2 to Makefile to define
+         FC_TRANS_VER2.
+       * Add a pointer for link stats allocation.
+       * Exported lpfc_get_hba_sym_node_name for use by FC_TRANS_VER2
+         sysfs routines.
+       * Fix discovery problem in lip testing: if device sends an ELS cmd
+         (i.e. LOGO) before our FLOGI completes it should be LS_RJT'ed.
+       * Moved #defines around to provide target_add/remove for upstream
+         kernel deliverables only not SLES9.  Provided ifdefs to #include
+         target_block/unblock only if FC_TRANS_VER1.
+       * Add sanity check in lpfc_nlp_list move setting nlp_Target
+         outside #ifdef.
+       * Added a blocked member to the lpfc_target structure for
+         block/unblock.  This member allows the driver to know when to
+         unblock for pci_remove_one or pci_add_one.  #ifdef'd some more
+         block/unblock stuff and removed some defensive checks from
+         target_block/unblock.
+       * Moved + 5 second window to dev_loss_tmo setting and updated
+         comments.
+       * Removed NULL target check from target_block/unblock and fixed up
+         a few comments.
+       * Enable sysfs attributes on 2.6.5 kernels and remove extra
+         compatibility code.
+       * Remove any and all trailing whitespace.
+       * Added message 0718 and return error when dma_map_single fails.
+       * Changed the fcpCntl2 commands to include an FCP_ prefix to get
+         rid of build warnings on later 2.6.9-rc kernels.  Build
+         conflicts with scsi/scsi.h.  Remove inclusions of scsi/scsi.h
+         from hbadisc.c, sli.c, and fcp.c since these modules had no
+         dependencies on scsi.h.
+       * Fixed a bug with RSCN handling. A RSCN received on one device,
+         shouldn't affect other devices not referenced by the RSCN.
+       * Moved #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) to include
+         lpfc_jedec_to_ascii to prevent warning in SLES 9.
+       * Update Makefile to account for SLES 9 and scsi-target upstream
+         kernel.
+       * This checkin provides block/unblock hooks for the upstream scsi
+         target kernel and 2.6.5 on SLES9 SP1 with the block/unblock
+         patch.
+       * Discovery changes regarding setting targetp->pnode and
+         ndlp->nlp_Target Ensure fc_target_* routines are called properly
+         from discovery.  Remove list_del's from lpfc_cleanup().  Ensure
+         all the lpfc_consistent_bind_* routines don't set any driver
+         structure objects.
+       * Fix for timeout of READ_LA or READ_SPARAM mailbox command
+         causing panic.
+       * Cleanup list_del()'s for Discovery ndlp lists.
+       * Bug fixes for some insmod/rmmod crashes, link down crashes and
+         device loss crashes.
+       * Removed NLP_SEARCH_DEQUE.
+       * Call lpfc_target_unblock only if the targetp is nonNull and with
+         the host_lock held.
+       * Added qcmdcnt back along with misc bug fixes to discovery.
+       * Changed tgt_io to outfcpio lpfc_fcp.c.
+       * Fixed errors caused by LIP and cable pulls both with and without
+         block/unblock patch.
+       * For now we have to call fc_target_unblock and fc_target_block
+         with interrupts enabled.
+       * Save seg_cnt from dma_map_sg.  Save scatter-gather start address
+         and pass back to dma_unmap_sg in error with seg_cnt.
+       * Incorporating block/unblock calls into driver with ifdefs.  This
+         change is supported by scsi-target-2.6 kernel and forward only.
+       * Merged in some discovery bug fixes and added tgt io counters.
+       * Added sysfs attributes/interfaces: read only attribute
+         "management_version" and write only attribute "issue_lip".
+       * Fix build on big endian machines: while #if was OK with
+         __BIG_ENDIAN which defined as 4321, __BIG_ENDIAN_BITFIELD has to
+         be tested with #ifdef because it does not have any value, it is
+         either defined or not.
+       * Add fabric_name and port_type attributes.
+       * Change mdelay to msleep.  mdelay works, but wastefully uses cpu
+         resources without a lock held. Revert to msleep.  Tested with
+         sg_reset for bus and three attached targets.
+       * Added the customary #ifndef...#define...#endif to
+         lpfc_version.h.
+       * Integrate patches from Christoph Hellwig: two new helpers common
+         to lpfc_sli_resume_iocb and lpfc_sli_issue_iocb - singificant
+         cleanup of those two functions - the unused SLI_IOCB_USE_TXQ is
+         gone - lpfc_sli_issue_iocb_wait loses it's flags argument
+         totally.
+       * Fix in lpfc_sli.c: we can not store a 5 bit value in a 4-bit
+         field.
+       * Moved some routines out of lpfc_fcp.c into more appropriate
+         files.
+       * Whitespace cleanup: remove all trailing whitespace.
+       * Make lpfc_disc_ndlp_show static to lpfc_fcp.c.
+       * Remove leftover printk and replace some with
+         printk(KERN_WARNING)
+       * Trivial: fix a few long lines and a soft tab.
+       * Remove warnings generated by Sparse against driver (make
+         C=1). Mostly these are "using integer as pointer warnings"
+         i.e. use NULL instead of 0.
+       * Integrated patch from Christoph Hellwig: Quite a lot of changes
+         here, the most notable is that the phba->slim2p lpfc_dmabuf goes
+         away in favour of a typede pointer and a dma_addr_t.  Due to the
+         typed pointer lots of the cast mess can go away, and while at it
+         I also replaced the messy SLI2_SLIM_t with a simple struct
+         lpfc2_sli2_slim that only contains the part of the union we care
+         about while using SLI2_SLIM_SIZE for all size calculations
+         directly.
+       * Integrated patch from Christoph Hellwig: This streamlines the
+         I/O completion path a little more, especially taking care of
+         fast-pathing the non-error case.  Also removes tons of dead
+         members and defines from lpfc_scsi.h - e.g. lpfc_target is down
+         to nothing more then the lpfc_nodelist pointer.
+       * Added binary sysfs file to issue mbox commands
+       * Replaced #if __BIG_ENDIAN with #if __BIG_ENDIAN_BITFIELD for
+         compatibility with the user space applications.
+       * Decrease the amount of data in proc_info.
+       * Condense nodelist flag members.
+       * Expand INFO for discovery sysfs shost entries.
+       * Notify user if information exceeds 4k sysfs limit.
+       * Removed a bunch of unused #defines.
+       * Added initial sysfs discovery shost attributes.
+       * Remove unused #defines lpfc_disc.h.
+       * Fixed failMask nodelist settings.
+       * Cleanup some old comments / unused variables.
+       * Add LP101 to list of recognized adapters.
+
+Changes from 20040908 to 20040920
+
+       * Changed version number to 8.0.12
+       * Removed used #defines: DEFAULT_PCI_LATENCY_CLOCKS and
+         PCI_LATENCY_VALUE from lpfc_hw.h.
+       * Changes to accomodate rnid.
+       * Fix RSCN handling so RSCN NS queries only effect NPorts found in
+         RSCN data.
+       * If we rcv a plogi on a NPort queued up for discovery, clear the
+         NLP_NPR_2B_DISC bit since rcv plogi logic will force NPort thru
+         discovery.
+       * Ensure lpfc_target is also cleaned up in lpfc_cleanup().
+       * Preliminary changes for block/unblock kernel API extensions in
+         progress with linux-scsi list.  These are name changes and
+         prototype changes only.
+       * Added send_abts flag to lpfc_els_abort. For rcv LOGO when ADISC
+         sent, the XRI of the LOGO rcv'ed is the same as the ADISC
+         sent. Thus we cannot ABTS the ADISC before sending the LOGO ACC.
+       * Weed out some unused fc_flags.  Add FC_DISC_TMO.
+       * board_online sysfs attribute added to support libdfc functions
+         InitDiagEnv and SetBrdEnv.
+       * Streamline code in lpfc_els_retry fixup abort case in
+         lpfc_els_timeout_handler().
+       * Flush discovery/ELS events when we bring SLI layer down.
+       * ctlreg and slimem binary attributes added to support libdfc
+         read/write mem/ctl functions.
+       * Integrated Christoph Hellwig's patch: Cleanup
+         lpfc_sli_ringpostbuf_get.
+       * Modified lpfc_slave_alloc and lpfc_slave_destroy to allocate and
+         free a dummy target pointer.  This allows queuecommand to skip
+         the NULL target pointer check and avoid the console spam when
+         slave_alloc fails.
+       * Fix cfg_scan_down logic, it was reversed.
+       * Init list head ctrspbuflist.
+       * Change name of lpfc_driver_abort to lpfc_els_abort since it is
+         only valid for ELS ring.
+       * Remove unused third argument for lpfc_consistent_bind_get().
+       * Fix up iotag fields in lpfc_prep_els_iocb().
+       * Remove log message on code path triggered by lpfc_els_abort().
+       * Set host->unique_id in lpfc_fcp.c.
+       * Removed deadwood: lpfc_target.pHba not necessary anymore.
+       * Integrated patch from Christoph Hellwig: remove dead
+         SLI_IOCB_POLL handling.
+       * Integrated patch from Christoph Hellwig: Streamline I/O
+         submission and completion path a little.
+       * Remove unnecessary lpfc_brd_no.  Ensure brd_no assignment is
+         unique.
+       * Removed unused MAX_FCP_LUN.
+       * Use mod_timer instead of add_timer for fdmi in lpfc_ct.c.
+       * Fixed misc discovery problems.
+       * Move stopping timers till just before lpfc_mem_free() call.
+       * Fix up NameServer reglogin error path.
+       * Cleanup possible outstanding discovery timers on rmmod.
+       * Fix discovery NPort to NPort pt2pt problem.
+       * Get rid of ip_tmofunc / scsi_tmofunc.
+       * Integrated patch from Christoph Hellwig:
+         lpfc_disc_done/lpfc_do_dpc cleanup - lpfc_disc_done can return
+         void - move lpfc_do_dpc and lpfc_disc_done to lpfc_hbadisc.c -
+         remove checking of list emptiness before calling lpfc_disc_done,
+         it handles the emtpy list case just fine and the additional
+         instructions cost less then the bustlocked spinlock operations.
+       * Integrated patch from Christoph Hellwig: This adds a new 64bit
+         counter instead, brd_no isn't reused anymore.  Also some tiny
+         whitespace cleanups in surrounding code.
+       * Reorder functions in lpfc_els.c to remove need for prototypes.
+       * Removed unsed prototypes from lpfc_crtn.h -
+         lpfc_ip_timeout_handler, lpfc_read_pci and lpfc_revoke.
+       * Removed some unused prototypes from lpfc_crtn.h -
+         lpfc_scsi_hba_reset, lpfc_scsi_issue_inqsn,
+         lpfc_scsi_issue_inqp0, lpfc_scsi_timeout_handler.
+       * Integrated patch from Christoph Hellwig: remove TRUE/FALSE
+         usage.
+       * Integrated patch from Christoph Hellwig: Remove unused function
+         prototypes lpfc_set_pkt_len and lpfc_get_pkt_data from
+         lpfc_crtn.h - fixes build warnings.
+       * Removed unused struct lpfc_dmabufip definition from lpfc_mem.h.
+       * Removed pre-2.6.5 MODULE_VERSION macro from lpfc_compat.h.
+       * Fixing missing static and removing dead code.
+       * Adding nodewwn, portwwn and portfcid shost attributes.
+       * Initial support for CT via sysfs. request payloads of size less
+         than PAGE_SIZE and rsp payloads of size PAGE_SIZE are supported.
+         Driver maintains a list of rsp's and passes back rsp's
+         corresponding to the pid of the calling process.
+       * Support for RefreshInformation, GetAdapterAttributes,
+         GetPortStatistics.
+       * Make nodev-tmo default to 20 seconds.
+       * Fix up some DSM error cases, unreg_login rpi where needed.
+       * Fix up comments for fc_target_block / fc_target_unblock.
+       * Fix up code for scsi_block_requests / scsi_unblock_requests.
+       * Add NLP_FCP_TARGET for nodeinfo support.
+       * Move suspend/resume in lpfc_nlp_list under appropriate case -
+         Used host_lock for DPC to avoid race (remove dpc_lock)
+       * Fix some corner cases for PLOGI receive - simplify error case
+         for cmpl_reglogin_reglogin_issue.
+       * Bug fix for ppc64 EEH MMIO panic - always do readl after
+         writel's of HBA registers to force flush.
+       * Get rid of initial static routine declarations in lpfc_hbadisc.c
+         and lpfc_els.c.
+       * Updates to discovery processing.
+
+Changes from 20040823 to 20040908
+
+       * Changed version number to 8.0.11
+       * Removed persistent binding code.
+       * Display both ASC and ASCQ info.
+       * Fixed link down->up transitions when linkdown tmo expires. Fix
+         was in the defensive error checking at the start of
+         queuecommand.
+       * Removed lpfc_scsi_timeout_handler as this timer is no longer
+         required.  The midlayer will exhaust retries and then call
+         lpfc_abort_handler, lpfc_reset_lun_handler, and
+         lpfc_reset_target_handler.
+       * Minimal support for SCSI flat space addressing/volume set
+         addressing.  Use 16 bits of LUN address so that flat
+         addressing/VSA will work.
+       * Changed 2 occurences of if( 1 != f(x)) to if(f(x) != 1)
+       * Drop include of lpfc_cfgparm.h.
+       * Reduce stack usage of lpfc_fdmi_cmd in lpfc_ct.c.
+       * Add minimum range checking property to /sys write/store
+         functions.
+       * Fix display of node_name and port_name via fc transport
+         attr.
+       * Removed biosparam code.
+       * Removed range checking. phba->config[] array elements are now
+         embedded into the hba struct. lpfc_config_setup() has been
+         removed.
+       * Collapsed lpfc_scsi_cmd_start into lpfc_queuecommand and cleaned
+         up combined routines.
+       * Removed unused prototypes myprint and
+         lpfc_sched_service_high_priority_queue.
+       * Removed unused function lpfc_nodev.
+       * Removed scsi_cmnd->timeout_per_command cancelation. SCSI midlayer
+         now times out all commands - FW is instructed to not timeout.
+       * Removed polling code from lpfc_scsi_cmd_start. Reorganized
+         queuecommand and cmd_start some.
+
+Changes from 20040810 to 20040823
+
+       * Changed version number to 8.0.10
+       * Additional timer changes as per Arjan / Christoph's comments.
+       * Used mod_timer() instead of del_timer_sync() where appropriate.
+       * Fixed a use after free case (panic on 2.6.8.1 with
+         CONFIG_DEBUG_SLAB set).
+       * Fix compile warning in lpfc_fcp.c.
+       * Minor fix for log message, that prints unassigned brdno which is
+         zero.
+       * Move scsi_host_alloc() to the beginning of probe_one(). This
+         ensures that host_lock is available at later stages and also
+         avoids tons of unnecessary initializing if host_alloc()
+         fails.
+       * Removed else clause from lpfc_slave_configure that set
+         sdev->queue_depth.  The driver informs the midlayer of its
+         setting in the template and only overrides if queue tagging is
+         enabled.
+       * Added PCI_DEVICE_ID_ZEPHYR and PCI_DEVICE_ID_ZFLY (Junior
+         Zephyr) support
+
+Changes from 20040730 to 20040810
+       
+       * Changed version number to 8.0.9
+       * Removed per HBA driver lock.  Driver now uses the host->host_lock
+       * Restored support for the 2.6.5 kernel for those linux distributions
+         shipped with the 2.6.5 kernel.
+       * Applied patch from Christoph Hellwig (hch@infradead.org) as follows
+         "[PATCH] use scsi host private data in ->proc_info.  
+       * Applied patch from Christoph Hellwig (hch@infradead.org) as follows
+         "Re: [Emulex] Ready for next round.  This patch cleans up the memory 
+         allocation routines a little and fixes a missing mempool_destroy and
+         some missing error handling."
+       * Changed pointers assignments from 0 to NULL.
+       * Added fixes to the lpfc_reset_lun_handler and lpfc_reset_bus_handler
+         entry points that caused kernel to Oops or hang.
+       * Added fixes to targetless hosts that caused modprobe and insmod to 
hang.
+       * Ongoing cleanup to many files
+         
+Changes from 20040723 to 20040730
+
+       * Changed version number to 8.0.8
+       * Removed unused LPFN_DRIVER_VERSION #define.
+       * Folded lpfc_findnode_scsiid into lpfc_find_target, its only
+         caller.
+       * Removed 2 unneeded arguments to lpfc_find_target (lun and
+         create_flag).
+       * Make lpfc_sli_reset_on_init = 1
+       * Minor cleanup to quieten sparse.
+       * Removed missing function = 0 in tmo routine in lpfc_els.c.
+       * Moved additional binding parameters into lpfc_defaults.c:
+         lpfc_automap / lpfc_fcp_bind_method
+       * Use msecs_to_jiffies() where applicable.
+       * Only use queue depth attribute only after SLI HBA setup was
+         completed.
+       * Put in memory barriers for PPC
+       * Added PCI_DEVICE_ID_HELIOS and PCI_DEVICE_ID_JFLY (Junior
+         Helios) support
+       * Added 4&10 gigabit choices in user option link_speed
+       * Updated timer logic: Set timer data after init_timer use
+         timer_pending() instead of expires.
+       * Removed some remnants of IP over FC support from Kconfig and
+         Makefile.
+       * Remove redundant prototypes for lpfc_handle_eratt,
+         lpfc_handle_latt and lpfc_read_pci.
+       * Ongoing cleanup of lpfc_init.c.
+       * Changed LPFC_CFG_DFT_HBA_Q_DEPTH -> LPFC_CFG_HBA_Q_DEPTH.
+       * Another cleanup stab at lpfc_ct.c. Remove castings, structure
+         code sanely, remove redundant code, reorganize code so that
+         functions are invoked after definition.
+
+Changes from 20040716 to 20040723
+
+       * Changed version number to 8.0.7
+       * Cleanup of lpfc_ct.c. Removed number of casts, removed tons of
+         dead/redundant code, cleaned up badly and poorly written code,
+         cleaned up return values.
+       * Fixed Persistent binding implementation
+       * Removed all references to lpfc_scsi_req_tmo
+       * Removed last references to lun_skip config parameter.
+       * Removed LPFC_DEV_RPTLUN node failure bit because we don't issue
+         REPORT_LUNS from the driver anymore.
+       * Removed LUN-tracking in driver.  Removed lpfc_lun struct and
+         moved any functionality we still need to lpfc_target.
+       * Added new lpfc_jedec_to_ascii() call and replace two instances
+         of duplicate code with calls to this function.
+       * Removed Volume Set Addressing handling on LUN IDs.
+       * Applied patch from Christoph Hellwig (hch@infradead.org) that
+         removes dead code belonging to lpfc_build_scsi_cmnd() and its
+         call path. This is related to the recently removed report_lun
+         code.
+
+Changes from 20040709 to 20040716
+
+       * Changed version number to 8.0.6
+       * Removed internal report LUNs usage.  Removed functions:
+         lpfc_disc_issue_rptlun, lpfc_disc_cmpl_rptlun,
+         lpfc_disc_retry_rptlun and their use.
+       * Removed usused scheduler prototypes in lpfc_crtn.h
+       * Replace lpfc_geportname() with generic memcmp().
+       * Rearrange code in lpfc_rcv_plogi_plogi_issue() to make it a
+         little more readable.
+       * Remove redundant port_cmp != 2 check in if
+         (!port_cmp) { .... if (port_cmp != 2).... }
+       * Clock changes: removed struct clk_data and timerList.
+       * Clock changes: seperate nodev_tmo and els_retry_delay into 2
+         seperate timers and convert to 1 argument changed
+         LPFC_NODE_FARP_PEND_t to struct lpfc_node_farp_pend convert
+         ipfarp_tmo to 1 argument convert target struct tmofunc and
+         rtplunfunc to 1 argument * cr_count, cr_delay and
+         discovery_threads are only needed to be module_params and not
+         visible via sysfs.
+
+Changes from 20040614 to 20040709
+
+       * Changed version number to 8.0.5
+       * Make lpfc_info static.
+       * Make lpfc_get_scsi_buf static.
+       * Print a warning if pci_set_mwi returns an error.
+       * Changed SERV_PARM to struct serv_parm.
+       * Changed LS_RJT to struct ls_rjt.
+       * Changed CSP to struct csp.
+       * Changed CLASS_PARMS to struct class_parms.
+       * Some cosmetic coding style cleanups to lpfc_fcp.c.
+       * Providing a sysfs interface that dumps the last 32
+         LINK_[UP|DOWN] and RSCN events.
+       * Get rid of delay_iodone timer.
+       * Remove qfull timers and qfull logic.
+       * Convert mbox_tmo, nlp_xri_tmo to 1 argment clock handler
+       * Removed duplicate extern defs of the bind variables.
+       * Streamline usage of the defines CLASS2 and CLASS3, removing
+         un-necessary checks on config[LPFC_CFG_FCP_CLASS].
+       * Moving the persistent binding variables to new file
+         lpfc_defaults.c
+       * Changed LPFC_SCSI_BUF_t to struct lpfc_scsi_buf.
+       * Moved config specific code from probe_one() into
+         config_setup(). Removing a redundant check on scandown value
+         from bind_setup() as this is already done in config_setup().
+       * Changed LPFC_SLI_t to struct lpfc_sli.
+       * Changed FCP_CMND to struct fcp_cmnd.
+       * Changed FCP_RSP to struct fcp_rsp.
+       * Remove the need for buf_tmo.
+       * Changed ULP_BDE64 to struct ulp_bde64.
+       * Changed ULP_BDE to struct ulp_bde.
+       * Cleanup lpfc_os_return_scsi_cmd() and it's call path.
+       * Removed lpfc_no_device_delay.
+       * Consolidating lpfc_hba_put_event() into lpfc_put_event().
+       * Removed following attributes and their functionality:
+         lpfc_extra_io_tmo, lpfc_nodev_holdio, lpfc_delay_rsp_err,
+         lpfc_tgt_queue_depth and lpfc_check_cond_err.
+       * Clock changes consolidating timers, just in the struct lpfc_hba,
+         to get rid of clkData and pass only one argument to timeout
+         routine. Also, removing need for outstanding clock linked list
+         to stop these timers at rmmod.
+       * Move lpfc.conf contents into lpfc_fcp.c. Removing per adapter
+         attributes in favor of global attributes.
+       * Fix a potential null pointer reference of pmbuf in lpfc_ct.c.
+       * On reset_lun, issue LUN_RESET as opposed to ABORT_TASK_SET.
+       * Removed SCSI_REQ_TMO related code.
+       * Introducing two new defines LPFC_ATTR_R and LPFC_ATTR_RW that do
+         a module_param, MODULE_PARM_DESC, lpfc_param_show,
+         [lpfc_param_store] and CLASS_DEVICE_ATTRIBUTE.
+       * Properly clean up when allocation of a linked BDE fails in the
+         SCSI queuecommand path.
+       * Fail SCSI command if dma_map_sg call fails.
+       * Remove unused macros SWAP_ALWAYS and SWAP_ALWAYS16.
+       * Reset context2 to 0 on exit in
+         lpfc_sli_issue_iocb_wait_high_priority() and
+         lpfc_sli_issue_iocb_wait().
+       * Arranging lpfc_scsiport.c to follow style of use after
+         definition. This removes the need for the cruft of forward
+         declarations. Also removing a redundant #define ScsiResult as it
+         already available elsewhere.
+       * Applying "Streamline lpfc error handling" patch from Christoph
+         Hellwig (hch@infradead.org) with following modifications: fix
+         mem leaks, remove some misplaced code that need not be there,
+         print a message on exit (old code prints two (entry/exit)), make
+         ret values consistent (either 1/0 or SUCCESS/FAILURE), keep all
+         eh routines in a single file (lpfc_scsiport.c).
+       * Move contents of lpfc_module_param.h into lpfc_fcp.c.
+       * Changed sysfs attributes to CLASS_DEVICE_ATTRIBUTES (previously
+         DEVICE_ATTRIBUTES). They now appear in
+         /sys/class/scsi_host/hostx (previously in
+         /sys/bus/pci/drivers/lpfc/devx).
+       * Removed lpfc_syfs.h and lpfc_sysfs.c.
+       * Cleanup of config params.  Throttle params have been removed.
+         max_lun has been removed. max_target is replaced with a #define,
+         lun_skip is removed.  Remove ipfc config params and related
+         code.
+       * Changed DMABUF_t usage to struct lpfc_dmabuf.
+       * Downsizing iCfgParam structure to include a_string, a_low, a_hi
+         and a_default values only.
+       * Free SCSI buf safety memory pool on shutdown to eliminate memory
+         leak.
+       * Change lpfc_printf_log to a #define. Also include phba->brd_no
+         and newline in the print string rather than in the #define.
+       * Remove code that optionally locates Host Group Pointers in host
+         memory SLIM since this is no longer needed for PPC64, once
+         CONFIG_PORT uses HBA's view of its BAR0.
+       * Removed the forward declarations of the sli functions and
+         rearranging the code in lpfc_sli.c.
+       * Removed the preamble functionality from logging.
+       * Make lpfc_sli_hba_setup() return negative error codes on error
+         and correct the comment left over in lpfc_fcp.c
+       * Removed the lpfc_loadtime variable.
+       * Put a space between all ifs and their open parens '('.
+       * Change Studly_Caps LPFC_SCSI_BUF_t to struct lpfc_scsi_buf.
+       * Fixed insmod hang after hardware error.
+       * Relocated scsi_host alloc to before we enable the interrupt
+         handler
+       * Add .tmp_versions directory to Makefile clean target.  This
+         directory is created in the 2.6.5+ build process (with Red Hat
+         kernels at least).
+       * Changing phba->config to kmalloc lpfc_icfgparam and not
+         *phba->config. This is manifesting itself as a panic in
+         pci_release_region().
+       * Fix for firmware download / board reset problem.
+       * Integrated patch from Christoph Hellwig (hch@infradead.org) to
+         reorganize and cleanup lpfc_fcp.c
+       * Don't abort commands immediately when there is an RSCN event to
+         give driver time to rediscover targets before the midlayer
+         retries the SCSI commands.
+
+Changes from 20040604 to 20040614
+
+       * Changed version number to 8.0.4
+       * Removed lpfc_valid_lun function.
+       * Added scsi_buf safety pool to address scsi_buf failures in
+         queuecommand under low memory conditions.  Allocations now come
+         from kmalloc initially, but if kmalloc fails, the allocation
+         comes from the safety pool.
+       * Modified lpfc_slave_alloc to only set the scsi_device->hostdata
+         pointer if the driver has discovered the target.  This routine
+         always returns success now as well since no error ever occurs in
+         the alloc routine.
+       * Mask only info and warning messages.  Print all error messages
+         irrespective of mask.
+       * Removing lpfc_log_chk_msg_disabled()
+       * Changed lpfc_printf_log to take struct lpfc_hba * directly
+         instead of a "board number".
+       * Convert dma_sync_single to pci_dma_sync_single_for_{device/cpu}.
+       * Implemented new style log messages. The message strings are now
+         embedded in the call to lpfc_printf_log.
+       * Decreased FLOGI discovery timeout to 20 seconds.
+       * On error in lpfc_pci_probe_one() return -1 and not 1.
+       * Allow for board numbers that are not sequential, paving the way
+         for hotplug support.
+       * scsi_add_host() can fail, so wrap it around in an if(). Also
+         initiate scsi_scan_host() after attaching the sysfs attributes.
+       * lpfc_release_version is used only in lpfc_ct.c, so move it there
+         and mark it as static.
+       * Removed lpfc_sleep_ms and replaced with mdelay or schedule calls
+         directly
+       * Removed all (struct list_head *) casts from clkData-related list
+         handling in list_add, list_del macros.
+       * Removed EXPORT_SYMBOLs.
+       * Removed LPFC_MIN_QFULL and lpfc_qthrottle_up.
+       * Replace LPFCSCSITARGET_t with struct lpfc_target.
+       * Replace LPFCSCSILUN_t with struct lpfc_lun.
+       * Remove unused struct declarations (fcPathId and fcRouteId) from
+         lpfc_scsi.h.
+       * Rewrite use of FC transport attributes.
+       * Fix crash when link is lost.  This was due to lpfc_delay_iodone
+         calling list_del on an object that was never put on a list.
+       * Remove trailing spaces at the end of all lines.
+       * Set MAX_FCP_TARGET to 256 from 0xff.  Set MAX_FCP_LUN and
+         MAX_FCP_CMDS to their decimal equivalents and updated
+         documentation.
+
+Changes from 20040526 to 20040604
+
+       * Changed version number to 8.0.3
+       * Completed sysfs FC transport support.
+       * Removed unused fields in SCSI LUN and SCSI Target structures:
+         void *pTargetProto; void *pTargetOSEnv; void *pLunOSEnv;
+       * Modified list_for_each to list_for_each_entry. Modified
+         list_for_each_safe to list_for_each_entry_safe.
+       * Remove lpfc_dfc.h file.
+       * Changed pHba->phba, pCommand->pcmd
+       * Changed plogi_ndlp -> plogindlp, pos_tmp->postmp, pRsp->prsp,
+         pCmd->pcmd
+       * Changed pText -> ptext
+       * Changed p_tmp_buff -> ptmpbuff
+       * Changed pBufList -> pbuflist, pRsp -> prsp, pCmd -> pcmd
+       * Changed *pos_tmp -> *postmp, *p_mbuf -> *pmbuf
+       * Following changes are made to the SCSI fast path: Added
+         DMA_BUF_t member to the lpfc_scsi_buf_t.  This will reduce a
+         memory allocation in the scsi fast path.  Added check for
+         targetp == NULL in the scsi fast path.  Increased number of
+         scatter gather entries in lpfc_scsi_dma_ext to 4 from 3 and
+         changed the size of lpfc_scsi_dma_ext to 264
+       * Fixing some missing static lpfc_nportdisc.c.
+       * Reordered #include lines so that lpfc.h doesn't have to #include
+         other header files.
+       * Remove lpfc_get_hba_sym_node_name() as a global EXPORT and make
+         it static.
+       * Move struct clk_data definition from lpfc_hw.h to lpfc_sli.h.
+       * Changed LPFC_IOCBQ_t to struct lpfc_iocbq.
+       * Changed LPFC_SLI_RING_t to struct lpfc_sli_ring.
+       * Changed LPFC_NODELIST_t to struct lpfc_nodelist.
+       * Rearranged lpfc_nportdisc.c by moving state machine array
+         (lpfc_disc_action) and the one function that uses it,
+         lpfc_disc_state_machine, to the end of the file, removing the
+         need for the raft of prototypes at the top.
+       * Changed LPFC_BINDLIST_t to struct lpfc_bindlist.
+       * Removed lpfc_issue_ct_rsp(), lpfc_sleep(), lpfc_add_bind(),
+         lpfc_del_bind(), lpfc_sli_wake_mbox_wait() and
+         lpfc_sli_issue_mbox_wait().
+       * Fixed a large number of overly-long lines.
+       * Fixed some discovery problems: Introduced deferred ndlp removal
+         when in DSM to avoid panic when in nested DMSs Fix NportId
+         fffc01 handling to not relogin after LOGO fixed handling of LOGO
+         on PLOGI issue.
+       * Changed SLI_CT_REQUEST to lpfc_sli_ct_request.
+       * Changed NAME_TYPE to struct lpfc_name.
+       * Changed lpfcCfgParam_t to struct lpfc_cfgparam.
+       * Changed LPFC_STAT_t to struct lpfc_stats.
+       * Changed HBAEVT_t to struct lpfc_hba_event.
+       * Changed Studly_Caps lpfcHBA_t to struct lpfc_hba.
+       * Removed no longer used tasklet_running flag.
+       * Removing *PSOME_VAR typedefs and using SOME_VAR* directly.
+       * Changing .use_clustering to ENABLE_CLUSTERING.
+       * Modify lpfc_queuecommand to return SCSI_MLQUEUE_HOST_BUSY when
+         it can't queue a SCSI command.  Also, remove cmnds_in_flight
+         member of struct lpfcHBA for 2.6 kernels as it was only needed
+         to determine what to return from queuecommand.
+       * Change return type of lpfc_evt_iocb_free to void as it doesn't
+         return anything.
+       * Remove unused cmnd_retry_list and in_retry members in struct
+         lpfcHBA.
+       * Remove some instances of unneeded casting of kmalloc's return in
+         lpfc_scsiport.c
+       * Remove lpfc_linux_attach() and lpfc_linux_detach(). Integrate
+         them into lpfc_probe_one() and lpfc_release_one() respectively.
+       * Remove lpfc_num_iocbs, lpfc_num_bufs module parameters
+       * Remove #defines for NUM_NODES, NUM_BUFS and NUM_IOCBS
+
+Changes from 20040515 to 20040526
+
+       * Changing version number to 8.0.2.
+       * Including dma-mapping.h as one of the include headers.  Also
+         rearrange the #include order.
+       * Make functions static as appropriate.
+       * queuecommand() will now return SCSI_MLQUEUE_HOST_BUSY instead of
+         1 to backpressure midlayer.
+       * Removed function prototypes for lpfc_start_timer() and
+         lpfc_stop_timer()
+       * Changed timer support to be inline.  Clk_data is now declared
+         right next to the corresponding timer_list entry so we don't
+         have to allocate these clk_data dynamically.
+       * Add readls after writels to PCI space to flush the writes.
+       * Fix misspelled word "safety" in function names.
+       * Fix up comments in lpfc.conf for per HBA parameters to reflect
+         new implementation.
+       * Change lpfc_proc_info handler to get the Nodename from
+         fc_nodename and not fc_portname.
+       * Fix up some comments and whitespace in lpfc_fcp.c.
+       * Formatting changes: get rid of leading spaces in code
+       * Move discovery processing from tasklet to a kernel thread.
+       * Move ndlp node from unmap list to map list if ADISC completed
+         successfully.
+       * Flush all the ELS IOCBs when there is a link event.
+       * LP9802 qdepth is twice the LP9802DC qdepth.  Delay
+         elx_sched_init after READ_CONFIG to get max_xri from the
+         firmware.  Reset ELX_CFG_DFT_HBA_Q_DEPTH to max_xri after
+         READ_CONFIG
+       * Fix fc_get_cfg_parm() to be more robust and support embedded hex
+         values.  The lpfc_param's are now defined as:
+         lpfc_log_verbose="lpfc:0,lpfc0:0x10,lpfc1:4,lpfc100:0xffff" The
+         "," delimter does not matter. It can be anything or not exist at
+         all. ie param = "lpfc:0lpfc0:0x10.lpfc1:4txtlpfc100:0xffff" will
+         also work.  Additionally the string is treated as case
+         insensitive.
+       * Changed all usage of lpfc_find_lun_device() to lpfc_find_lun().
+       * Removed unnecessary wrappers lpfc_find_lun_device() and
+         lpfc_tran_find_lun().
+       * Switch from using internal bus/id/lun to similar data from
+         scsi_device structure.
+       * Eliminate one-line function lpfc_find_target()
+       * Added slave_alloc, slave_destory
+       * lpfc_scsi_cmd_start can now acquire lun pointer from
+         scsi_device->hostdata, which is setup in slave_alloc.
+       * Eliminate unnecessary checking on every cmd just to see if we
+         are accessing the device the first time.
+       * Remove assumption in lpfc_reset_lun_handler that a valid
+         lpfc_scsi_buf is hung off of linux's scsi_cmnd->host_scribble
+         when our reset is called.
+
+Changes from 20040507 to 20040515
+
+       * Changed version to 8.0.1
+       * Fixed crash on driver rmmod after error injection tests and
+         lpfc_tasklet deadlock.
+       * Modified lpfc.conf to remove limit on number of support hosts
+       * Removed HBAAPI 
+       * Removed duplication of SCSI opcodes from lpfc_fcp.h that are
+         available in scsi/scsi.h
+       * Rework module_param usage
+       * Added MODULE_PARAM_DESC for various module_params
+       * Removed #define EXPORT_SYMTAB
+       * Removed #includes of if_arp.h and rtnetlink.h
+       * Removed string "Open Source" from MODULE_DESC
+       * Cleanup duplicated string definitions used by MODULE_DESC
+       * Renamed lpfc_pci_[detect|release] to lpfc_pci_[probe|remove]_one
+       * Fix formatting of lpfc_driver
+       * Remove unnecessary memset to 0 of lpfcDRVR
+       * Attach driver attributes always unless pci_module_init failed
+       * Remove all one-line wrappers from lpfc_mem.
+       * Remove lpfc_sysfs_set_[show|store] as it is no longer needed
+       * Redo lpfc_sysfs_params_[show|store] to one value per attribute rule
+       * Breakdown lpfc_sysfs_info_show into smaller one value per attribute
+       * Use device attributes instead of driver attributes where appropriate
+       * Remove no longer needed EXPORT_SYMBOLs
+       * Remove some unused code (1600 msg's related)
+
+Changes from 20040429 to 20040507
+
+       * Change version to 8.0.0
+       * Fix the number of cmd / rsp ring entries in lpfc_fcp.c to match
+         the divisions setup in lpfc_hw.h.
+       * Remove phba->iflag reference.
+       * Several locking improvements.
+       * Remove functions lpfc_drvr_init_lock, lpfc_drvr_lock,
+         lpfc_drvr_unlock and lpfc_hipri_*.
+       * Remove LPFC_DRVR_LOCK and LPFC_DRVR_UNLOCK macros.
+       * Make lpfc_info() use lpfc_get_hba_model_desc() instead of
+         rewriting almost identical code.
+       * Fix 1 overly long line in each of lpfc_cfgparm.h, lpfc_ftp.c and
+         lpfc_sli.c.
+       * Fix build for Red Hat 2.6.3 kernel by #defining MODULE_VERSION
+         only if it isn't already defined.
+       * Change elx_sli_issue_mbox_wait to return correct error code to
+         the caller.
+       * In some of the els completion routines, after calling
+         lpfc_elx_chk_latt, driver ignores the return code of the
+         lpfc_elx_chk_latt. This will prevent the discovery state machine
+         restarting correctly when there are link events in the middle of
+         discovery state machine running. Fix this by exiting discovery
+         state machine if lpfc_els_chk_latt returns a non zero value.
+       * Removed MAX_LPFC_BRDS from lpfc_diag.h
+       * Removed unused first_check.
+       * Remove some unused fields and defines.
+       * Change lpfc-param names to lpfc_param.
+       * Add use of MODULE_VERSION macro for 2.6 kernels.
+       * Shorten length of some of the comment lines to make them more
+         readable.
+       * Move FCP_* definitions to their own header file, lpfc_fcp.h.
+       * Remove unused prototypes from lpfc_crtn.h: fcptst, iptst,
+         lpfc_DELAYMS.
+       * Remove duplicated prototypes from lpfc_crtn.h:
+         lpfc_config_port_prep, lpfc_config_port_post,
+         lpfc_hba_down_prep.
+       * Removed some unused export_symbols.
+       * Install driver files into */drivers/scsi/lpfc instead of
+         */drivers/scsi.
+
+Changes from 20040426 to 20040429
+
+       * Declared export symbol lpfc_page_alloc and lpfc_page_free
+       * Changed lpfc version number to 6.98.3
+       * Move the definition of MAX_LPFC_BRDS to the only header file
+         that uses it (lpfc_diag.h).
+       * Change lpfc_sli_wake_iocb_wait to do a regular wake_up since
+         lpfc_sli_issue_iocb_wait now sleeps uninterruptible.
+       * Replace list_for_each() with list_for_each_safe() when a list
+         element could be deleted.
+       * Fix IOCB memory leak
+
+Changes from 20040416 to 20040426
+
+       * Change lpfc_config_port_prep() to interpret word 4 of the DUMP
+         mbox response as a byte-count
+       * Add info attribute to sysfs
+       * Minor formatting (spaces to tabs) cleanup in lpfc_sched.h
+       * Remove unused log message number 732
+       * Completing MODULE_PARM -> module_param changes
+       * Removed unused targetenable module parameter
+       * Removed locks from lpfc_sli_issue_mbox_wait routine
+       * Removed code that retry 29,00 check condition
+       * Removed code that manipulates rspSnsLen.
+       * Fix use of lun-q-depth config param
+       * Fix severity inconsistency with log message 249
+       * Removed lpfc_max_target from lpfc_linux_attach
+       * Replace references to lpfcDRVR.pHba[] with lpfc_get_phba_by_inst()
+       * Change lpfc_param to lpfc-param
+       * Partially removed 32 HBA restriction within driver.  Incorported
+         lpfc_instcnt, lpfc_instance[], and pHba[] into lpfcDRVR
+         structure Added routines lpfc_get_phba_by_inst()
+         lpfc_get_inst_by_phba() lpfc_check_valid_phba()
+       * Turn on attributes "set" & "params" by default.
+       * Further formatting/whitespace/line length cleanup on: lpfc_ct.c
+         lpfc_els.c lpfc_fcp.c lpfc_hbadisc.c lpfc_init.c lpfc_ipport.c
+         lpfc_mbox.c lpfc_nportdisc.c lpfc_sched.c lpfc_sched.h
+         lpfc_scsi.h lpfc_scsiport.c lpfc_sli.c and lpfc_sli.h
+       * Add log message 249 to log any unsupported device addressing
+         modes encountered.
+       * Add support for 256 targets and 256 LUNs
+       * Fixed panic in lpfc_linkdown.
+       * Removed (struct list_head*) casting in several calls to list_del
+       * Free irq reservation and kill running timers when insmod or
+         modprobe are killed via ctrl-c
+       * Remove drivers/scsi from include path
+       * Wrap use of log message 311 in macro
+       * Detect failure return from pci_map_sg call in lpfc_os_prep_io
+       * Fix use-after-free of IOCB in lpfc_sli_process_sol_iocb which
+         was causing an Oops on 2.6.5 kernel.
+       * Cleanup use of several gotos not used for error exit.
+       * Replace memcpy_toio() and memcpy_toio() with endian-dependent
+         lpfc_memcpy_to_slim() and lpfc_memcpy_from_slim() so that for
+         big endian hosts like PPC64, the SLIM is accessed 4 bytes at a
+         time instead of as a byte-stream.
+
+Changes from 20040409 to 20040416
+
+       * The scsi_register and scsi_alloc_host OS calls can fail and
+         return a zero-valued host pointer.  A ctrl-C on 2.6 kernels
+         during driver load will cause this and the driver to panic.
+         Fixed this bug.  Also found a bug in the error_x handling with
+         lpfc_sli_hba_down - it was in the wrong place and the driver
+         lock was not held, but needed to be (in lpfc_linux_attach) Fixed
+         both.  Did some minor comment clean up.
+       * Removed unwanted (void *) castings.
+       * Replace define of INVALID_PHYS, with kernel 2.6.5's
+         dma_mapping_error() and add a inline function for earlier
+         kernels.  Remove lpfc_bad_scatterlist().
+       * Clean up formatting in hbaapi.h, lpfc.h, lpfc_cfgparm.h,
+         lpfc_crtn.h, lpfc_ct.c, lpfc_diag.h, lpfc_disc.h, lpfc_els.c,
+         lpfc_fcp.c, lpfc_hbadisc.c, lpfc_hw.h, lpfc_init.c,
+         lpfc_ipport.c, lpfc_logmsg.c, lpfc_logmsg.h and lpfc_scsiport.c
+         - mostly replacing groups of 8 spaces with hard tabs and keeping
+         lines to 80 column max..
+       * Removed LPFC_DRVR_LOCK call from lpfc_unblock_requests for 2.4
+         kernels.  The lpfc_scsi_done routine already unlocks the driver
+         lock since it expects this lock to be held.
+       * Removed global lock capabilities from driver lock routines
+       * Remove SA_INTERRUPT flag from request_irq
+       * Move dma_addr_t cast inside of getPaddr macro as everywhere
+         getPaddr is used, the return is cast to dma_addr_t.
+       * Clean up formatting in lpfc_sli.c and lpfc_sysfs.c - mostly
+          replacing groups of 8 spaces with hard tabs and keeping lines
+          to 80 column max.
+       * Fix build for RHEL 2.1 BOOT kernels by always #including
+         interrupt.h in lpfc.h.
+       * Fix RHEL 3 build by #defining EXPORT_SYMTAB.
+       * Replace sprintf with snprintf in lpfc_proc_info.
+       * Fix build warnings on 2.6 kernels - remove no longer used calls
+         to  character device initialization.
+       * Initial support code for discovery in tasklet conversion.
+       * Removing char interface and ioctl code.
+       * Change all elx prefixes to lpfc
+       * Replace lpfc_write_slim() & lpfc_read_slim() with memcpy_toio(),
+         memcpy_fromio(), writel() & readl().
+
+Changes from 20040402 to 20040409
+
+       * Replaced lpfc_read_hbaregs_plus_offset and
+         lpfc_write_hbaregs_plus_offset functions with readl and writel.
+       * Get rid of long mdelay's in insmod path
+       * Changed the way our pci_device_id structures are initialized
+       * Replace lpfc_read/write_CA/HA/HC/HS with calls to readl() &
+         writel() directly.
+       * Increase SLI2_SLIM to 16K Increase cmd / rsp IOCBs accordingly
+       * Removed lpfc_els_chk_latt from the lpfc_config_post function.
+         lpfc_els_chk_latt will enable the link event interrupts when
+         flogi is pending which causes two discovery state machines
+         running parallely.
+       * Add pci_disable_device to unload path.
+       * Move lpfc_sleep_event from lpfc_fcp.c to lpfc_util_ioctl.c
+       * Call dma_map_single() & pci_map_single() directly instead of via
+         macro lpfc_pci_map().  Allow address 0 for PPC64.
+       * Change sleep to uninterruptible in lpfc_sli_issue_icob_wait
+         because this function doesn't handle signals.
+       * Move lpfc_wakeup_event from lpfc_fcp.c to lpfc_ioctl.c
+       * Remove unneeded #include <linux/netdevice.h>
+       * Remove unused clock variables lpfc_clkCnt and lpfc_sec_clk.
+       * Get rid of capitalization of function names.
+       * Removed lpfc_addr_sprintf.
+       * Implemented gotos in lpfc_linux_attach for error cases.
+       * Replace mlist->dma.list = dmp->dma.list; to mlist = dmp.
+       * Remove functions lpfc_get_OsNameVersion and elx_wakeup. Change
+         elx_wakeup to wake_up_interruptible
+       * Add function lpfc_get_os_nameversion and change
+         lpfc_get_OsNameVersion to lpfc_get_os_nameversion.
+       * Remove lpfc_get_OsNameVersion
+       * Change driver name to a consistent lpfc in every visible place.
+       * Fix build warning: removed unused variable ret in lpfc_fdmi_tmo.
+       * Remove lpfc_utsname_nodename_check function
+       * Remove functions lpfc_register_intr and lpfc_unregister_intr
+       * Fill in owner field in lpfc_ops file_operations struct and
+         remove now unnecessary open and close entry points.
+       * Change function name prefixes from elx_ to lpfc_
+       * Remove special case check for TUR in elx_os_prep_io()
+       * Renamed elx_scsi.h to lpfc_scsi.h
+       * Renamed elx_sched.h to lpfc_sched.h
+       * Renamed elx_mem.h to lpfc_mem.h
+       * Renamed elx_sli.h to lpfc_sli.h
+       * Renamed elx_logmsg.h to lpfc_logmsg.h
+       * Renamed elx.h to lpfc.h
+       * Renamed elx_sli.c to lpfc_sli.c
+       * Renamed elx_sched.c to lpfc_sched.c
+       * Renamed elx_mem.c to lpfc_mem.c
+       * Renamed elx_logmsg.c to lpfc_logmsg.c
+       * Renamed lpfcLINUXfcp.c lpfc_fcp.c
+       * Renamed elx_clock.c to lpfc_clock.c
+       * Reduce stack usage in lpfc_info().
+       * Move lpip_stats structure from lpfc_hba.h to lpfc_ip.h.
+       * Move lpfc_stats and HBAEVT_t structures from lpfc_hba.h to
+         lpfc.h
+       * Remove lpfc_hba.h
+       * Remove duplicate rc definitions from 
+       * Removed code which used next pointer to store mbox structure.
+       * Cleaned up list iterations.
+       * Removed non list manipulation of the next pointers.
+       * Change list_del()/INIT_LIST_HEAD sequences to list_del_init()
+       * In ELX_IOCBQ_t: Moved hipri_trigger field to iocb_flag. Combined
+         hipri_wait_queue and rsp_iocb in union
+       * Replaced casting from list_head with list_entry macro.
+       * Added ct_ndlp_context field to the ELX_IOCBQ_t.
+       * Do not use DMABUf_t list to store ndlp context
+       * Return 0 from lpfc_process_iotcl_util() when ELX_INITBRDS
+         succeeds.
+       * remove elx_os_scsiport.h
+       * Do not use DMABUf_t list to hold rpi context
+       * Replace elx_cfg_* names with lpfc_cfg-*
+       * Moved FCP activity to ring 0.  Moved ELS/CT activity to ring 2.
+       * Clean up formatting of elx_sli.h (tabs for indents, 80 column
+         lines).
+       * Remove unused elxclock declaration in elx_sli.h.
+       * Since everywhere IOCB_ENTRY is used, the return value is cast,
+         move the cast into the macro.
+       * Split ioctls out into seperate files
+
+Changes from 20040326 to 20040402
+
+       * Updated ChangeLog for 20040402 SourceForge drop.
+       * Use safe list iterator for ndlp list
+       * Added code to return NLP_STE_FREED_NODE from the discovery
+         state machine functions if the node is freed from the
+         function.
+       * Fixes to DMABUF_t handling
+       * Fix for load error in discovery
+       * Remove loop_cnt variable from lpfc_rcv_plogi_unused_node.
+       * Remove nle. reference.
+        * Remove support for building 2.4 drivers
+       * Remove elx_util.h and replace elx_disc.h with lpfc_disc.h
+       * Implemented the Linux list macros in the discovery code.
+         Also moved elx_disc.h contents into lpfc_disc.h
+       * Unused variable cleanup
+       * Use Linux list macros for DMABUF_t
+       * Break up ioctls into 3 sections, dfc, util, hbaapi
+         rearranged code so this could be easily seperated into a
+         differnet module later All 3 are currently turned on by
+         defines in lpfc_ioctl.c LPFC_DFC_IOCTL, LPFC_UTIL_IOCTL,
+         LPFC_HBAAPI_IOCTL
+       * Misc cleanup: some goto's; add comments; clarify function
+         args
+       * Added code to use list macro for ELXSCSITARGET_t.
+       * New list implementation for ELX_MBOXQ_t
+       * Cleaned up some list_head casting.
+       * Put IPFC ifdef around two members of struct lpfc_nodelist.
+       * Cleaned up iocb list using list macros and list_head data
+         structure.
+       * lpfc_online() was missing some timer routines that were
+         started by lpfc_linux_attach().  These routines are now also
+         started by lpfc_online().  lpfc_offline() only stopped
+         els_timeout routine.  It now stops all timeout routines
+         associated with that hba.
+       * Replace seperate next and prev pointers in struct
+         lpfc_bindlist with list_head type.  In elxHBA_t, replace
+         fc_nlpbind_start and _end with fc_nlpbind_list and use
+         list_head macros to access it.
+       * Fix ulpStatus for aborting I/Os overlaps with newer firmware
+         ulpStatus values
+       * Rework params_show/store to be consistent as the other
+         routines.  Remove generic'ness and rely on set attribute.
+       * Remove unused log message.
+       * Collapse elx_crtn.h and prod_crtn.h into lpfc_crtn.h
+       * Ifdef Scheduler specific routines
+       * Removed following ununsed ioclt's: ELX_READ_IOCB
+         ELX_READ_MEMSEG ELX_READ_BINFO ELX_READ_EINVAL ELX_READ_LHBA
+         ELX_READ_LXHBA ELX_SET ELX_DBG LPFC_TRACE 
+       * Removed variable fc_dbg_flg
+       * Fixed a bug where HBA_Q_DEPTH was set incorrectly for
+         3-digit HBAs.  Also changed can_queue so midlayer will only
+         send (HBA_Q_DEPTH - 10) cmds.
+       * Clean up code in the error path, check condition.  Remove
+         ununsed sense-related fields in lun structure.
+       * Added code for safety pools for following objects: mbuf/bpl,
+         mbox, iocb, ndlp, bind
+       * Wrapped '#include <elx_sched.h>' in '#ifdef USE_SCHEDULER'.
+       * Fixed 'make clean' target.
+        * Build now ignores elx_sched.o, and includes lpfc_sysfs.o.
+       * Wrapped lpfndd.o target in BUILD_IPFC ifdef.
+       * Removed elx_os.h inclusion in implementation files.
+       * Removed ELX_OS_IO_t data structure and put data direction
+         and non scatter/gather physical address into the scsi buffer
+         structure directly.  Moved DRVR_LOCK, putPaddr, getPaddr
+         macros and some defines into elx.h since they are required
+         by the whole driver.
+       * Migrated following ioctls (debug) ELX_DISPLAY_PCI_ALL
+         ELX_DEVP ELX_READ_BPLIST ELX_RESET_QDEPTH ELX_STAT.
+       * Step 1 of attempt to move all Debug ioctls to sysfs.
+         Implemented the following IOCTLs in sysfs: ELX_WRITE_HC
+         ELX_WRITE_HS ELX_WRITE_HA ELX_WRITE_CA ELX_READ_HC
+         ELX_READ_HS ELX_READ_HA ELX_READ_CA ELX_READ_MB ELX_RESET
+         ELX_READ_HBA ELX_INSTANCE ELX_LIP.  Also introduced
+         attribute "set" to be used in conjuction with the above
+         attributes.
+       * Removed DLINK, enque and deque declarations now that clock
+         doesn't use them anymore
+       * Separated install rule so that BUILD_IPFC has to be set when
+         make is called in order for the install rule to attempt to
+         copy the lpfndd.o driver.  This change fixes a bug that
+         occurs because the install rule by default attempted to
+         install lpfndd.o, whereas the default make rule did not by
+         default build lpfndd.o.
+       * Keep track if hbaapi index numbers need to be refreshed.
+       * Removed prod_os.h from include list.
+       * Removed LPFC_LOCK and LPFC_UNLOCK macros.  Added OS calls
+         into elx_os_scsiport.c.  This file is now empty.
+       * Added spin_lock_irqsave and spin_unlock_irqrestore calls
+         into code directly and removed LPFC_LOCK_ and _UNLOCK_
+         macros
+       * Remove references to "elx_clock.h"
+       * Added utsname.h to include list.  The previous checkin to
+         elx_os.h removed its inclusion of utsname.h since there is
+         precious little in the file.  However, lpfcLINUXfcp.c needs
+         it and now has it.
+       * Removed some commented-out code
+       * Removed elx_lck_t data structure, stray elxDRVR_t type, and
+         include from file.  No longer used.
+       * Removed two PCI Sync defines.  Removed includes - not
+         needed.  Cleaned up macro lines.
+       * Added two functions from elxLINUXfcp.c.  These functions
+         were IPFC specific.
+       * Removed hipri lock abstractions and added OS call into code.
+         Removed elx_lck_t and added spinlock_t directly. Moved two
+         IPFC functions into lpfc_ipport.c
+       * Moved IP specific structures to lpfc_ip.h file.
+       * lpfc_ipfarp_timeout() uses system timer.  Remove all usages
+         of old internal clock support.
+       * Made changes to compile without IPFC support for the default
+         build.  Added ifdef IPFC for all lpfc_ip.h includes.
+       * Patched elx_free_scsi_buf
+       * Removed elx_sched.o from 2.6 dependencies
+       * Reworked lpfc_pcimap.
+       * Use Linux swap macros to replace ELX swapping macros
+         (SWAP_SHORT, SWAP_LONG, SWAP_DATA, SWAP_DATA16,
+         PCIMEM_SHORT, PCIMEM_LONG, PCIMEM_DATA).
+       * move in_interrupt() check inside of elx_sleep_ms()
+       * Moved location of pci.h include.
+       * Restored elx_lck_t types in elxHBA_t.
+       * Removed elx_pci_dma_sync call.  Also removed some PCI
+         defines from elx_hw.h and removed the spinlock_t locks that
+         are no longer used in elx.h
+       * elx_iodone() now uses system timer.
+       * elx_qfull_retry() now uses system timer.
+       * lpfc_put_buf(), lpfc_ip_xri_timeout() and
+         lpfc_ip_timeout_handler() now use system timer.
+       * lpfc_fdmi_tmo() and lpfc_qthrottle_up() now use system
+          timer.
+       * Removed num_bufs and num_iocbs configuration parameters.
+       * Fixed a memory corruption bug. This was caused by a memory
+         write to ndlp structure from lpfc_cmpl_els_acc function.
+         This ndlp structure was freed from lpfc_els_unsol_event.
+       * lpfc_disc_timeout() and lpfc_establish_link_tmo() now use
+         system timer.  Also update lpfc_els_retry_delay() to do a
+         single lock release at the end.
+       * Remove use of PAN (pseudo adapter number).
+       * Reintroduced usage of the cross compiler for building on
+         ppc64 to remove build errors that were cropping up when
+         using the standard gcc compiler.
+       * Fix no-unlock-before return in lpfc_els_retry_delay which was
+         causing  a deadlock on insmod in some environments.
+       * Minor format changes fix up comments
+       * Create utility clock function elx_start_timer() and
+         elx_stop_timer().  All timeout routines now use these common
+         routines.
+       * Minor formating changes fix up comments
+       * Minor formatting changes get rid of failover defines for
+         syntax checking
+       * Minor formatting changes remove ISCSI defines.
+       * Fix typo in install target for 2.4 kernels.
+       * Removed unused elx_scsi_add_timer extern function
+         declaration.
+       * Cleanup casting around DMA masks.
+       * Comment out lpfndd.o modules_install section as lpfndd.o is
+         not generated if CONFIG_NET_LPFC is not set. Also refer to
+         BASEINCLUDE only in out of kernel source module builds as it
+         will not exist otherwise.
+       * Removed unused malloc counters from lpfcLINUXfcp.c.
+       * Remove some unnecessary #includes in lpfcLINUXfcp.c
+       * Remove unncessary #includes in elxLINUXfcp.c
+       * Minor formatting cleanups in Makefile to avoid some
+          linewrapping.
+       * Removed unused elx_mem_pool data structure.
+       * Remove several unnecessary #includes.
+       * Moving fix for memory leak in ioctl lip area to sysfs's lip.
+       * Removed unused elx_dma_handle_t elx_acc_handle_t
+         FC_MAX_SEGSZ and FC_MAX_POOL.
+       * Rewrite of Makefile. Fixes breakages with make -j4 during
+         kernel compile. Does not recompile all files on every
+         build. Uses the kernel build's definitions of CFLAGS,
+         MODFLAGS etc. Removed "make rpm" option.
+       * Removed unused #defines CLOSED, DEAD, OPENED, NORMAL_OPEN
+         and unneeded #include of elx_sched.h in elx.h.
+       * Several log message updates
+       * Add PCI_DEVICE_ID_FIREFLY for LP6000
+       * Fixed known issues in 20040326: driver crashes on rmmod in
+         both 2.4 and 2.6 kernels
+       
+
+Changes from 20040319 to 20040326
+
+       * Updated ChangeLog for 20040326 SourceForge drop.
+       * remove lpfc_isr / lpfc_tmr logic fixed up 8 spaces from
+         previous checkins with tabs
+       * replace elx_in_intr() with in_interrupt()
+       * Remove unused messages 1602 and 1603.
+       * Fix the following issues with log messages: Remove unused
+         messages 406, 407, 409, 927, 928, 1201, 1202, 1204, 1205, 1206
+         and 1207.  Create a new message 738 to fix duplicate instances
+         of 736.
+       * Removed remaining pci interface abstractions from elxLINUXfcp.c.
+         Implemented OS calls directly in all remaining files and cleaned
+         up modules.  Removed prototypes as well.
+       * Removed following functions/structures elx_mem_dmapool
+         elx_idx_dmapool elx_size_dmapool elx_kmem_lock dfc_data_alloc
+         dfc_data_free dfc_mem struct mbuf_info elx_acc_handle_t
+         data_handle elx_dma_handle_t dma_handle struct elx_memseg
+         MEMSEG_t
+       * lpfc_els_timeout_handler() now uses system timer.
+       * Further cleanup of #ifdef powerpc
+       * lpfc_scsi_timeout_handler() now uses system timer.
+       * Replace common driver's own defines for endianess w/ Linux's
+         __BIG_ENDIAN etc.
+       * Added #ifdef IPFC for all IPFC specific code.
+       * lpfc_disc_retry_rptlun() now uses system timer.
+       * lpfc_npr_timeout() now uses system timer.
+       * Modified detect code, on insmod, to only wait a max of 2 secs if
+         link comes up and there are no devices.
+       * Move remaining message logging functions into
+         elx_logmsg.c/elx_logmsg.h.
+       * Added code to clear link attention bit when there is a pending
+         link event and the memory allocation for read_la mail box
+         command fails.
+       * Removed function calls for mapping bar registers and allocating
+         kernel virtual memory mappings to the mapped bars Removed
+         prototypes, lpfc_driver_cache_line, and pci_bar1_map rename to
+         pci_bar2_map.
+       * Allocate mbox only if the hba_state is in ready state.
+       * Complete lip support via sysfs. To lip, echo brdnum >
+         /sys/bus/pci/drivers/lpfc/lip.
+       * moving sysfs show/store implementations to lpfc_sysfs.c. Also add
+         support for lip.
+       * Add files: lpfc_sysfs.c, lpfc_sysfs.h
+       * move LPFC_DRIVER_NAME and LPFC_MODULE_DESC out of lpfcLINUXfcp.c
+         to lpfc_version.h, since it is now needed in lpfc_sysfs.c
+       * elx_mbox_timeout now uses system timer
+       * Changed lpfc_nodev_timeout, lpfc_els_retry_delay and
+         lpfc_linkdown_timeout to use the system timer instead of
+         internal clock support.
+       * Move remaining message logging functions in elx_util.c to
+         elx_logmsg.c.
+       * Remove some unnecessary typecasting.
+       * Remove log message that is no longer used (was used by
+         elx_str_atox).
+       * Replaced DLINK_t and SLINK_t by standard Linux list_head
+       * Removed deque macro
+       * Replaced ELX_DLINK_t ans ELX_SLINK_t by Linux struct list_head
+         (except for clock)
+       * Removed following functions from code: linux_kmalloc linux_kfree
+         elx_alloc_bigbuf elx_free_bigbuf
+       * Removed following abstract functions from the code.  elx_malloc
+         elx_free elx_ip_get_rcv_buf elx_ip_free_rcv_buf
+         elx_mem_alloc_dmabuf elx_mem_alloc_dmabufext elx_mem_alloc_dma
+         elx_mem_alloc_buf lpfc_bufmap
+       * Removed custom PCI configuration #defines and replaced with
+         OS-provided #defines. Also added linux/pci.h to *.c files.
+       * Remove elx_str_ctox.  Replace elx_str_atox with sscanf.
+       * Many indentation/whitespace fixes.
+       * Replace elx_str_ctox with isxdigit where it was only used to
+         check the value of a character.
+       * Removed following functions from the code.  elx_kmem_free
+         elx_kmem_alloc elx_kmem_zalloc
+       * Change use of 2.4 SCSI typedef Scsi_Host_Template to  struct
+         scsi_host_template for 2.6 kernels.
+       * Change use of 2.4 SCSI typedefs (Scsi_Device, Scsi_Cmnd,
+         Scsi_Request) the their real struct names.
+       * Move 2.6 compatibility irqreturn definitions to lpfc_compat.h.
+         Protect these definitions from conflicting with similar ones in
+         later 2.4 kernels.
+       * Remove unused definitions: LINUX_TGT_t, LINUX_LUN_t,
+         LINUX_BUF_t, elx_lun_t, SET_ADAPTER_STATUS.
+       * Convert pci_ calls to linux 2.6 dma_ equivalents.
+       * Removed unused types: struct buf, struct sc_buf, T_SCSIBUF
+         typedef.
+       * Fix Makefile so that 2.4 drivers don't always rebuild all files.
+       * Remove unused _static_ and fc_lun_t definitions.
+       * Cleaned up some memory pool implementation code.
+       * Fix panic with char dev changes. Turns out that 2.6.4 code does
+         the same in kernel space with the 2.4 interface style
+         definitions. So remove the new char dev code altogether.
+       * Remove typecasting from fc_get_cfg_param and consolidate
+         multiple instances of the parameter switch into a single
+         instance.
+       * Use lpfc_is_LC_HBA() macro that tests pcidev->device directly
+         instead of saving a private copy that undergoes varied shifting
+         & casting.
+       * Removed usage of all memory pools.
+
+Changes from 20040312 to 20040319
+       
+       * Use dev_warn instead of printk for 2.6 kernels
+       * Correct Iocbq completion routine for 2.6 kernel case
+       * Change void *pOSCmd to Scsi_Smnd *pCmd
+       * Change void *pOScmd to struct sk_buff *pCmd
+       * Remove data directon code.
+       * Removed memory pool for buf/bpl buffers and use kmalloc/kfree
+         pci_pool_alloc/free directly.
+       * Move PPC check for DMA address 0 in scatter-gather list, into
+         lpfc_compat.h
+       * Always use pci_unmap_single() instead of pci_unmap_page()
+       * Clean up the 2.6 vs 2.4 #if blocks.
+       * Conditionalize Scheduler
+       * Add a comment to explain a little what the first Makefile
+         section does.
+       * Removed lpfc_intr_post
+       * Sysfs new display format. Also added write functionality. You
+         can [ echo "0 log_verbose 3" >
+         /sys/bus/pci/drivers/lpfc/params]. Hex support yet to be added.
+       * Removed several #ifdef powerpc, including for a discovery issue
+         in lpfc_ValidLun()
+       * Change elx_printf_log to use vsprintf.
+       * Added lpfc_compat.h provides macros to aid compilation in the
+         Linux 2.4 kernel over various platform architectures.  Initially
+         support mapping to a DMA address.
+       * Removed memory pool for nlp/bind buffers and use kmalloc/kfree
+         directly.
+       * Removed memory pool for iocb buffers and use kmalloc/kfree
+         directly.
+       * Removed memory pool for mailbox buffers and use kmalloc/kfree
+         directly.
+       * Cleaned up back and forth casts
+       * Initial support for sysfs for 2.6 kernel.
+       * Changed elx_dma_addr_t to dma_addr_t
+       * Fix a 2.6 kernel check to be >= 2.6.0 instead of > (was missing
+         2.6.0).
+       * Remove elx_printf and elx_str_sprintf. Replace elx_print with
+         printk.
+       * Replace elx_printf with printk.
+       * Replace elx_str_sprintf with sprintf.
+       * Removed the mem_lock, its prototype, function, macro, and
+         iflags.
+       * Use kmalloc/kfree for ELX_SCSI_BUF_t
+       * Use linux pci_pools for SCSI_DMA_EXT
+       * Use linux pci_pools for BPLs.
+       * Minor cleanup of DFC args for PPC64.
+       * Several small indentation cleanups.
+       * New Linux 2.6 style of char device registration.
+       * Migrated members of LPFCHBA_t and LINUX_HBA_t into elxHBA_t
+       * Use strcpy, strncmp, isdigit, strlen instead of abstractions
+       * Cleanup of driver_template.
+       * Facilitate compile time turn on/off of lpfc_network_on.
+       * Split large source files into smaller, better named ones.
+
+Changes from 2.10a to 20040312
+
+       * Fix build for 2.4 kernels
+       * Move driver version macros into lpfc_version.h file.
+       * Fixed data miscompare with LIP.
+       * Removed elx_sli, elx_ioc, elx_disc, elx_sch routines,
+         prototypes, and reference points.
+       * Correct the space insertions with hardtabs
+       * Remove routine call pointers in ELX_SLI_INIT_t struct.
+       * Removed module locks except for drvr, mem, and clock.
+       * Removed unused module locks from sourcebase. Kept drvr_lock,
+         mem_lock, and clock_lock.
+       * Change NULL to 0
diff -urN linux/Documentation/scsi/lpfc.txt linux/Documentation/scsi/lpfc.txt
--- linux/Documentation/scsi/lpfc.txt   1970/01/01 00:00:00
+++ linux/Documentation/scsi/lpfc.txt   2005-04-29 12:14:59.955276000 +0100     
1.1
@@ -0,0 +1,83 @@
+
+LPFC Driver Release Notes:
+
+=============================================================================
+
+
+                               IMPORTANT:
+
+  Starting in the 8.0.17 release, the driver began to be targeted strictly
+  toward the upstream kernel. As such, we removed #ifdefs for older kernels
+  (pre 2.6.10). The 8.0.16 release should be used if the driver is to be
+  run on one of the older kernels.
+
+  The proposed modifications to the transport layer for FC remote ports
+  and extended attribute support is now part of the upstream kernel
+  as of 2.6.12. We no longer need to provide patches for this support,
+  nor a *full* version which has old an new kernel support.
+  
+  The driver now requires a 2.6.12 (if pre-release, 2.6.12-rc1) or later
+  kernel.
+  
+  Please heed these dependencies....
+
+
+   ********************************************************************
+
+
+The following information is provided for additional background on the
+history of the driver as we push for upstream acceptance.
+
+Cable pull and temporary device Loss:
+
+  In older revisions of the lpfc driver, the driver internally queued i/o 
+  received from the midlayer. In the cases where a cable was pulled, link
+  jitter, or a device temporarily loses connectivity (due to its cable
+  being removed, a switch rebooting, or a device reboot), the driver could
+  hide the disappearance of the device from the midlayer. I/O's issued to
+  the LLDD would simply be queued for a short duration, allowing the device
+  to reappear or link come back alive, with no inadvertant side effects
+  to the system. If the driver did not hide these conditions, i/o would be
+  errored by the driver, the mid-layer would exhaust its retries, and the
+  device would be taken offline. Manual intervention would be required to
+  re-enable the device.
+
+  The community supporting kernel.org has driven an effort to remove
+  internal queuing from all LLDDs. The philosophy is that internal
+  queuing is unnecessary as the block layer already performs the 
+  queuing. Removing the queues from the LLDD makes a more predictable
+  and more simple LLDD.
+
+  As a potential new addition to kernel.org, the 8.x driver was asked to
+  have all internal queuing removed. Emulex complied with this request.
+  In explaining the impacts of this change, Emulex has worked with the
+  community in modifying the behavior of the SCSI midlayer so that SCSI
+  devices can be temporarily suspended while transport events (such as
+  those described) can occur.  
+
+  The proposed patch was posted to the linux-scsi mailing list. The patch
+  is contained in the 2.6.10-rc2 (and later) patch kits. As such, this
+  patch is part of the standard 2.6.10 kernel.
+
+  By default, the driver expects the patches for block/unblock interfaces
+  to be present in the kernel. No #define needs to be set to enable support.
+
+
+Kernel Support
+
+  This source package is targeted for the upstream kernel only. (See notes
+  at the top of this file). It relies on interfaces that are slowing
+  migrating into the kernel.org kernel.
+
+  At this time, the driver requires the 2.6.12 (if pre-release, 2.6.12-rc1)
+  kernel.
+
+  If a driver is needed for older kernels please utilize the 8.0.16
+  driver sources.
+
+
+Patches
+
+  Thankfully, at this time, patches are not needed.
+
+
diff -urN linux/Documentation/scsi/scsi_mid_low_api.txt 
linux/Documentation/scsi/scsi_mid_low_api.txt
--- linux/Documentation/scsi/scsi_mid_low_api.txt       2005/01/13 14:05:16     
1.14
+++ linux/Documentation/scsi/scsi_mid_low_api.txt       2005/04/29 11:14:59     
1.15
@@ -389,8 +389,6 @@
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_report_bus_reset - report scsi _bus_ reset observed
    scsi_set_device - place device reference in host structure
-   scsi_to_pci_dma_dir - convert SCSI subsystem direction flag to PCI
-   scsi_to_sbus_dma_dir - convert SCSI subsystem direction flag to SBUS
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unregister - [calls scsi_host_put()]
@@ -757,48 +755,6 @@
 
 
 /**
- * scsi_to_pci_dma_dir - convert SCSI subsystem direction flag to PCI
- * @scsi_data_direction: SCSI subsystem direction flag
- *
- *      Returns DMA_TO_DEVICE given SCSI_DATA_WRITE,
- *              DMA_FROM_DEVICE given SCSI_DATA_READ
- *              DMA_BIDIRECTIONAL given SCSI_DATA_UNKNOWN
- *              else returns DMA_NONE
- *
- *      Might block: no
- *
- *      Notes: The SCSI subsystem now uses the same values for these
- *      constants as the PCI subsystem so this function is a nop.
- *      The recommendation is not to use this conversion function anymore
- *      (in the 2.6 kernel series) as it is not needed.
- *
- *      Defined in: drivers/scsi/scsi.h .
- **/
-int scsi_to_pci_dma_dir(unsigned char scsi_data_direction)
-
-
-/**
- * scsi_to_sbus_dma_dir - convert SCSI subsystem direction flag to SBUS
- * @scsi_data_direction: SCSI subsystem direction flag
- *
- *      Returns DMA_TO_DEVICE given SCSI_DATA_WRITE,
- *              FROM_DEVICE given SCSI_DATA_READ
- *              DMA_BIDIRECTIONAL given SCSI_DATA_UNKNOWN
- *              else returns DMA_NONE
- *
- *      Notes: The SCSI subsystem now uses the same values for these
- *      constants as the SBUS subsystem so this function is a nop.
- *      The recommendation is not to use this conversion function anymore
- *      (in the 2.6 kernel series) as it is not needed.
- *
- *      Might block: no
- *
- *      Defined in: drivers/scsi/scsi.h .
- **/
-int scsi_to_sbus_dma_dir(unsigned char scsi_data_direction)
-
-
-/**
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  *                      device to determine if and when there is a need
  *                      to adjust the queue depth on the device.
diff -urN linux/Documentation/scsi/qla2xxx.revision.notes 
linux/Documentation/scsi/qla2xxx.revision.notes
--- linux/Documentation/scsi/Attic/qla2xxx.revision.notes       2005-04-29 
12:14:59.994462000 +0100     1.1
+++ linux/Documentation/scsi/Attic/qla2xxx.revision.notes       1970/01/01 
00:00:00+0100
@@ -1,457 +0,0 @@
-/*
- * QLogic ISP2200 and ISP2300 Linux Driver Revision List File.
- *
- ********************************************************************
- *
- * Revision History
- *
- *  Rev  8.00.00b8     December 5, 2003        AV
- *     - Instruct mid-layer to perform initial scan.
- *
- *  Rev  8.00.00b7     December 5, 2003        AV
- *     - Resync with Linux Kernel 2.6.0-test11.
- *     - Add basic NVRAM parser (extras/qla_nvr).
- *
- *  Rev  8.00.00b7-pre11 December 3, 2003      AV
- *     - Sanitize the scsi_qla_host structure:
- *       - Purge unused elements.
- *       - Reorganize high-priority members (cache coherency).
- *     - Add support for NVRAM access via a sysfs binary attribute:
- *       - Consolidate semaphore locking access.
- *     - Fix more PCI posting issues.
- *     - Add extras directory for dump/NVRAM tools.
- *     - Remove unused qla_vendor.c file.
- *
- *  Rev  8.00.00b7-pre11 November 26, 2003     DG/AV
- *     - Merge several patches from Christoph Hellwig [hch@lst.de]:
- *       - in Linux 2.6 both pci and the scsi layer use the generic
- *         dma direction bits, use them directly instead of the scsi
- *         and pci variants and the (noop) conversion routines.
- *     - Fix _IOXX_BAD() usage for external IOCTL interface.
- *     - Use atomic construct for HA loop_state member.
- *     - Add generic model description text for HBA types.
- *
- *  Rev  8.00.00b7-pre5        November 17, 2003       AV
- *     - Merge several patches from Christoph Hellwig [hch@lst.de]:
- *       - patch to split the driver into a common qla2xxx.ko and a
- *         qla2?00.ko for each HBA type - the latter modules are
- *         only very small wrappers, mostly for the firmware
- *         images, all the meat is in the common qla2xxx.ko.
- *       - make the failover code optional.
- *       - kill useless lock_kernel in dpc thread startup.
- *       - no need for modversions hacks in 2.6 (or 2.4).
- *       - kill qla2x00_register_with_Linux.
- *       - simplify EH code, cmd or it's hostdata can't be NULL, no
- *         need to search whether the host it's ours, the midlayer
- *         makes sure it won't call into a driver for some else
- *         host.
- *     - Merge several patches from Jes Sorensen
- *       [jes@wildopensource.com]:
- *       - Call qla2x00_config_dma_addressing() before performing
- *         any consistent allocations. This is required since the
- *         dma mask settings will affect the memory
- *         pci_alloc_consistent() will return.
- *       - Call pci_set_consistent_dma_mask() to allow for 64 bit
- *         consistent allocations, required on some platforms such
- *         as the SN2.
- *       - Wait 20 usecs (not sure how long is really necessary,
- *         but this seems safe) after setting CSR_ISP_SOFT_RESET in
- *         the ctrl_status register as the card doesn't respond to
- *         PCI reads while in reset state. This causes a machine
- *         check on some architectures.
- *       - Flush PCI writes before calling udelay() to ensure the
- *         write is not sitting idle in-flight for a while before
- *         hitting the hardware.
- *       - Include linux/vmalloc.h in qla_os.c since it uses
- *         vmalloc().
- *       - Use auto-negotiate link speed when using default
- *         parameters rather than NVRAM settings. Disable NVRAM
- *         reading on SN2 since it's not possible to execute the
- *         HBA's BIOS on an SN2. I suggest doing something similar
- *         for all architectures that do not provide x86 BIOS
- *         emulation.
- *     - Clean-up slab-cache allocations:
- *       - locking.
- *       - mempool allocations in case of low-memory situations.
- *     - Fallback to GA_NXT scan if GID_PT call returns more than
- *       MAX_FIBRE_DEVICES.
- *     - Preserve iterating port ID across GA_NXT calls in
- *       qla2x00_find_all_fabric_devs().
- *     - Pre-calculate ASCII firmware dump length as to not incur the
- *       cost-to-calculate at each invocation of a read().
- *
- *  Rev  8.00.00b6     November 4, 2003        AV
- *     - Add new 2300 TPX firmware (3.02.18).
- *
- *  Rev  8.00.00b6-pre25 October 20, 2003      RA/AV
- *     - Resync with Linux Kernel 2.6.0-test9.
- *     - Rework firmware dump process:
- *       - Use binary attribute within sysfs tree.
- *       - Add user-space tool (gdump.sh) to retrieve formatted
- *         buffer.
- *       - Add ISP2100 support.
- *     - Use a slab cache for SRB allocations to reduce memory
- *       pressure.
- *     - Initial conversion of driver logging methods to a new
- *       qla_printk() function which uses dev_printk (Daniel
- *       Stekloff, IBM).
- *     - Further reduce stack usage in qla2x00_configure_local_loop()
- *       and qla2x00_find_all_fabric_devs().
- *     - Separate port state used for routing of I/O's from port
- *       mgmt-login retry etc.
- *
- *  Rev  8.00.00b6-pre19 October 13, 2003      AV
- *     - Resync with Linux Kernel 2.6.0-test7-bk5.
- *     - Add intelligent RSCN event handling:
- *       - reduce scan time during 'port' RSCN events by only
- *         querying specified port ids.
- *       - Available on ISP23xx cards only.
- *     - Increase maximum number of recognizable targets from 256
- *       to 512.
- *       - Backend changes were previously added to support TPX
- *         (2K logins) firmware.  Mid-layer can now scan for targets
- *         (H, B, T, L) where 512 < T >= 0.
- *     - Remove IP support from driver.
- *       - Switch firmware types from IP->TP for ISP22xx and
- *         IPX->TPX for ISP23xx cards.
- *       - Remove files qla_ip.[ch].
- *     - Remove type designations from firmware filenames.
- *
- *  Rev  8.00.00b6-pre11 September 15, 2003    DG/AV
- *     - Resync with 6.06.00.
- *     - Resync with Linux Kernel 2.6.0-test5-bk3.
- *     - Add new 2300 IPX firmware (3.02.15).
- *
- *  Rev  8.00.00b5     July 31, 2003           AV
- *     - Always create an fc_lun_t entry for lun 0 - as the mid-
- *       layer requires access to this lun for discovery to occur.
- *     - General sanitizing:
- *       - Add generic firmware option definitions.
- *       - Generalize retrieval/update of firmware options.
- *       - Fix compile errors which occur with extended debug.
- *       - Handle failure cases for scsi_add_host() and
- *         down_interruptible().
- *     - Host template updates:
- *       - Use standard bios_param callback function.
- *       - Disable clustering.
- *       - Remove unchecked_is_dma entry.
- *
- *  Rev  8.00.00b5-pre5        July 29, 2003           DG/AV
- *     - Resync with 6.06.00b13.
- *     - Resync with Linux Kernel 2.6.0-test2.
- *     - Pass the complete loop_id, not the masked (0xff) value
- *       while issuing mailbox commands (qla_mbx.c/qla_fo.c/
- *       qla_iocb.c/qla_init.c).
- *     - Properly handle zero-length return status for an RLC CDB.
- *     - Create an fclun_t structure for 'disconnected' luns,
- *       peripheral-qualifier of 001b.
- *     - Remove unused LIP-sequence register access during AE 8010.
- *     - Generalize qla2x00_mark_device_lost() to handle forced 
- *       login request -- modify all direct/indirect invocations 
- *       with proper flag.
- *     - Save RSCN notification (AE 8015h) data in a proper and 
- *       consistent format (domain, area, al_pa).
- *     - General sanitizing:
- *       - scsi_qla_host structure member reordering for cache-line
- *         coherency.
- *       - Remove unused SCSI opcodes, endian-swap definitions.
- *       - Remove CMD_* pre-processor defines.
- *       - Remove unused SCSIFCHOTSWAP/GAMAP/MULTIHOST codes.
- *     - Backout patch which added a per-scsi_qla_host scsi host
- *       spinlock, since mid-layer already defines one.
- *     - Add new 2300 IPX firmware (3.02.15).
- *
- *  Rev  8.00.00b4     July 14, 2003           RA/DG/AV
- *     - Resync with 6.06.00b12.
- *     - Resync with Linux Kernel 2.6.0-test1.
- *     - Remove IOCB throttling code -- originally #if'd.
- *     - Remove apidev_*() routines since proc_mknod() has been
- *       removed -- need alternate IOCTL interface.
- *     - Merge several performance/fix patches from Arjan van de
- *       Ven:
- *       - Undefined operation >> 32.
- *       - No need to acquire mid-layer lock during command
- *         callback. 
- *       - Use a per-HBA mid-layer lock.
- *       - Use a non-locked cycle for setting the count of the
- *         newly allocated sp (qla2x00_get_new_sp()).
- *       - Modify semantic behavior of qla2x00_queuecommand():
- *         - Reduce cacheline bouncing by having I/Os submitted
- *           by the IRQ handler.
- *         - Remove extraneous calls to qla2x00_next() during I/O
- *           queuing.
- *       - Use list_splice_init() during qla2x00_done() handling
- *         of commands to reduce list_lock contention.
- *       - RIO mode support for ISP2200:
- *         - Implementation differs slightly from original patch.
- *       - Do not use bottom-half handler (tasklet/work queue)
- *         for qla2x00_done() processing.
- *
- *  Rev  8.00.00b4-pre22 July 12, 2003         AV
- *     - Check for 'Process Response Queue' requests early during
- *       the Host Status check.
- *     - General sanitizing:
- *       - srb_t structure rewrite, removal of unused members.
- *       - Remove unused fcdev array, fabricid, and PORT_*
- *         definitions.
- *       - Remove unused config_reg_t PCI definitions.
- *     - Add new 2200 IP firmware (2.02.06).
- *     - Add new 2300 IPX firmware (3.02.14).
- *
- *  Rev  8.00.00b4-pre19 June 30, 2003         AV
- *     - Resync with Linux Kernel 2.5.73-bk8.
- *     - Rework IOCB command queuing methods:
- *       - Upper-layer driver *MUST* properly set the direction
- *         bit of SCSI commands.
- *       - Generalize 32bit/64bit queuing path functions.
- *       - Remove costly page-boundary cross check when using
- *         64bit address capable IOCBs.
- *
- *  Rev  8.00.00b4-pre15 June 19, 2003         AV
- *     - Resync with 6.06.00b11.
- *     - Continue fcport list consolidation work:
- *       - Updated IOCTL implementations to use new fcports 
- *         list.
- *     - Modified product ID check to not verify ISP chip
- *       revision -- ISP2312 v3 (qla2x00_chip_diag()).
- *     - Add new 2300 IPX firmware (3.02.13):
- *
- *  Rev  8.00.00b4-pre13 June 19, 2003         AV
- *     - Fix build process for qla2100 driver -- no support
- *       for IP.
- *     - SCSI host template modifications:
- *       - Set sg_tablesize based on the derived DMA mask.
- *       - Increase max_sectors since only limit within RISC
- *         is transfer of (((2^32) - 1) >> 9) sectors.
- *
- *  Rev  8.00.00b4-pre12 June 18, 2003         RA, DG, RL, AV
- *     - Resync with 6.06.00b10.
- *     - Resync with Linux Kernel 2.5.72.
- *     - Initial fcport list consolidation work:
- *       - fcports/fcinitiators/fcdev/fc_ip --> ha->fcports
- *         list.
- *
- *  Rev  8.00.00b4-pre7         June 05, 2003          AV
- *     - Properly release PCI resouces in init-failure case.
- *     - Reconcile disparite function return code definitions.
- *
- *  Rev  8.00.00b4-pre4         June 03, 2003          AV
- *     - Resync with Linux Kernel 2.5.70-bk8:
- *       - SHT proc_info() changes.
- *     - Restructure SNS Generic Services routines:
- *       - Add qla_gs.c file to driver distribution.
- *     - Configure PCI latency timer for ISP23xx.
- *
- *  Rev  8.00.00b4-pre3         June 02, 2003          RA, DG, RL, AV
- *     - Resync with 6.06.00b5.
- *     - Rework (again) PCI I/O space configuration
- *       (Anton Blanchard):
- *       - Use pci_set_mwi() routine;
- *         - Remove uneeded qla2x00_set_cache_line() function.
- *       - Remove extraneous modification of PCI_COMMAND word.
- *
- *  Rev  8.00.00b3      May 29, 2003           AV
- *     - Resync with Linux Kernel 2.5.70.
- *     - Move RISC paused check from ISR fast-path.
- *
- *  Rev  8.00.00b3-pre8 May 26, 2003           AV
- *     - Add new 2300 IPX firmware (3.02.12):
- *     - Rework PCI I/O space configuration.
- *
- *  Rev  8.00.00b3-pre6        May 22, 2003            RA, DG, RL, AV
- *     - Resync with 6.06.00b3.
- *
- *  Rev  8.00.00b3-pre4        May 21 2003             AV
- *     - Add new 2300 IPX firmware (3.02.11):
- *       - Remove 2300 TPX firmware from distribution.
- *
- *  Rev  8.00.00b3-pre3        May 21 2003             AV
- *     - Properly setup PCI configuation space during
- *       initialization:
- *       - Properly configure Memory-Mapped I/O during early
- *         configuration stage.
- *     - Rework IP functionality to support 2k logins.
- *     - Add new 2300 IPX firmware (3.02.11):
- *       - Remove 2300 TPX firmware from distribution.
- *
- *  Rev  8.00.00b3-pre2        May ??, 2003            RA, DG, RL, AV
- *     - Resync with 6.06.00b1.
- *
- *  Rev  8.00.00b3-pre1        May ??, 2003            RA, DG, RL, AV
- *     - Resync with 6.05.00.
- *
- *  Rev  8.00.00b2     May 19, 2003            AV
- *     - Simplify dma_addr_t handling during command queuing given
- *       new block-layer defined restrictions:
- *       - Physical addresses not spanning 4GB boundaries.
- *     - Firmware versions: 2100 TP (1.19.24), 2200 IP (2.02.05),
- *       2300 TPX (3.02.10).
- *
- *  Rev  8.00.00b2-pre1        May 13, 2003            AV
- *     - Add support for new 'Hotplug initialization' model. 
- *     - Simplify host template by removing unused callbacks.
- *     - Use scsicam facilities to determine geometry.
- *     - Fix compilation issues for non-ISP23xx builds:
- *       - Correct register references in qla_dbg.c.
- *       - Correct Makefile build process.
- *
- *  Rev  8.00.00b1     May 05, 2003            AV
- *     - Resync with Linux Kernel 2.5.69.
- *     - Firmware versions: 2100 TP (1.19.24), 2200 TP (2.02.05),
- *       2300 TPX (3.02.10).
- *
- *  Rev  8.00.00b1-pre45 April ??, 2003                AV
- *     - Resync with Linux Kernel 2.5.68-bk11:
- *     - Fix improper return-code assignment during fabric
- *       discovery.
- *     - Remove additional extraneous #defines from
- *       qla_settings.h.
- *       - USE_PORTNAME -- FO will always use portname.
- *     - Default queue depth size set to 64.
- *
- *  Rev  8.00.00b1-pre42 April ??, 2003                AV
- *     - Convert bottom-half tasklet to a work_queue.
- *     - Initial basic coding of dynamic queue depth handling
- *       during QUEUE FULL statuses.
- *     - Fix mailbox interface problem with
- *       qla2x00_get_retry_cnt().
- *
- *  Rev  8.00.00b1-pre41 April ??, 2003                AV
- *     - Convert build defines qla2[1|2|3]00 macros to
- *       qla2[1|2|3]xx due to module name stringification clashes.
- *     - Add additional ISP2322 checks during board configuration.
- *
- *  Rev  8.00.00b1-pre40 April ??, 2003                AV
- *     - Resync with Linux Kernel 2.5.68-bk8:
- *       - Updated IRQ handler interface.
- *     - Add ISP dump code (stub) in case of SYSTEM_ERROR on
- *       ISP2100.
- *     - Add new 2200 IP firmware (2.02.05).
- *
- *  Rev  8.00.00b1-pre39 April ??, 2003                AV
- *     - Resync with Linux Kernel 2.5.68.
- *     - Add simple build.sh script to aid in external compilation.
- *     - Clean-break with Kernel 2.4 compatibility.
- *       - Rework DPC routine -- completion routines for signaling.
- *     - Re-add HBAAPI character device node for IOCTL support.
- *     - Remove residual QLA2X_PERFORMANCE defines.
- *     - Allocate SP pool via __get_free_pages() rather than
- *       individual kmalloc()'s.
- *     - Inform SCSI mid-layer of 16-byte CDB support
- *       (host->max_cmd_len):
- *       - Remove unecessary 'more_cdb' handling code from
- *         qla_iocb.c and qla_xioct.c.
- *     - Reduce duplicate code in fabric scanning logic (MS IOCB
- *       preparation).
- *     - Add ISP dump code in case of SYSTEM_ERROR.
- *     - Remove 2300 VIX firmware from distribution:
- *       - Add initial code for IPX support.
- *     - Add new 2300 TPX firmware (3.02.10).
- *
- *  Rev  8.00.00b1-pre34 April ??, 2003                AV
- *     - Resync with Linux Kernel 2.5.67.
- *     - Use domain/area/al_pa fields when displaying PortID 
- *       values -- addresses endianess issues.
- *     - Rework large case statement to check 'common' CDB commands
- *       early in qla2x00_get_cmd_direction().
- *
- *  Rev  8.00.00b1-pre31 April ??, 2003                AV
- *     - Update makefile to support PPC64 build.
- *     - Retool NVRAM configuration routine and structures:
- *       - Consoldate ISP21xx/ISP22xx/ISP23xx configuration
- *         (struct nvram_t).
- *       - Remove big/little endian support structures in favor of
- *         simplified bit-operations within byte fields.
- *     - Fix long-standing 'static' buffer sharing problem in 
- *       qla2x00_configure_fabric().
- *
- *  Rev  8.00.00b1-pre30 April ??, 2003                AV
- *     - Complete implementation of GID_PT scan.
- *     - Use consistent MS IOCB invocation method to query SNS:
- *       - Add RNN_ID and RSNN_NN registrations in a fabric.
- *     - Remove unused Mailbox Command 6Eh (Send SNS) support
- *       structures.
- *     - Use 64bit safe IOCBs while issuing INQUIRY and RLC during
- *       topology scan.
- *     - Until reimplementation of fcdev_t/fcport list
- *       consolidation, valid loop_id ranges are still limited from
- *       0x00 through 0xFF -- enforce this within the code.
- *
- *  Rev  8.00.00b1-pre27 March ??, 2003                AV
- *     - Resync with 6.05.00b9.
- *     - Retool HBA PCI configuration -- qla2x00_pci_config().
- *     - Remove inconsistent use of delay routines (UDELAY/SYS*).
- *     - Continue to teardown/clean/add comments and debug
- *       routines.
- *     - Properly swap bytes of the device's nodename in
- *       qla2x00_configure_local_loop().
- *
- *  Rev  8.00.00b1-pre25 March ??, 2003                AV
- *     - Resync with 6.05.00b8.
- *
- *  Rev  8.00.00b1-pre23 March ??, 2003                AV
- *     - Remove (#define) IOCB usage throttling.
- *     - Abstract interrupt polling with qla2x00_poll().
- *     - Modify lun scanning logic:
- *       - If the device does not support the SCSI Report Luns
- *         command, the driver will now only scan from 0 to the
- *         max#-luns as defined in the NVRAM (BIOS), rather than
- *         blindly scanning from 0 to 255 -- which could result in
- *         an increase in startup time when running against slow
- *         (JBOD) devices.
- *     - Rework reset logic in qla2x00_reset_chip() (spec).
- *
- *  Rev  8.00.00b1-pre22 March ??, 2003                AV
- *     - Resync with 6.05.00b7.
- *     - Cleanup (rewrite) ISR handler.
- *     - Rename kmem_zalloc --> qla2x00_kmem_zalloc():
- *       - This function will eventually be removed.
- *     - Add new 2300 VIX firmware (3.02.09):
- *       - Support for Tape, Fabric, 2K logins, IP, and VI.
- *
- *  Rev  8.00.00b1-pre18 March ??, 2003                AV
- *     - Support 232x type ISPs.
- *     - Support single firmware for each ISP type:
- *       - Restructure brd_info/fw_info methods.
- *       - Streamline firmware load process.
- *       - Properly query firmware for version information.
- *     - Remove extraneous scsi_qla_host members:
- *       - device_id ==> pdev->device
- *     - Fix fc4 features (RFF_ID) registration.
- *     - Convert kmem_zalloc --> qla2x00_kmem_zalloc().
- *     - Remove unused/extraneous #defines (USE_PORTNAME).
- *
- *  Rev  8.00.00b1-pre14 March ??, 2003                AV
- *     - Resync with 6.05.00b6.
- *     - Initial source-code restructuring effort.
- *       - Build procedure.
- *       - Source file layout -- intuitive component layout.
- *       - Remove unused #defines (*PERFORMANCE, WORD_FW_LOAD, etc).
- *     - Add support for 2K logins (TPX -- firmware).
- *     - Add module parameter ql2xsuspendcount.
- *     - Add new 2200 IP/TP firmware (2.02.04).
- *
- *  Rev  8.00.00b1-pre9        March ??, 2003  RL/DG/RA/AV
- *     - Use kernel struct list_head for fcport and fclun lists.
- *     - Remove extraneous (L|M)S_64BITS() and QL21_64*() defines.
- *
- *  Rev  8.00.00b1-pre8        February 28, 2003       RL/DG/RA/AV
- *     - Resync with 6.05.00b3.
- *
- *  Rev  8.00.00b1-pre7        February 23, 2003       RL/DG/RA/AV
- *     - Add alternate fabric scanning logic (GID_PT/GNN_ID/GPN_ID).
- *     - Remove use of deprecated function check_region().
- *     - Add new 2300 IP/TP firmware (3.02.08).
- *
- *  Rev  8.00.00b1-pre5        January 28, 2003        RL/DG/RA/AV
- *     - Resync with 6.05.00b3.
- *     - Consolidate device_reg structure definitions for ISP types.
- *     - Add support for new queue-depth selection.
- *     - Add new 2300 IP/TP firmware (3.02.07).
- *
- *  Rev  8.00.00b1-pre1        January 17, 2003        AV
- *     - Initial branch from 6.04.00b8 driver.
- *     - Remove VMWARE specific code.
- *     - Add support for pci_driver interface.
- *
- ********************************************************************/
diff -urN linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- linux/arch/arm/kernel/process.c     2005/02/07 02:54:30     1.49
+++ linux/arch/arm/kernel/process.c     2005/04/29 11:15:00     1.50
@@ -168,12 +168,11 @@
 
 EXPORT_SYMBOL(machine_restart);
 
-void show_regs(struct pt_regs * regs)
+void __show_regs(struct pt_regs *regs)
 {
-       unsigned long flags;
-
-       flags = condition_codes(regs);
+       unsigned long flags = condition_codes(regs);
 
+       printk("CPU: %d\n", smp_processor_id());
        print_symbol("PC is at %s\n", instruction_pointer(regs));
        print_symbol("LR is at %s\n", regs->ARM_lr);
        printk("pc : [<%08lx>]    lr : [<%08lx>]    %s\n"
@@ -213,6 +212,14 @@
        }
 }
 
+void show_regs(struct pt_regs * regs)
+{
+       printk("\n");
+       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
+       __show_regs(regs);
+       __backtrace();
+}
+
 void show_fpregs(struct user_fp *regs)
 {
        int i;
diff -urN linux/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c
--- linux/arch/arm/kernel/sys_arm.c     2005/03/18 17:36:45     1.38
+++ linux/arch/arm/kernel/sys_arm.c     2005/04/29 11:15:00     1.39
@@ -51,13 +51,6 @@
        return error;
 }
 
-/*
- * This is the lowest virtual address we can permit any user space
- * mapping to be mapped at.  This is particularly important for
- * non-high vector CPUs.
- */
-#define MIN_MAP_ADDR   (PAGE_SIZE)
-
 /* common code for old and new mmaps */
 inline long do_mmap2(
        unsigned long addr, unsigned long len,
@@ -69,7 +62,7 @@
 
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-       if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
+       if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
                goto out;
 
        error = -EBADF;
@@ -122,7 +115,7 @@
 {
        unsigned long ret = -EINVAL;
 
-       if (flags & MREMAP_FIXED && new_addr < MIN_MAP_ADDR)
+       if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
                goto out;
 
        down_write(&current->mm->mmap_sem);
diff -urN linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- linux/arch/arm/kernel/traps.c       2005/04/08 18:57:50     1.49
+++ linux/arch/arm/kernel/traps.c       2005/04/29 11:15:00     1.50
@@ -31,9 +31,6 @@
 
 #include "ptrace.h"
 
-extern void c_backtrace (unsigned long fp, int pmode);
-extern void show_pte(struct mm_struct *mm, unsigned long addr);
-
 const char *processor_modes[]=
 { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , 
"UK7_26" ,
   "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", 
"UK15_26",
@@ -216,8 +213,7 @@
 
        printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
        print_modules();
-       printk("CPU: %d\n", smp_processor_id());
-       show_regs(regs);
+       __show_regs(regs);
        printk("Process %s (pid: %d, stack limit = 0x%p)\n",
                tsk->comm, tsk->pid, tsk->thread_info + 1);
 
@@ -482,7 +478,7 @@
                       current->pid, current->comm, no);
                dump_instr(regs);
                if (user_mode(regs)) {
-                       show_regs(regs);
+                       __show_regs(regs);
                        c_backtrace(regs->ARM_fp, processor_mode(regs));
                }
        }
diff -urN linux/arch/arm/lib/bitops.h linux/arch/arm/lib/bitops.h
--- linux/arch/arm/lib/bitops.h 1970/01/01 00:00:00
+++ linux/arch/arm/lib/bitops.h 2005-04-29 12:15:00.191752000 +0100     1.1
@@ -0,0 +1,33 @@
+       .macro  bitop, instr
+       and     r2, r0, #7
+       mov     r3, #1
+       mov     r3, r3, lsl r2
+       save_and_disable_irqs ip, r2
+       ldrb    r2, [r1, r0, lsr #3]
+       \instr  r2, r2, r3
+       strb    r2, [r1, r0, lsr #3]
+       restore_irqs ip
+       mov     pc, lr
+       .endm
+
+/**
+ * testop - implement a test_and_xxx_bit operation.
+ * @instr: operational instruction
+ * @store: store instruction
+ *
+ * Note: we can trivially conditionalise the store instruction
+ * to avoid dirting the data cache.
+ */
+       .macro  testop, instr, store
+       add     r1, r1, r0, lsr #3
+       and     r3, r0, #7
+       mov     r0, #1
+       save_and_disable_irqs ip, r2
+       ldrb    r2, [r1]
+       tst     r2, r0, lsl r3
+       \instr  r2, r2, r0, lsl r3
+       \store  r2, [r1]
+       restore_irqs ip
+       moveq   r0, #0
+       mov     pc, lr
+       .endm
diff -urN linux/arch/arm/lib/changebit.S linux/arch/arm/lib/changebit.S
--- linux/arch/arm/lib/changebit.S      2002/07/05 05:04:37     1.4
+++ linux/arch/arm/lib/changebit.S      2005/04/29 11:15:00     1.5
@@ -9,6 +9,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include "bitops.h"
                 .text
 
 /* Purpose  : Function to change a bit
@@ -17,12 +18,4 @@
 ENTRY(_change_bit_be)
                eor     r0, r0, #0x18           @ big endian byte ordering
 ENTRY(_change_bit_le)
-               and     r2, r0, #7
-               mov     r3, #1
-               mov     r3, r3, lsl r2
-               save_and_disable_irqs ip, r2
-               ldrb    r2, [r1, r0, lsr #3]
-               eor     r2, r2, r3
-               strb    r2, [r1, r0, lsr #3]
-               restore_irqs ip
-               RETINSTR(mov,pc,lr)
+       bitop   eor
diff -urN linux/arch/arm/lib/clearbit.S linux/arch/arm/lib/clearbit.S
--- linux/arch/arm/lib/clearbit.S       2002/07/05 05:04:37     1.4
+++ linux/arch/arm/lib/clearbit.S       2005/04/29 11:15:00     1.5
@@ -9,6 +9,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include "bitops.h"
                 .text
 
 /*
@@ -18,14 +19,4 @@
 ENTRY(_clear_bit_be)
                eor     r0, r0, #0x18           @ big endian byte ordering
 ENTRY(_clear_bit_le)
-               and     r2, r0, #7
-               mov     r3, #1
-               mov     r3, r3, lsl r2
-               save_and_disable_irqs ip, r2
-               ldrb    r2, [r1, r0, lsr #3]
-               bic     r2, r2, r3
-               strb    r2, [r1, r0, lsr #3]
-               restore_irqs ip
-               RETINSTR(mov,pc,lr)
-
-
+       bitop   bic
diff -urN linux/arch/arm/lib/setbit.S linux/arch/arm/lib/setbit.S
--- linux/arch/arm/lib/setbit.S 2002/07/05 05:04:37     1.4
+++ linux/arch/arm/lib/setbit.S 2005/04/29 11:15:00     1.5
@@ -9,6 +9,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include "bitops.h"
                .text
 
 /*
@@ -18,12 +19,4 @@
 ENTRY(_set_bit_be)
                eor     r0, r0, #0x18           @ big endian byte ordering
 ENTRY(_set_bit_le)
-               and     r2, r0, #7
-               mov     r3, #1
-               mov     r3, r3, lsl r2
-               save_and_disable_irqs ip, r2
-               ldrb    r2, [r1, r0, lsr #3]
-               orr     r2, r2, r3
-               strb    r2, [r1, r0, lsr #3]
-               restore_irqs ip
-               RETINSTR(mov,pc,lr)
+       bitop   orr
diff -urN linux/arch/arm/lib/testchangebit.S linux/arch/arm/lib/testchangebit.S
--- linux/arch/arm/lib/testchangebit.S  2002/07/05 05:04:37     1.4
+++ linux/arch/arm/lib/testchangebit.S  2005/04/29 11:15:00     1.5
@@ -9,21 +9,10 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include "bitops.h"
                 .text
 
 ENTRY(_test_and_change_bit_be)
                eor     r0, r0, #0x18           @ big endian byte ordering
 ENTRY(_test_and_change_bit_le)
-               add     r1, r1, r0, lsr #3
-               and     r3, r0, #7
-               mov     r0, #1
-               save_and_disable_irqs ip, r2
-               ldrb    r2, [r1]
-               tst     r2, r0, lsl r3
-               eor     r2, r2, r0, lsl r3
-               strb    r2, [r1]
-               restore_irqs ip
-               moveq   r0, #0
-               RETINSTR(mov,pc,lr)
-
-
+       testop  eor, strb
diff -urN linux/arch/arm/lib/testclearbit.S linux/arch/arm/lib/testclearbit.S
--- linux/arch/arm/lib/testclearbit.S   2002/07/05 05:04:37     1.4
+++ linux/arch/arm/lib/testclearbit.S   2005/04/29 11:15:00     1.5
@@ -9,21 +9,10 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include "bitops.h"
                 .text
 
 ENTRY(_test_and_clear_bit_be)
                eor     r0, r0, #0x18           @ big endian byte ordering
 ENTRY(_test_and_clear_bit_le)
-               add     r1, r1, r0, lsr #3      @ Get byte offset
-               and     r3, r0, #7              @ Get bit offset
-               mov     r0, #1
-               save_and_disable_irqs ip, r2
-               ldrb    r2, [r1]
-               tst     r2, r0, lsl r3
-               bic     r2, r2, r0, lsl r3
-               strb    r2, [r1]
-               restore_irqs ip
-               moveq   r0, #0
-               RETINSTR(mov,pc,lr)
-
-
+       testop  bicne, strneb
diff -urN linux/arch/arm/lib/testsetbit.S linux/arch/arm/lib/testsetbit.S
--- linux/arch/arm/lib/testsetbit.S     2002/07/05 05:04:37     1.4
+++ linux/arch/arm/lib/testsetbit.S     2005/04/29 11:15:00     1.5
@@ -9,21 +9,10 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include "bitops.h"
                 .text
 
 ENTRY(_test_and_set_bit_be)
                eor     r0, r0, #0x18           @ big endian byte ordering
 ENTRY(_test_and_set_bit_le)
-               add     r1, r1, r0, lsr #3      @ Get byte offset
-               and     r3, r0, #7              @ Get bit offset
-               mov     r0, #1
-               save_and_disable_irqs ip, r2
-               ldrb    r2, [r1]
-               tst     r2, r0, lsl r3
-               orr     r2, r2, r0, lsl r3
-               strb    r2, [r1]
-               restore_irqs ip
-               moveq   r0, #0
-               RETINSTR(mov,pc,lr)
-
-
+       testop  orreq, streqb
diff -urN linux/arch/arm/mach-footbridge/dc21285-timer.c 
linux/arch/arm/mach-footbridge/dc21285-timer.c
--- linux/arch/arm/mach-footbridge/dc21285-timer.c      2004/10/25 20:44:10     
1.1
+++ linux/arch/arm/mach-footbridge/dc21285-timer.c      2005/04/29 11:15:00     
1.2
@@ -51,8 +51,6 @@
  */
 static void __init footbridge_timer_init(void)
 {
-       isa_rtc_init();
-
        timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
 
        *CSR_TIMER1_CLR  = 0;
@@ -60,6 +58,8 @@
        *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | 
TIMER_CNTL_DIV16;
 
        setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
+
+       isa_rtc_init();
 }
 
 struct sys_timer footbridge_timer = {
diff -urN linux/arch/arm/mach-ixp4xx/Kconfig linux/arch/arm/mach-ixp4xx/Kconfig
--- linux/arch/arm/mach-ixp4xx/Kconfig  2005/02/07 02:54:31     1.6
+++ linux/arch/arm/mach-ixp4xx/Kconfig  2005/04/29 11:15:00     1.7
@@ -41,7 +41,7 @@
        help
          Say 'Y' here if you want your kernel to support Intel's
          IXDP465 Development Platform (Also known as BMP).
-         For more information on this platform, see Documentation/arm/IXP4xx.
+         For more information on this platform, see 
<file:Documentation/arm/IXP4xx>.
 
 
 #
diff -urN linux/arch/arm/mach-sa1100/h3600.c linux/arch/arm/mach-sa1100/h3600.c
--- linux/arch/arm/mach-sa1100/h3600.c  2004/12/27 02:15:48     1.17
+++ linux/arch/arm/mach-sa1100/h3600.c  2005/04/29 11:15:00     1.18
@@ -130,7 +130,7 @@
        return 0;
 }
 
-static void h3600_irda_set_speed(struct device *dev, int speed)
+static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
 {
        if (speed < 4000000) {
                clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
diff -urN linux/arch/arm/mm/fault.c linux/arch/arm/mm/fault.c
--- linux/arch/arm/mm/fault.c   2004/08/13 07:18:51     1.4
+++ linux/arch/arm/mm/fault.c   2005/04/29 11:15:00     1.5
@@ -108,14 +108,15 @@
  */
 static void
 __do_user_fault(struct task_struct *tsk, unsigned long addr,
-               unsigned int fsr, int code, struct pt_regs *regs)
+               unsigned int fsr, unsigned int sig, int code,
+               struct pt_regs *regs)
 {
        struct siginfo si;
 
 #ifdef CONFIG_DEBUG_USER
        if (user_debug & UDBG_SEGV) {
-               printk(KERN_DEBUG "%s: unhandled page fault at 0x%08lx, code 
0x%03x\n",
-                      tsk->comm, addr, fsr);
+               printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, 
code 0x%03x\n",
+                      tsk->comm, sig, addr, fsr);
                show_pte(tsk->mm, addr);
                show_regs(regs);
        }
@@ -124,11 +125,11 @@
        tsk->thread.address = addr;
        tsk->thread.error_code = fsr;
        tsk->thread.trap_no = 14;
-       si.si_signo = SIGSEGV;
+       si.si_signo = sig;
        si.si_errno = 0;
        si.si_code = code;
        si.si_addr = (void __user *)addr;
-       force_sig_info(SIGSEGV, &si, tsk);
+       force_sig_info(sig, &si, tsk);
 }
 
 void
@@ -140,7 +141,7 @@
         * have no context to handle this fault with.
         */
        if (user_mode(regs))
-               __do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs);
+               __do_user_fault(tsk, addr, fsr, SIGSEGV, SEGV_MAPERR, regs);
        else
                __do_kernel_fault(mm, addr, fsr, regs);
 }
@@ -201,10 +202,11 @@
                goto out;
 
        /*
-        * If we are out of memory for pid1,
-        * sleep for a while and retry
+        * If we are out of memory for pid1, sleep for a while and retry
         */
+       up_read(&mm->mmap_sem);
        yield();
+       down_read(&mm->mmap_sem);
        goto survive;
 
 check_stack:
@@ -219,7 +221,7 @@
 {
        struct task_struct *tsk;
        struct mm_struct *mm;
-       int fault;
+       int fault, sig, code;
 
        tsk = current;
        mm  = tsk->mm;
@@ -242,55 +244,45 @@
                return 0;
 
        /*
-        * We had some memory, but were unable to
-        * successfully fix up this page fault.
-        */
-       if (fault == 0)
-               goto do_sigbus;
-
-       /*
         * If we are in kernel mode at this point, we
         * have no context to handle this fault with.
         */
        if (!user_mode(regs))
                goto no_context;
 
-       if (fault == VM_FAULT_OOM) {
+       switch (fault) {
+       case VM_FAULT_OOM:
                /*
-                * We ran out of memory, or some other thing happened to
-                * us that made us unable to handle the page fault gracefully.
+                * We ran out of memory, or some other thing
+                * happened to us that made us unable to handle
+                * the page fault gracefully.
                 */
                printk("VM: killing process %s\n", tsk->comm);
                do_exit(SIGKILL);
-       } else
-               __do_user_fault(tsk, addr, fsr, fault == VM_FAULT_BADACCESS ?
-                               SEGV_ACCERR : SEGV_MAPERR, regs);
-       return 0;
+               return 0;
 
+       case 0:
+               /*
+                * We had some memory, but were unable to
+                * successfully fix up this page fault.
+                */
+               sig = SIGBUS;
+               code = BUS_ADRERR;
+               break;
 
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-do_sigbus:
-       /*
-        * Send a sigbus, regardless of whether we were in kernel
-        * or user mode.
-        */
-       tsk->thread.address = addr;
-       tsk->thread.error_code = fsr;
-       tsk->thread.trap_no = 14;
-       force_sig(SIGBUS, tsk);
-#ifdef CONFIG_DEBUG_USER
-       if (user_debug & UDBG_BUS) {
-               printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n",
-                       current->comm, addr, instruction_pointer(regs));
+       default:
+               /*
+                * Something tried to access memory that
+                * isn't in our memory map..
+                */
+               sig = SIGSEGV;
+               code = fault == VM_FAULT_BADACCESS ?
+                       SEGV_ACCERR : SEGV_MAPERR;
+               break;
        }
-#endif
 
-       /* Kernel mode? Handle exceptions or die */
-       if (user_mode(regs))
-               return 0;
+       __do_user_fault(tsk, addr, fsr, sig, code, regs);
+       return 0;
 
 no_context:
        __do_kernel_fault(mm, addr, fsr, regs);
diff -urN linux/arch/arm/mm/init.c linux/arch/arm/mm/init.c
--- linux/arch/arm/mm/init.c    2005/03/18 17:36:47     1.56
+++ linux/arch/arm/mm/init.c    2005/04/29 11:15:00     1.57
@@ -223,6 +223,9 @@
         * This doesn't seem to be used by the Linux memory
         * manager any more.  If we can get rid of it, we
         * also get rid of some of the stuff above as well.
+        *
+        * Note: max_low_pfn and max_pfn reflect the number
+        * of _pages_ in the system, not the maximum PFN.
         */
        max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
        max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
diff -urN linux/arch/arm26/kernel/sys_arm.c linux/arch/arm26/kernel/sys_arm.c
--- linux/arch/arm26/kernel/sys_arm.c   2005/01/13 14:05:20     1.5
+++ linux/arch/arm26/kernel/sys_arm.c   2005/04/29 11:15:00     1.6
@@ -64,10 +64,10 @@
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
        /*
-        * If we are doing a fixed mapping, and address < PAGE_SIZE,
+        * If we are doing a fixed mapping, and address < FIRST_USER_ADDRESS,
         * then deny it.
         */
-       if (flags & MAP_FIXED && addr < PAGE_SIZE && vectors_base() == 0)
+       if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
                goto out;
 
        error = -EBADF;
@@ -121,11 +121,10 @@
        unsigned long ret = -EINVAL;
 
        /*
-        * If we are doing a fixed mapping, and address < PAGE_SIZE,
+        * If we are doing a fixed mapping, and address < FIRST_USER_ADDRESS,
         * then deny it.
         */
-       if (flags & MREMAP_FIXED && new_addr < PAGE_SIZE &&
-           vectors_base() == 0)
+       if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
                goto out;
 
        down_write(&current->mm->mmap_sem);
diff -urN linux/arch/i386/kernel/vsyscall-note.S 
linux/arch/i386/kernel/vsyscall-note.S
--- linux/arch/i386/kernel/vsyscall-note.S      1970/01/01 00:00:00
+++ linux/arch/i386/kernel/vsyscall-note.S      2005-04-29 12:15:00.758444000 
+0100     1.1
@@ -0,0 +1,25 @@
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+
+#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type)                        \
+       .section name, flags;                                                 \
+       .balign 4;                                                            \
+       .long 1f - 0f;          /* name length */                             \
+       .long 3f - 2f;          /* data length */                             \
+       .long type;             /* note type */                               \
+0:     .asciz vendor;          /* vendor name */                             \
+1:     .balign 4;                                                            \
+2:
+
+#define ASM_ELF_NOTE_END                                                     \
+3:     .balign 4;              /* pad out section */                         \
+       .previous
+
+       ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0)
+       .long LINUX_VERSION_CODE
+       ASM_ELF_NOTE_END
diff -urN linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile
--- linux/arch/i386/kernel/Makefile     2005/03/18 17:36:48     1.70
+++ linux/arch/i386/kernel/Makefile     2005/04/29 11:15:00     1.71
@@ -56,7 +56,8 @@
 SYSCFLAGS_vsyscall-int80.so    = $(vsyscall-flags)
 
 $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
+$(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
+                     $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE
        $(call if_changed,syscall)
 
 # We also create a special relocatable object that should mirror the symbol
@@ -67,5 +68,6 @@
 $(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
 
 SYSCFLAGS_vsyscall-syms.o = -r
-$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds $(obj)/vsyscall-sysenter.o FORCE
+$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
+                       $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
        $(call if_changed,syscall)
diff -urN linux/arch/i386/kernel/apic.c linux/arch/i386/kernel/apic.c
--- linux/arch/i386/kernel/apic.c       2005/04/08 18:57:53     1.63
+++ linux/arch/i386/kernel/apic.c       2005/04/29 11:15:00     1.64
@@ -548,7 +548,7 @@
        unsigned int apic_thmr;
 } apic_pm_state;
 
-static int lapic_suspend(struct sys_device *dev, u32 state)
+static int lapic_suspend(struct sys_device *dev, pm_message_t state)
 {
        unsigned long flags;
 
diff -urN linux/arch/i386/kernel/efi.c linux/arch/i386/kernel/efi.c
--- linux/arch/i386/kernel/efi.c        2005/03/18 17:36:48     1.6
+++ linux/arch/i386/kernel/efi.c        2005/04/29 11:15:00     1.7
@@ -46,8 +46,8 @@
 
 struct efi efi;
 EXPORT_SYMBOL(efi);
-static struct efi efi_phys __initdata;
-struct efi_memory_map memmap __initdata;
+static struct efi efi_phys;
+struct efi_memory_map memmap;
 
 /*
  * We require an early boot_ioremap mapping mechanism initially
diff -urN linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux/arch/i386/kernel/entry.S      2005/04/08 18:57:53     1.99
+++ linux/arch/i386/kernel/entry.S      2005/04/29 11:15:00     1.100
@@ -245,6 +245,9 @@
 
 restore_all:
        movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
+       # Warning: OLDSS(%esp) contains the wrong/random values if we
+       # are returning to the kernel.
+       # See comments in process.c:copy_thread() for details.
        movb OLDSS(%esp), %ah
        movb CS(%esp), %al
        andl $(VM_MASK | (4 << 8) | 3), %eax
diff -urN linux/arch/i386/kernel/i8259.c linux/arch/i386/kernel/i8259.c
--- linux/arch/i386/kernel/i8259.c      2005/03/18 17:36:48     1.48
+++ linux/arch/i386/kernel/i8259.c      2005/04/29 11:15:00     1.49
@@ -262,7 +262,7 @@
        return 0;
 }
 
-static int i8259A_suspend(struct sys_device *dev, u32 state)
+static int i8259A_suspend(struct sys_device *dev, pm_message_t state)
 {
        save_ELCR(irq_trigger);
        return 0;
diff -urN linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- linux/arch/i386/kernel/io_apic.c    2005/04/08 18:57:53     1.88
+++ linux/arch/i386/kernel/io_apic.c    2005/04/29 11:15:00     1.89
@@ -2299,7 +2299,7 @@
 };
 static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
 
-static int ioapic_suspend(struct sys_device *dev, u32 state)
+static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
 {
        struct IO_APIC_route_entry *entry;
        struct sysfs_ioapic_data *data;
diff -urN linux/arch/i386/kernel/nmi.c linux/arch/i386/kernel/nmi.c
--- linux/arch/i386/kernel/nmi.c        2005/04/08 18:57:53     1.27
+++ linux/arch/i386/kernel/nmi.c        2005/04/29 11:15:00     1.28
@@ -265,7 +265,7 @@
 
 static int nmi_pm_active; /* nmi_active before suspend */
 
-static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
+static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
 {
        nmi_pm_active = nmi_active;
        disable_lapic_nmi_watchdog();
diff -urN linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- linux/arch/i386/kernel/process.c    2005/04/08 18:57:53     1.97
+++ linux/arch/i386/kernel/process.c    2005/04/29 11:15:00     1.98
@@ -405,7 +405,17 @@
        childregs->esp = esp;
 
        p->thread.esp = (unsigned long) childregs;
-       p->thread.esp0 = (unsigned long) (childregs+1);
+       /*
+        * The below -8 is to reserve 8 bytes on top of the ring0 stack.
+        * This is necessary to guarantee that the entire "struct pt_regs"
+        * is accessable even if the CPU haven't stored the SS/ESP registers
+        * on the stack (interrupt gate does not save these registers
+        * when switching to the same priv ring).
+        * Therefore beware: accessing the xss/esp fields of the
+        * "struct pt_regs" is possible, but they may contain the
+        * completely wrong values.
+        */
+       p->thread.esp0 = (unsigned long) (childregs+1) - 8;
 
        p->thread.eip = (unsigned long) ret_from_fork;
 
@@ -548,13 +558,6 @@
         */
        tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
 }
-/*
- * This special macro can be used to load a debugging register
- */
-#define loaddebug(thread,register) \
-               __asm__("movl %0,%%db" #register  \
-                       : /* no output */ \
-                       :"r" (thread->debugreg[register]))
 
 /*
  *     switch_to(x,yn) should switch tasks from x to y.
diff -urN linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- linux/arch/i386/kernel/signal.c     2005/03/18 17:36:48     1.60
+++ linux/arch/i386/kernel/signal.c     2005/04/29 11:15:00     1.61
@@ -618,7 +618,7 @@
                 * inside the kernel.
                 */
                if (unlikely(current->thread.debugreg[7])) {
-                       __asm__("movl %0,%%db7" : : "r" 
(current->thread.debugreg[7]));
+                       loaddebug(&current->thread, 7);
                }
 
                /* Whee!  Actually deliver the signal.  */
diff -urN linux/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- linux/arch/i386/kernel/smpboot.c    2005/03/18 17:36:48     1.67
+++ linux/arch/i386/kernel/smpboot.c    2005/04/29 11:15:00     1.68
@@ -62,6 +62,8 @@
 int smp_num_siblings = 1;
 int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
 EXPORT_SYMBOL(phys_proc_id);
+int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
+EXPORT_SYMBOL(cpu_core_id);
 
 /* bitmap of online cpus */
 cpumask_t cpu_online_map;
@@ -885,6 +887,7 @@
 void *xquad_portio;
 
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
@@ -907,6 +910,9 @@
        cpus_clear(cpu_sibling_map[0]);
        cpu_set(0, cpu_sibling_map[0]);
 
+       cpus_clear(cpu_core_map[0]);
+       cpu_set(0, cpu_core_map[0]);
+
        /*
         * If we couldn't find an SMP configuration at boot time,
         * get out of here now!
@@ -919,6 +925,8 @@
                        printk(KERN_NOTICE "Local APIC not detected."
                                           " Using dummy APIC emulation.\n");
                map_cpu_to_logical_apicid();
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
@@ -942,6 +950,8 @@
                printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell 
your hw vendor)\n");
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
@@ -955,6 +965,8 @@
                printk(KERN_INFO "SMP mode deactivated, forcing use of dummy 
APIC emulation.\n");
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
@@ -1035,10 +1047,13 @@
         * construct cpu_sibling_map[], so that we can tell sibling CPUs
         * efficiently.
         */
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
                cpus_clear(cpu_sibling_map[cpu]);
+               cpus_clear(cpu_core_map[cpu]);
+       }
 
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               struct cpuinfo_x86 *c = cpu_data + cpu;
                int siblings = 0;
                int i;
                if (!cpu_isset(cpu, cpu_callout_map))
@@ -1048,7 +1063,7 @@
                        for (i = 0; i < NR_CPUS; i++) {
                                if (!cpu_isset(i, cpu_callout_map))
                                        continue;
-                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                               if (cpu_core_id[cpu] == cpu_core_id[i]) {
                                        siblings++;
                                        cpu_set(i, cpu_sibling_map[cpu]);
                                }
@@ -1060,6 +1075,18 @@
 
                if (siblings != smp_num_siblings)
                        printk(KERN_WARNING "WARNING: %d siblings found for 
CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
+
+               if (c->x86_num_cores > 1) {
+                       for (i = 0; i < NR_CPUS; i++) {
+                               if (!cpu_isset(i, cpu_callout_map))
+                                       continue;
+                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                                       cpu_set(i, cpu_core_map[cpu]);
+                               }
+                       }
+               } else {
+                       cpu_core_map[cpu] = cpu_sibling_map[cpu];
+               }
        }
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
diff -urN linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- linux/arch/i386/kernel/time.c       2005/04/08 18:57:53     1.61
+++ linux/arch/i386/kernel/time.c       2005/04/29 11:15:00     1.62
@@ -376,7 +376,7 @@
 
 static long clock_cmos_diff, sleep_start;
 
-static int timer_suspend(struct sys_device *dev, u32 state)
+static int timer_suspend(struct sys_device *dev, pm_message_t state)
 {
        /*
         * Estimate time zone so that set_time can update the clock
diff -urN linux/arch/i386/kernel/vsyscall.lds.S 
linux/arch/i386/kernel/vsyscall.lds.S
--- linux/arch/i386/kernel/vsyscall.lds.S       2004/09/19 12:30:03     1.1
+++ linux/arch/i386/kernel/vsyscall.lds.S       2005/04/29 11:15:00     1.2
@@ -23,7 +23,7 @@
   . = VSYSCALL_BASE + 0x400;
 
   .text           : { *(.text) }               :text =0x90909090
-
+  .note                  : { *(.note.*) }              :text :note
   .eh_frame_hdr   : { *(.eh_frame_hdr) }       :text :eh_frame_hdr
   .eh_frame       : { KEEP (*(.eh_frame)) }    :text
   .dynamic        : { *(.dynamic) }            :text :dynamic
@@ -43,6 +43,7 @@
 {
   text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
   dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+  note PT_NOTE FLAGS(4); /* PF_R */
   eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
 }
 
diff -urN linux/arch/i386/kernel/acpi/boot.c linux/arch/i386/kernel/acpi/boot.c
--- linux/arch/i386/kernel/acpi/boot.c  2005/01/13 14:05:24     1.23
+++ linux/arch/i386/kernel/acpi/boot.c  2005/04/29 11:15:01     1.24
@@ -608,6 +608,12 @@
        acpi_fadt.sci_int = fadt->sci_int;
 #endif
 
+#ifdef CONFIG_ACPI_BUS
+       /* initialize rev and apic_phys_dest_mode for x86_64 genapic */
+       acpi_fadt.revision = fadt->revision;
+       acpi_fadt.force_apic_physical_destination_mode = 
fadt->force_apic_physical_destination_mode;
+#endif
+
 #ifdef CONFIG_X86_PM_TIMER
        /* detect the location of the ACPI PM Timer */
        if (fadt->revision >= FADT2_REVISION_ID) {
diff -urN linux/arch/i386/kernel/cpu/amd.c linux/arch/i386/kernel/cpu/amd.c
--- linux/arch/i386/kernel/cpu/amd.c    2005/01/13 14:05:24     1.13
+++ linux/arch/i386/kernel/cpu/amd.c    2005/04/29 11:15:01     1.14
@@ -24,6 +24,9 @@
 
 static void __init init_amd(struct cpuinfo_x86 *c)
 {
+#ifdef CONFIG_SMP
+       int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
+#endif
        u32 l, h;
        int mbytes = num_physpages >> (20-PAGE_SHIFT);
        int r;
@@ -188,23 +191,25 @@
        }
 
        display_cacheinfo(c);
-       detect_ht(c);
-
-#ifdef CONFIG_X86_HT
-       /* AMD dual core looks like HT but isn't really. Hide it from the
-          scheduler. This works around problems with the domain scheduler.
-          Also probably gives slightly better scheduling and disables
-          SMT nice which is harmful on dual core.
-          TBD tune the domain scheduler for dual core. */
-       if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
-               smp_num_siblings = 1;
-#endif
 
        if (cpuid_eax(0x80000000) >= 0x80000008) {
                c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
                if (c->x86_num_cores & (c->x86_num_cores - 1))
                        c->x86_num_cores = 1;
        }
+
+#ifdef CONFIG_SMP
+       /*
+        * On a AMD dual core setup the lower bits of the APIC id
+        * distingush the cores.  Assumes number of cores is a power
+        * of two.
+        */
+       if (c->x86_num_cores > 1) {
+               cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+               printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
+                      cpu, c->x86_num_cores, cpu_core_id[cpu]);
+       }
+#endif
 }
 
 static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff -urN linux/arch/i386/kernel/cpu/common.c 
linux/arch/i386/kernel/cpu/common.c
--- linux/arch/i386/kernel/cpu/common.c 2005/04/08 18:57:53     1.30
+++ linux/arch/i386/kernel/cpu/common.c 2005/04/29 11:15:01     1.31
@@ -434,10 +434,10 @@
 void __init detect_ht(struct cpuinfo_x86 *c)
 {
        u32     eax, ebx, ecx, edx;
-       int     index_lsb, index_msb, tmp;
+       int     index_msb, tmp;
        int     cpu = smp_processor_id();
 
-       if (!cpu_has(c, X86_FEATURE_HT))
+       if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
                return;
 
        cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -446,7 +446,6 @@
        if (smp_num_siblings == 1) {
                printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
        } else if (smp_num_siblings > 1 ) {
-               index_lsb = 0;
                index_msb = 31;
 
                if (smp_num_siblings > NR_CPUS) {
@@ -455,21 +454,34 @@
                        return;
                }
                tmp = smp_num_siblings;
-               while ((tmp & 1) == 0) {
-                       tmp >>=1 ;
-                       index_lsb++;
-               }
-               tmp = smp_num_siblings;
                while ((tmp & 0x80000000 ) == 0) {
                        tmp <<=1 ;
                        index_msb--;
                }
-               if (index_lsb != index_msb )
+               if (smp_num_siblings & (smp_num_siblings - 1))
                        index_msb++;
                phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
 
                printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
                       phys_proc_id[cpu]);
+
+               smp_num_siblings = smp_num_siblings / c->x86_num_cores;
+
+               tmp = smp_num_siblings;
+               index_msb = 31;
+               while ((tmp & 0x80000000) == 0) {
+                       tmp <<=1 ;
+                       index_msb--;
+               }
+
+               if (smp_num_siblings & (smp_num_siblings - 1))
+                       index_msb++;
+
+               cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+
+               if (c->x86_num_cores > 1)
+                       printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
+                              cpu_core_id[cpu]);
        }
 }
 #endif
diff -urN linux/arch/i386/kernel/cpu/intel.c linux/arch/i386/kernel/cpu/intel.c
--- linux/arch/i386/kernel/cpu/intel.c  2005/01/13 14:05:24     1.28
+++ linux/arch/i386/kernel/cpu/intel.c  2005/04/29 11:15:01     1.29
@@ -77,6 +77,27 @@
 }
 
 
+/*
+ * find out the number of processor cores on the die
+ */
+static int __init num_cpu_cores(struct cpuinfo_x86 *c)
+{
+       unsigned int eax;
+
+       if (c->cpuid_level < 4)
+               return 1;
+
+       __asm__("cpuid"
+               : "=a" (eax)
+               : "0" (4), "c" (0)
+               : "bx", "dx");
+
+       if (eax & 0x1f)
+               return ((eax >> 26) + 1);
+       else
+               return 1;
+}
+
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
        unsigned int l2 = 0;
@@ -139,6 +160,8 @@
        if ( p )
                strcpy(c->x86_model_id, p);
        
+       c->x86_num_cores = num_cpu_cores(c);
+
        detect_ht(c);
 
        /* Work around errata */
diff -urN linux/arch/i386/kernel/cpu/proc.c linux/arch/i386/kernel/cpu/proc.c
--- linux/arch/i386/kernel/cpu/proc.c   2005/01/13 14:05:24     1.16
+++ linux/arch/i386/kernel/cpu/proc.c   2005/04/29 11:15:01     1.17
@@ -94,8 +94,13 @@
        if (c->x86_cache_size >= 0)
                seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
 #ifdef CONFIG_X86_HT
-       seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
-       seq_printf(m, "siblings\t: %d\n", c->x86_num_cores * smp_num_siblings);
+       if (c->x86_num_cores * smp_num_siblings > 1) {
+               seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
+               seq_printf(m, "siblings\t: %d\n",
+                               c->x86_num_cores * smp_num_siblings);
+               seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]);
+               seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
+       }
 #endif
        
        /* We use exception 16 if we have hardware math and we've either seen 
it or the CPU claims it is internal */
@@ -126,6 +131,7 @@
        seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n",
                     c->loops_per_jiffy/(500000/HZ),
                     (c->loops_per_jiffy/(5000/HZ)) % 100);
+
        return 0;
 }
 
diff -urN linux/arch/i386/kernel/cpu/mtrr/generic.c 
linux/arch/i386/kernel/cpu/mtrr/generic.c
--- linux/arch/i386/kernel/cpu/mtrr/generic.c   2005/04/08 18:57:53     1.12
+++ linux/arch/i386/kernel/cpu/mtrr/generic.c   2005/04/29 11:15:01     1.13
@@ -193,7 +193,8 @@
 
        rdmsr(MTRRphysBase_MSR(index), lo, hi);
        if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
-           || (vr->base_hi & 0xfUL) != (hi & 0xfUL)) {
+           || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
+               (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
                mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
                changed = TRUE;
        }
@@ -201,7 +202,8 @@
        rdmsr(MTRRphysMask_MSR(index), lo, hi);
 
        if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
-           || (vr->mask_hi & 0xfUL) != (hi & 0xfUL)) {
+           || (vr->mask_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
+               (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
                mtrr_wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
                changed = TRUE;
        }
diff -urN linux/arch/i386/kernel/cpu/mtrr/main.c 
linux/arch/i386/kernel/cpu/mtrr/main.c
--- linux/arch/i386/kernel/cpu/mtrr/main.c      2005/03/18 17:36:49     1.13
+++ linux/arch/i386/kernel/cpu/mtrr/main.c      2005/04/29 11:15:01     1.14
@@ -614,40 +614,21 @@
                mtrr_if = &generic_mtrr_ops;
                size_or_mask = 0xff000000;      /* 36 bits */
                size_and_mask = 0x00f00000;
-                       
-               switch (boot_cpu_data.x86_vendor) {
-               case X86_VENDOR_AMD:
-                       /* The original Athlon docs said that
-                          total addressable memory is 44 bits wide.
-                          It was not really clear whether its MTRRs
-                          follow this or not. (Read: 44 or 36 bits).
-                          However, "x86-64_overview.pdf" explicitly
-                          states that "previous implementations support
-                          36 bit MTRRs" and also provides a way to
-                          query the width (in bits) of the physical
-                          addressable memory on the Hammer family.
-                        */
-                       if (boot_cpu_data.x86 == 15
-                           && (cpuid_eax(0x80000000) >= 0x80000008)) {
-                               u32 phys_addr;
-                               phys_addr = cpuid_eax(0x80000008) & 0xff;
-                               size_or_mask =
-                                   ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
-                               size_and_mask = ~size_or_mask & 0xfff00000;
-                       }
-                       /* Athlon MTRRs use an Intel-compatible interface for 
-                        * getting and setting */
-                       break;
-               case X86_VENDOR_CENTAUR:
-                       if (boot_cpu_data.x86 == 6) {
-                               /* VIA Cyrix family have Intel style MTRRs, but 
don't support PAE */
-                               size_or_mask = 0xfff00000;      /* 32 bits */
-                               size_and_mask = 0;
-                       }
-                       break;
-               
-               default:
-                       break;
+
+               /* This is an AMD specific MSR, but we assume(hope?) that
+                  Intel will implement it to when they extend the address
+                  bus of the Xeon. */
+               if (cpuid_eax(0x80000000) >= 0x80000008) {
+                       u32 phys_addr;
+                       phys_addr = cpuid_eax(0x80000008) & 0xff;
+                       size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
+                       size_and_mask = ~size_or_mask & 0xfff00000;
+               } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
+                          boot_cpu_data.x86 == 6) {
+                       /* VIA C* family have Intel style MTRRs, but
+                          don't support PAE */
+                       size_or_mask = 0xfff00000;      /* 32 bits */
+                       size_and_mask = 0;
                }
        } else {
                switch (boot_cpu_data.x86_vendor) {
diff -urN linux/arch/i386/mach-voyager/voyager_thread.c 
linux/arch/i386/mach-voyager/voyager_thread.c
--- linux/arch/i386/mach-voyager/voyager_thread.c       2004/06/26 15:15:09     
1.5
+++ linux/arch/i386/mach-voyager/voyager_thread.c       2005/04/29 11:15:01     
1.6
@@ -126,7 +126,6 @@
 
        kvoyagerd_running = 1;
 
-       reparent_to_init();
        daemonize(THREAD_NAME);
 
        set_timeout = 0;
diff -urN linux/arch/i386/mm/hugetlbpage.c linux/arch/i386/mm/hugetlbpage.c
--- linux/arch/i386/mm/hugetlbpage.c    2005/04/08 18:57:54     1.32
+++ linux/arch/i386/mm/hugetlbpage.c    2005/04/29 11:15:01     1.33
@@ -249,15 +249,8 @@
                        goto out;
                }
 
-               if (!pte_none(*pte)) {
-                       pmd_t *pmd = (pmd_t *) pte;
-
-                       page = pmd_page(*pmd);
-                       pmd_clear(pmd);
-                       mm->nr_ptes--;
-                       dec_page_state(nr_page_table_pages);
-                       page_cache_release(page);
-               }
+               if (!pte_none(*pte))
+                       continue;
 
                idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
                        + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
diff -urN linux/arch/i386/mm/pgtable.c linux/arch/i386/mm/pgtable.c
--- linux/arch/i386/mm/pgtable.c        2005/01/25 04:27:56     1.16
+++ linux/arch/i386/mm/pgtable.c        2005/04/29 11:15:01     1.17
@@ -255,6 +255,6 @@
        if (PTRS_PER_PMD > 1)
                for (i = 0; i < USER_PTRS_PER_PGD; ++i)
                        kmem_cache_free(pmd_cache, (void 
*)__va(pgd_val(pgd[i])-1));
-       /* in the non-PAE case, clear_page_range() clears user pgd entries */
+       /* in the non-PAE case, free_pgtables() clears user pgd entries */
        kmem_cache_free(pgd_cache, pgd);
 }
diff -urN linux/arch/i386/oprofile/nmi_int.c linux/arch/i386/oprofile/nmi_int.c
--- linux/arch/i386/oprofile/nmi_int.c  2005/02/13 20:16:15     1.20
+++ linux/arch/i386/oprofile/nmi_int.c  2005/04/29 11:15:01     1.21
@@ -32,7 +32,7 @@
 
 #ifdef CONFIG_PM
 
-static int nmi_suspend(struct sys_device *dev, u32 state)
+static int nmi_suspend(struct sys_device *dev, pm_message_t state)
 {
        if (nmi_enabled == 1)
                nmi_stop();
diff -urN linux/arch/i386/pci/irq.c linux/arch/i386/pci/irq.c
--- linux/arch/i386/pci/irq.c   2005/03/18 17:36:50     1.23
+++ linux/arch/i386/pci/irq.c   2005/04/29 11:15:01     1.24
@@ -495,6 +495,7 @@
                case PCI_DEVICE_ID_INTEL_ICH6_1:
                case PCI_DEVICE_ID_INTEL_ICH7_0:
                case PCI_DEVICE_ID_INTEL_ICH7_1:
+               case PCI_DEVICE_ID_INTEL_ESB2_0:
                        r->name = "PIIX/ICH";
                        r->get = pirq_piix_get;
                        r->set = pirq_piix_set;
diff -urN linux/arch/ia64/mm/hugetlbpage.c linux/arch/ia64/mm/hugetlbpage.c
--- linux/arch/ia64/mm/hugetlbpage.c    2005/04/08 18:57:54     1.22
+++ linux/arch/ia64/mm/hugetlbpage.c    2005/04/29 11:15:01     1.23
@@ -186,46 +186,30 @@
        return NULL;
 }
 
-/*
- * Same as generic free_pgtables(), except constant PGDIR_* and pgd_offset
- * are hugetlb region specific.
- */
-void hugetlb_free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *prev,
-       unsigned long start, unsigned long end)
+void hugetlb_free_pgd_range(struct mmu_gather **tlb,
+                       unsigned long addr, unsigned long end,
+                       unsigned long floor, unsigned long ceiling)
 {
-       unsigned long first = start & HUGETLB_PGDIR_MASK;
-       unsigned long last = end + HUGETLB_PGDIR_SIZE - 1;
-       struct mm_struct *mm = tlb->mm;
-
-       if (!prev) {
-               prev = mm->mmap;
-               if (!prev)
-                       goto no_mmaps;
-               if (prev->vm_end > start) {
-                       if (last > prev->vm_start)
-                               last = prev->vm_start;
-                       goto no_mmaps;
-               }
-       }
-       for (;;) {
-               struct vm_area_struct *next = prev->vm_next;
+       /*
+        * This is called only when is_hugepage_only_range(addr,),
+        * and it follows that is_hugepage_only_range(end,) also.
+        *
+        * The offset of these addresses from the base of the hugetlb
+        * region must be scaled down by HPAGE_SIZE/PAGE_SIZE so that
+        * the standard free_pgd_range will free the right page tables.
+        *
+        * If floor and ceiling are also in the hugetlb region, they
+        * must likewise be scaled down; but if outside, left unchanged.
+        */
 
-               if (next) {
-                       if (next->vm_start < start) {
-                               prev = next;
-                               continue;
-                       }
-                       if (last > next->vm_start)
-                               last = next->vm_start;
-               }
-               if (prev->vm_end > first)
-                       first = prev->vm_end;
-               break;
-       }
-no_mmaps:
-       if (last < first)       /* for arches with discontiguous pgd indices */
-               return;
-       clear_page_range(tlb, first, last);
+       addr = htlbpage_to_page(addr);
+       end  = htlbpage_to_page(end);
+       if (is_hugepage_only_range(tlb->mm, floor, HPAGE_SIZE))
+               floor = htlbpage_to_page(floor);
+       if (is_hugepage_only_range(tlb->mm, ceiling, HPAGE_SIZE))
+               ceiling = htlbpage_to_page(ceiling);
+
+       free_pgd_range(tlb, addr, end, floor, ceiling);
 }
 
 void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, 
unsigned long end)
diff -urN linux/arch/m68k/defconfig linux/arch/m68k/defconfig
--- linux/arch/m68k/defconfig   2005/01/13 14:05:27     1.26
+++ linux/arch/m68k/defconfig   2005/04/29 11:15:01     1.27
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:36 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:05:31 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -25,22 +27,22 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -92,6 +94,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -112,6 +115,7 @@
 #
 CONFIG_AMIGA_FLOPPY=y
 # CONFIG_AMIGA_Z2RAM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -130,6 +134,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -164,6 +169,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -207,7 +213,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -324,16 +329,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -353,6 +348,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -393,6 +398,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -420,6 +429,11 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -428,6 +442,7 @@
 CONFIG_FB_AMIGA_ECS=y
 CONFIG_FB_AMIGA_AGA=y
 # CONFIG_FB_FM2 is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -440,6 +455,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -453,10 +469,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -467,6 +479,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_AMIGA_BUILTIN_SERIAL=y
@@ -483,6 +500,10 @@
 # CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
@@ -544,7 +565,6 @@
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -608,7 +628,10 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEBUG_BUGVERBOSE=y
 
 #
 # Security options
@@ -622,6 +645,10 @@
 # CONFIG_CRYPTO is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
diff -urN linux/arch/m68k/configs/amiga_defconfig 
linux/arch/m68k/configs/amiga_defconfig
--- linux/arch/m68k/configs/amiga_defconfig     2005/01/13 14:05:27     1.4
+++ linux/arch/m68k/configs/amiga_defconfig     2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:22:54 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:05:59 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -104,6 +106,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -116,9 +119,10 @@
 #
 CONFIG_PARPORT=m
 # CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_AMIGA=m
 CONFIG_PARPORT_MFC3=m
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 CONFIG_PARPORT_1284=y
 
 #
@@ -133,6 +137,7 @@
 CONFIG_AMIGA_Z2RAM=y
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -152,6 +157,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -212,6 +218,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -225,7 +232,6 @@
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
@@ -273,6 +279,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -296,7 +304,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -394,11 +401,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -470,7 +475,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # ARCnet devices
@@ -564,17 +568,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -593,21 +586,43 @@
 CONFIG_MOUSE_AMIGA=y
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
 # CONFIG_JOYSTICK_IFORCE is not set
 # CONFIG_JOYSTICK_WARRIOR is not set
 # CONFIG_JOYSTICK_MAGELLAN is not set
 # CONFIG_JOYSTICK_SPACEORB is not set
 # CONFIG_JOYSTICK_SPACEBALL is not set
 # CONFIG_JOYSTICK_STINGER is not set
-# CONFIG_JOYSTICK_TWIDDLER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
 # CONFIG_JOYSTICK_DB9 is not set
 # CONFIG_JOYSTICK_GAMECON is not set
 # CONFIG_JOYSTICK_TURBOGRAFX is not set
 CONFIG_JOYSTICK_AMIGA=m
+# CONFIG_JOYSTICK_JOYDUMP is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -653,6 +668,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -680,6 +699,11 @@
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_CIRRUS=m
@@ -688,6 +712,7 @@
 CONFIG_FB_AMIGA_ECS=y
 CONFIG_FB_AMIGA_AGA=y
 CONFIG_FB_FM2=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -707,6 +732,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -722,10 +748,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -736,6 +758,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_AMIGA_BUILTIN_SERIAL=y
@@ -758,10 +785,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -916,13 +949,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -941,7 +980,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -959,6 +999,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/apollo_defconfig 
linux/arch/m68k/configs/apollo_defconfig
--- linux/arch/m68k/configs/apollo_defconfig    2005/01/13 14:05:27     1.4
+++ linux/arch/m68k/configs/apollo_defconfig    2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:22:58 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:00 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -99,6 +101,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -118,6 +121,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -137,6 +141,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -171,6 +176,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -196,6 +202,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -219,7 +227,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -320,11 +327,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -396,7 +401,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -469,16 +473,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -496,6 +490,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -536,6 +540,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -581,10 +589,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -595,6 +599,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_DN_SERIAL=y
@@ -615,10 +624,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -773,13 +788,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -798,7 +819,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -816,6 +838,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/atari_defconfig 
linux/arch/m68k/configs/atari_defconfig
--- linux/arch/m68k/configs/atari_defconfig     2005/01/13 14:05:27     1.4
+++ linux/arch/m68k/configs/atari_defconfig     2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:11 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:18 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -100,6 +102,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -112,8 +115,9 @@
 #
 CONFIG_PARPORT=m
 # CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_ATARI=m
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 CONFIG_PARPORT_1284=y
 
 #
@@ -125,6 +129,7 @@
 #
 CONFIG_ATARI_FLOPPY=y
 # CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -144,6 +149,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -201,6 +207,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -228,6 +235,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -251,7 +260,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -349,11 +357,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -425,7 +431,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -499,17 +504,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -529,6 +523,17 @@
 CONFIG_INPUT_UINPUT=m
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -574,6 +579,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -601,9 +610,15 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -619,6 +634,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -634,10 +650,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -648,6 +660,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_ATARI_MFPSER=m
@@ -672,9 +689,15 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -828,13 +851,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -853,7 +882,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -871,6 +901,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/bvme6000_defconfig 
linux/arch/m68k/configs/bvme6000_defconfig
--- linux/arch/m68k/configs/bvme6000_defconfig  2005/01/13 14:05:27     1.4
+++ linux/arch/m68k/configs/bvme6000_defconfig  2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:15 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:19 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -99,6 +101,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -118,6 +121,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -137,6 +141,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -171,6 +176,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -196,6 +202,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -219,7 +227,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -320,11 +327,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -395,7 +400,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -468,16 +472,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -495,6 +489,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -535,6 +539,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -580,10 +588,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -594,6 +598,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_BVME6000_SCC=y
@@ -614,10 +623,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -772,13 +787,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -797,7 +818,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -815,6 +837,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/hp300_defconfig 
linux/arch/m68k/configs/hp300_defconfig
--- linux/arch/m68k/configs/hp300_defconfig     2005/01/13 14:05:27     1.4
+++ linux/arch/m68k/configs/hp300_defconfig     2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:40 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:21 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -100,6 +102,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -119,6 +122,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -138,6 +142,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -172,6 +177,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -197,6 +203,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -220,7 +228,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -321,11 +328,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -397,7 +402,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -470,16 +474,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -497,6 +491,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -537,6 +541,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -582,10 +590,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -596,6 +600,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 
@@ -614,10 +623,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -772,13 +787,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -797,7 +818,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -815,6 +837,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/mac_defconfig 
linux/arch/m68k/configs/mac_defconfig
--- linux/arch/m68k/configs/mac_defconfig       2005/01/13 14:05:27     1.4
+++ linux/arch/m68k/configs/mac_defconfig       2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:44 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:24 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -101,6 +103,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -120,6 +123,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -139,6 +143,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -196,6 +201,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -223,6 +229,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -258,7 +266,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -356,11 +363,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -435,7 +440,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -512,16 +516,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -539,6 +533,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -579,6 +583,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -606,10 +614,16 @@
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_VALKYRIE=y
 CONFIG_FB_MAC=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -630,6 +644,7 @@
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_MAC_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -643,10 +658,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -657,6 +668,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_MAC_SCC=y
@@ -679,10 +695,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -846,18 +868,24 @@
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
+CONFIG_NLS_UTF8=y
 
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -876,7 +904,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -894,6 +923,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/mvme147_defconfig 
linux/arch/m68k/configs/mvme147_defconfig
--- linux/arch/m68k/configs/mvme147_defconfig   2005/01/13 14:05:28     1.4
+++ linux/arch/m68k/configs/mvme147_defconfig   2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:49 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:28 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -99,6 +101,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -118,6 +121,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -137,6 +141,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -171,6 +176,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -197,6 +203,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -220,7 +228,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -321,11 +328,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -397,7 +402,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -470,16 +474,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -497,6 +491,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -537,6 +541,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -564,8 +572,14 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -584,6 +598,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -597,10 +612,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -611,6 +622,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_MVME147_SCC=y
@@ -631,10 +647,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -791,13 +813,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -816,7 +844,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -834,6 +863,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/mvme16x_defconfig 
linux/arch/m68k/configs/mvme16x_defconfig
--- linux/arch/m68k/configs/mvme16x_defconfig   2005/01/13 14:05:28     1.4
+++ linux/arch/m68k/configs/mvme16x_defconfig   2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:53 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:31 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -99,6 +101,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -118,6 +121,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -137,6 +141,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -171,6 +176,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -196,6 +202,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -219,7 +227,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -320,11 +327,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -396,7 +401,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -469,16 +473,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -496,6 +490,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -536,6 +540,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -563,8 +571,14 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -583,6 +597,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -596,10 +611,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -610,6 +621,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 CONFIG_MVME162_SCC=y
@@ -630,10 +646,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -790,13 +812,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -815,7 +843,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -833,6 +862,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/q40_defconfig 
linux/arch/m68k/configs/q40_defconfig
--- linux/arch/m68k/configs/q40_defconfig       2005/01/13 14:05:28     1.4
+++ linux/arch/m68k/configs/q40_defconfig       2005/04/29 11:15:01     1.5
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:23:57 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:34 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -101,6 +103,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -123,6 +126,7 @@
 #
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -142,6 +146,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -200,6 +205,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -213,7 +219,6 @@
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
@@ -250,6 +255,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -273,7 +280,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -374,11 +380,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -450,7 +454,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # ARCnet devices
@@ -539,17 +542,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_Q40KBD=m
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -570,6 +562,17 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_Q40KBD=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -610,6 +613,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -637,9 +644,15 @@
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_Q40=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -658,6 +671,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -673,10 +687,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -687,6 +697,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 
@@ -705,10 +720,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -863,13 +884,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -888,7 +915,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -906,6 +934,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/sun3_defconfig 
linux/arch/m68k/configs/sun3_defconfig
--- linux/arch/m68k/configs/sun3_defconfig      2005/04/08 18:57:55     1.5
+++ linux/arch/m68k/configs/sun3_defconfig      2005/04/29 11:15:01     1.6
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:24:01 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:37 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -87,6 +89,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -106,6 +109,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -125,6 +129,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -159,6 +164,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -185,6 +191,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -208,7 +216,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -309,11 +316,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -385,7 +390,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -459,16 +463,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -486,6 +480,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -526,6 +530,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -553,8 +561,14 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -573,6 +587,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -586,10 +601,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -600,6 +611,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 
@@ -618,10 +634,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -779,13 +801,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -804,7 +832,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -822,6 +851,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/m68k/configs/sun3x_defconfig 
linux/arch/m68k/configs/sun3x_defconfig
--- linux/arch/m68k/configs/sun3x_defconfig     2005/04/08 18:57:55     1.5
+++ linux/arch/m68k/configs/sun3x_defconfig     2005/04/29 11:15:01     1.6
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-m68k
-# Sun Dec 26 11:24:05 2004
+# Linux kernel version: 2.6.12-rc2-m68k
+# Tue Apr  5 14:06:40 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 
 #
 # Code maturity level options
@@ -14,6 +15,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,23 +28,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -98,6 +100,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -117,6 +120,7 @@
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -136,6 +140,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -170,6 +175,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -196,6 +202,8 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -219,7 +227,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
@@ -320,11 +327,9 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
@@ -396,7 +401,6 @@
 # CONFIG_BONDING is not set
 CONFIG_EQUALIZER=m
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -469,16 +473,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -496,6 +490,16 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -536,6 +540,10 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -563,8 +571,14 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -583,6 +597,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -596,10 +611,6 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; 
see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -610,6 +621,11 @@
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Character devices
 #
 
@@ -628,10 +644,16 @@
 # CONFIG_REISERFS_FS_XATTR is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -789,13 +811,19 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
@@ -814,7 +842,8 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -832,6 +861,10 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
diff -urN linux/arch/mips/defconfig linux/arch/mips/defconfig
--- linux/arch/mips/defconfig   2005/04/08 18:57:58     1.287
+++ linux/arch/mips/defconfig   2005/04/29 11:15:02     1.288
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:21:00 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:00:41 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/atlas_defconfig 
linux/arch/mips/configs/atlas_defconfig
--- linux/arch/mips/configs/atlas_defconfig     2005/04/08 18:57:58     1.51
+++ linux/arch/mips/configs/atlas_defconfig     2005/04/29 11:15:02     1.52
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:21:01 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:22 2005
 #
 CONFIG_MIPS=y
 
@@ -341,6 +341,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
diff -urN linux/arch/mips/configs/capcella_defconfig 
linux/arch/mips/configs/capcella_defconfig
--- linux/arch/mips/configs/capcella_defconfig  2005/04/08 18:57:58     1.51
+++ linux/arch/mips/configs/capcella_defconfig  2005/04/29 11:15:02     1.52
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:11 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:25 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/cobalt_defconfig 
linux/arch/mips/configs/cobalt_defconfig
--- linux/arch/mips/configs/cobalt_defconfig    2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/cobalt_defconfig    2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:15 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:29 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1000_defconfig 
linux/arch/mips/configs/db1000_defconfig
--- linux/arch/mips/configs/db1000_defconfig    2005/04/08 18:57:58     1.54
+++ linux/arch/mips/configs/db1000_defconfig    2005/04/29 11:15:02     1.55
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:15 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:31 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1100_defconfig 
linux/arch/mips/configs/db1100_defconfig
--- linux/arch/mips/configs/db1100_defconfig    2005/04/08 18:57:58     1.53
+++ linux/arch/mips/configs/db1100_defconfig    2005/04/29 11:15:02     1.54
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:18 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:34 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1500_defconfig 
linux/arch/mips/configs/db1500_defconfig
--- linux/arch/mips/configs/db1500_defconfig    2005/04/08 18:57:58     1.56
+++ linux/arch/mips/configs/db1500_defconfig    2005/04/29 11:15:02     1.57
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:20 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:37 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1550_defconfig 
linux/arch/mips/configs/db1550_defconfig
--- linux/arch/mips/configs/db1550_defconfig    2005/04/08 18:57:58     1.31
+++ linux/arch/mips/configs/db1550_defconfig    2005/04/29 11:15:02     1.32
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:21 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:13:39 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ddb5476_defconfig 
linux/arch/mips/configs/ddb5476_defconfig
--- linux/arch/mips/configs/ddb5476_defconfig   2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/ddb5476_defconfig   2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:22 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:39 2005
 #
 CONFIG_MIPS=y
 
@@ -586,6 +586,7 @@
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_E1356 is not set
 # CONFIG_FB_S1D13XXX is not set
diff -urN linux/arch/mips/configs/ddb5477_defconfig 
linux/arch/mips/configs/ddb5477_defconfig
--- linux/arch/mips/configs/ddb5477_defconfig   2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/ddb5477_defconfig   2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:23 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:42 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/decstation_defconfig 
linux/arch/mips/configs/decstation_defconfig
--- linux/arch/mips/configs/decstation_defconfig        2005/04/08 18:57:58     
1.49
+++ linux/arch/mips/configs/decstation_defconfig        2005/04/29 11:15:02     
1.50
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:23 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:45 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/e55_defconfig 
linux/arch/mips/configs/e55_defconfig
--- linux/arch/mips/configs/e55_defconfig       2005/04/08 18:57:58     1.50
+++ linux/arch/mips/configs/e55_defconfig       2005/04/29 11:15:02     1.51
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:25 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:48 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ev64120_defconfig 
linux/arch/mips/configs/ev64120_defconfig
--- linux/arch/mips/configs/ev64120_defconfig   2005/04/08 18:57:58     1.47
+++ linux/arch/mips/configs/ev64120_defconfig   2005/04/29 11:15:02     1.48
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:26 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:51 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ev96100_defconfig 
linux/arch/mips/configs/ev96100_defconfig
--- linux/arch/mips/configs/ev96100_defconfig   2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/ev96100_defconfig   2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:26 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:53 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ip22_defconfig 
linux/arch/mips/configs/ip22_defconfig
--- linux/arch/mips/configs/ip22_defconfig      2005/04/08 18:57:58     1.57
+++ linux/arch/mips/configs/ip22_defconfig      2005/04/29 11:15:02     1.58
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:27 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:14:55 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ip27_defconfig 
linux/arch/mips/configs/ip27_defconfig
--- linux/arch/mips/configs/ip27_defconfig      2005/04/08 18:57:58     1.61
+++ linux/arch/mips/configs/ip27_defconfig      2005/04/29 11:15:02     1.62
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:28 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:16:37 2005
 #
 CONFIG_MIPS=y
 
@@ -321,6 +321,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
diff -urN linux/arch/mips/configs/ip32_defconfig 
linux/arch/mips/configs/ip32_defconfig
--- linux/arch/mips/configs/ip32_defconfig      2005/04/08 18:57:58     1.51
+++ linux/arch/mips/configs/ip32_defconfig      2005/04/29 11:15:02     1.52
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:29 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:16:41 2005
 #
 CONFIG_MIPS=y
 
@@ -274,7 +274,7 @@
 #
 # SCSI Transport Attributes
 #
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 
@@ -314,6 +314,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
diff -urN linux/arch/mips/configs/it8172_defconfig 
linux/arch/mips/configs/it8172_defconfig
--- linux/arch/mips/configs/it8172_defconfig    2005/04/08 18:57:58     1.47
+++ linux/arch/mips/configs/it8172_defconfig    2005/04/29 11:15:02     1.48
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:30 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:16:44 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ivr_defconfig 
linux/arch/mips/configs/ivr_defconfig
--- linux/arch/mips/configs/ivr_defconfig       2005/04/08 18:57:58     1.47
+++ linux/arch/mips/configs/ivr_defconfig       2005/04/29 11:15:02     1.48
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:31 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:16:46 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/jaguar-atx_defconfig 
linux/arch/mips/configs/jaguar-atx_defconfig
--- linux/arch/mips/configs/jaguar-atx_defconfig        2005/04/08 18:57:58     
1.52
+++ linux/arch/mips/configs/jaguar-atx_defconfig        2005/04/29 11:15:02     
1.53
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:32 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:16:48 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/jmr3927_defconfig 
linux/arch/mips/configs/jmr3927_defconfig
--- linux/arch/mips/configs/jmr3927_defconfig   2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/jmr3927_defconfig   2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:32 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:26 2005
 #
 CONFIG_MIPS=y
 
@@ -560,6 +560,7 @@
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_E1356 is not set
 # CONFIG_FB_S1D13XXX is not set
diff -urN linux/arch/mips/configs/lasat200_defconfig 
linux/arch/mips/configs/lasat200_defconfig
--- linux/arch/mips/configs/lasat200_defconfig  2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/lasat200_defconfig  2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:33 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:31 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/malta_defconfig 
linux/arch/mips/configs/malta_defconfig
--- linux/arch/mips/configs/malta_defconfig     2005/04/08 18:57:58     1.50
+++ linux/arch/mips/configs/malta_defconfig     2005/04/29 11:15:02     1.51
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:34 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:37 2005
 #
 CONFIG_MIPS=y
 
@@ -372,6 +372,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
diff -urN linux/arch/mips/configs/mpc30x_defconfig 
linux/arch/mips/configs/mpc30x_defconfig
--- linux/arch/mips/configs/mpc30x_defconfig    2005/04/08 18:57:58     1.52
+++ linux/arch/mips/configs/mpc30x_defconfig    2005/04/29 11:15:02     1.53
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:35 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:40 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_3_defconfig 
linux/arch/mips/configs/ocelot_3_defconfig
--- linux/arch/mips/configs/ocelot_3_defconfig  2005/04/08 18:57:58     1.20
+++ linux/arch/mips/configs/ocelot_3_defconfig  2005/04/29 11:15:02     1.21
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:36 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:45 2005
 #
 CONFIG_MIPS=y
 
@@ -313,6 +313,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
@@ -679,6 +680,7 @@
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_E1356 is not set
 # CONFIG_FB_S1D13XXX is not set
diff -urN linux/arch/mips/configs/ocelot_c_defconfig 
linux/arch/mips/configs/ocelot_c_defconfig
--- linux/arch/mips/configs/ocelot_c_defconfig  2005/04/08 18:57:58     1.46
+++ linux/arch/mips/configs/ocelot_c_defconfig  2005/04/29 11:15:02     1.47
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:37 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:48 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_defconfig 
linux/arch/mips/configs/ocelot_defconfig
--- linux/arch/mips/configs/ocelot_defconfig    2005/04/08 18:57:58     1.48
+++ linux/arch/mips/configs/ocelot_defconfig    2005/04/29 11:15:02     1.49
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:37 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:51 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_g_defconfig 
linux/arch/mips/configs/ocelot_g_defconfig
--- linux/arch/mips/configs/ocelot_g_defconfig  2005/04/08 18:57:58     1.41
+++ linux/arch/mips/configs/ocelot_g_defconfig  2005/04/29 11:15:02     1.42
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:38 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:54 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/osprey_defconfig 
linux/arch/mips/configs/osprey_defconfig
--- linux/arch/mips/configs/osprey_defconfig    2005/04/08 18:57:58     1.47
+++ linux/arch/mips/configs/osprey_defconfig    2005/04/29 11:15:02     1.48
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:39 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:57 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pb1100_defconfig 
linux/arch/mips/configs/pb1100_defconfig
--- linux/arch/mips/configs/pb1100_defconfig    2005/04/08 18:57:58     1.50
+++ linux/arch/mips/configs/pb1100_defconfig    2005/04/29 11:15:02     1.51
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:40 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:20:59 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pb1500_defconfig 
linux/arch/mips/configs/pb1500_defconfig
--- linux/arch/mips/configs/pb1500_defconfig    2005/04/08 18:57:58     1.56
+++ linux/arch/mips/configs/pb1500_defconfig    2005/04/29 11:15:02     1.57
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:41 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:02 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pb1550_defconfig 
linux/arch/mips/configs/pb1550_defconfig
--- linux/arch/mips/configs/pb1550_defconfig    2005/04/08 18:57:58     1.46
+++ linux/arch/mips/configs/pb1550_defconfig    2005/04/29 11:15:02     1.47
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:42 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:05 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/rm200_defconfig 
linux/arch/mips/configs/rm200_defconfig
--- linux/arch/mips/configs/rm200_defconfig     2005/04/08 18:57:58     1.57
+++ linux/arch/mips/configs/rm200_defconfig     2005/04/29 11:15:02     1.58
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:43 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:09 2005
 #
 CONFIG_MIPS=y
 
@@ -381,6 +381,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
diff -urN linux/arch/mips/configs/sb1250-swarm_defconfig 
linux/arch/mips/configs/sb1250-swarm_defconfig
--- linux/arch/mips/configs/sb1250-swarm_defconfig      2005/04/08 18:57:58     
1.54
+++ linux/arch/mips/configs/sb1250-swarm_defconfig      2005/04/29 11:15:02     
1.55
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:44 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:12 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/sead_defconfig 
linux/arch/mips/configs/sead_defconfig
--- linux/arch/mips/configs/sead_defconfig      2005/04/08 18:57:58     1.46
+++ linux/arch/mips/configs/sead_defconfig      2005/04/29 11:15:02     1.47
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:45 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:14 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/tb0226_defconfig 
linux/arch/mips/configs/tb0226_defconfig
--- linux/arch/mips/configs/tb0226_defconfig    2005/04/08 18:57:58     1.50
+++ linux/arch/mips/configs/tb0226_defconfig    2005/04/29 11:15:02     1.51
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:46 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:16 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/tb0229_defconfig 
linux/arch/mips/configs/tb0229_defconfig
--- linux/arch/mips/configs/tb0229_defconfig    2005/04/08 18:57:58     1.53
+++ linux/arch/mips/configs/tb0229_defconfig    2005/04/29 11:15:02     1.54
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:47 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:19 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/workpad_defconfig 
linux/arch/mips/configs/workpad_defconfig
--- linux/arch/mips/configs/workpad_defconfig   2005/04/08 18:57:58     1.50
+++ linux/arch/mips/configs/workpad_defconfig   2005/04/29 11:15:02     1.51
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:48 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:21 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/yosemite_defconfig 
linux/arch/mips/configs/yosemite_defconfig
--- linux/arch/mips/configs/yosemite_defconfig  2005/04/08 18:57:58     1.52
+++ linux/arch/mips/configs/yosemite_defconfig  2005/04/29 11:15:02     1.53
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2
-# Fri Apr  8 18:22:48 2005
+# Linux kernel version: 2.6.12-rc3
+# Thu Apr 28 18:21:24 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/parisc/lib/iomap.c linux/arch/parisc/lib/iomap.c
--- linux/arch/parisc/lib/iomap.c       2005/01/25 04:28:01     1.1
+++ linux/arch/parisc/lib/iomap.c       2005/04/29 11:15:03     1.2
@@ -43,10 +43,14 @@
 struct iomap_ops {
        unsigned int (*read8)(void __iomem *);
        unsigned int (*read16)(void __iomem *);
+       unsigned int (*read16be)(void __iomem *);
        unsigned int (*read32)(void __iomem *);
+       unsigned int (*read32be)(void __iomem *);
        void (*write8)(u8, void __iomem *);
        void (*write16)(u16, void __iomem *);
+       void (*write16be)(u16, void __iomem *);
        void (*write32)(u32, void __iomem *);
+       void (*write32be)(u32, void __iomem *);
        void (*read8r)(void __iomem *, void *, unsigned long);
        void (*read16r)(void __iomem *, void *, unsigned long);
        void (*read32r)(void __iomem *, void *, unsigned long);
@@ -122,9 +126,13 @@
 static const struct iomap_ops ioport_ops = {
        ioport_read8,
        ioport_read16,
+       ioport_read16,
+       ioport_read32,
        ioport_read32,
        ioport_write8,
        ioport_write16,
+       ioport_write16,
+       ioport_write32,
        ioport_write32,
        ioport_read8r,
        ioport_read16r,
@@ -146,11 +154,21 @@
        return readw(addr);
 }
 
+static unsigned int iomem_read16be(void __iomem *addr)
+{
+       return __raw_readw(addr);
+}
+
 static unsigned int iomem_read32(void __iomem *addr)
 {
        return readl(addr);
 }
 
+static unsigned int iomem_read32be(void __iomem *addr)
+{
+       return __raw_readl(addr);
+}
+
 static void iomem_write8(u8 datum, void __iomem *addr)
 {
        writeb(datum, addr);
@@ -161,11 +179,21 @@
        writew(datum, addr);
 }
 
+static void iomem_write16be(u16 datum, void __iomem *addr)
+{
+       __raw_writew(datum, addr);
+}
+
 static void iomem_write32(u32 datum, void __iomem *addr)
 {
        writel(datum, addr);
 }
 
+static void iomem_write32be(u32 datum, void __iomem *addr)
+{
+       __raw_writel(datum, addr);
+}
+
 static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
 {
        while (count--) {
@@ -217,10 +245,14 @@
 static const struct iomap_ops iomem_ops = {
        iomem_read8,
        iomem_read16,
+       iomem_read16be,
        iomem_read32,
+       iomem_read32be,
        iomem_write8,
        iomem_write16,
+       iomem_write16be,
        iomem_write32,
+       iomem_write32be,
        iomem_read8r,
        iomem_read16r,
        iomem_read32r,
@@ -253,6 +285,13 @@
        return le16_to_cpup((u16 *)addr);
 }
 
+unsigned int ioread16be(void __iomem *addr)
+{
+       if (unlikely(INDIRECT_ADDR(addr)))
+               return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr);
+       return *((u16 *)addr);
+}
+
 unsigned int ioread32(void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
@@ -260,6 +299,13 @@
        return le32_to_cpup((u32 *)addr);
 }
 
+unsigned int ioread32be(void __iomem *addr)
+{
+       if (unlikely(INDIRECT_ADDR(addr)))
+               return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr);
+       return *((u32 *)addr);
+}
+
 void iowrite8(u8 datum, void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr))) {
@@ -278,6 +324,15 @@
        }
 }
 
+void iowrite16be(u16 datum, void __iomem *addr)
+{
+       if (unlikely(INDIRECT_ADDR(addr))) {
+               iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr);
+       } else {
+               *((u16 *)addr) = datum;
+       }
+}
+
 void iowrite32(u32 datum, void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr))) {
@@ -287,6 +342,15 @@
        }
 }
 
+void iowrite32be(u32 datum, void __iomem *addr)
+{
+       if (unlikely(INDIRECT_ADDR(addr))) {
+               iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr);
+       } else {
+               *((u32 *)addr) = datum;
+       }
+}
+
 /* Repeating interfaces */
 
 void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
@@ -406,10 +470,14 @@
 
 EXPORT_SYMBOL(ioread8);
 EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread16be);
 EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(ioread32be);
 EXPORT_SYMBOL(iowrite8);
 EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite16be);
 EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(iowrite32be);
 EXPORT_SYMBOL(ioread8_rep);
 EXPORT_SYMBOL(ioread16_rep);
 EXPORT_SYMBOL(ioread32_rep);
diff -urN linux/arch/ppc/Kconfig linux/arch/ppc/Kconfig
--- linux/arch/ppc/Kconfig      2005/04/08 18:57:59     1.46
+++ linux/arch/ppc/Kconfig      2005/04/29 11:15:03     1.47
@@ -98,13 +98,19 @@
 
 config PTE_64BIT
        bool
-       depends on 44x
-       default y
+       depends on 44x || E500
+       default y if 44x
+       default y if E500 && PHYS_64BIT
 
 config PHYS_64BIT
-       bool
-       depends on 44x
-       default y
+       bool 'Large physical address support' if E500
+       depends on 44x || E500
+       default y if 44x
+       ---help---
+         This option enables kernel support for larger than 32-bit physical
+         addresses.  This features is not be available on all e500 cores.
+
+         If in doubt, say N here.
 
 config ALTIVEC
        bool "AltiVec Support"
diff -urN linux/arch/ppc/boot/simple/Makefile 
linux/arch/ppc/boot/simple/Makefile
--- linux/arch/ppc/boot/simple/Makefile 2005/04/08 18:58:00     1.30
+++ linux/arch/ppc/boot/simple/Makefile 2005/04/29 11:15:03     1.31
@@ -123,10 +123,13 @@
          end-$(pcore)                  := pcore
    cacheflag-$(pcore)                  := -include $(clear_L2_L3)
 
+# Really only valid if CONFIG_6xx=y
       zimage-$(CONFIG_PPC_PREP)                := zImage-PPLUS
 zimageinitrd-$(CONFIG_PPC_PREP)                := zImage.initrd-PPLUS
+ifeq ($(CONFIG_6xx),y)
      extra.o-$(CONFIG_PPC_PREP)                := prepmap.o
         misc-$(CONFIG_PPC_PREP)                += misc-prep.o mpc10x_memory.o
+endif
          end-$(CONFIG_PPC_PREP)                := prep
 
          end-$(CONFIG_SANDPOINT)       := sandpoint
diff -urN linux/arch/ppc/kernel/head_fsl_booke.S 
linux/arch/ppc/kernel/head_fsl_booke.S
--- linux/arch/ppc/kernel/head_fsl_booke.S      2005/04/08 18:58:00     1.1
+++ linux/arch/ppc/kernel/head_fsl_booke.S      2005/04/29 11:15:03     1.2
@@ -347,6 +347,38 @@
        mtspr   SPRN_SRR1,r3
        rfi                     /* change context and jump to start_kernel */
 
+/* Macros to hide the PTE size differences
+ *
+ * FIND_PTE -- walks the page tables given EA & pgdir pointer
+ *   r10 -- EA of fault
+ *   r11 -- PGDIR pointer
+ *   r12 -- free
+ *   label 2: is the bailout case
+ *
+ * if we find the pte (fall through):
+ *   r11 is low pte word
+ *   r12 is pointer to the pte
+ */
+#ifdef CONFIG_PTE_64BIT
+#define PTE_FLAGS_OFFSET       4
+#define FIND_PTE       \
+       rlwinm  r12, r10, 13, 19, 29;   /* Compute pgdir/pmd offset */  \
+       lwzx    r11, r12, r11;          /* Get pgd/pmd entry */         \
+       rlwinm. r12, r11, 0, 0, 20;     /* Extract pt base address */   \
+       beq     2f;                     /* Bail if no table */          \
+       rlwimi  r12, r10, 23, 20, 28;   /* Compute pte address */       \
+       lwz     r11, 4(r12);            /* Get pte entry */
+#else
+#define PTE_FLAGS_OFFSET       0
+#define FIND_PTE       \
+       rlwimi  r11, r10, 12, 20, 29;   /* Create L1 (pgdir/pmd) address */     
\
+       lwz     r11, 0(r11);            /* Get L1 entry */                      
\
+       rlwinm. r12, r11, 0, 0, 19;     /* Extract L2 (pte) base address */     
\
+       beq     2f;                     /* Bail if no table */                  
\
+       rlwimi  r12, r10, 22, 20, 29;   /* Compute PTE address */               
\
+       lwz     r11, 0(r12);            /* Get Linux PTE */
+#endif
+
 /*
  * Interrupt vector entry code
  *
@@ -405,13 +437,7 @@
        mfspr   r11,SPRN_SPRG3
        lwz     r11,PGDIR(r11)
 4:
-       rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
-       lwz     r11, 0(r11)             /* Get L1 entry */
-       rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
-       beq     2f                      /* Bail if no table */
-
-       rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
-       lwz     r11, 0(r12)             /* Get Linux PTE */
+       FIND_PTE
 
        /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
        andi.   r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
@@ -420,14 +446,12 @@
 
        /* Update 'changed'. */
        ori     r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
-       stw     r11, 0(r12)             /* Update Linux page table */
+       stw     r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
 
        /* MAS2 not updated as the entry does exist in the tlb, this
           fault taken to detect state transition (eg: COW -> DIRTY)
         */
-       lis     r12, MAS3_RPN@h
-       ori     r12, r12, _PAGE_HWEXEC | MAS3_RPN@l
-       and     r11, r11, r12
+       andi.   r11, r11, _PAGE_HWEXEC
        rlwimi  r11, r11, 31, 27, 27    /* SX <- _PAGE_HWEXEC */
        ori     r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static 
perms */
 
@@ -439,7 +463,10 @@
        /* find the TLB index that caused the fault.  It has to be here. */
        tlbsx   0, r10
 
-       mtspr   SPRN_MAS3,r11
+       /* only update the perm bits, assume the RPN is fine */
+       mfspr   r12, SPRN_MAS3
+       rlwimi  r12, r11, 0, 20, 31
+       mtspr   SPRN_MAS3,r12
        tlbwe
 
        /* Done...restore registers and get out of here.  */
@@ -530,18 +557,15 @@
        lwz     r11,PGDIR(r11)
 
 4:
-       rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
-       lwz     r11, 0(r11)             /* Get L1 entry */
-       rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
-       beq     2f                      /* Bail if no table */
-
-       rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
-       lwz     r11, 0(r12)             /* Get Linux PTE */
-       andi.   r13, r11, _PAGE_PRESENT
-       beq     2f
+       FIND_PTE
+       andi.   r13, r11, _PAGE_PRESENT /* Is the page present? */
+       beq     2f                      /* Bail if not present */
 
+#ifdef CONFIG_PTE_64BIT
+       lwz     r13, 0(r12)
+#endif
        ori     r11, r11, _PAGE_ACCESSED
-       stw     r11, 0(r12)
+       stw     r11, PTE_FLAGS_OFFSET(r12)
 
         /* Jump to common tlb load */
        b       finish_tlb_load
@@ -594,18 +618,15 @@
        lwz     r11,PGDIR(r11)
 
 4:
-       rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
-       lwz     r11, 0(r11)             /* Get L1 entry */
-       rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
-       beq     2f                      /* Bail if no table */
-
-       rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
-       lwz     r11, 0(r12)             /* Get Linux PTE */
-       andi.   r13, r11, _PAGE_PRESENT
-       beq     2f
+       FIND_PTE
+       andi.   r13, r11, _PAGE_PRESENT /* Is the page present? */
+       beq     2f                      /* Bail if not present */
 
+#ifdef CONFIG_PTE_64BIT
+       lwz     r13, 0(r12)
+#endif
        ori     r11, r11, _PAGE_ACCESSED
-       stw     r11, 0(r12)
+       stw     r11, PTE_FLAGS_OFFSET(r12)
 
        /* Jump to common TLB load point */
        b       finish_tlb_load
@@ -690,27 +711,39 @@
         */
 
        mfspr   r12, SPRN_MAS2
+#ifdef CONFIG_PTE_64BIT
+       rlwimi  r12, r11, 26, 24, 31    /* extract ...WIMGE from pte */
+#else
        rlwimi  r12, r11, 26, 27, 31    /* extract WIMGE from pte */
+#endif
        mtspr   SPRN_MAS2, r12
 
        bge     5, 1f
 
-       /* addr > TASK_SIZE */
-       li      r10, (MAS3_UX | MAS3_UW | MAS3_UR)
-       andi.   r13, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
-       andi.   r12, r11, _PAGE_USER    /* Test for _PAGE_USER */
-       iseleq  r12, 0, r10
-       and     r10, r12, r13
-       srwi    r12, r10, 1
+       /* is user addr */
+       andi.   r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
+       andi.   r10, r11, _PAGE_USER    /* Test for _PAGE_USER */
+       srwi    r10, r12, 1
        or      r12, r12, r10   /* Copy user perms into supervisor */
+       iseleq  r12, 0, r12
        b       2f
 
-       /* addr <= TASK_SIZE */
+       /* is kernel addr */
 1:     rlwinm  r12, r11, 31, 29, 29    /* Extract _PAGE_HWWRITE into SW */
        ori     r12, r12, (MAS3_SX | MAS3_SR)
 
+#ifdef CONFIG_PTE_64BIT
+2:     rlwimi  r12, r13, 24, 0, 7      /* grab RPN[32:39] */
+       rlwimi  r12, r11, 24, 8, 19     /* grab RPN[40:51] */
+       mtspr   SPRN_MAS3, r12
+BEGIN_FTR_SECTION
+       srwi    r10, r13, 8             /* grab RPN[8:31] */
+       mtspr   SPRN_MAS7, r10
+END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
+#else
 2:     rlwimi  r11, r12, 0, 20, 31     /* Extract RPN from PTE and merge with 
perms */
        mtspr   SPRN_MAS3, r11
+#endif
        tlbwe
 
        /* Done...restore registers and get out of here.  */
diff -urN linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- linux/arch/ppc/kernel/signal.c      2005/03/18 17:36:56     1.44
+++ linux/arch/ppc/kernel/signal.c      2005/04/29 11:15:03     1.45
@@ -708,7 +708,6 @@
        if (current->flags & PF_FREEZE) {
                refrigerator(PF_FREEZE);
                signr = 0;
-               ret = regs->gpr[3];
                if (!signal_pending(current))
                        goto no_signal;
        }
@@ -719,7 +718,7 @@
        newsp = frame = 0;
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
+ no_signal:
        if (TRAP(regs) == 0x0C00                /* System Call! */
            && regs->ccr & 0x10000000           /* error signalled */
            && ((ret = regs->gpr[3]) == ERESTARTSYS
@@ -735,7 +734,6 @@
                        regs->gpr[3] = EINTR;
                        /* note that the cr0.SO bit is already set */
                } else {
-no_signal:
                        regs->nip -= 4; /* Back up & retry system call */
                        regs->result = 0;
                        regs->trap = 0;
diff -urN linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- linux/arch/ppc/kernel/time.c        2005/01/25 04:28:02     1.46
+++ linux/arch/ppc/kernel/time.c        2005/04/29 11:15:03     1.47
@@ -89,8 +89,6 @@
 
 extern unsigned long wall_jiffies;
 
-static long time_offset;
-
 DEFINE_SPINLOCK(rtc_lock);
 
 EXPORT_SYMBOL(rtc_lock);
@@ -272,7 +270,6 @@
 
        time_adjust = 0;                /* stop active adjtime() */
        time_status |= STA_UNSYNC;
-       time_state = TIME_ERROR;        /* p. 24, (a) */
        time_maxerror = NTP_PHASE_LIMIT;
        time_esterror = NTP_PHASE_LIMIT;
        write_sequnlock_irqrestore(&xtime_lock, flags);
diff -urN linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- linux/arch/ppc/kernel/traps.c       2005/04/08 18:58:00     1.51
+++ linux/arch/ppc/kernel/traps.c       2005/04/29 11:15:03     1.52
@@ -679,6 +679,7 @@
        fixed = fix_alignment(regs);
        if (fixed == 1) {
                regs->nip += 4; /* skip over emulated instruction */
+               emulate_single_step(regs);
                return;
        }
        if (fixed == -EFAULT) {
@@ -805,6 +806,13 @@
        if (regs->msr & MSR_VEC)
                giveup_altivec(current);
        preempt_enable();
+       if (!user_mode(regs)) {
+               printk(KERN_ERR "altivec assist exception in kernel mode"
+                      " at %lx\n", regs->nip);
+               debugger(regs);
+               die("altivec assist exception", regs, SIGFPE);
+               return;
+       }
 
        err = emulate_altivec(regs);
        if (err == 0) {
diff -urN linux/arch/ppc/mm/pgtable.c linux/arch/ppc/mm/pgtable.c
--- linux/arch/ppc/mm/pgtable.c 2005/03/18 17:36:56     1.25
+++ linux/arch/ppc/mm/pgtable.c 2005/04/29 11:15:03     1.26
@@ -74,7 +74,7 @@
 #define p_mapped_by_tlbcam(x)  (0UL)
 #endif /* HAVE_TLBCAM */
 
-#ifdef CONFIG_44x
+#ifdef CONFIG_PTE_64BIT
 /* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
 #define PGDIR_ORDER    1
 #else
@@ -142,13 +142,13 @@
        __free_page(ptepage);
 }
 
-#ifndef CONFIG_44x
+#ifndef CONFIG_PHYS_64BIT
 void __iomem *
 ioremap(phys_addr_t addr, unsigned long size)
 {
        return __ioremap(addr, size, _PAGE_NO_CACHE);
 }
-#else /* CONFIG_44x */
+#else /* CONFIG_PHYS_64BIT */
 void __iomem *
 ioremap64(unsigned long long addr, unsigned long size)
 {
@@ -162,7 +162,7 @@
 
        return ioremap64(addr64, size);
 }
-#endif /* CONFIG_44x */
+#endif /* CONFIG_PHYS_64BIT */
 
 void __iomem *
 __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
@@ -193,7 +193,7 @@
         */
        if ( mem_init_done && (p < virt_to_phys(high_memory)) )
        {
-               printk("__ioremap(): phys addr "PTE_FMT" is RAM lr %p\n", p,
+               printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p,
                       __builtin_return_address(0));
                return NULL;
        }
diff -urN linux/arch/ppc/platforms/chrp_time.c 
linux/arch/ppc/platforms/chrp_time.c
--- linux/arch/ppc/platforms/chrp_time.c        2005/02/07 02:54:35     1.5
+++ linux/arch/ppc/platforms/chrp_time.c        2005/04/29 11:15:03     1.6
@@ -115,8 +115,6 @@
        chrp_cmos_clock_write(save_control, RTC_CONTROL);
        chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
 
-       if ( (time_state == TIME_ERROR) || (time_state == TIME_BAD) )
-               time_state = TIME_OK;
        spin_unlock(&rtc_lock);
        return 0;
 }
diff -urN linux/arch/ppc/platforms/gemini_setup.c 
linux/arch/ppc/platforms/gemini_setup.c
--- linux/arch/ppc/platforms/gemini_setup.c     2005/03/18 17:36:56     1.10
+++ linux/arch/ppc/platforms/gemini_setup.c     2005/04/29 11:15:03     1.11
@@ -433,9 +433,6 @@
        /* done writing */
        gemini_rtc_write(reg, M48T35_RTC_CONTROL);
 
-       if ((time_state == TIME_ERROR) || (time_state == TIME_BAD))
-               time_state = TIME_OK;
-
        return 0;
 }
 
diff -urN linux/arch/ppc/platforms/pmac_cache.S 
linux/arch/ppc/platforms/pmac_cache.S
--- linux/arch/ppc/platforms/pmac_cache.S       2005/03/18 17:36:57     1.2
+++ linux/arch/ppc/platforms/pmac_cache.S       2005/04/29 11:15:03     1.3
@@ -28,6 +28,9 @@
  */
 
 _GLOBAL(flush_disable_caches)
+#ifndef CONFIG_6xx
+       blr
+#else
 BEGIN_FTR_SECTION
        b       flush_disable_745x
 END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
@@ -323,3 +326,4 @@
        mtmsr   r11             /* restore DR and EE */
        isync
        blr
+#endif /* CONFIG_6xx */
diff -urN linux/arch/ppc/platforms/pmac_cpufreq.c 
linux/arch/ppc/platforms/pmac_cpufreq.c
--- linux/arch/ppc/platforms/pmac_cpufreq.c     2005/04/08 18:58:00     1.17
+++ linux/arch/ppc/platforms/pmac_cpufreq.c     2005/04/29 11:15:03     1.18
@@ -1,13 +1,18 @@
 /*
  *  arch/ppc/platforms/pmac_cpufreq.c
  *
- *  Copyright (C) 2002 - 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
  *  Copyright (C) 2004        John Steele Scott <toojays@toojays.net>
  *
  * 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.
  *
+ * TODO: Need a big cleanup here. Basically, we need to have different
+ * cpufreq_driver structures for the different type of HW instead of the
+ * current mess. We also need to better deal with the detection of the
+ * type of machine.
+ *
  */
 
 #include <linux/config.h>
@@ -35,6 +40,7 @@
 #include <asm/time.h>
 #include <asm/system.h>
 #include <asm/open_pic.h>
+#include <asm/keylargo.h>
 
 /* WARNING !!! This will cause calibrate_delay() to be called,
  * but this is an __init function ! So you MUST go edit
@@ -61,11 +67,13 @@
 static unsigned int low_freq;
 static unsigned int hi_freq;
 static unsigned int cur_freq;
+static unsigned int sleep_freq;
 
 /*
  * Different models uses different mecanisms to switch the frequency
  */
 static int (*set_speed_proc)(int low_speed);
+static unsigned int (*get_speed_proc)(void);
 
 /*
  * Some definitions used by the various speedprocs
@@ -73,6 +81,8 @@
 static u32 voltage_gpio;
 static u32 frequency_gpio;
 static u32 slew_done_gpio;
+static int no_schedule;
+static int has_cpu_l2lve;
 
 
 #define PMAC_CPU_LOW_SPEED     1
@@ -90,6 +100,14 @@
        {0,                     CPUFREQ_TABLE_END},
 };
 
+static inline void local_delay(unsigned long ms)
+{
+       if (no_schedule)
+               mdelay(ms);
+       else
+               msleep(ms);
+}
+
 static inline void wakeup_decrementer(void)
 {
        set_dec(tb_ticks_per_jiffy);
@@ -118,20 +136,48 @@
  */
 static int __pmac cpu_750fx_cpu_speed(int low_speed)
 {
-#ifdef DEBUG_FREQ
-       printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
-#endif
+       u32 hid2;
+
+       if (low_speed == 0) {
+               /* ramping up, set voltage first */
+               pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 
0x05);
+               /* Make sure we sleep for at least 1ms */
+               local_delay(10);
+
+               /* tweak L2 for high voltage */
+               if (has_cpu_l2lve) {
+                       hid2 = mfspr(SPRN_HID2);
+                       hid2 &= ~0x2000;
+                       mtspr(SPRN_HID2, hid2);
+               }
+       }
 #ifdef CONFIG_6xx
        low_choose_750fx_pll(low_speed);
 #endif
-#ifdef DEBUG_FREQ
-       printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
-       debug_calc_bogomips();
-#endif
+       if (low_speed == 1) {
+               /* tweak L2 for low voltage */
+               if (has_cpu_l2lve) {
+                       hid2 = mfspr(SPRN_HID2);
+                       hid2 |= 0x2000;
+                       mtspr(SPRN_HID2, hid2);
+               }
+
+               /* ramping down, set voltage last */
+               pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 
0x04);
+               local_delay(10);
+       }
 
        return 0;
 }
 
+static unsigned int __pmac cpu_750fx_get_cpu_speed(void)
+{
+       if (mfspr(SPRN_HID1) & HID1_PS)
+               return low_freq;
+       else
+               return hi_freq;
+}
+
 /* Switch CPU speed using DFS */
 static int __pmac dfs_set_cpu_speed(int low_speed)
 {
@@ -139,22 +185,25 @@
                /* ramping up, set voltage first */
                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 
0x05);
                /* Make sure we sleep for at least 1ms */
-               msleep(1);
+               local_delay(1);
        }
 
        /* set frequency */
+#ifdef CONFIG_6xx
        low_choose_7447a_dfs(low_speed);
+#endif
+       udelay(100);
 
        if (low_speed == 1) {
                /* ramping down, set voltage last */
                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 
0x04);
-               msleep(1);
+               local_delay(1);
        }
 
        return 0;
 }
 
-static unsigned int __pmac dfs_get_cpu_speed(unsigned int cpu)
+static unsigned int __pmac dfs_get_cpu_speed(void)
 {
        if (mfspr(SPRN_HID1) & HID1_DFS)
                return low_freq;
@@ -167,30 +216,35 @@
  */
 static int __pmac gpios_set_cpu_speed(int low_speed)
 {
-       int gpio;
+       int gpio, timeout = 0;
 
        /* If ramping up, set voltage first */
        if (low_speed == 0) {
                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 
0x05);
                /* Delay is way too big but it's ok, we schedule */
-               msleep(10);
+               local_delay(10);
        }
 
        /* Set frequency */
+       gpio =  pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+       if (low_speed == ((gpio & 0x01) == 0))
+               goto skip;
+
        pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
                          low_speed ? 0x04 : 0x05);
        udelay(200);
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               if (++timeout > 100)
+                       break;
+               local_delay(1);
                gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, 
slew_done_gpio, 0);
        } while((gpio & 0x02) == 0);
-
+ skip:
        /* If ramping down, set voltage last */
        if (low_speed == 1) {
                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 
0x04);
                /* Delay is way too big but it's ok, we schedule */
-               msleep(10);
+               local_delay(10);
        }
 
 #ifdef DEBUG_FREQ
@@ -207,6 +261,8 @@
        struct adb_request req;
        unsigned long save_l2cr;
        unsigned long save_l3cr;
+       unsigned int pic_prio;
+       unsigned long flags;
 
        preempt_disable();
 
@@ -214,7 +270,8 @@
        printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 #endif
        /* Disable all interrupt sources on openpic */
-       openpic_set_priority(0xf);
+       pic_prio = openpic_get_priority();
+       openpic_set_priority(0xf);
 
        /* Make sure the decrementer won't interrupt us */
        asm volatile("mtdec %0" : : "r" (0x7fffffff));
@@ -224,7 +281,7 @@
        asm volatile("mtdec %0" : : "r" (0x7fffffff));
 
        /* We can now disable MSR_EE */
-       local_irq_disable();
+       local_irq_save(flags);
 
        /* Giveup the FPU & vec */
        enable_kernel_fp();
@@ -277,10 +334,10 @@
        wakeup_decrementer();
 
        /* Restore interrupts */
-       openpic_set_priority(0);
+       openpic_set_priority(pic_prio);
 
        /* Let interrupts flow again ... */
-       local_irq_enable();
+       local_irq_restore(flags);
 
 #ifdef DEBUG_FREQ
        debug_calc_bogomips();
@@ -291,9 +348,11 @@
        return 0;
 }
 
-static int __pmac do_set_cpu_speed(int speed_mode)
+static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 {
        struct cpufreq_freqs freqs;
+       unsigned long l3cr;
+       static unsigned long prev_l3cr;
 
        freqs.old = cur_freq;
        freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
@@ -302,14 +361,35 @@
        if (freqs.old == freqs.new)
                return 0;
 
-       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       if (notify)
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       if (speed_mode == PMAC_CPU_LOW_SPEED &&
+           cpu_has_feature(CPU_FTR_L3CR)) {
+               l3cr = _get_L3CR();
+               if (l3cr & L3CR_L3E) {
+                       prev_l3cr = l3cr;
+                       _set_L3CR(0);
+               }
+       }
        set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
-       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       if (speed_mode == PMAC_CPU_HIGH_SPEED &&
+           cpu_has_feature(CPU_FTR_L3CR)) {
+               l3cr = _get_L3CR();
+               if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
+                       _set_L3CR(prev_l3cr);
+       }
+       if (notify)
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
        cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
 
        return 0;
 }
 
+static unsigned int __pmac pmac_cpufreq_get_speed(unsigned int cpu)
+{
+       return cur_freq;
+}
+
 static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy)
 {
        return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
@@ -325,7 +405,7 @@
                        target_freq, relation, &newstate))
                return -EINVAL;
 
-       return do_set_cpu_speed(newstate);
+       return do_set_cpu_speed(newstate, 1);
 }
 
 unsigned int __pmac pmac_get_one_cpufreq(int i)
@@ -349,19 +429,65 @@
 static u32 __pmac read_gpio(struct device_node *np)
 {
        u32 *reg = (u32 *)get_property(np, "reg", NULL);
+       u32 offset;
 
        if (reg == NULL)
                return 0;
        /* That works for all keylargos but shall be fixed properly
-        * some day...
+        * some day... The problem is that it seems we can't rely
+        * on the "reg" property of the GPIO nodes, they are either
+        * relative to the base of KeyLargo or to the base of the
+        * GPIO space, and the device-tree doesn't help.
+        */
+       offset = *reg;
+       if (offset < KEYLARGO_GPIO_LEVELS0)
+               offset += KEYLARGO_GPIO_LEVELS0;
+       return offset;
+}
+
+static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 
state)
+{
+       /* Ok, this could be made a bit smarter, but let's be robust for now. We
+        * always force a speed change to high speed before sleep, to make sure
+        * we have appropriate voltage and/or bus speed for the wakeup process,
+        * and to make sure our loops_per_jiffies are "good enough", that is 
will
+        * not cause too short delays if we sleep in low speed and wake in high
+        * speed..
+        */
+       no_schedule = 1;
+       sleep_freq = cur_freq;
+       if (cur_freq == low_freq)
+               do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0);
+       return 0;
+}
+
+static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
+{
+       /* If we resume, first check if we have a get() function */
+       if (get_speed_proc)
+               cur_freq = get_speed_proc();
+       else
+               cur_freq = 0;
+
+       /* We don't, hrm... we don't really know our speed here, best
+        * is that we force a switch to whatever it was, which is
+        * probably high speed due to our suspend() routine
         */
-       return 0x50 + (*reg);
+       do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED
+                        : PMAC_CPU_HIGH_SPEED, 0);
+
+       no_schedule = 0;
+       return 0;
 }
 
 static struct cpufreq_driver pmac_cpufreq_driver = {
        .verify         = pmac_cpufreq_verify,
        .target         = pmac_cpufreq_target,
+       .get            = pmac_cpufreq_get_speed,
        .init           = pmac_cpufreq_cpu_init,
+       .suspend        = pmac_cpufreq_suspend,
+       .resume         = pmac_cpufreq_resume,
+       .flags          = CPUFREQ_PM_NO_WARN,
        .name           = "powermac",
        .owner          = THIS_MODULE,
 };
@@ -461,14 +587,14 @@
 static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
 {
        struct device_node *volt_gpio_np;
-       u32 *reg;
-       struct cpufreq_driver *driver = &pmac_cpufreq_driver;
 
-       /* Look for voltage GPIO */
+       if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+               return 1;
+
        volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
-       reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
-       voltage_gpio = *reg;
-       if (!volt_gpio_np){
+       if (volt_gpio_np)
+               voltage_gpio = read_gpio(volt_gpio_np);
+       if (!voltage_gpio){
                printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
                return 1;
        }
@@ -478,9 +604,37 @@
        low_freq = cur_freq/2;
 
        /* Read actual frequency from CPU */
-       driver->get = dfs_get_cpu_speed;
-       cur_freq = driver->get(0);
+       cur_freq = dfs_get_cpu_speed();
        set_speed_proc = dfs_set_cpu_speed;
+       get_speed_proc = dfs_get_cpu_speed;
+
+       return 0;
+}
+
+static int __pmac pmac_cpufreq_init_750FX(struct device_node *cpunode)
+{
+       struct device_node *volt_gpio_np;
+       u32 pvr, *value;
+
+       if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+               return 1;
+
+       hi_freq = cur_freq;
+       value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
+       if (!value)
+               return 1;
+       low_freq = (*value) / 1000;
+
+       volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+       if (volt_gpio_np)
+               voltage_gpio = read_gpio(volt_gpio_np);
+
+       pvr = mfspr(SPRN_PVR);
+       has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
+
+       set_speed_proc = cpu_750fx_cpu_speed;
+       get_speed_proc = cpu_750fx_get_cpu_speed;
+       cur_freq = cpu_750fx_get_cpu_speed();
 
        return 0;
 }
@@ -543,16 +697,8 @@
                set_speed_proc = pmu_set_cpu_speed;
        }
        /* Else check for 750FX */
-       else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) {
-               if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
-                       goto out;
-               hi_freq = cur_freq;
-               value = (u32 *)get_property(cpunode, "reduced-clock-frequency", 
NULL);
-               if (!value)
-                       goto out;
-               low_freq = (*value) / 1000;             
-               set_speed_proc = cpu_750fx_cpu_speed;
-       }
+       else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
+               pmac_cpufreq_init_750FX(cpunode);
 out:
        if (set_speed_proc == NULL)
                return -ENODEV;
diff -urN linux/arch/ppc/platforms/pmac_feature.c 
linux/arch/ppc/platforms/pmac_feature.c
--- linux/arch/ppc/platforms/pmac_feature.c     2005/04/08 18:58:00     1.20
+++ linux/arch/ppc/platforms/pmac_feature.c     2005/04/29 11:15:03     1.21
@@ -74,8 +74,7 @@
  */
 struct macio_chip macio_chips[MAX_MACIO_CHIPS]  __pmacdata;
 
-struct macio_chip* __pmac
-macio_find(struct device_node* child, int type)
+struct macio_chip* __pmac macio_find(struct device_node* child, int type)
 {
        while(child) {
                int     i;
@@ -88,6 +87,7 @@
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(macio_find);
 
 static const char* macio_names[] __pmacdata =
 {
@@ -1779,32 +1779,6 @@
        if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
                return -EPERM;
 
-#ifdef CONFIG_CPU_FREQ_PMAC
-       /* XXX should be elsewhere */
-       if (machine_is_compatible("PowerBook6,5") ||
-           machine_is_compatible("PowerBook6,4") ||
-           machine_is_compatible("PowerBook5,5") ||
-           machine_is_compatible("PowerBook5,4")) {
-               struct device_node *volt_gpio_np;
-               u32 *reg = NULL;
-
-               volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
-               if (volt_gpio_np != NULL)
-                       reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
-               if (reg != NULL) {
-                       /* Set the CPU voltage high if sleeping */
-                       if (value == 1) {
-                               pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
-                                                 *reg, 0x05);
-                       } else if (value == 0 && (mfspr(SPRN_HID1) & HID1_DFS)) 
{
-                               pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
-                                                 *reg, 0x04);
-                       }
-                       mdelay(2);
-               }
-       }
-#endif /* CONFIG_CPU_FREQ_PMAC */
-
        if (value == 1)
                return core99_sleep();
        else if (value == 0)
@@ -2970,3 +2944,48 @@
        if (pmac_early_vresume_proc)
                pmac_early_vresume_proc(pmac_early_vresume_data);
 }
+
+/*
+ * AGP related suspend/resume code
+ */
+
+static struct pci_dev *pmac_agp_bridge __pmacdata;
+static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
+static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
+
+void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
+                                int (*suspend)(struct pci_dev *bridge),
+                                int (*resume)(struct pci_dev *bridge))
+{
+       if (suspend || resume) {
+               pmac_agp_bridge = bridge;
+               pmac_agp_suspend = suspend;
+               pmac_agp_resume = resume;
+               return;
+       }
+       if (bridge != pmac_agp_bridge)
+               return;
+       pmac_agp_suspend = pmac_agp_resume = NULL;
+       return;
+}
+EXPORT_SYMBOL(pmac_register_agp_pm);
+
+void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
+{
+       if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
+               return;
+       if (pmac_agp_bridge->bus != dev->bus)
+               return;
+       pmac_agp_suspend(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_suspend_agp_for_card);
+
+void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
+{
+       if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
+               return;
+       if (pmac_agp_bridge->bus != dev->bus)
+               return;
+       pmac_agp_resume(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff -urN linux/arch/ppc/platforms/pmac_smp.c 
linux/arch/ppc/platforms/pmac_smp.c
--- linux/arch/ppc/platforms/pmac_smp.c 2005/03/18 17:36:57     1.16
+++ linux/arch/ppc/platforms/pmac_smp.c 2005/04/29 11:15:03     1.17
@@ -116,6 +116,8 @@
 
 /* Sync flag for HW tb sync */
 static volatile int sec_tb_reset = 0;
+static unsigned int pri_tb_hi, pri_tb_lo;
+static unsigned int pri_tb_stamp;
 
 static void __init core99_init_caches(int cpu)
 {
@@ -453,7 +455,7 @@
 #endif
        struct device_node *cpus, *firstcpu;
        int i, ncpus = 0, boot_cpu = -1;
-       u32 *tbprop;
+       u32 *tbprop = NULL;
 
        if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
        cpus = firstcpu = find_type_devices("cpu");
@@ -576,46 +578,74 @@
        }
 }
 
-void __init smp_core99_take_timebase(void)
+/* not __init, called in sleep/wakeup code */
+void smp_core99_take_timebase(void)
 {
-       /* Secondary processor "takes" the timebase by freezing
-        * it, resetting its local TB and telling CPU 0 to go on
-        */
-       pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
-       pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
+       unsigned long flags;
+
+       /* tell the primary we're here */
+       sec_tb_reset = 1;
        mb();
 
-       set_dec(tb_ticks_per_jiffy);
-       set_tb(0, 0);
-       last_jiffy_stamp(smp_processor_id()) = 0;
+       /* wait for the primary to set pri_tb_hi/lo */
+       while (sec_tb_reset < 2)
+               mb();
 
+       /* set our stuff the same as the primary */
+       local_irq_save(flags);
+       set_dec(1);
+       set_tb(pri_tb_hi, pri_tb_lo);
+       last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;
+       mb();
+
+       /* tell the primary we're done */
+               sec_tb_reset = 0;
        mb();
-               sec_tb_reset = 1;
+       local_irq_restore(flags);
 }
 
-void __init smp_core99_give_timebase(void)
+/* not __init, called in sleep/wakeup code */
+void smp_core99_give_timebase(void)
 {
+       unsigned long flags;
        unsigned int t;
 
-       /* Primary processor waits for secondary to have frozen
-        * the timebase, resets local TB, and kick timebase again
-        */
-       /* wait for the secondary to have reset its TB before proceeding */
-       for (t = 1000; t > 0 && !sec_tb_reset; --t)
-               udelay(1000);
-       if (t == 0)
+       /* wait for the secondary to be in take_timebase */
+       for (t = 100000; t > 0 && !sec_tb_reset; --t)
+               udelay(10);
+       if (!sec_tb_reset) {
                printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
+               return;
+       }
 
-               set_dec(tb_ticks_per_jiffy);
-       set_tb(0, 0);
-       last_jiffy_stamp(smp_processor_id()) = 0;
+       /* freeze the timebase and read it */
+       /* disable interrupts so the timebase is disabled for the
+          shortest possible time */
+       local_irq_save(flags);
+       pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
+       pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
+       mb();
+       pri_tb_hi = get_tbu();
+       pri_tb_lo = get_tbl();
+       pri_tb_stamp = last_jiffy_stamp(smp_processor_id());
        mb();
 
+       /* tell the secondary we're ready */
+       sec_tb_reset = 2;
+       mb();
+
+       /* wait for the secondary to have taken it */
+       for (t = 100000; t > 0 && sec_tb_reset; --t)
+               udelay(10);
+       if (sec_tb_reset)
+               printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
+       else
+               smp_tb_synchronized = 1;
+
        /* Now, restart the timebase by leaving the GPIO to an open collector */
                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
         pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
-
-       smp_tb_synchronized = 1;
+       local_irq_restore(flags);
 }
 
 
diff -urN linux/arch/ppc/platforms/prep_pci.c 
linux/arch/ppc/platforms/prep_pci.c
--- linux/arch/ppc/platforms/prep_pci.c 2005/01/13 14:05:32     1.16
+++ linux/arch/ppc/platforms/prep_pci.c 2005/04/29 11:15:03     1.17
@@ -1245,8 +1245,13 @@
                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
        }
 
-       /* Setup the Winbond or Via PIB */
-       prep_pib_init();
+       /* Setup the Winbond or Via PIB - prep_pib_init() is coded for
+        * the non-openpic case, but it breaks (at least) the Utah
+        * (Powerstack II Pro4000), so only call it if we have an
+        * openpic.
+        */
+       if (have_openpic)
+               prep_pib_init();
 }
 
 static void __init
diff -urN linux/arch/ppc/syslib/m8xx_wdt.c linux/arch/ppc/syslib/m8xx_wdt.c
--- linux/arch/ppc/syslib/m8xx_wdt.c    2004/09/19 12:30:05     1.1
+++ linux/arch/ppc/syslib/m8xx_wdt.c    2005/04/29 11:15:03     1.2
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/8xx_immap.h>
@@ -18,6 +19,12 @@
 
 static int wdt_timeout;
 
+static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *);
+static struct irqaction m8xx_wdt_irqaction = {
+       .handler = m8xx_wdt_interrupt,
+       .name = "watchdog",
+};
+
 void m8xx_wdt_reset(void)
 {
        volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
@@ -84,8 +91,8 @@
        imap->im_sit.sit_piscr =
            (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE;
 
-       if (request_irq(PIT_INTERRUPT, m8xx_wdt_interrupt, 0, "watchdog", NULL))
-               panic("m8xx_wdt: could not allocate watchdog irq!");
+       if (setup_irq(PIT_INTERRUPT, &m8xx_wdt_irqaction))
+               panic("m8xx_wdt: error setting up the watchdog irq!");
 
        printk(KERN_NOTICE
               "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc);
diff -urN linux/arch/ppc/syslib/open_pic.c linux/arch/ppc/syslib/open_pic.c
--- linux/arch/ppc/syslib/open_pic.c    2005/01/25 04:28:03     1.21
+++ linux/arch/ppc/syslib/open_pic.c    2005/04/29 11:15:03     1.22
@@ -78,7 +78,6 @@
  */
 #ifdef notused
 static void openpic_enable_8259_pass_through(void);
-static u_int openpic_get_priority(void);
 static u_int openpic_get_spurious(void);
 static void openpic_set_sense(u_int irq, int sense);
 #endif /* notused */
@@ -465,8 +464,7 @@
        (void)openpic_read(&OpenPIC->THIS_CPU.EOI);
 }
 
-#ifdef notused
-static u_int openpic_get_priority(void)
+u_int openpic_get_priority(void)
 {
        DECL_THIS_CPU;
 
@@ -474,7 +472,6 @@
        return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
                                 OPENPIC_CURRENT_TASK_PRIORITY_MASK);
 }
-#endif /* notused */
 
 void openpic_set_priority(u_int pri)
 {
diff -urN linux/arch/ppc/syslib/open_pic_defs.h 
linux/arch/ppc/syslib/open_pic_defs.h
--- linux/arch/ppc/syslib/open_pic_defs.h       2005/01/13 14:05:33     1.2
+++ linux/arch/ppc/syslib/open_pic_defs.h       2005/04/29 11:15:03     1.3
@@ -172,9 +172,6 @@
     OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS];
 };
 
-extern volatile struct OpenPIC __iomem *OpenPIC;
-
-
     /*
      *  Current Task Priority Register
      */
diff -urN linux/arch/ppc/syslib/ppc4xx_pic.c linux/arch/ppc/syslib/ppc4xx_pic.c
--- linux/arch/ppc/syslib/ppc4xx_pic.c  2005/03/18 17:36:58     1.8
+++ linux/arch/ppc/syslib/ppc4xx_pic.c  2005/04/29 11:15:03     1.9
@@ -41,7 +41,10 @@
 #define UIC_HANDLERS(n)                                                        
\
 static void ppc4xx_uic##n##_enable(unsigned int irq)                   \
 {                                                                      \
-       ppc_cached_irq_mask[n] |= IRQ_MASK_UIC##n(irq);                 \
+       u32 mask = IRQ_MASK_UIC##n(irq);                                \
+       if (irq_desc[irq].status & IRQ_LEVEL)                           \
+               mtdcr(DCRN_UIC_SR(UIC##n), mask);                       \
+       ppc_cached_irq_mask[n] |= mask;                                 \
        mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);             \
 }                                                                      \
                                                                        \
diff -urN linux/arch/ppc/syslib/ppc85xx_common.c 
linux/arch/ppc/syslib/ppc85xx_common.c
--- linux/arch/ppc/syslib/ppc85xx_common.c      2005/01/25 04:28:03     1.2
+++ linux/arch/ppc/syslib/ppc85xx_common.c      2005/04/29 11:15:03     1.3
@@ -31,3 +31,11 @@
 }
 
 EXPORT_SYMBOL(get_ccsrbar);
+
+/* For now this is a pass through */
+phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
+{
+       return addr;
+};
+EXPORT_SYMBOL(fixup_bigphys_addr);
+
diff -urN linux/arch/ppc64/Kconfig linux/arch/ppc64/Kconfig
--- linux/arch/ppc64/Kconfig    2005/04/08 18:58:02     1.37
+++ linux/arch/ppc64/Kconfig    2005/04/29 11:15:03     1.38
@@ -40,10 +40,6 @@
        bool
        default y
 
-config FRAME_POINTER
-       bool
-       default y
-
 # We optimistically allocate largepages from the VM, so make the limit
 # large enough (16MB). This badly named config option is actually
 # max order + 1
diff -urN linux/arch/ppc64/kernel/head.S linux/arch/ppc64/kernel/head.S
--- linux/arch/ppc64/kernel/head.S      2005/04/08 18:58:02     1.40
+++ linux/arch/ppc64/kernel/head.S      2005/04/29 11:15:04     1.41
@@ -922,7 +922,9 @@
 altivec_unavailable_common:
        EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
 #ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
        bne     .load_up_altivec        /* if from user, just load it up */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif
        bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
diff -urN linux/arch/ppc64/kernel/maple_setup.c 
linux/arch/ppc64/kernel/maple_setup.c
--- linux/arch/ppc64/kernel/maple_setup.c       2005/01/13 14:05:34     1.2
+++ linux/arch/ppc64/kernel/maple_setup.c       2005/04/29 11:15:04     1.3
@@ -142,7 +142,7 @@
        if (physport) {
                void *comport;
                /* Map the uart for udbg. */
-               comport = (void *)__ioremap(physport, 16, _PAGE_NO_CACHE);
+               comport = (void *)ioremap(physport, 16);
                udbg_init_uart(comport, default_speed);
 
                ppc_md.udbg_putc = udbg_putc;
diff -urN linux/arch/ppc64/kernel/of_device.c 
linux/arch/ppc64/kernel/of_device.c
--- linux/arch/ppc64/kernel/of_device.c 2004/02/19 03:06:24     1.1
+++ linux/arch/ppc64/kernel/of_device.c 2005/04/29 11:15:04     1.2
@@ -104,7 +104,7 @@
        return 0;
 }
 
-static int of_device_suspend(struct device *dev, u32 state)
+static int of_device_suspend(struct device *dev, pm_message_t state)
 {
        struct of_device * of_dev = to_of_device(dev);
        struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
diff -urN linux/arch/ppc64/kernel/pSeries_setup.c 
linux/arch/ppc64/kernel/pSeries_setup.c
--- linux/arch/ppc64/kernel/pSeries_setup.c     2005/03/18 17:36:59     1.7
+++ linux/arch/ppc64/kernel/pSeries_setup.c     2005/04/29 11:15:04     1.8
@@ -363,7 +363,7 @@
                find_udbg_vterm();
        else if (physport) {
                /* Map the uart for udbg. */
-               comport = (void *)__ioremap(physport, 16, _PAGE_NO_CACHE);
+               comport = (void *)ioremap(physport, 16);
                udbg_init_uart(comport, default_speed);
 
                ppc_md.udbg_putc = udbg_putc;
diff -urN linux/arch/ppc64/kernel/pci.c linux/arch/ppc64/kernel/pci.c
--- linux/arch/ppc64/kernel/pci.c       2005/04/08 18:58:02     1.31
+++ linux/arch/ppc64/kernel/pci.c       2005/04/29 11:15:04     1.32
@@ -547,8 +547,9 @@
        if (range == NULL || (rlen < sizeof(struct isa_range))) {
                printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
                       "mapping 64k\n");
-               __ioremap_explicit(phb_io_base_phys, (unsigned 
long)phb_io_base_virt, 
-                                  0x10000, _PAGE_NO_CACHE);
+               __ioremap_explicit(phb_io_base_phys,
+                                  (unsigned long)phb_io_base_virt,
+                                  0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED);
                return; 
        }
        
@@ -576,7 +577,7 @@
 
                __ioremap_explicit(phb_io_base_phys, 
                                   (unsigned long) phb_io_base_virt, 
-                                  size, _PAGE_NO_CACHE);
+                                  size, _PAGE_NO_CACHE | _PAGE_GUARDED);
        }
 }
 
@@ -692,7 +693,7 @@
        struct resource *res;
 
        hose->io_base_virt = __ioremap(hose->io_base_phys, size,
-                                       _PAGE_NO_CACHE);
+                                       _PAGE_NO_CACHE | _PAGE_GUARDED);
        DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
                hose->global_number, hose->io_base_phys,
                (unsigned long) hose->io_base_virt);
@@ -780,7 +781,8 @@
        if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
                return 1;
        printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, 
size);
-       if (__ioremap_explicit(start_phys, start_virt, size, _PAGE_NO_CACHE))
+       if (__ioremap_explicit(start_phys, start_virt, size,
+                              _PAGE_NO_CACHE | _PAGE_GUARDED))
                return 1;
 
        return 0;
diff -urN linux/arch/ppc64/kernel/pmac_feature.c 
linux/arch/ppc64/kernel/pmac_feature.c
--- linux/arch/ppc64/kernel/pmac_feature.c      2005/04/08 18:58:02     1.9
+++ linux/arch/ppc64/kernel/pmac_feature.c      2005/04/29 11:15:04     1.10
@@ -64,8 +64,7 @@
  */
 struct macio_chip macio_chips[MAX_MACIO_CHIPS]  __pmacdata;
 
-struct macio_chip* __pmac
-macio_find(struct device_node* child, int type)
+struct macio_chip* __pmac macio_find(struct device_node* child, int type)
 {
        while(child) {
                int     i;
@@ -78,6 +77,7 @@
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(macio_find);
 
 static const char* macio_names[] __pmacdata =
 {
@@ -250,6 +250,30 @@
        return 0;
 }
 
+static long __pmac g5_i2s_enable(struct device_node *node, long param, long 
value)
+{
+       /* Very crude implementation for now */
+       struct macio_chip* macio = &macio_chips[0];
+       unsigned long flags;
+
+       if (value == 0)
+               return 0; /* don't disable yet */
+
+       LOCK(flags);
+       MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE |
+                 KL3_I2S0_CLK18_ENABLE);
+       udelay(10);
+       MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE |
+                 K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE);
+       udelay(10);
+       MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET);
+       UNLOCK(flags);
+       udelay(10);
+
+       return 0;
+}
+
+
 #ifdef CONFIG_SMP
 static long __pmac g5_reset_cpu(struct device_node* node, long param, long 
value)
 {
@@ -337,6 +361,7 @@
        { PMAC_FTR_READ_GPIO,           g5_read_gpio },
        { PMAC_FTR_WRITE_GPIO,          g5_write_gpio },
        { PMAC_FTR_GMAC_PHY_RESET,      g5_eth_phy_reset },
+       { PMAC_FTR_SOUND_CHIP_ENABLE,   g5_i2s_enable },
 #ifdef CONFIG_SMP
        { PMAC_FTR_RESET_CPU,           g5_reset_cpu },
 #endif /* CONFIG_SMP */
@@ -674,3 +699,67 @@
        dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
 #endif
 }
+
+/*
+ * Early video resume hook
+ */
+
+static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
+static void *pmac_early_vresume_data __pmacdata;
+
+void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
+{
+       if (_machine != _MACH_Pmac)
+               return;
+       preempt_disable();
+       pmac_early_vresume_proc = proc;
+       pmac_early_vresume_data = data;
+       preempt_enable();
+}
+EXPORT_SYMBOL(pmac_set_early_video_resume);
+
+
+/*
+ * AGP related suspend/resume code
+ */
+
+static struct pci_dev *pmac_agp_bridge __pmacdata;
+static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
+static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
+
+void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
+                                int (*suspend)(struct pci_dev *bridge),
+                                int (*resume)(struct pci_dev *bridge))
+{
+       if (suspend || resume) {
+               pmac_agp_bridge = bridge;
+               pmac_agp_suspend = suspend;
+               pmac_agp_resume = resume;
+               return;
+       }
+       if (bridge != pmac_agp_bridge)
+               return;
+       pmac_agp_suspend = pmac_agp_resume = NULL;
+       return;
+}
+EXPORT_SYMBOL(pmac_register_agp_pm);
+
+void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
+{
+       if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
+               return;
+       if (pmac_agp_bridge->bus != dev->bus)
+               return;
+       pmac_agp_suspend(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_suspend_agp_for_card);
+
+void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
+{
+       if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
+               return;
+       if (pmac_agp_bridge->bus != dev->bus)
+               return;
+       pmac_agp_resume(pmac_agp_bridge);
+}
+EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff -urN linux/arch/ppc64/kernel/ppc_ksyms.c 
linux/arch/ppc64/kernel/ppc_ksyms.c
--- linux/arch/ppc64/kernel/ppc_ksyms.c 2005/03/18 17:36:59     1.25
+++ linux/arch/ppc64/kernel/ppc_ksyms.c 2005/04/29 11:15:04     1.26
@@ -74,7 +74,7 @@
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(giveup_altivec);
 #endif
-EXPORT_SYMBOL(flush_icache_range);
+EXPORT_SYMBOL(__flush_icache_range);
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_PPC_ISERIES
diff -urN linux/arch/ppc64/kernel/prom.c linux/arch/ppc64/kernel/prom.c
--- linux/arch/ppc64/kernel/prom.c      2005/04/08 18:58:02     1.42
+++ linux/arch/ppc64/kernel/prom.c      2005/04/29 11:15:04     1.43
@@ -544,12 +544,6 @@
        if (ip != NULL)
                nsizec = *ip;
 
-       /* the f50 sets the name to 'display' and 'compatible' to what we
-        * expect for the name -- Cort
-        */
-       if (!strcmp(np->name, "display"))
-               np->name = get_property(np, "compatible", NULL);
-
        if (!strcmp(np->name, "device-tree") || np->parent == NULL)
                ifunc = interpret_root_props;
        else if (np->type == 0)
@@ -885,6 +879,7 @@
                                          const char *full_path, void *data)
 {
        char *type = get_flat_dt_prop(node, "device_type", NULL);
+       u32 *prop;
 
        /* We are scanning "cpu" nodes only */
        if (type == NULL || strcmp(type, "cpu") != 0)
@@ -916,6 +911,20 @@
                }
        }
 
+       /* Check if we have a VMX and eventually update CPU features */
+       prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL);
+       if (prop && (*prop) > 0) {
+               cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+               cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+       }
+
+       /* Same goes for Apple's "altivec" property */
+       prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
+       if (prop) {
+               cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+               cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+       }
+
        return 0;
 }
 
@@ -1104,7 +1113,9 @@
 
        DBG("Scanning CPUs ...\n");
 
-       /* Retreive hash table size from flattened tree */
+       /* Retreive hash table size from flattened tree plus other
+        * CPU related informations (altivec support, boot CPU ID, ...)
+        */
        scan_flat_dt(early_init_dt_scan_cpus, NULL);
 
        /* If hash size wasn't obtained above, we calculate it now based on
diff -urN linux/arch/ppc64/kernel/traps.c linux/arch/ppc64/kernel/traps.c
--- linux/arch/ppc64/kernel/traps.c     2005/03/18 17:36:59     1.33
+++ linux/arch/ppc64/kernel/traps.c     2005/04/29 11:15:04     1.34
@@ -450,14 +450,12 @@
 
 void altivec_unavailable_exception(struct pt_regs *regs)
 {
-#ifndef CONFIG_ALTIVEC
        if (user_mode(regs)) {
                /* A user program has executed an altivec instruction,
                   but this kernel doesn't support altivec. */
                _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
                return;
        }
-#endif
        printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
                          "%lx at %lx\n", regs->trap, regs->nip);
        die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
diff -urN linux/arch/ppc64/kernel/vdso.c linux/arch/ppc64/kernel/vdso.c
--- linux/arch/ppc64/kernel/vdso.c      2005/03/18 17:36:59     1.1
+++ linux/arch/ppc64/kernel/vdso.c      2005/04/29 11:15:04     1.2
@@ -213,13 +213,14 @@
                vdso_base = VDSO64_MBASE;
        }
 
+       current->thread.vdso_base = 0;
+
        /* vDSO has a problem and was disabled, just don't "enable" it for the
         * process
         */
-       if (vdso_pages == 0) {
-               current->thread.vdso_base = 0;
+       if (vdso_pages == 0)
                return 0;
-       }
+
        vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
        if (vma == NULL)
                return -ENOMEM;
@@ -230,12 +231,16 @@
        memset(vma, 0, sizeof(*vma));
 
        /*
-        * pick a base address for the vDSO in process space. We have a default
-        * base of 1Mb on which we had a random offset up to 1Mb.
-        * XXX: Add possibility for a program header to specify that location
+        * pick a base address for the vDSO in process space. We try to put it
+        * at vdso_base which is the "natural" base for it, but we might fail
+        * and end up putting it elsewhere.
         */
+       vdso_base = get_unmapped_area(NULL, vdso_base,
+                                     vdso_pages << PAGE_SHIFT, 0, 0);
+       if (vdso_base & ~PAGE_MASK)
+               return (int)vdso_base;
+
        current->thread.vdso_base = vdso_base;
-       /*  + ((unsigned long)vma & 0x000ff000); */
 
        vma->vm_mm = mm;
        vma->vm_start = current->thread.vdso_base;
diff -urN linux/arch/ppc64/mm/hugetlbpage.c linux/arch/ppc64/mm/hugetlbpage.c
--- linux/arch/ppc64/mm/hugetlbpage.c   2005/04/08 18:58:03     1.19
+++ linux/arch/ppc64/mm/hugetlbpage.c   2005/04/29 11:15:04     1.20
@@ -203,8 +203,6 @@
        unsigned long start = seg << SID_SHIFT;
        unsigned long end = (seg+1) << SID_SHIFT;
        struct vm_area_struct *vma;
-       unsigned long addr;
-       struct mmu_gather *tlb;
 
        BUG_ON(seg >= 16);
 
@@ -213,41 +211,6 @@
        if (vma && (vma->vm_start < end))
                return -EBUSY;
 
-       /* Clean up any leftover PTE pages in the region */
-       spin_lock(&mm->page_table_lock);
-       tlb = tlb_gather_mmu(mm, 0);
-       for (addr = start; addr < end; addr += PMD_SIZE) {
-               pgd_t *pgd = pgd_offset(mm, addr);
-               pmd_t *pmd;
-               struct page *page;
-               pte_t *pte;
-               int i;
-
-               if (pgd_none(*pgd))
-                       continue;
-               pmd = pmd_offset(pgd, addr);
-               if (!pmd || pmd_none(*pmd))
-                       continue;
-               if (pmd_bad(*pmd)) {
-                       pmd_ERROR(*pmd);
-                       pmd_clear(pmd);
-                       continue;
-               }
-               pte = (pte_t *)pmd_page_kernel(*pmd);
-               /* No VMAs, so there should be no PTEs, check just in case. */
-               for (i = 0; i < PTRS_PER_PTE; i++) {
-                       BUG_ON(!pte_none(*pte));
-                       pte++;
-               }
-               page = pmd_page(*pmd);
-               pmd_clear(pmd);
-               mm->nr_ptes--;
-               dec_page_state(nr_page_table_pages);
-               pte_free_tlb(tlb, page);
-       }
-       tlb_finish_mmu(tlb, start, end);
-       spin_unlock(&mm->page_table_lock);
-
        return 0;
 }
 
@@ -430,16 +393,6 @@
        flush_tlb_pending();
 }
 
-void hugetlb_free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *prev,
-                          unsigned long start, unsigned long end)
-{
-       /* Because the huge pgtables are only 2 level, they can take
-        * at most around 4M, much less than one hugepage which the
-        * process is presumably entitled to use.  So we don't bother
-        * freeing up the pagetables on unmap, and wait until
-        * destroy_context() to clean up the lot. */
-}
-
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
        struct mm_struct *mm = current->mm;
diff -urN linux/arch/ppc64/mm/init.c linux/arch/ppc64/mm/init.c
--- linux/arch/ppc64/mm/init.c  2005/04/08 18:58:03     1.43
+++ linux/arch/ppc64/mm/init.c  2005/04/29 11:15:04     1.44
@@ -155,7 +155,8 @@
                ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea);
 
                pa = abs_to_phys(pa);
-               set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, 
__pgprot(flags)));
+               set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+                                                         __pgprot(flags)));
                spin_unlock(&ioremap_mm.page_table_lock);
        } else {
                unsigned long va, vpn, hash, hpteg;
@@ -191,12 +192,9 @@
 
        if ((flags & _PAGE_PRESENT) == 0)
                flags |= pgprot_val(PAGE_KERNEL);
-       if (flags & (_PAGE_NO_CACHE | _PAGE_WRITETHRU))
-               flags |= _PAGE_GUARDED;
 
-       for (i = 0; i < size; i += PAGE_SIZE) {
+       for (i = 0; i < size; i += PAGE_SIZE)
                map_io_page(ea+i, pa+i, flags);
-       }
 
        return (void __iomem *) (ea + (addr & ~PAGE_MASK));
 }
@@ -205,7 +203,7 @@
 void __iomem *
 ioremap(unsigned long addr, unsigned long size)
 {
-       return __ioremap(addr, size, _PAGE_NO_CACHE);
+       return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
 }
 
 void __iomem *
@@ -272,7 +270,8 @@
                        return 1;
                }
                if (ea != (unsigned long) area->addr) {
-                       printk(KERN_ERR "unexpected addr return from 
im_get_area\n");
+                       printk(KERN_ERR "unexpected addr return from "
+                              "im_get_area\n");
                        return 1;
                }
        }
@@ -315,7 +314,8 @@
                        continue;
                if (pte_present(page))
                        continue;
-               printk(KERN_CRIT "Whee.. Swapped out page in kernel page 
table\n");
+               printk(KERN_CRIT "Whee.. Swapped out page in kernel page"
+                      " table\n");
        } while (address < end);
 }
 
@@ -352,7 +352,7 @@
  * Access to IO memory should be serialized by driver.
  * This code is modeled after vmalloc code - unmap_vm_area()
  *
- * XXX what about calls before mem_init_done (ie python_countermeasures())     
+ * XXX what about calls before mem_init_done (ie python_countermeasures())
  */
 void iounmap(volatile void __iomem *token)
 {
diff -urN linux/arch/sh/kernel/cpu/bus.c linux/arch/sh/kernel/cpu/bus.c
--- linux/arch/sh/kernel/cpu/bus.c      2004/06/26 15:15:12     1.1
+++ linux/arch/sh/kernel/cpu/bus.c      2005/04/29 11:15:04     1.2
@@ -31,7 +31,7 @@
        return shdev->dev_id == shdrv->dev_id;
 }
 
-static int sh_bus_suspend(struct device *dev, u32 state)
+static int sh_bus_suspend(struct device *dev, pm_message_t state)
 {
        struct sh_dev *shdev = to_sh_dev(dev);
        struct sh_driver *shdrv = to_sh_driver(dev->driver);
diff -urN linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c
--- linux/arch/sparc/kernel/ptrace.c    2005/03/18 17:37:04     1.31
+++ linux/arch/sparc/kernel/ptrace.c    2005/04/29 11:15:04     1.32
@@ -530,18 +530,6 @@
                        pt_error_return(regs, EIO);
                        goto out_tsk;
                }
-               if (addr != 1) {
-                       if (addr & 3) {
-                               pt_error_return(regs, EINVAL);
-                               goto out_tsk;
-                       }
-#ifdef DEBUG_PTRACE
-                       printk ("Original: %08lx %08lx\n", 
child->thread.kregs->pc, child->thread.kregs->npc);
-                       printk ("Continuing with %08lx %08lx\n", addr, addr+4);
-#endif
-                       child->thread.kregs->pc = addr;
-                       child->thread.kregs->npc = addr + 4;
-               }
 
                if (request == PTRACE_SYSCALL)
                        set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff -urN linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- linux/arch/sparc64/kernel/ptrace.c  2005/02/13 20:16:19     1.34
+++ linux/arch/sparc64/kernel/ptrace.c  2005/04/29 11:15:04     1.35
@@ -103,6 +103,55 @@
        /* nothing to do */
 }
 
+/* To get the necessary page struct, access_process_vm() first calls
+ * get_user_pages().  This has done a flush_dcache_page() on the
+ * accessed page.  Then our caller (copy_{to,from}_user_page()) did
+ * to memcpy to read/write the data from that page.
+ *
+ * Now, the only thing we have to do is:
+ * 1) flush the D-cache if it's possible than an illegal alias
+ *    has been created
+ * 2) flush the I-cache if this is pre-cheetah and we did a write
+ */
+void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
+                        unsigned long uaddr, void *kaddr,
+                        unsigned long len, int write)
+{
+       BUG_ON(len > PAGE_SIZE);
+
+#ifdef DCACHE_ALIASING_POSSIBLE
+       /* If bit 13 of the kernel address we used to access the
+        * user page is the same as the virtual address that page
+        * is mapped to in the user's address space, we can skip the
+        * D-cache flush.
+        */
+       if ((uaddr ^ kaddr) & (1UL << 13)) {
+               unsigned long start = __pa(kaddr);
+               unsigned long end = start + len;
+
+               if (tlb_type == spitfire) {
+                       for (; start < end; start += 32)
+                               spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
+               } else {
+                       for (; start < end; start += 32)
+                               __asm__ __volatile__(
+                                       "stxa %%g0, [%0] %1\n\t"
+                                       "membar #Sync"
+                                       : /* no outputs */
+                                       : "r" (va),
+                                       "i" (ASI_DCACHE_INVALIDATE));
+               }
+       }
+#endif
+       if (write && tlb_type == spitfire) {
+               unsigned long start = (unsigned long) kaddr;
+               unsigned long end = start + len;
+
+               for (; start < end; start += 32)
+                       flushi(start);
+       }
+}
+
 asmlinkage void do_ptrace(struct pt_regs *regs)
 {
        int request = regs->u_regs[UREG_I0];
@@ -227,7 +276,7 @@
                        pt_error_return(regs, -res);
                else
                        pt_os_succ_return(regs, tmp64, (void __user *) data);
-               goto flush_and_out;
+               goto out_tsk;
        }
 
        case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -253,7 +302,7 @@
                        pt_error_return(regs, -res);
                else
                        pt_succ_return(regs, res);
-               goto flush_and_out;
+               goto out_tsk;
        }
 
        case PTRACE_GETREGS: {
@@ -485,12 +534,12 @@
                                          (char __user *)addr2, data);
                if (res == data) {
                        pt_succ_return(regs, 0);
-                       goto flush_and_out;
+                       goto out_tsk;
                }
                if (res >= 0)
                        res = -EIO;
                pt_error_return(regs, -res);
-               goto flush_and_out;
+               goto out_tsk;
        }
 
        case PTRACE_WRITETEXT:
@@ -499,12 +548,12 @@
                                           addr, data);
                if (res == data) {
                        pt_succ_return(regs, 0);
-                       goto flush_and_out;
+                       goto out_tsk;
                }
                if (res >= 0)
                        res = -EIO;
                pt_error_return(regs, -res);
-               goto flush_and_out;
+               goto out_tsk;
        }
        case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
                addr = 1;
@@ -514,25 +563,6 @@
                        pt_error_return(regs, EIO);
                        goto out_tsk;
                }
-               if (addr != 1) {
-                       unsigned long pc_mask = ~0UL;
-
-                       if ((child->thread_info->flags & _TIF_32BIT) != 0)
-                               pc_mask = 0xffffffff;
-
-                       if (addr & 3) {
-                               pt_error_return(regs, EINVAL);
-                               goto out_tsk;
-                       }
-#ifdef DEBUG_PTRACE
-                       printk ("Original: %016lx %016lx\n",
-                               child->thread_info->kregs->tpc,
-                               child->thread_info->kregs->tnpc);
-                       printk ("Continuing with %016lx %016lx\n", addr, 
addr+4);
-#endif
-                       child->thread_info->kregs->tpc = (addr & pc_mask);
-                       child->thread_info->kregs->tnpc = ((addr + 4) & 
pc_mask);
-               }
 
                if (request == PTRACE_SYSCALL) {
                        set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -590,27 +620,6 @@
                goto out_tsk;
        }
        }
-flush_and_out:
-       {
-               unsigned long va;
-
-               if (tlb_type == cheetah || tlb_type == cheetah_plus) {
-                       for (va = 0; va < (1 << 16); va += (1 << 5))
-                               spitfire_put_dcache_tag(va, 0x0);
-                       /* No need to mess with I-cache on Cheetah. */
-               } else {
-                       for (va =  0; va < L1DCACHE_SIZE; va += 32)
-                               spitfire_put_dcache_tag(va, 0x0);
-                       if (request == PTRACE_PEEKTEXT ||
-                           request == PTRACE_POKETEXT ||
-                           request == PTRACE_READTEXT ||
-                           request == PTRACE_WRITETEXT) {
-                               for (va =  0; va < (PAGE_SIZE << 1); va += 32)
-                                       spitfire_put_icache_tag(va, 0x0);
-                               __asm__ __volatile__("flush %g6");
-                       }
-               }
-       }
 out_tsk:
        if (child)
                put_task_struct(child);
diff -urN linux/arch/sparc64/kernel/signal32.c 
linux/arch/sparc64/kernel/signal32.c
--- linux/arch/sparc64/kernel/signal32.c        2005/03/18 17:37:04     1.61
+++ linux/arch/sparc64/kernel/signal32.c        2005/04/29 11:15:04     1.62
@@ -192,10 +192,13 @@
                        err |= __put_user(from->si_uid, &to->si_uid);
                        break;
                case __SI_FAULT >> 16:
-               case __SI_POLL >> 16:
                        err |= __put_user(from->si_trapno, &to->si_trapno);
                        err |= __put_user((unsigned long)from->si_addr, 
&to->si_addr);
                        break;
+               case __SI_POLL >> 16:
+                       err |= __put_user(from->si_band, &to->si_band);
+                       err |= __put_user(from->si_fd, &to->si_fd);
+                       break;
                case __SI_RT >> 16: /* This is not generated by the kernel as 
of now.  */
                case __SI_MESGQ >> 16:
                        err |= __put_user(from->si_pid, &to->si_pid);
diff -urN linux/arch/sparc64/kernel/sys_sparc32.c 
linux/arch/sparc64/kernel/sys_sparc32.c
--- linux/arch/sparc64/kernel/sys_sparc32.c     2005/04/08 18:58:04     1.124
+++ linux/arch/sparc64/kernel/sys_sparc32.c     2005/04/29 11:15:04     1.125
@@ -352,11 +352,11 @@
        err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
        err |= put_user(stat->size, &statbuf->st_size);
        err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
-       err |= put_user(0, &statbuf->__unused1);
+       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
        err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
-       err |= put_user(0, &statbuf->__unused2);
+       err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
        err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
-       err |= put_user(0, &statbuf->__unused3);
+       err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
        err |= put_user(stat->blksize, &statbuf->st_blksize);
        err |= put_user(stat->blocks, &statbuf->st_blocks);
        err |= put_user(0, &statbuf->__unused4[0]);
@@ -365,6 +365,68 @@
        return err;
 }
 
+int cp_compat_stat64(struct kstat *stat, struct compat_stat64 __user *statbuf)
+{
+       int err;
+
+       err  = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
+       err |= put_user(stat->ino, &statbuf->st_ino);
+       err |= put_user(stat->mode, &statbuf->st_mode);
+       err |= put_user(stat->nlink, &statbuf->st_nlink);
+       err |= put_user(stat->uid, &statbuf->st_uid);
+       err |= put_user(stat->gid, &statbuf->st_gid);
+       err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
+       err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
+       err |= put_user(stat->size, &statbuf->st_size);
+       err |= put_user(stat->blksize, &statbuf->st_blksize);
+       err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
+       err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
+       err |= put_user(stat->blocks, &statbuf->st_blocks);
+       err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+       err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+       err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+       err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+       err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+       err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+       err |= put_user(0, &statbuf->__unused4);
+       err |= put_user(0, &statbuf->__unused5);
+
+       return err;
+}
+
+asmlinkage long compat_sys_stat64(char __user * filename,
+               struct compat_stat64 __user *statbuf)
+{
+       struct kstat stat;
+       int error = vfs_stat(filename, &stat);
+
+       if (!error)
+               error = cp_compat_stat64(&stat, statbuf);
+       return error;
+}
+
+asmlinkage long compat_sys_lstat64(char __user * filename,
+               struct compat_stat64 __user *statbuf)
+{
+       struct kstat stat;
+       int error = vfs_lstat(filename, &stat);
+
+       if (!error)
+               error = cp_compat_stat64(&stat, statbuf);
+       return error;
+}
+
+asmlinkage long compat_sys_fstat64(unsigned int fd,
+               struct compat_stat64 __user * statbuf)
+{
+       struct kstat stat;
+       int error = vfs_fstat(fd, &stat);
+
+       if (!error)
+               error = cp_compat_stat64(&stat, statbuf);
+       return error;
+}
+
 asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
 {
        return sys_sysfs(option, arg1, arg2);
diff -urN linux/arch/sparc64/kernel/systbls.S 
linux/arch/sparc64/kernel/systbls.S
--- linux/arch/sparc64/kernel/systbls.S 2005/01/25 04:28:06     1.69
+++ linux/arch/sparc64/kernel/systbls.S 2005/04/29 11:15:04     1.70
@@ -32,7 +32,7 @@
        .word sys32_umount, sys32_setgid16, sys32_getgid16, sys32_signal, 
sys32_geteuid16
 /*50*/ .word sys32_getegid16, sys_acct, sys_nis_syscall, sys_getgid, 
compat_sys_ioctl
        .word sys32_reboot, sys32_mmap2, sys_symlink, sys32_readlink, 
sys32_execve
-/*60*/ .word sys32_umask, sys_chroot, compat_sys_newfstat, sys_fstat64, 
sys_getpagesize
+/*60*/ .word sys32_umask, sys_chroot, compat_sys_newfstat, compat_sys_fstat64, 
sys_getpagesize
        .word sys32_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid
 /*70*/ .word sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect
        .word sys_madvise, sys_vhangup, sys32_truncate64, sys_mincore, 
sys32_getgroups16
@@ -46,8 +46,8 @@
        .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, 
sys_nis_syscall, sys_getcwd
 /*120*/        .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, 
sys32_fchown16, sys_fchmod
        .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, 
sys_truncate
-/*130*/        .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, 
sys_nis_syscall
-       .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, sys_stat64
+/*130*/        .word sys_ftruncate, sys_flock, compat_sys_lstat64, 
sys_nis_syscall, sys_nis_syscall
+       .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, 
compat_sys_stat64
 /*140*/        .word sys32_sendfile64, sys_nis_syscall, sys32_futex, 
sys_gettid, compat_sys_getrlimit
        .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, 
sys_pciconfig_read, sys_pciconfig_write
 /*150*/        .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, 
sys_poll, sys_getdents64
@@ -75,7 +75,7 @@
 /*260*/        .word compat_sys_sched_getaffinity, 
compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, 
sys_timer_getoverrun
        .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, 
compat_sys_io_setup, sys_io_destroy
 /*270*/        .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, 
sys32_mq_open, sys_mq_unlink
-       .word sys_mq_timedsend, sys_mq_timedreceive, compat_sys_mq_notify, 
compat_sys_mq_getsetattr, compat_sys_waitid
+       .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, 
compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
 /*280*/        .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
 
 #endif /* CONFIG_COMPAT */
@@ -98,7 +98,7 @@
        .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
 /*50*/ .word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, 
sys_ioctl
        .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve
-/*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_nis_syscall, 
sys_getpagesize
+/*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_stat64, sys_getpagesize
        .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall
 /*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys64_munmap, 
sys_mprotect
        .word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, 
sys_getgroups
@@ -112,8 +112,8 @@
        .word sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_getsockopt, 
sys_getcwd
 /*120*/        .word sys_readv, sys_writev, sys_settimeofday, sys_fchown, 
sys_fchmod
        .word sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
-/*130*/        .word sys_ftruncate, sys_flock, sys_nis_syscall, sys_sendto, 
sys_shutdown
-       .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_nis_syscall
+/*130*/        .word sys_ftruncate, sys_flock, sys_lstat64, sys_sendto, 
sys_shutdown
+       .word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
 /*140*/        .word sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, 
sys_getrlimit
        .word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, 
sys_pciconfig_write
 /*150*/        .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, 
sys_poll, sys_getdents64
diff -urN linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- linux/arch/sparc64/mm/init.c        2005/04/08 18:58:05     1.88
+++ linux/arch/sparc64/mm/init.c        2005/04/29 11:15:04     1.89
@@ -201,13 +201,24 @@
 
 void flush_dcache_page(struct page *page)
 {
-       struct address_space *mapping = page_mapping(page);
-       int dirty = test_bit(PG_dcache_dirty, &page->flags);
-       int dirty_cpu = dcache_dirty_cpu(page);
-       int this_cpu = get_cpu();
+       struct address_space *mapping;
+       int this_cpu;
 
+       /* Do not bother with the expensive D-cache flush if it
+        * is merely the zero page.  The 'bigcore' testcase in GDB
+        * causes this case to run millions of times.
+        */
+       if (page == ZERO_PAGE(0))
+               return;
+
+       this_cpu = get_cpu();
+
+       mapping = page_mapping(page);
        if (mapping && !mapping_mapped(mapping)) {
+               int dirty = test_bit(PG_dcache_dirty, &page->flags);
                if (dirty) {
+                       int dirty_cpu = dcache_dirty_cpu(page);
+
                        if (dirty_cpu == this_cpu)
                                goto out;
                        smp_flush_dcache_page_impl(page, dirty_cpu);
diff -urN linux/arch/um/include/choose-mode.h 
linux/arch/um/include/choose-mode.h
--- linux/arch/um/include/choose-mode.h 2005/04/08 18:58:06     1.3
+++ linux/arch/um/include/choose-mode.h 2005/04/29 11:15:04     1.4
@@ -11,6 +11,13 @@
 #if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
 #define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
 
+extern int mode_tt;
+static inline void *__choose_mode(void *tt, void *skas) {
+       return mode_tt ? tt : skas;
+}
+
+#define __CHOOSE_MODE(tt, skas) (*( (typeof(tt) *) __choose_mode(&(tt), 
&(skas))))
+
 #elif defined(UML_CONFIG_MODE_SKAS)
 #define CHOOSE_MODE(tt, skas) (skas)
 
@@ -21,22 +28,8 @@
 #define CHOOSE_MODE_PROC(tt, skas, args...) \
        CHOOSE_MODE(tt(args), skas(args))
 
-extern int mode_tt;
-static inline void *__choose_mode(void *tt, void *skas) {
-       return mode_tt ? tt : skas;
-}
-
-#define __CHOOSE_MODE(tt, skas) (*( (typeof(tt) *) __choose_mode(&(tt), 
&(skas))))
-
+#ifndef __CHOOSE_MODE
+#define __CHOOSE_MODE(tt, skas) CHOOSE_MODE(tt, skas)
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff -urN linux/arch/x86_64/ia32/ia32_binfmt.c 
linux/arch/x86_64/ia32/ia32_binfmt.c
--- linux/arch/x86_64/ia32/ia32_binfmt.c        2005/02/13 20:16:20     1.28
+++ linux/arch/x86_64/ia32/ia32_binfmt.c        2005/04/29 11:15:04     1.29
@@ -312,6 +312,10 @@
 
 static void elf32_init(struct pt_regs *);
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+#define arch_setup_additional_pages syscall32_setup_pages
+extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
+
 #include "../../../fs/binfmt_elf.c" 
 
 static void elf32_init(struct pt_regs *regs)
diff -urN linux/arch/x86_64/ia32/syscall32.c linux/arch/x86_64/ia32/syscall32.c
--- linux/arch/x86_64/ia32/syscall32.c  2005/01/25 04:28:08     1.11
+++ linux/arch/x86_64/ia32/syscall32.c  2005/04/29 11:15:04     1.12
@@ -9,6 +9,7 @@
 #include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/stringify.h>
+#include <linux/security.h>
 #include <asm/proto.h>
 #include <asm/tlbflush.h>
 #include <asm/ia32_unistd.h>
@@ -30,51 +31,57 @@
 char *syscall32_page; 
 static int use_sysenter = -1;
 
-/*
- * Map the 32bit vsyscall page on demand.
- *
- * RED-PEN: This knows too much about high level VM.
- *
- * Alternative would be to generate a vma with appropriate backing options
- * and let it be handled by generic VM.
- */
-int __map_syscall32(struct mm_struct *mm, unsigned long address)
-{ 
-       pgd_t *pgd;
-       pud_t *pud;
-       pte_t *pte;
-       pmd_t *pmd;
-       int err = -ENOMEM;
-
-       spin_lock(&mm->page_table_lock); 
-       pgd = pgd_offset(mm, address);
-       pud = pud_alloc(mm, pgd, address);
-       if (pud) {
-               pmd = pmd_alloc(mm, pud, address);
-               if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) {
-                       if (pte_none(*pte)) {
-                               set_pte(pte,
-                                       mk_pte(virt_to_page(syscall32_page),
-                                              PAGE_KERNEL_VSYSCALL32));
-                       }
-                       /* Flush only the local CPU. Other CPUs taking a fault
-                          will just end up here again
-                          This probably not needed and just paranoia. */
-                       __flush_tlb_one(address);
-                       err = 0;
-               }
-       }
-       spin_unlock(&mm->page_table_lock);
-       return err;
+static struct page *
+syscall32_nopage(struct vm_area_struct *vma, unsigned long adr, int *type)
+{
+       struct page *p = virt_to_page(adr - vma->vm_start + syscall32_page);
+       get_page(p);
+       return p;
 }
 
-int map_syscall32(struct mm_struct *mm, unsigned long address)
+/* Prevent VMA merging */
+static void syscall32_vma_close(struct vm_area_struct *vma)
 {
-       int err;
-       down_read(&mm->mmap_sem);
-       err = __map_syscall32(mm, address);
-       up_read(&mm->mmap_sem);
-       return err;
+}
+
+static struct vm_operations_struct syscall32_vm_ops = {
+       .close = syscall32_vma_close,
+       .nopage = syscall32_nopage,
+};
+
+struct linux_binprm;
+
+/* Setup a VMA at program startup for the vsyscall page */
+int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
+{
+       int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT;
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
+
+       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+       if (!vma)
+               return -ENOMEM;
+       if (security_vm_enough_memory(npages)) {
+               kmem_cache_free(vm_area_cachep, vma);
+               return -ENOMEM;
+       }
+
+       memset(vma, 0, sizeof(struct vm_area_struct));
+       /* Could randomize here */
+       vma->vm_start = VSYSCALL32_BASE;
+       vma->vm_end = VSYSCALL32_END;
+       /* MAYWRITE to allow gdb to COW and set breakpoints */
+       vma->vm_flags = 
VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYEXEC|VM_MAYWRITE;
+       vma->vm_flags |= mm->def_flags;
+       vma->vm_page_prot = protection_map[vma->vm_flags & 7];
+       vma->vm_ops = &syscall32_vm_ops;
+       vma->vm_mm = mm;
+
+       down_write(&mm->mmap_sem);
+       insert_vm_struct(mm, vma);
+       mm->total_vm += npages;
+       up_write(&mm->mmap_sem);
+       return 0;
 }
 
 static int __init init_syscall32(void)
@@ -82,7 +89,6 @@
        syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); 
        if (!syscall32_page) 
                panic("Cannot allocate syscall32 page"); 
-       SetPageReserved(virt_to_page(syscall32_page));
        if (use_sysenter > 0) {
                memcpy(syscall32_page, syscall32_sysenter,
                       syscall32_sysenter_end - syscall32_sysenter);
diff -urN linux/arch/x86_64/ia32/vsyscall-sigreturn.S 
linux/arch/x86_64/ia32/vsyscall-sigreturn.S
--- linux/arch/x86_64/ia32/vsyscall-sigreturn.S 2004/04/12 20:23:27     1.1
+++ linux/arch/x86_64/ia32/vsyscall-sigreturn.S 2005/04/29 11:15:04     1.2
@@ -118,3 +118,6 @@
 
        .align 4
 .LENDFDE3:
+
+#include "../../i386/kernel/vsyscall-note.S"
+
diff -urN linux/arch/x86_64/kernel/aperture.c 
linux/arch/x86_64/kernel/aperture.c
--- linux/arch/x86_64/kernel/aperture.c 2005/01/13 14:05:43     1.10
+++ linux/arch/x86_64/kernel/aperture.c 2005/04/29 11:15:04     1.11
@@ -33,11 +33,13 @@
 
 int fix_aperture __initdata = 1;
 
-/* This code runs before the PCI subsystem is initialized, so just 
-   access the northbridge directly. */
-
 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
 
+static struct resource aper_res = {
+       .name = "Aperture",
+       .flags = IORESOURCE_MEM,
+};
+
 static u32 __init allocate_aperture(void) 
 {
 #ifdef CONFIG_DISCONTIGMEM
@@ -53,11 +55,24 @@
        aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
 
        /* 
-        * Aperture has to be naturally aligned. This means an 2GB aperture 
won't 
-        * have much chances to find a place in the lower 4GB of memory. 
-        * Unfortunately we cannot move it up because that would make the 
-        * IOMMU useless.
+        * Aperture has to be naturally aligned. This means an 2GB
+        * aperture won't have much chances to find a place in the
+        * lower 4GB of memory.  Unfortunately we cannot move it up
+        * because that would make the IOMMU useless.
         */
+
+       /* First try to find some free unused space */
+       if (!allocate_resource(&iomem_resource, &aper_res,
+                              aper_size,
+                              0, 0xffffffff,
+                              aper_size,
+                              NULL, NULL)) {
+               printk(KERN_INFO "Putting aperture at %lx-%lx\n",
+                      aper_res.start, aper_res.end);
+               return aper_res.start;
+       }
+
+       /* No free space found. Go on to waste some memory... */
        p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
        if (!p || __pa(p)+aper_size > 0xffffffff) {
                printk("Cannot allocate aperture memory hole (%p,%uK)\n",
@@ -66,7 +81,7 @@
                        free_bootmem_node(nd0, (unsigned long)p, aper_size); 
                return 0;
        }
-       printk("Mapping aperture over %d KB of RAM @ %lx\n",  
+       printk("Mapping aperture over %d KB of precious RAM @ %lx\n",
               aper_size >> 10, __pa(p)); 
        return (u32)__pa(p); 
 }
@@ -87,10 +102,16 @@
                printk("Aperture from %s pointing to e820 RAM. 
Ignoring.\n",name);
                return 0; 
        } 
+       /* Don't check the resource here because the aperture is usually
+          in an e820 reserved area, and we allocated these earlier. */
        return 1;
 } 
 
-/* Find a PCI capability */ 
+/*
+ * Find a PCI capability.
+ * This code runs before the PCI subsystem is initialized, so just
+ * access the northbridge directly.
+ */
 static __u32 __init find_cap(int num, int slot, int func, int cap) 
 { 
        u8 pos;
@@ -255,8 +276,6 @@
                   fallback_aper_force) { 
                printk("Your BIOS doesn't leave a aperture memory hole\n");
                printk("Please enable the IOMMU option in the BIOS setup\n");
-               printk("This costs you %d MB of RAM\n",
-                      32 << fallback_aper_order);
 
                aper_order = fallback_aper_order;
                aper_alloc = allocate_aperture();
diff -urN linux/arch/x86_64/kernel/apic.c linux/arch/x86_64/kernel/apic.c
--- linux/arch/x86_64/kernel/apic.c     2005/03/18 17:37:08     1.28
+++ linux/arch/x86_64/kernel/apic.c     2005/04/29 11:15:04     1.29
@@ -457,7 +457,7 @@
        unsigned int apic_thmr;
 } apic_pm_state;
 
-static int lapic_suspend(struct sys_device *dev, u32 state)
+static int lapic_suspend(struct sys_device *dev, pm_message_t state)
 {
        unsigned long flags;
 
diff -urN linux/arch/x86_64/kernel/e820.c linux/arch/x86_64/kernel/e820.c
--- linux/arch/x86_64/kernel/e820.c     2005/04/08 18:58:07     1.8
+++ linux/arch/x86_64/kernel/e820.c     2005/04/29 11:15:04     1.9
@@ -511,3 +511,62 @@
        end_user_pfn >>= PAGE_SHIFT;    
 } 
 
+unsigned long pci_mem_start = 0xaeedbabe;
+
+/*
+ * Search for the biggest gap in the low 32 bits of the e820
+ * memory space.  We pass this space to PCI to assign MMIO resources
+ * for hotplug or unconfigured devices in.
+ * Hopefully the BIOS let enough space left.
+ */
+__init void e820_setup_gap(void)
+{
+       unsigned long gapstart, gapsize;
+       unsigned long last;
+       int i;
+       int found = 0;
+
+       last = 0x100000000ull;
+       gapstart = 0x10000000;
+       gapsize = 0x400000;
+       i = e820.nr_map;
+       while (--i >= 0) {
+               unsigned long long start = e820.map[i].addr;
+               unsigned long long end = start + e820.map[i].size;
+
+               /*
+                * Since "last" is at most 4GB, we know we'll
+                * fit in 32 bits if this condition is true
+                */
+               if (last > end) {
+                       unsigned long gap = last - end;
+
+                       if (gap > gapsize) {
+                               gapsize = gap;
+                               gapstart = end;
+                               found = 1;
+                       }
+               }
+               if (start < last)
+                       last = start;
+       }
+
+       if (!found) {
+               gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024;
+               printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit 
address range\n"
+                      KERN_ERR "PCI: Unassigned devices with 32bit resource 
registers may break!\n");
+       }
+
+       /*
+        * Start allocating dynamic PCI memory a bit into the gap,
+        * aligned up to the nearest megabyte.
+        *
+        * Question: should we try to pad it up a bit (do something
+        * like " + (gapsize >> 3)" in there too?). We now have the
+        * technology.
+        */
+       pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+
+       printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: 
%lx:%lx)\n",
+               pci_mem_start, gapstart, gapsize);
+}
diff -urN linux/arch/x86_64/kernel/entry.S linux/arch/x86_64/kernel/entry.S
--- linux/arch/x86_64/kernel/entry.S    2005/04/08 18:58:07     1.25
+++ linux/arch/x86_64/kernel/entry.S    2005/04/29 11:15:04     1.26
@@ -44,10 +44,7 @@
 
        .code64
 
-#ifdef CONFIG_PREEMPT
-#define preempt_stop cli
-#else
-#define preempt_stop
+#ifndef CONFIG_PREEMPT
 #define retint_kernel retint_restore_args
 #endif 
        
@@ -197,7 +194,7 @@
  */            
        .globl ret_from_sys_call
 ret_from_sys_call:
-       movl $_TIF_WORK_MASK,%edi
+       movl $_TIF_ALLWORK_MASK,%edi
        /* edi: flagmask */
 sysret_check:          
        GET_THREAD_INFO(%rcx)
@@ -223,18 +220,13 @@
        jmp sysret_check
 
        /* Handle a signal */ 
+       /* edx: work flags (arg3) */
 sysret_signal:
        sti
-       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
-       jz    1f
-
-       /* Really a signal */
-       /* edx: work flags (arg3) */
        leaq do_notify_resume(%rip),%rax
        leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
        xorl %esi,%esi # oldset -> arg2
        call ptregscall_common
-1:     movl $_TIF_NEED_RESCHED,%edi
        jmp sysret_check
        
        /* Do syscall tracing */
@@ -289,6 +281,7 @@
        pushq %rdi
        call schedule
        popq %rdi
+       cli
        jmp int_with_check
 
        /* handle signals and tracing -- both require a full stack frame */
@@ -302,9 +295,7 @@
        leaq 8(%rsp),%rdi       # &ptregs -> arg1       
        call syscall_trace_leave
        popq %rdi
-       btr  $TIF_SYSCALL_TRACE,%edi
-       btr  $TIF_SYSCALL_AUDIT,%edi
-       btr  $TIF_SINGLESTEP,%edi
+       andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
        jmp int_restore_rest
        
 int_signal:
@@ -460,7 +451,6 @@
        andl %edi,%edx
        jnz  retint_careful
 retint_swapgs:         
-       cli
        swapgs 
 retint_restore_args:                           
        cli
@@ -492,8 +482,6 @@
        jmp retint_check
        
 retint_signal:
-       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
-       jz    retint_swapgs
        sti
        SAVE_REST
        movq $-1,ORIG_RAX(%rsp)                         
@@ -502,7 +490,6 @@
        call do_notify_resume
        RESTORE_REST
        cli
-       movl $_TIF_NEED_RESCHED,%edi
        GET_THREAD_INFO(%rcx)   
        jmp retint_check
 
@@ -589,6 +576,7 @@
        movq ORIG_RAX(%rsp),%rsi
        movq $-1,ORIG_RAX(%rsp)
        call \sym
+       cli
        .endm
        
 /*
@@ -804,10 +792,6 @@
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8         
        paranoidentry do_debug
-       /* switch back to process stack to restore the state ptrace touched */
-       movq %rax,%rsp  
-       testl $3,CS(%rsp)
-       jnz   paranoid_userspace        
        jmp paranoid_exit
        CFI_ENDPROC
 
@@ -817,37 +801,49 @@
        pushq $-1
        CFI_ADJUST_CFA_OFFSET 8         
        paranoidentry do_nmi
+       /*
+        * "Paranoid" exit path from exception stack.
+        * Paranoid because this is used by NMIs and cannot take
+        * any kernel state for granted.
+        * We don't do kernel preemption checks here, because only
+        * NMI should be common and it does not enable IRQs and
+        * cannot get reschedule ticks.
+        */
        /* ebx: no swapgs flag */
 paranoid_exit:
        testl %ebx,%ebx                         /* swapgs needed? */
        jnz paranoid_restore
+       testl $3,CS(%rsp)
+       jnz   paranoid_userspace
 paranoid_swapgs:       
-       cli
        swapgs
 paranoid_restore:      
        RESTORE_ALL 8
        iretq
 paranoid_userspace:    
-       cli
        GET_THREAD_INFO(%rcx)
-       movl threadinfo_flags(%rcx),%edx
-       testl $_TIF_NEED_RESCHED,%edx
-       jnz paranoid_resched
-       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
-       jnz paranoid_signal
-       jmp paranoid_swapgs
-paranoid_resched:              
+       movl threadinfo_flags(%rcx),%ebx
+       andl $_TIF_WORK_MASK,%ebx
+       jz paranoid_swapgs
+       movq %rsp,%rdi                  /* &pt_regs */
+       call sync_regs
+       movq %rax,%rsp                  /* switch stack for scheduling */
+       testl $_TIF_NEED_RESCHED,%ebx
+       jnz paranoid_schedule
+       movl %ebx,%edx                  /* arg3: thread flags */
        sti
-       call schedule
-       jmp paranoid_exit
-paranoid_signal:               
-       sti
-       xorl %esi,%esi /* oldset */
-       movq %rsp,%rdi /* &pt_regs */
+       xorl %esi,%esi                  /* arg2: oldset */
+       movq %rsp,%rdi                  /* arg1: &pt_regs */
        call do_notify_resume
-       jmp paranoid_exit
+       cli
+       jmp paranoid_userspace
+paranoid_schedule:
+       sti
+       call schedule
+       cli
+       jmp paranoid_userspace
        CFI_ENDPROC
-       
+
 ENTRY(int3)
        zeroentry do_int3       
 
@@ -870,9 +866,6 @@
 ENTRY(double_fault)
        CFI_STARTPROC
        paranoidentry do_double_fault
-       movq %rax,%rsp
-       testl $3,CS(%rsp)
-       jnz paranoid_userspace          
        jmp paranoid_exit
        CFI_ENDPROC
 
@@ -886,9 +879,6 @@
 ENTRY(stack_segment)
        CFI_STARTPROC
        paranoidentry do_stack_segment
-       movq %rax,%rsp
-       testl $3,CS(%rsp)
-       jnz paranoid_userspace
        jmp paranoid_exit
        CFI_ENDPROC
 
diff -urN linux/arch/x86_64/kernel/genapic.c linux/arch/x86_64/kernel/genapic.c
--- linux/arch/x86_64/kernel/genapic.c  2005/01/13 14:05:43     1.2
+++ linux/arch/x86_64/kernel/genapic.c  2005/04/29 11:15:04     1.3
@@ -20,6 +20,10 @@
 #include <asm/smp.h>
 #include <asm/ipi.h>
 
+#if defined(CONFIG_ACPI_BUS)
+#include <acpi/acpi_bus.h>
+#endif
+
 /* which logical CPU number maps to which CPU (physical APIC ID) */
 u8 x86_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
 EXPORT_SYMBOL(x86_cpu_to_apicid);
@@ -47,6 +51,18 @@
                goto print;
        }
 
+#if defined(CONFIG_ACPI_BUS)
+       /*
+        * Some x86_64 machines use physical APIC mode regardless of how many
+        * procs/clusters are present (x86_64 ES7000 is an example).
+        */
+       if (acpi_fadt.revision > FADT2_REVISION_ID)
+               if (acpi_fadt.force_apic_physical_destination_mode) {
+                       genapic = &apic_cluster;
+                       goto print;
+               }
+#endif
+
        memset(cluster_cnt, 0, sizeof(cluster_cnt));
 
        for (i = 0; i < NR_CPUS; i++) {
diff -urN linux/arch/x86_64/kernel/head.S linux/arch/x86_64/kernel/head.S
--- linux/arch/x86_64/kernel/head.S     2005/04/08 18:58:07     1.17
+++ linux/arch/x86_64/kernel/head.S     2005/04/29 11:15:04     1.18
@@ -200,14 +200,22 @@
        .quad  init_thread_union+THREAD_SIZE-8
 
 ENTRY(early_idt_handler)
+       cmpl $2,early_recursion_flag(%rip)
+       jz  1f
+       incl early_recursion_flag(%rip)
        xorl %eax,%eax
        movq 8(%rsp),%rsi       # get rip
        movq (%rsp),%rdx
        movq %cr2,%rcx
        leaq early_idt_msg(%rip),%rdi
        call early_printk
+       cmpl $2,early_recursion_flag(%rip)
+       jz  1f
+       call dump_stack
 1:     hlt
        jmp 1b
+early_recursion_flag:
+       .long 0
 
 early_idt_msg:
        .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
diff -urN linux/arch/x86_64/kernel/i8259.c linux/arch/x86_64/kernel/i8259.c
--- linux/arch/x86_64/kernel/i8259.c    2005/04/08 18:58:07     1.20
+++ linux/arch/x86_64/kernel/i8259.c    2005/04/29 11:15:04     1.21
@@ -409,7 +409,7 @@
        return 0;
 }
 
-static int i8259A_suspend(struct sys_device *dev, u32 state)
+static int i8259A_suspend(struct sys_device *dev, pm_message_t state)
 {
        save_ELCR(irq_trigger);
        return 0;
diff -urN linux/arch/x86_64/kernel/io_apic.c linux/arch/x86_64/kernel/io_apic.c
--- linux/arch/x86_64/kernel/io_apic.c  2005/03/18 17:37:08     1.32
+++ linux/arch/x86_64/kernel/io_apic.c  2005/04/29 11:15:04     1.33
@@ -1712,7 +1712,7 @@
 };
 static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
 
-static int ioapic_suspend(struct sys_device *dev, u32 state)
+static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
 {
        struct IO_APIC_route_entry *entry;
        struct sysfs_ioapic_data *data;
diff -urN linux/arch/x86_64/kernel/mce.c linux/arch/x86_64/kernel/mce.c
--- linux/arch/x86_64/kernel/mce.c      2005/01/25 04:28:08     1.15
+++ linux/arch/x86_64/kernel/mce.c      2005/04/29 11:15:04     1.16
@@ -33,6 +33,7 @@
 static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
 static unsigned long console_logged;
 static int notify_user;
+static int rip_msr;
 
 /*
  * Lockless MCE logging infrastructure.
@@ -124,6 +125,23 @@
               test_bit(X86_FEATURE_MCA, &c->x86_capability);
 }
 
+static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
+{
+       if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) {
+               m->rip = regs->rip;
+               m->cs = regs->cs;
+       } else {
+               m->rip = 0;
+               m->cs = 0;
+       }
+       if (rip_msr) {
+               /* Assume the RIP in the MSR is exact. Is this true? */
+               m->mcgstatus |= MCG_STATUS_EIPV;
+               rdmsrl(rip_msr, m->rip);
+               m->cs = 0;
+       }
+}
+
 /* 
  * The actual machine check handler
  */
@@ -176,14 +194,7 @@
                if (m.status & MCI_STATUS_ADDRV)
                        rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);
 
-               if (regs && (m.mcgstatus & MCG_STATUS_RIPV)) {
-                       m.rip = regs->rip;
-                       m.cs = regs->cs;
-               } else {
-                       m.rip = 0;
-                       m.cs = 0;
-               }
-
+               mce_get_rip(&m, regs);
                if (error_code != -1)
                        rdtscll(m.tsc);
                wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0);
@@ -296,6 +307,9 @@
                printk(KERN_INFO "MCE: warning: using only %d banks\n", banks);
                banks = NR_BANKS; 
        }
+       /* Use accurate RIP reporting if available. */
+       if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9)
+               rip_msr = MSR_IA32_MCG_EIP;
 
        /* Log the machine checks left over from the previous reset.
           This also clears all registers */
@@ -365,18 +379,23 @@
 
 static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, 
loff_t *off)
 {
-       unsigned long cpu_tsc[NR_CPUS];
+       unsigned long *cpu_tsc;
        static DECLARE_MUTEX(mce_read_sem);
        unsigned next;
        char __user *buf = ubuf;
        int i, err;
 
+       cpu_tsc = kmalloc(NR_CPUS * sizeof(long), GFP_KERNEL);
+       if (!cpu_tsc)
+               return -ENOMEM;
+
        down(&mce_read_sem); 
        next = rcu_dereference(mcelog.next);
 
        /* Only supports full reads right now */
        if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { 
                up(&mce_read_sem);
+               kfree(cpu_tsc);
                return -EINVAL;
        }
 
@@ -407,6 +426,7 @@
                }
        }       
        up(&mce_read_sem);
+       kfree(cpu_tsc);
        return err ? -EFAULT : buf - ubuf; 
 }
 
diff -urN linux/arch/x86_64/kernel/nmi.c linux/arch/x86_64/kernel/nmi.c
--- linux/arch/x86_64/kernel/nmi.c      2005/01/25 04:28:08     1.22
+++ linux/arch/x86_64/kernel/nmi.c      2005/04/29 11:15:04     1.23
@@ -130,12 +130,6 @@
        mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
-#ifdef CONFIG_SMP
-               /* Check cpu_callin_map here because that is set
-                  after the timer is started. */
-               if (!cpu_isset(cpu, cpu_callin_map))
-                       continue;
-#endif
                if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
                        printk("CPU#%d: NMI appears to be stuck (%d)!\n", 
                               cpu,
@@ -254,7 +248,7 @@
 
 static int nmi_pm_active; /* nmi_active before suspend */
 
-static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
+static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
 {
        nmi_pm_active = nmi_active;
        disable_lapic_nmi_watchdog();
@@ -336,7 +330,7 @@
 {
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_AMD:
-               if (boot_cpu_data.x86 < 6)
+               if (boot_cpu_data.x86 != 15)
                        return;
                if (strstr(boot_cpu_data.x86_model_id, "Screwdriver"))
                        return;
diff -urN linux/arch/x86_64/kernel/ptrace.c linux/arch/x86_64/kernel/ptrace.c
--- linux/arch/x86_64/kernel/ptrace.c   2005/03/18 17:37:08     1.21
+++ linux/arch/x86_64/kernel/ptrace.c   2005/04/29 11:15:04     1.22
@@ -63,6 +63,12 @@
        return (*((unsigned long *)stack));
 }
 
+static inline struct pt_regs *get_child_regs(struct task_struct *task)
+{
+       struct pt_regs *regs = (void *)task->thread.rsp0;
+       return regs - 1;
+}
+
 /*
  * this routine will put a word on the processes privileged stack. 
  * the offset is how far from the base addr as stored in the TSS.  
@@ -80,6 +86,130 @@
        return 0;
 }
 
+#define LDT_SEGMENT 4
+
+unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs 
*regs)
+{
+       unsigned long addr, seg;
+
+       addr = regs->rip;
+       seg = regs->cs & 0xffff;
+
+       /*
+        * We'll assume that the code segments in the GDT
+        * are all zero-based. That is largely true: the
+        * TLS segments are used for data, and the PNPBIOS
+        * and APM bios ones we just ignore here.
+        */
+       if (seg & LDT_SEGMENT) {
+               u32 *desc;
+               unsigned long base;
+
+               down(&child->mm->context.sem);
+               desc = child->mm->context.ldt + (seg & ~7);
+               base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 
0xff000000);
+
+               /* 16-bit code segment? */
+               if (!((desc[1] >> 22) & 1))
+                       addr &= 0xffff;
+               addr += base;
+               up(&child->mm->context.sem);
+       }
+       return addr;
+}
+
+static int is_at_popf(struct task_struct *child, struct pt_regs *regs)
+{
+       int i, copied;
+       unsigned char opcode[16];
+       unsigned long addr = convert_rip_to_linear(child, regs);
+
+       copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
+       for (i = 0; i < copied; i++) {
+               switch (opcode[i]) {
+               /* popf */
+               case 0x9d:
+                       return 1;
+
+                       /* CHECKME: 64 65 */
+
+               /* opcode and address size prefixes */
+               case 0x66: case 0x67:
+                       continue;
+               /* irrelevant prefixes (segment overrides and repeats) */
+               case 0x26: case 0x2e:
+               case 0x36: case 0x3e:
+               case 0x64: case 0x65:
+               case 0xf0: case 0xf2: case 0xf3:
+                       continue;
+
+               /* REX prefixes */
+               case 0x40 ... 0x4f:
+                       continue;
+
+                       /* CHECKME: f0, f2, f3 */
+
+               /*
+                * pushf: NOTE! We should probably not let
+                * the user see the TF bit being set. But
+                * it's more pain than it's worth to avoid
+                * it, and a debugger could emulate this
+                * all in user space if it _really_ cares.
+                */
+               case 0x9c:
+               default:
+                       return 0;
+               }
+       }
+       return 0;
+}
+
+static void set_singlestep(struct task_struct *child)
+{
+       struct pt_regs *regs = get_child_regs(child);
+
+       /*
+        * Always set TIF_SINGLESTEP - this guarantees that
+        * we single-step system calls etc..  This will also
+        * cause us to set TF when returning to user mode.
+        */
+       set_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+       /*
+        * If TF was already set, don't do anything else
+        */
+       if (regs->eflags & TRAP_FLAG)
+               return;
+
+       /* Set TF on the kernel stack.. */
+       regs->eflags |= TRAP_FLAG;
+
+       /*
+        * ..but if TF is changed by the instruction we will trace,
+        * don't mark it as being "us" that set it, so that we
+        * won't clear it by hand later.
+        *
+        * AK: this is not enough, LAHF and IRET can change TF in user space 
too.
+        */
+       if (is_at_popf(child, regs))
+               return;
+
+       child->ptrace |= PT_DTRACE;
+}
+
+static void clear_singlestep(struct task_struct *child)
+{
+       /* Always clear TIF_SINGLESTEP... */
+       clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+       /* But touch TF only if it was set by us.. */
+       if (child->ptrace & PT_DTRACE) {
+               struct pt_regs *regs = get_child_regs(child);
+               regs->eflags &= ~TRAP_FLAG;
+               child->ptrace &= ~PT_DTRACE;
+       }
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -87,11 +217,7 @@
  */
 void ptrace_disable(struct task_struct *child)
 { 
-       long tmp;
-
-       clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-       tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
-       put_stack_long(child, EFL_OFFSET, tmp);
+       clear_singlestep(child);
 }
 
 static int putreg(struct task_struct *child,
@@ -338,8 +464,7 @@
                }
                break;
        case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall 
*/
-       case PTRACE_CONT: { /* restart after signal. */
-               long tmp;
+       case PTRACE_CONT:    /* restart after signal. */
 
                ret = -EIO;
                if ((unsigned long) data > _NSIG)
@@ -350,14 +475,11 @@
                        clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
                clear_tsk_thread_flag(child, TIF_SINGLESTEP);
                child->exit_code = data;
-       /* make sure the single step bit is not set. */
-               tmp = get_stack_long(child, EFL_OFFSET);
-               tmp &= ~TRAP_FLAG;
-               put_stack_long(child, EFL_OFFSET,tmp);
+               /* make sure the single step bit is not set. */
+               clear_singlestep(child);
                wake_up_process(child);
                ret = 0;
                break;
-       }
 
 #ifdef CONFIG_IA32_EMULATION
                /* This makes only sense with 32bit programs. Allow a
@@ -394,41 +516,28 @@
  * perhaps it should be put in the status that it wants to 
  * exit.
  */
-       case PTRACE_KILL: {
-               long tmp;
-
+       case PTRACE_KILL:
                ret = 0;
                if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
                        break;
                clear_tsk_thread_flag(child, TIF_SINGLESTEP);
                child->exit_code = SIGKILL;
                /* make sure the single step bit is not set. */
-               tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
-               put_stack_long(child, EFL_OFFSET, tmp);
+               clear_singlestep(child);
                wake_up_process(child);
                break;
-       }
-
-       case PTRACE_SINGLESTEP: {  /* set the trap flag. */
-               long tmp;
 
+       case PTRACE_SINGLESTEP:    /* set the trap flag. */
                ret = -EIO;
                if ((unsigned long) data > _NSIG)
                        break;
                clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
-               if ((child->ptrace & PT_DTRACE) == 0) {
-                       /* Spurious delayed TF traps may occur */
-                       child->ptrace |= PT_DTRACE;
-               }
-               tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG;
-               put_stack_long(child, EFL_OFFSET, tmp);
-               set_tsk_thread_flag(child, TIF_SINGLESTEP);
+               set_singlestep(child);
                child->exit_code = data;
                /* give it a chance to run. */
                wake_up_process(child);
                ret = 0;
                break;
-       }
 
        case PTRACE_DETACH:
                /* detach a process that was attached. */
diff -urN linux/arch/x86_64/kernel/setup.c linux/arch/x86_64/kernel/setup.c
--- linux/arch/x86_64/kernel/setup.c    2005/04/08 18:58:07     1.42
+++ linux/arch/x86_64/kernel/setup.c    2005/04/29 11:15:04     1.43
@@ -76,9 +76,6 @@
 
 int acpi_numa __initdata;
 
-/* For PCI or other memory-mapped resources */
-unsigned long pci_mem_start = 0x10000000;
-
 /* Boot loader ID as an integer, for the benefit of proc_dointvec */
 int bootloader_type;
 
@@ -330,6 +327,10 @@
                else if (!memcmp(from, "acpi=strict", 11)) {
                        acpi_strict = 1;
                }
+#ifdef CONFIG_X86_IO_APIC
+               else if (!memcmp(from, "acpi_skip_timer_override", 24))
+                       acpi_skip_timer_override = 1;
+#endif
 #endif
 
                if (!memcmp(from, "nolapic", 7) ||
@@ -495,7 +496,6 @@
 
 void __init setup_arch(char **cmdline_p)
 {
-       unsigned long low_mem_size;
        unsigned long kernel_end;
 
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
@@ -654,13 +654,7 @@
                request_resource(&ioport_resource, &standard_io_resources[i]);
        }
 
-       /* Will likely break when you have unassigned resources with more
-          than 4GB memory and bridges that don't support more than 4GB. 
-          Doing it properly would require to use pci_alloc_consistent
-          in this case. */
-       low_mem_size = ((end_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
-       if (low_mem_size > pci_mem_start)
-               pci_mem_start = low_mem_size;
+       e820_setup_gap();
 
 #ifdef CONFIG_GART_IOMMU
        iommu_hole_init();
@@ -679,7 +673,7 @@
 {
        unsigned int *v;
 
-       if (c->x86_cpuid_level < 0x80000004)
+       if (c->extended_cpuid_level < 0x80000004)
                return 0;
 
        v = (unsigned int *) c->x86_model_id;
@@ -695,7 +689,7 @@
 {
        unsigned int n, dummy, eax, ebx, ecx, edx;
 
-       n = c->x86_cpuid_level;
+       n = c->extended_cpuid_level;
 
        if (n >= 0x80000005) {
                cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
@@ -725,14 +719,46 @@
        }
 }
 
+#ifdef CONFIG_SMP
+/*
+ * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
+ * Assumes number of cores is a power of two.
+ */
+static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+       int cpu = c->x86_apicid;
+       int node = 0;
+       if (c->x86_num_cores == 1)
+               return;
+       cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+
+#ifdef CONFIG_NUMA
+       /* When an ACPI SRAT table is available use the mappings from SRAT
+          instead. */
+       if (acpi_numa <= 0) {
+               node = cpu_core_id[cpu];
+               if (!node_online(node))
+                       node = first_node(node_online_map);
+               cpu_to_node[cpu] = node;
+       } else {
+               node = cpu_to_node[cpu];
+       }
+#endif
+       printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
+                       cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
+#endif
+}
+#else
+static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
+{
+}
+#endif
 
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
        int r;
        int level;
-#ifdef CONFIG_NUMA
-       int cpu;
-#endif
 
        /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
           3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
@@ -755,26 +781,12 @@
        } 
        display_cacheinfo(c);
 
-       if (c->x86_cpuid_level >= 0x80000008) {
+       if (c->extended_cpuid_level >= 0x80000008) {
                c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
                if (c->x86_num_cores & (c->x86_num_cores - 1))
                        c->x86_num_cores = 1;
 
-#ifdef CONFIG_NUMA
-               /* On a dual core setup the lower bits of apic id
-                  distingush the cores. Fix up the CPU<->node mappings
-                  here based on that.
-                  Assumes number of cores is a power of two.
-                  When using SRAT use mapping from SRAT. */
-               cpu = c->x86_apicid;
-               if (acpi_numa <= 0 && c->x86_num_cores > 1) {
-                       cpu_to_node[cpu] = cpu >> hweight32(c->x86_num_cores - 
1);
-                       if (!node_online(cpu_to_node[cpu]))
-                               cpu_to_node[cpu] = first_node(node_online_map);
-               }
-               printk(KERN_INFO "CPU %d(%d) -> Node %d\n",
-                               cpu, c->x86_num_cores, cpu_to_node[cpu]);
-#endif
+               amd_detect_cmp(c);
        }
 
        return r;
@@ -784,10 +796,10 @@
 {
 #ifdef CONFIG_SMP
        u32     eax, ebx, ecx, edx;
-       int     index_lsb, index_msb, tmp;
+       int     index_msb, tmp;
        int     cpu = smp_processor_id();
        
-       if (!cpu_has(c, X86_FEATURE_HT))
+       if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
                return;
 
        cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -796,7 +808,6 @@
        if (smp_num_siblings == 1) {
                printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
        } else if (smp_num_siblings > 1) {
-               index_lsb = 0;
                index_msb = 31;
                /*
                 * At this point we only support two siblings per
@@ -808,45 +819,65 @@
                        return;
                }
                tmp = smp_num_siblings;
-               while ((tmp & 1) == 0) {
-                       tmp >>=1 ;
-                       index_lsb++;
-               }
-               tmp = smp_num_siblings;
                while ((tmp & 0x80000000 ) == 0) {
                        tmp <<=1 ;
                        index_msb--;
                }
-               if (index_lsb != index_msb )
+               if (smp_num_siblings & (smp_num_siblings - 1))
                        index_msb++;
                phys_proc_id[cpu] = phys_pkg_id(index_msb);
                
                printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
                       phys_proc_id[cpu]);
+
+               smp_num_siblings = smp_num_siblings / c->x86_num_cores;
+
+               tmp = smp_num_siblings;
+               index_msb = 31;
+               while ((tmp & 0x80000000) == 0) {
+                       tmp <<=1 ;
+                       index_msb--;
+               }
+               if (smp_num_siblings & (smp_num_siblings - 1))
+                       index_msb++;
+
+               cpu_core_id[cpu] = phys_pkg_id(index_msb);
+
+               if (c->x86_num_cores > 1)
+                       printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
+                              cpu_core_id[cpu]);
        }
 #endif
 }
 
-static void __init sched_cmp_hack(struct cpuinfo_x86 *c)
+/*
+ * find out the number of processor cores on the die
+ */
+static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_SMP
-       /* AMD dual core looks like HT but isn't really. Hide it from the
-          scheduler. This works around problems with the domain scheduler.
-          Also probably gives slightly better scheduling and disables
-          SMT nice which is harmful on dual core.
-          TBD tune the domain scheduler for dual core. */
-       if (c->x86_vendor == X86_VENDOR_AMD && cpu_has(c, 
X86_FEATURE_CMP_LEGACY))
-               smp_num_siblings = 1;
-#endif
+       unsigned int eax;
+
+       if (c->cpuid_level < 4)
+               return 1;
+
+       __asm__("cpuid"
+               : "=a" (eax)
+               : "0" (4), "c" (0)
+               : "bx", "dx");
+
+       if (eax & 0x1f)
+               return ((eax >> 26) + 1);
+       else
+               return 1;
 }
-       
+
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
        /* Cache sizes */
        unsigned n;
 
        init_intel_cacheinfo(c);
-       n = c->x86_cpuid_level;
+       n = c->extended_cpuid_level;
        if (n >= 0x80000008) {
                unsigned eax = cpuid_eax(0x80000008);
                c->x86_virt_bits = (eax >> 8) & 0xff;
@@ -855,6 +886,9 @@
 
        if (c->x86 == 15)
                c->x86_cache_alignment = c->x86_clflush_size * 2;
+       if (c->x86 >= 15)
+               set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+       c->x86_num_cores = intel_num_cpu_cores(c);
 }
 
 void __init get_cpu_vendor(struct cpuinfo_x86 *c)
@@ -892,7 +926,7 @@
        c->x86_cache_alignment = c->x86_clflush_size;
        c->x86_num_cores = 1;
        c->x86_apicid = c == &boot_cpu_data ? 0 : c - cpu_data;
-       c->x86_cpuid_level = 0;
+       c->extended_cpuid_level = 0;
        memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
        /* Get vendor name */
@@ -939,7 +973,7 @@
 
        /* AMD-defined flags: level 0x80000001 */
        xlvl = cpuid_eax(0x80000000);
-       c->x86_cpuid_level = xlvl;
+       c->extended_cpuid_level = xlvl;
        if ((xlvl & 0xffff0000) == 0x80000000) {
                if (xlvl >= 0x80000001) {
                        c->x86_capability[1] = cpuid_edx(0x80000001);
@@ -984,7 +1018,6 @@
 
        select_idle_routine(c);
        detect_ht(c); 
-       sched_cmp_hack(c);
 
        /*
         * On SMP, boot_cpu_data holds the common feature set between
@@ -1055,7 +1088,8 @@
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* Other (Linux-defined) */
-               "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, 
NULL, NULL,
+               "cxmmx", NULL, "cyrix_arr", "centaur_mcr", "k8c+",
+               "constant_tsc", NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1113,8 +1147,14 @@
                seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
        
 #ifdef CONFIG_SMP
-       seq_printf(m, "physical id\t: %d\n", phys_proc_id[c - cpu_data]);
-       seq_printf(m, "siblings\t: %d\n", c->x86_num_cores * smp_num_siblings);
+       if (smp_num_siblings * c->x86_num_cores > 1) {
+               int cpu = c - cpu_data;
+               seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]);
+               seq_printf(m, "siblings\t: %d\n",
+                               c->x86_num_cores * smp_num_siblings);
+               seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]);
+               seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
+       }
 #endif 
 
        seq_printf(m,
@@ -1156,12 +1196,8 @@
                                        seq_printf(m, " [%d]", i);
                        }
        }
-       seq_printf(m, "\n");
-
-       if (c->x86_num_cores > 1)
-               seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
 
-       seq_printf(m, "\n\n"); 
+       seq_printf(m, "\n\n");
 
        return 0;
 }
diff -urN linux/arch/x86_64/kernel/signal.c linux/arch/x86_64/kernel/signal.c
--- linux/arch/x86_64/kernel/signal.c   2005/04/08 18:58:07     1.28
+++ linux/arch/x86_64/kernel/signal.c   2005/04/29 11:15:05     1.29
@@ -185,7 +185,6 @@
 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned 
long mask, struct task_struct *me)
 {
        int err = 0;
-       unsigned long eflags;
 
        err |= __put_user(0, &sc->gs);
        err |= __put_user(0, &sc->fs);
@@ -209,11 +208,7 @@
        err |= __put_user(me->thread.trap_no, &sc->trapno);
        err |= __put_user(me->thread.error_code, &sc->err);
        err |= __put_user(regs->rip, &sc->rip);
-       eflags = regs->eflags;
-       if (current->ptrace & PT_PTRACED) {
-               eflags &= ~TF_MASK;
-       }
-       err |= __put_user(eflags, &sc->eflags);
+       err |= __put_user(regs->eflags, &sc->eflags);
        err |= __put_user(mask, &sc->oldmask);
        err |= __put_user(me->thread.cr2, &sc->cr2);
 
@@ -323,14 +318,9 @@
        regs->rsp = (unsigned long)frame;
 
        set_fs(USER_DS);
-       if (regs->eflags & TF_MASK) {
-               if ((current->ptrace & (PT_PTRACED | PT_DTRACE)) == (PT_PTRACED 
| PT_DTRACE)) {
-                       ptrace_notify(SIGTRAP);
-               } else {
-                       regs->eflags &= ~TF_MASK;
-               }
-       }
-
+       regs->eflags &= ~TF_MASK;
+       if (test_thread_flag(TIF_SINGLESTEP))
+               ptrace_notify(SIGTRAP);
 #ifdef DEBUG_SIG
        printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
                current->comm, current->pid, frame, regs->rip, frame->pretcode);
@@ -378,6 +368,18 @@
                }
        }
 
+       /*
+        * If TF is set due to a debugger (PT_DTRACE), clear the TF
+        * flag so that register information in the sigcontext is
+        * correct.
+        */
+       if (unlikely(regs->eflags & TF_MASK)) {
+               if (likely(current->ptrace & PT_DTRACE)) {
+                       current->ptrace &= ~PT_DTRACE;
+                       regs->eflags &= ~TF_MASK;
+               }
+       }
+
 #ifdef CONFIG_IA32_EMULATION
        if (test_thread_flag(TIF_IA32)) {
                if (ka->sa.sa_flags & SA_SIGINFO)
diff -urN linux/arch/x86_64/kernel/smp.c linux/arch/x86_64/kernel/smp.c
--- linux/arch/x86_64/kernel/smp.c      2005/04/08 18:58:07     1.27
+++ linux/arch/x86_64/kernel/smp.c      2005/04/29 11:15:05     1.28
@@ -27,6 +27,7 @@
 #include <asm/mach_apic.h>
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
+#include <asm/apicdef.h>
 
 /*
  *     Smarter SMP flushing macros. 
@@ -413,3 +414,27 @@
                atomic_inc(&call_data->finished);
        }
 }
+
+int safe_smp_processor_id(void)
+{
+       int apicid, i;
+
+       if (disable_apic)
+               return 0;
+
+       apicid = hard_smp_processor_id();
+       if (x86_cpu_to_apicid[apicid] == apicid)
+               return apicid;
+
+       for (i = 0; i < NR_CPUS; ++i) {
+               if (x86_cpu_to_apicid[i] == apicid)
+                       return i;
+       }
+
+       /* No entries in x86_cpu_to_apicid?  Either no MPS|ACPI,
+        * or called too early.  Either way, we must be CPU 0. */
+       if (x86_cpu_to_apicid[0] == BAD_APICID)
+               return 0;
+
+       return 0; /* Should not happen */
+}
diff -urN linux/arch/x86_64/kernel/smpboot.c linux/arch/x86_64/kernel/smpboot.c
--- linux/arch/x86_64/kernel/smpboot.c  2005/04/08 18:58:07     1.36
+++ linux/arch/x86_64/kernel/smpboot.c  2005/04/29 11:15:05     1.37
@@ -12,8 +12,7 @@
  *     Pentium Pro and Pentium-II/Xeon MP machines.
  *     Original development of Linux SMP code supported by Caldera.
  *
- *     This code is released under the GNU General Public License version 2 or
- *     later.
+ *     This code is released under the GNU General Public License version 2
  *
  *     Fixes
  *             Felix Koop      :       NR_CPUS used properly
@@ -31,9 +30,13 @@
  *             Tigran Aivazian :       fixed "0.00 in /proc/uptime on SMP" bug.
  *     Maciej W. Rozycki       :       Bits for genuine 82489DX APICs
  *     Andi Kleen              :       Changed for SMP boot into long mode.
- *             Rusty Russell   :       Hacked into shape for new "hotplug" 
boot process. 
+ *             Rusty Russell   :       Hacked into shape for new "hotplug" 
boot process.
+ *      Andi Kleen              :       Converted to new state machine.
+ *                                     Various cleanups.
+ *                                     Probably mostly hotplug CPU ready now.
  */
 
+
 #include <linux/config.h>
 #include <linux/init.h>
 
@@ -54,30 +57,49 @@
 #include <asm/tlbflush.h>
 #include <asm/proto.h>
 
+/* Change for real CPU hotplug. Note other files need to be fixed
+   first too. */
+#define __cpuinit __init
+#define __cpuinitdata __initdata
+
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
 /* Package ID of each logical CPU */
 u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
 EXPORT_SYMBOL(phys_proc_id);
+EXPORT_SYMBOL(cpu_core_id);
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map;
 
+EXPORT_SYMBOL(cpu_online_map);
+
+/*
+ * Private maps to synchronize booting between AP and BP.
+ * Probably not needed anymore, but it makes for easier debugging. -AK
+ */
 cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
-static cpumask_t smp_commenced_mask;
+
+cpumask_t cpu_possible_map;
+EXPORT_SYMBOL(cpu_possible_map);
 
 /* Per CPU bogomips and other parameters */
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 
+/* Set when the idlers are all forked */
+int smp_threads_ready;
+
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
 
 /*
  * Trampoline 80x86 program as an array.
  */
 
-extern unsigned char trampoline_data [];
-extern unsigned char trampoline_end  [];
+extern unsigned char trampoline_data[];
+extern unsigned char trampoline_end[];
 
 /*
  * Currently trivial. Write the real->protected mode
@@ -85,7 +107,7 @@
  * has made sure it's suitably aligned.
  */
 
-static unsigned long __init setup_trampoline(void)
+static unsigned long __cpuinit setup_trampoline(void)
 {
        void *tramp = __va(SMP_TRAMPOLINE_BASE); 
        memcpy(tramp, trampoline_data, trampoline_end - trampoline_data);
@@ -97,7 +119,7 @@
  * a given CPU
  */
 
-static void __init smp_store_cpu_info(int id)
+static void __cpuinit smp_store_cpu_info(int id)
 {
        struct cpuinfo_x86 *c = cpu_data + id;
 
@@ -106,145 +128,101 @@
 }
 
 /*
- * TSC synchronization.
+ * Synchronize TSCs of CPUs
  *
- * We first check whether all CPUs have their TSC's synchronized,
- * then we print a warning if not, and always resync.
+ * This new algorithm is less accurate than the old "zero TSCs"
+ * one, but we cannot zero TSCs anymore in the new hotplug CPU
+ * model.
  */
 
-static atomic_t tsc_start_flag = ATOMIC_INIT(0);
-static atomic_t tsc_count_start = ATOMIC_INIT(0);
-static atomic_t tsc_count_stop = ATOMIC_INIT(0);
-static unsigned long long tsc_values[NR_CPUS];
+static atomic_t __cpuinitdata tsc_flag;
+static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock);
+static unsigned long long __cpuinitdata bp_tsc, ap_tsc;
 
 #define NR_LOOPS 5
 
-extern unsigned int fast_gettimeoffset_quotient;
-
-static void __init synchronize_tsc_bp (void)
+static void __cpuinit sync_tsc_bp_init(int init)
 {
-       int i;
-       unsigned long long t0;
-       unsigned long long sum, avg;
-       long long delta;
-       long one_usec;
-       int buggy = 0;
-
-       printk(KERN_INFO "checking TSC synchronization across %u CPUs: 
",num_booting_cpus());
-
-       one_usec = cpu_khz; 
-
-       atomic_set(&tsc_start_flag, 1);
-       wmb();
-
-       /*
-        * We loop a few times to get a primed instruction cache,
-        * then the last pass is more or less synchronized and
-        * the BP and APs set their cycle counters to zero all at
-        * once. This reduces the chance of having random offsets
-        * between the processors, and guarantees that the maximum
-        * delay between the cycle counters is never bigger than
-        * the latency of information-passing (cachelines) between
-        * two CPUs.
-        */
-       for (i = 0; i < NR_LOOPS; i++) {
-               /*
-                * all APs synchronize but they loop on '== num_cpus'
-                */
-               while (atomic_read(&tsc_count_start) != num_booting_cpus()-1) 
mb();
-               atomic_set(&tsc_count_stop, 0);
-               wmb();
-               /*
-                * this lets the APs save their current TSC:
-                */
-               atomic_inc(&tsc_count_start);
-
-               sync_core();
-               rdtscll(tsc_values[smp_processor_id()]);
-               /*
-                * We clear the TSC in the last loop:
-                */
-               if (i == NR_LOOPS-1)
-                       write_tsc(0, 0);
-
-               /*
-                * Wait for all APs to leave the synchronization point:
-                */
-               while (atomic_read(&tsc_count_stop) != num_booting_cpus()-1) 
mb();
-               atomic_set(&tsc_count_start, 0);
-               wmb();
-               atomic_inc(&tsc_count_stop);
-       }
-
-       sum = 0;
-       for (i = 0; i < NR_CPUS; i++) {
-               if (cpu_isset(i, cpu_callout_map)) {
-               t0 = tsc_values[i];
-               sum += t0;
-       }
-       }
-       avg = sum / num_booting_cpus();
-
-       sum = 0;
-       for (i = 0; i < NR_CPUS; i++) {
-               if (!cpu_isset(i, cpu_callout_map))
-                       continue;
-
-               delta = tsc_values[i] - avg;
-               if (delta < 0)
-                       delta = -delta;
-               /*
-                * We report bigger than 2 microseconds clock differences.
-                */
-               if (delta > 2*one_usec) {
-                       long realdelta;
-                       if (!buggy) {
-                               buggy = 1;
-                               printk("\n");
-                       }
-                       realdelta = delta / one_usec;
-                       if (tsc_values[i] < avg)
-                               realdelta = -realdelta;
+       if (init)
+               _raw_spin_lock(&tsc_sync_lock);
+       else
+               _raw_spin_unlock(&tsc_sync_lock);
+       atomic_set(&tsc_flag, 0);
+}
 
-                       printk("BIOS BUG: CPU#%d improperly initialized, has 
%ld usecs TSC skew! FIXED.\n",
-                               i, realdelta);
-               }
+/*
+ * Synchronize TSC on AP with BP.
+ */
+static void __cpuinit __sync_tsc_ap(void)
+{
+       if (!cpu_has_tsc)
+               return;
+       Dprintk("AP %d syncing TSC\n", smp_processor_id());
 
-               sum += delta;
-       }
-       if (!buggy)
-               printk("passed.\n");
+       while (atomic_read(&tsc_flag) != 0)
+               cpu_relax();
+       atomic_inc(&tsc_flag);
+       mb();
+       _raw_spin_lock(&tsc_sync_lock);
+       wrmsrl(MSR_IA32_TSC, bp_tsc);
+       _raw_spin_unlock(&tsc_sync_lock);
+       rdtscll(ap_tsc);
+       mb();
+       atomic_inc(&tsc_flag);
+       mb();
 }
 
-static void __init synchronize_tsc_ap (void)
+static void __cpuinit sync_tsc_ap(void)
 {
        int i;
+       for (i = 0; i < NR_LOOPS; i++)
+               __sync_tsc_ap();
+}
 
-       /*
-        * Not every cpu is online at the time
-        * this gets called, so we first wait for the BP to
-        * finish SMP initialization:
-        */
-       while (!atomic_read(&tsc_start_flag)) mb();
-
-       for (i = 0; i < NR_LOOPS; i++) {
-               atomic_inc(&tsc_count_start);
-               while (atomic_read(&tsc_count_start) != num_booting_cpus()) 
mb();
+/*
+ * Synchronize TSC from BP to AP.
+ */
+static void __cpuinit __sync_tsc_bp(int cpu)
+{
+       if (!cpu_has_tsc)
+               return;
 
-               sync_core();
-               rdtscll(tsc_values[smp_processor_id()]);
-               if (i == NR_LOOPS-1)
-                       write_tsc(0, 0);
+       /* Wait for AP */
+       while (atomic_read(&tsc_flag) == 0)
+               cpu_relax();
+       /* Save BPs TSC */
+       sync_core();
+       rdtscll(bp_tsc);
+       /* Don't do the sync core here to avoid too much latency. */
+       mb();
+       /* Start the AP */
+       _raw_spin_unlock(&tsc_sync_lock);
+       /* Wait for AP again */
+       while (atomic_read(&tsc_flag) < 2)
+               cpu_relax();
+       rdtscl(bp_tsc);
+       barrier();
+}
 
-               atomic_inc(&tsc_count_stop);
-               while (atomic_read(&tsc_count_stop) != num_booting_cpus()) mb();
+static void __cpuinit sync_tsc_bp(int cpu)
+{
+       int i;
+       for (i = 0; i < NR_LOOPS - 1; i++) {
+               __sync_tsc_bp(cpu);
+               sync_tsc_bp_init(1);
        }
+       __sync_tsc_bp(cpu);
+       printk(KERN_INFO "Synced TSC of CPU %d difference %Ld\n",
+              cpu, ap_tsc - bp_tsc);
 }
-#undef NR_LOOPS
 
-static atomic_t init_deasserted;
+static atomic_t init_deasserted __cpuinitdata;
 
-static void __init smp_callin(void)
+/*
+ * Report back to the Boot Processor.
+ * Running on AP.
+ */
+void __cpuinit smp_callin(void)
 {
        int cpuid, phys_id;
        unsigned long timeout;
@@ -255,7 +233,8 @@
         * our local APIC.  We have to wait for the IPI or we'll
         * lock up on an APIC access.
         */
-       while (!atomic_read(&init_deasserted));
+       while (!atomic_read(&init_deasserted))
+               cpu_relax();
 
        /*
         * (This works even if the APIC is not enabled.)
@@ -286,7 +265,7 @@
                 */
                if (cpu_isset(cpuid, cpu_callout_map))
                        break;
-               rep_nop();
+               cpu_relax();
        }
 
        if (!time_before(jiffies, timeout)) {
@@ -304,8 +283,6 @@
        Dprintk("CALLIN, before setup_local_APIC().\n");
        setup_local_APIC();
 
-       local_irq_enable();
-
        /*
         * Get our bogomips.
         */
@@ -319,26 +296,16 @@
         */
        smp_store_cpu_info(cpuid);
 
-       local_irq_disable();
-
        /*
         * Allow the master to continue.
         */
        cpu_set(cpuid, cpu_callin_map);
-
-       /*
-        *      Synchronize the TSC with the BP
-        */
-       if (cpu_has_tsc)
-               synchronize_tsc_ap();
 }
 
-static int cpucount;
-
 /*
- * Activate a secondary processor.
+ * Setup code on secondary processor (after comming out of the trampoline)
  */
-void __init start_secondary(void)
+void __cpuinit start_secondary(void)
 {
        /*
         * Dont put anything before smp_callin(), SMP
@@ -348,17 +315,18 @@
        cpu_init();
        smp_callin();
 
+       /*
+        * Synchronize the TSC with the BP
+        */
+       sync_tsc_ap();
+
        /* otherwise gcc will move up the smp_processor_id before the cpu_init 
*/
        barrier();
 
-       Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); 
-       while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
-               rep_nop();
-
        Dprintk("cpu %d: setting up apic clock\n", smp_processor_id());         
        setup_secondary_APIC_clock();
 
-       Dprintk("cpu %d: enabling apic timer\n", smp_processor_id()); 
+       Dprintk("cpu %d: enabling apic timer\n", smp_processor_id());
 
        if (nmi_watchdog == NMI_IO_APIC) {
                disable_8259A_irq(0);
@@ -367,26 +335,22 @@
        }
 
 
-       enable_APIC_timer(); 
+       enable_APIC_timer();
 
        /*
-        * low-memory mappings have been cleared, flush them from
-        * the local TLBs too.
+        * Allow the master to continue.
         */
-       local_flush_tlb();
-
-       Dprintk("cpu %d eSetting cpu_online_map\n", smp_processor_id()); 
        cpu_set(smp_processor_id(), cpu_online_map);
-       wmb();
-       
+       mb();
+
        cpu_idle();
 }
 
-extern volatile unsigned long init_rsp; 
+extern volatile unsigned long init_rsp;
 extern void (*initial_code)(void);
 
 #if APIC_DEBUG
-static inline void inquire_remote_apic(int apicid)
+static void inquire_remote_apic(int apicid)
 {
        unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
        char *names[] = { "ID", "VERSION", "SPIV" };
@@ -423,7 +387,10 @@
 }
 #endif
 
-static int __init wakeup_secondary_via_INIT(int phys_apicid, unsigned int 
start_rip)
+/*
+ * Kick the secondary to wake up.
+ */
+static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int 
start_rip)
 {
        unsigned long send_status = 0, accept_status = 0;
        int maxlvt, timeout, num_starts, j;
@@ -546,33 +513,36 @@
        return (send_status | accept_status);
 }
 
-static void __init do_boot_cpu (int apicid)
+/*
+ * Boot one CPU.
+ */
+static int __cpuinit do_boot_cpu(int cpu, int apicid)
 {
        struct task_struct *idle;
        unsigned long boot_error;
-       int timeout, cpu;
+       int timeout;
        unsigned long start_rip;
-
-       cpu = ++cpucount;
        /*
         * We can't use kernel_thread since we must avoid to
         * reschedule the child.
         */
        idle = fork_idle(cpu);
-       if (IS_ERR(idle))
-               panic("failed fork for CPU %d", cpu);
+       if (IS_ERR(idle)) {
+               printk("failed fork for CPU %d\n", cpu);
+               return PTR_ERR(idle);
+       }
        x86_cpu_to_apicid[cpu] = apicid;
 
        cpu_pda[cpu].pcurrent = idle;
 
        start_rip = setup_trampoline();
 
-       init_rsp = idle->thread.rsp; 
+       init_rsp = idle->thread.rsp;
        per_cpu(init_tss,cpu).rsp0 = init_rsp;
        initial_code = start_secondary;
        clear_ti_thread_flag(idle->thread_info, TIF_FORK);
 
-       printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, 
apicid, 
+       printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, 
apicid,
               start_rip, init_rsp);
 
        /*
@@ -609,7 +579,7 @@
        /*
         * Starting actual IPI sequence...
         */
-       boot_error = wakeup_secondary_via_INIT(apicid, start_rip); 
+       boot_error = wakeup_secondary_via_INIT(apicid, start_rip);
 
        if (!boot_error) {
                /*
@@ -650,58 +620,131 @@
        if (boot_error) {
                cpu_clear(cpu, cpu_callout_map); /* was set here 
(do_boot_cpu()) */
                clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
-               cpucount--;
+               cpu_clear(cpu, cpu_present_map);
+               cpu_clear(cpu, cpu_possible_map);
                x86_cpu_to_apicid[cpu] = BAD_APICID;
                x86_cpu_to_log_apicid[cpu] = BAD_APICID;
+               return -EIO;
        }
+
+       return 0;
 }
 
-static void smp_tune_scheduling (void)
+cycles_t cacheflush_time;
+unsigned long cache_decay_ticks;
+
+/*
+ * Construct cpu_sibling_map[], so that we can tell the sibling CPU
+ * on SMT systems efficiently.
+ */
+static __cpuinit void detect_siblings(void)
 {
-       int cachesize;       /* kB   */
-       unsigned long bandwidth = 1000; /* MB/s */
-       /*
-        * Rough estimation for SMP scheduling, this is the number of
-        * cycles it takes for a fully memory-limited process to flush
-        * the SMP-local cache.
-        *
-        * (For a P5 this pretty much means we will choose another idle
-        *  CPU almost always at wakeup time (this is due to the small
-        *  L1 cache), on PIIs it's around 50-100 usecs, depending on
-        *  the cache size)
-        */
+       int cpu;
 
-       if (!cpu_khz) {
-               return;
-       } else {
-               cachesize = boot_cpu_data.x86_cache_size;
-               if (cachesize == -1) {
-                       cachesize = 16; /* Pentiums, 2x8kB cache */
-                       bandwidth = 100;
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               cpus_clear(cpu_sibling_map[cpu]);
+               cpus_clear(cpu_core_map[cpu]);
+       }
+
+       for_each_online_cpu (cpu) {
+               struct cpuinfo_x86 *c = cpu_data + cpu;
+               int siblings = 0;
+               int i;
+               if (smp_num_siblings > 1) {
+                       for_each_online_cpu (i) {
+                               if (cpu_core_id[cpu] == cpu_core_id[i]) {
+                                       siblings++;
+                                       cpu_set(i, cpu_sibling_map[cpu]);
+                               }
+                       }
+               } else {
+                       siblings++;
+                       cpu_set(cpu, cpu_sibling_map[cpu]);
                }
+
+               if (siblings != smp_num_siblings) {
+                       printk(KERN_WARNING
+              "WARNING: %d siblings found for CPU%d, should be %d\n",
+                              siblings, cpu, smp_num_siblings);
+                       smp_num_siblings = siblings;
+               }
+               if (c->x86_num_cores > 1) {
+                       for_each_online_cpu(i) {
+                               if (phys_proc_id[cpu] == phys_proc_id[i])
+                                       cpu_set(i, cpu_core_map[cpu]);
+                       }
+               } else
+                       cpu_core_map[cpu] = cpu_sibling_map[cpu];
        }
 }
 
 /*
- * Cycle through the processors sending APIC IPIs to boot each.
+ * Cleanup possible dangling ends...
  */
-
-static void __init smp_boot_cpus(unsigned int max_cpus)
+static __cpuinit void smp_cleanup_boot(void)
 {
-       unsigned apicid, cpu, bit, kicked;
+       /*
+        * Paranoid:  Set warm reset code and vector here back
+        * to default values.
+        */
+       CMOS_WRITE(0, 0xf);
 
-       nmi_watchdog_default();
+       /*
+        * Reset trampoline flag
+        */
+       *((volatile int *) phys_to_virt(0x467)) = 0;
 
+#ifndef CONFIG_HOTPLUG_CPU
        /*
-        * Setup boot CPU information
+        * Free pages reserved for SMP bootup.
+        * When you add hotplug CPU support later remove this
+        * Note there is more work to be done for later CPU bootup.
         */
-       smp_store_cpu_info(0); /* Final full version of the data */
-       printk(KERN_INFO "CPU%d: ", 0);
-       print_cpu_info(&cpu_data[0]);
 
-       current_thread_info()->cpu = 0;
-       smp_tune_scheduling();
+       free_page((unsigned long) __va(PAGE_SIZE));
+       free_page((unsigned long) __va(SMP_TRAMPOLINE_BASE));
+#endif
+}
+
+/*
+ * Fall back to non SMP mode after errors.
+ *
+ * RED-PEN audit/test this more. I bet there is more state messed up here.
+ */
+static __cpuinit void disable_smp(void)
+{
+       cpu_present_map = cpumask_of_cpu(0);
+       cpu_possible_map = cpumask_of_cpu(0);
+       if (smp_found_config)
+               phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
+       else
+               phys_cpu_present_map = physid_mask_of_physid(0);
+       cpu_set(0, cpu_sibling_map[0]);
+       cpu_set(0, cpu_core_map[0]);
+}
 
+/*
+ * Handle user cpus=... parameter.
+ */
+static __cpuinit void enforce_max_cpus(unsigned max_cpus)
+{
+       int i, k;
+       k = 0;
+       for (i = 0; i < NR_CPUS; i++) {
+               if (!cpu_possible(i))
+                       continue;
+               if (++k > max_cpus) {
+                       cpu_clear(i, cpu_possible_map);
+                       cpu_clear(i, cpu_present_map);
+               }
+       }
+}
+
+/*
+ * Various sanity checks.
+ */
+static int __cpuinit smp_sanity_check(unsigned max_cpus)
+{
        if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
                printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
                       hard_smp_processor_id());
@@ -714,14 +757,11 @@
         */
        if (!smp_found_config) {
                printk(KERN_NOTICE "SMP motherboard not detected.\n");
-               io_apic_irqs = 0;
-               cpu_online_map = cpumask_of_cpu(0);
-               cpu_set(0, cpu_sibling_map[0]);
-               phys_cpu_present_map = physid_mask_of_physid(0);
+               disable_smp();
                if (APIC_init_uniprocessor())
                        printk(KERN_NOTICE "Local APIC not detected."
                                           " Using dummy APIC emulation.\n");
-               goto smp_done;
+               return -1;
        }
 
        /*
@@ -741,198 +781,146 @@
                printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                        boot_cpu_id);
                printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell 
your hw vendor)\n");
-               io_apic_irqs = 0;
-               cpu_online_map = cpumask_of_cpu(0);
-               cpu_set(0, cpu_sibling_map[0]);
-               phys_cpu_present_map = physid_mask_of_physid(0);
-               disable_apic = 1;
-               goto smp_done;
+               nr_ioapics = 0;
+               return -1;
        }
 
-       verify_local_APIC();
-
        /*
         * If SMP should be disabled, then really disable it!
         */
        if (!max_cpus) {
-               smp_found_config = 0;
                printk(KERN_INFO "SMP mode deactivated, forcing use of dummy 
APIC emulation.\n");
-               io_apic_irqs = 0;
-               cpu_online_map = cpumask_of_cpu(0);
-               cpu_set(0, cpu_sibling_map[0]);
-               phys_cpu_present_map = physid_mask_of_physid(0);
-               disable_apic = 1;
-               goto smp_done;
+               nr_ioapics = 0;
+               return -1;
        }
 
-       connect_bsp_APIC();
-       setup_local_APIC();
-
-       if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id)
-               BUG();
-
-       x86_cpu_to_apicid[0] = boot_cpu_id;
-
-       /*
-        * Now scan the CPU present map and fire up the other CPUs.
-        */
-       Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map));
+       return 0;
+}
 
-       kicked = 1;
-       for (bit = 0; kicked < NR_CPUS && bit < MAX_APICS; bit++) {
-               apicid = cpu_present_to_apicid(bit);
-               /*
-                * Don't even attempt to start the boot CPU!
-                */
-               if (apicid == boot_cpu_id || (apicid == BAD_APICID))
-                       continue;
+/*
+ * Prepare for SMP bootup.  The MP table or ACPI has been read
+ * earlier.  Just do some sanity checking here and enable APIC mode.
+ */
+void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
+{
+       int i;
 
-               if (!physid_isset(apicid, phys_cpu_present_map))
-                       continue;
-               if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
-                       continue;
+       nmi_watchdog_default();
+       current_cpu_data = boot_cpu_data;
+       current_thread_info()->cpu = 0;  /* needed? */
 
-               do_boot_cpu(apicid);
-               ++kicked;
-       }
+       enforce_max_cpus(max_cpus);
 
        /*
-        * Cleanup possible dangling ends...
+        * Fill in cpu_present_mask
         */
-       {
-               /*
-                * Install writable page 0 entry to set BIOS data area.
-                */
-               local_flush_tlb();
-
-               /*
-                * Paranoid:  Set warm reset code and vector here back
-                * to default values.
-                */
-               CMOS_WRITE(0, 0xf);
-
-               *((volatile int *) phys_to_virt(0x467)) = 0;
+       for (i = 0; i < NR_CPUS; i++) {
+               int apicid = cpu_present_to_apicid(i);
+               if (physid_isset(apicid, phys_cpu_present_map)) {
+                       cpu_set(i, cpu_present_map);
+                       /* possible map would be different if we supported real
+                          CPU hotplug. */
+                       cpu_set(i, cpu_possible_map);
+               }
        }
 
-       /*
-        * Allow the user to impress friends.
-        */
-
-       Dprintk("Before bogomips.\n");
-       if (!cpucount) {
-               printk(KERN_INFO "Only one processor found.\n");
-       } else {
-               unsigned long bogosum = 0;
-               for (cpu = 0; cpu < NR_CPUS; cpu++)
-                       if (cpu_isset(cpu, cpu_callout_map))
-                               bogosum += cpu_data[cpu].loops_per_jiffy;
-               printk(KERN_INFO "Total of %d processors activated (%lu.%02lu 
BogoMIPS).\n",
-                       cpucount+1,
-                       bogosum/(500000/HZ),
-                       (bogosum/(5000/HZ))%100);
-               Dprintk("Before bogocount - setting activated=1.\n");
+       if (smp_sanity_check(max_cpus) < 0) {
+               printk(KERN_INFO "SMP disabled\n");
+               disable_smp();
+               return;
        }
 
+
        /*
-        * Construct cpu_sibling_map[], so that we can tell the
-        * sibling CPU efficiently.
+        * Switch from PIC to APIC mode.
         */
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
-               cpus_clear(cpu_sibling_map[cpu]);
-
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
-               int siblings = 0;
-               int i;
-               if (!cpu_isset(cpu, cpu_callout_map))
-                       continue;
-
-               if (smp_num_siblings > 1) {
-                       for (i = 0; i < NR_CPUS; i++) {
-                               if (!cpu_isset(i, cpu_callout_map))
-                                       continue;
-                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
-                                       siblings++;
-                                       cpu_set(i, cpu_sibling_map[cpu]);
-                               }
-                       }
-               } else { 
-                       siblings++;
-                       cpu_set(cpu, cpu_sibling_map[cpu]);
-               }
+       connect_bsp_APIC();
+       setup_local_APIC();
 
-               if (siblings != smp_num_siblings) {
-                       printk(KERN_WARNING 
-              "WARNING: %d siblings found for CPU%d, should be %d\n", 
-                              siblings, cpu, smp_num_siblings);
-                       smp_num_siblings = siblings;
-               }       
+       if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) {
+               panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
+                     GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id);
+               /* Or can we switch back to PIC here? */
        }
-
-       Dprintk("Boot done.\n");
+       x86_cpu_to_apicid[0] = boot_cpu_id;
 
        /*
-        * Here we can be sure that there is an IO-APIC in the system. Let's
-        * go and set it up:
+        * Now start the IO-APICs
         */
        if (!skip_ioapic_setup && nr_ioapics)
                setup_IO_APIC();
        else
                nr_ioapics = 0;
 
-       setup_boot_APIC_clock();
-
        /*
-        * Synchronize the TSC with the AP
+        * Set up local APIC timer on boot CPU.
         */
-       if (cpu_has_tsc && cpucount)
-               synchronize_tsc_bp();
 
- smp_done:
-       time_init_smp();
+       setup_boot_APIC_clock();
 }
 
-/* These are wrappers to interface to the new boot process.  Someone
-   who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */
-void __init smp_prepare_cpus(unsigned int max_cpus)
+/*
+ * Early setup to make printk work.
+ */
+void __init smp_prepare_boot_cpu(void)
 {
-       smp_boot_cpus(max_cpus);
+       int me = smp_processor_id();
+       cpu_set(me, cpu_online_map);
+       cpu_set(me, cpu_callout_map);
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+/*
+ * Entry point to boot a CPU.
+ *
+ * This is all __cpuinit, not __devinit for now because we don't support
+ * CPU hotplug (yet).
+ */
+int __cpuinit __cpu_up(unsigned int cpu)
 {
-       cpu_set(smp_processor_id(), cpu_online_map);
-       cpu_set(smp_processor_id(), cpu_callout_map);
-}
+       int err;
+       int apicid = cpu_present_to_apicid(cpu);
 
-int __devinit __cpu_up(unsigned int cpu)
-{
-       /* This only works at boot for x86.  See "rewrite" above. */
-       if (cpu_isset(cpu, smp_commenced_mask)) {
-               local_irq_enable();
-               return -ENOSYS;
+       WARN_ON(irqs_disabled());
+
+       Dprintk("++++++++++++++++++++=_---CPU UP  %u\n", cpu);
+
+       if (apicid == BAD_APICID || apicid == boot_cpu_id ||
+           !physid_isset(apicid, phys_cpu_present_map)) {
+               printk("__cpu_up: bad cpu %d\n", cpu);
+               return -EINVAL;
        }
+       sync_tsc_bp_init(1);
 
-       /* In case one didn't come up */
-       if (!cpu_isset(cpu, cpu_callin_map)) {
-               local_irq_enable();
-               return -EIO;
+       /* Boot it! */
+       err = do_boot_cpu(cpu, apicid);
+       if (err < 0) {
+               sync_tsc_bp_init(0);
+               Dprintk("do_boot_cpu failed %d\n", err);
+               return err;
        }
-       local_irq_enable();
+
+       sync_tsc_bp(cpu);
 
        /* Unleash the CPU! */
        Dprintk("waiting for cpu %d\n", cpu);
 
-       cpu_set(cpu, smp_commenced_mask);
        while (!cpu_isset(cpu, cpu_online_map))
-               mb();
+               cpu_relax();
        return 0;
 }
 
-void __init smp_cpus_done(unsigned int max_cpus)
+/*
+ * Finish the SMP boot.
+ */
+void __cpuinit smp_cpus_done(unsigned int max_cpus)
 {
+       zap_low_mappings();
+       smp_cleanup_boot();
+
 #ifdef CONFIG_X86_IO_APIC
        setup_ioapic_dest();
 #endif
-       zap_low_mappings();
-}
 
+       detect_siblings();
+       time_init_gtod();
+}
diff -urN linux/arch/x86_64/kernel/time.c linux/arch/x86_64/kernel/time.c
--- linux/arch/x86_64/kernel/time.c     2005/04/08 18:58:07     1.35
+++ linux/arch/x86_64/kernel/time.c     2005/04/29 11:15:05     1.36
@@ -614,6 +614,9 @@
         struct cpufreq_freqs *freq = data;
        unsigned long *lpj, dummy;
 
+       if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
+               return 0;
+
        lpj = &dummy;
        if (!(freq->flags & CPUFREQ_CONST_LOOPS))
 #ifdef CONFIG_SMP
@@ -622,8 +625,6 @@
        lpj = &boot_cpu_data.loops_per_jiffy;
 #endif
 
-
-
        if (!ref_freq) {
                ref_freq = freq->old;
                loops_per_jiffy_ref = *lpj;
@@ -915,9 +916,16 @@
        setup_irq(0, &irq0);
 
        set_cyc2ns_scale(cpu_khz / 1000);
+
+#ifndef CONFIG_SMP
+       time_init_gtod();
+#endif
 }
 
-void __init time_init_smp(void)
+/*
+ * Decide after all CPUs are booted what mode gettimeofday should use.
+ */
+void __init time_init_gtod(void)
 {
        char *timetype;
 
@@ -957,7 +965,7 @@
 static long clock_cmos_diff;
 static unsigned long sleep_start;
 
-static int timer_suspend(struct sys_device *dev, u32 state)
+static int timer_suspend(struct sys_device *dev, pm_message_t state)
 {
        /*
         * Estimate time zone so that set_time can update the clock
diff -urN linux/arch/x86_64/kernel/traps.c linux/arch/x86_64/kernel/traps.c
--- linux/arch/x86_64/kernel/traps.c    2005/04/08 18:58:07     1.42
+++ linux/arch/x86_64/kernel/traps.c    2005/04/29 11:15:05     1.43
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/nmi.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -119,95 +120,106 @@
 } 
 #endif
 
-unsigned long *in_exception_stack(int cpu, unsigned long stack) 
-{ 
-       int k;
+static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
+                                       unsigned *usedp, const char **idp)
+{
+       static const char ids[N_EXCEPTION_STACKS][8] = {
+               [DEBUG_STACK - 1] = "#DB",
+               [NMI_STACK - 1] = "NMI",
+               [DOUBLEFAULT_STACK - 1] = "#DF",
+               [STACKFAULT_STACK - 1] = "#SS",
+               [MCE_STACK - 1] = "#MC",
+       };
+       unsigned k;
+
        for (k = 0; k < N_EXCEPTION_STACKS; k++) {
-               struct tss_struct *tss = &per_cpu(init_tss, cpu);
-               unsigned long start = tss->ist[k] - EXCEPTION_STKSZ;
+               unsigned long end;
 
-               if (stack >= start && stack < tss->ist[k])
-                       return (unsigned long *)tss->ist[k];
+               end = per_cpu(init_tss, cpu).ist[k];
+               if (stack >= end)
+                       continue;
+               if (stack >= end - EXCEPTION_STKSZ) {
+                       if (*usedp & (1U << k))
+                               break;
+                       *usedp |= 1U << k;
+                       *idp = ids[k];
+                       return (unsigned long *)end;
+               }
        }
        return NULL;
-} 
+}
 
 /*
  * x86-64 can have upto three kernel stacks: 
  * process stack
  * interrupt stack
- * severe exception (double fault, nmi, stack fault) hardware stack
- * Check and process them in order.
+ * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
  */
 
 void show_trace(unsigned long *stack)
 {
        unsigned long addr;
-       unsigned long *irqstack, *irqstack_end, *estack_end;
-       const int cpu = safe_smp_processor_id();
+       const unsigned cpu = safe_smp_processor_id();
+       unsigned long *irqstack_end = (unsigned long *)cpu_pda[cpu].irqstackptr;
        int i;
+       unsigned used = 0;
 
        printk("\nCall Trace:");
-       i = 0; 
-       
-       estack_end = in_exception_stack(cpu, (unsigned long)stack); 
-       if (estack_end) { 
-               while (stack < estack_end) { 
-                       addr = *stack++; 
-                       if (__kernel_text_address(addr)) {
-                               i += printk_address(addr);
-                               i += printk(" "); 
-                               if (i > 50) {
-                                       printk("\n"); 
-                                       i = 0;
-                               }
-                       }
+
+#define HANDLE_STACK(cond) \
+       do while (cond) { \
+               addr = *stack++; \
+               if (kernel_text_address(addr)) { \
+                       /* \
+                        * If the address is either in the text segment of the \
+                        * kernel, or in the region which contains vmalloc'ed \
+                        * memory, it *may* be the address of a calling \
+                        * routine; if so, print it so that someone tracing \
+                        * down the cause of the crash will be able to figure \
+                        * out the call path that was taken. \
+                        */ \
+                       i += printk_address(addr); \
+                       if (i > 50) { \
+                               printk("\n       "); \
+                               i = 0; \
+                       } \
+                       else \
+                               i += printk(" "); \
+               } \
+       } while (0)
+
+       for(i = 0; ; ) {
+               const char *id;
+               unsigned long *estack_end;
+               estack_end = in_exception_stack(cpu, (unsigned long)stack,
+                                               &used, &id);
+
+               if (estack_end) {
+                       i += printk(" <%s> ", id);
+                       HANDLE_STACK (stack < estack_end);
+                       i += printk(" <EOE> ");
+                       stack = (unsigned long *) estack_end[-2];
+                       continue;
                }
-               i += printk(" <EOE> "); 
-               i += 7;
-               stack = (unsigned long *) estack_end[-2]; 
-       }  
-
-       irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr);
-       irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE + 
64);
-
-       if (stack >= irqstack && stack < irqstack_end) {
-               printk("<IRQ> ");  
-               while (stack < irqstack_end) {
-                       addr = *stack++;
-                       /*
-                        * If the address is either in the text segment of the
-                        * kernel, or in the region which contains vmalloc'ed
-                        * memory, it *may* be the address of a calling
-                        * routine; if so, print it so that someone tracing
-                        * down the cause of the crash will be able to figure
-                        * out the call path that was taken.
-                        */
-                        if (__kernel_text_address(addr)) {
-                                i += printk_address(addr);
-                                i += printk(" "); 
-                                if (i > 50) { 
-                                       printk("\n       ");
-                                        i = 0;
-                                } 
+               if (irqstack_end) {
+                       unsigned long *irqstack;
+                       irqstack = irqstack_end -
+                               (IRQSTACKSIZE - 64) / sizeof(*irqstack);
+
+                       if (stack >= irqstack && stack < irqstack_end) {
+                               i += printk(" <IRQ> ");
+                               HANDLE_STACK (stack < irqstack_end);
+                               stack = (unsigned long *) (irqstack_end[-1]);
+                               irqstack_end = NULL;
+                               i += printk(" <EOI> ");
+                               continue;
                        }
-               } 
-               stack = (unsigned long *) (irqstack_end[-1]);
-               printk(" <EOI> ");
-               i += 7;
-       } 
-
-       while (((long) stack & (THREAD_SIZE-1)) != 0) {
-               addr = *stack++;
-               if (__kernel_text_address(addr)) {
-                       i += printk_address(addr);
-                       i += printk(" "); 
-                       if (i > 50) { 
-                               printk("\n       ");
-                                        i = 0;
-                       } 
                }
+               break;
        }
+
+       HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
+#undef HANDLE_STACK
        printk("\n");
 }
 
@@ -243,6 +255,7 @@
                if (i && ((i % 4) == 0))
                        printk("\n       ");
                printk("%016lx ", *stack++);
+               touch_nmi_watchdog();
        }
        show_trace((unsigned long *)rsp);
 }
@@ -486,24 +499,8 @@
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
 DO_ERROR(18, SIGSEGV, "reserved", reserved)
-
-#define DO_ERROR_STACK(trapnr, signr, str, name) \
-asmlinkage void *do_##name(struct pt_regs * regs, long error_code) \
-{ \
-       struct pt_regs *pr = ((struct pt_regs *)(current->thread.rsp0))-1; \
-       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-                                                       == NOTIFY_STOP) \
-               return regs; \
-       if (regs->cs & 3) { \
-               memcpy(pr, regs, sizeof(struct pt_regs)); \
-               regs = pr; \
-       } \
-       do_trap(trapnr, signr, str, regs, error_code, NULL); \
-       return regs;            \
-}
-
-DO_ERROR_STACK(12, SIGBUS,  "stack segment", stack_segment)
-DO_ERROR_STACK( 8, SIGSEGV, "double fault", double_fault)
+DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
+DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
 
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
@@ -582,6 +579,8 @@
        printk("Do you have a strange power saving mode enabled?\n");
 }
 
+/* Runs on IST stack. This code must keep interrupts off all the time.
+   Nested NMIs are prevented by the CPU. */
 asmlinkage void default_do_nmi(struct pt_regs *regs)
 {
        unsigned char reason = 0;
@@ -627,20 +626,34 @@
        return;
 }
 
+/* Help handler running on IST stack to switch back to user stack
+   for scheduling or signal handling. The actual stack switch is done in
+   entry.S */
+asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs)
+{
+       struct pt_regs *regs = eregs;
+       /* Did already sync */
+       if (eregs == (struct pt_regs *)eregs->rsp)
+               ;
+       /* Exception from user space */
+       else if (eregs->cs & 3)
+               regs = ((struct pt_regs *)current->thread.rsp0) - 1;
+       /* Exception from kernel and interrupts are enabled. Move to
+          kernel process stack. */
+       else if (eregs->eflags & X86_EFLAGS_IF)
+               regs = (struct pt_regs *)(eregs->rsp -= sizeof(struct pt_regs));
+       if (eregs != regs)
+               *regs = *eregs;
+       return regs;
+}
+
 /* runs on IST stack. */
-asmlinkage void *do_debug(struct pt_regs * regs, unsigned long error_code)
+asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
 {
-       struct pt_regs *pr;
        unsigned long condition;
        struct task_struct *tsk = current;
        siginfo_t info;
 
-       pr = (struct pt_regs *)(current->thread.rsp0)-1;
-       if (regs->cs & 3) {
-               memcpy(pr, regs, sizeof(struct pt_regs));
-               regs = pr;
-       }       
-
 #ifdef CONFIG_CHECKING
        { 
               /* RED-PEN interaction with debugger - could destroy gs */
@@ -657,9 +670,9 @@
        asm("movq %%db6,%0" : "=r" (condition));
 
        if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
-                                               SIGTRAP) == NOTIFY_STOP) {
-               return regs;
-       }
+                                               SIGTRAP) == NOTIFY_STOP)
+               return;
+
        conditional_sti(regs);
 
        /* Mask out spurious debug traps due to lazy DR7 setting */
@@ -672,9 +685,7 @@
        tsk->thread.debugreg6 = condition;
 
        /* Mask out spurious TF errors due to lazy TF clearing */
-       if ((condition & DR_STEP) &&
-           (notify_die(DIE_DEBUGSTEP, "debugstep", regs, condition,
-                       1, SIGTRAP) != NOTIFY_STOP)) {
+       if (condition & DR_STEP) {
                /*
                 * The TF error should be masked out only if the current
                 * process is not traced and if the TRAP flag has been set
@@ -686,8 +697,14 @@
                 */
                 if ((regs->cs & 3) == 0)
                        goto clear_TF_reenable;
-               if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
-                       goto clear_TF;
+               /*
+                * Was the TF flag set by a debugger? If so, clear it now,
+                * so that register information is correct.
+                */
+               if (tsk->ptrace & PT_DTRACE) {
+                       regs->eflags &= ~TF_MASK;
+                       tsk->ptrace &= ~PT_DTRACE;
+               }
        }
 
        /* Ok, finally something we can handle */
@@ -703,18 +720,11 @@
        force_sig_info(SIGTRAP, &info, tsk);    
 clear_dr7:
        asm volatile("movq %0,%%db7"::"r"(0UL));
-       notify_die(DIE_DEBUG, "debug", regs, condition, 1, SIGTRAP);
-       return regs;
+       return;
 
 clear_TF_reenable:
        set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
-
-clear_TF:
-       /* RED-PEN could cause spurious errors */
-       if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP) 
-                                                               != NOTIFY_STOP)
        regs->eflags &= ~TF_MASK;
-       return regs;    
 }
 
 static int kernel_math_error(struct pt_regs *regs, char *str)
@@ -726,14 +736,8 @@
                return 1;
        }
        notify_die(DIE_GPF, str, regs, 0, 16, SIGFPE);
-#if 0
-       /* This should be a die, but warn only for now */
+       /* Illegal floating point operation in the kernel */
        die(str, regs, 0);
-#else
-       printk(KERN_DEBUG "%s: %s at ", current->comm, str);
-       printk_address(regs->rip);
-       printk("\n");
-#endif
        return 0;
 }
 
@@ -817,7 +821,7 @@
 
        conditional_sti(regs);
        if ((regs->cs & 3) == 0 &&
-               kernel_math_error(regs, "simd math error"))
+               kernel_math_error(regs, "kernel simd math error"))
                return;
 
        /*
diff -urN linux/arch/x86_64/mm/fault.c linux/arch/x86_64/mm/fault.c
--- linux/arch/x86_64/mm/fault.c        2005/01/25 04:28:09     1.27
+++ linux/arch/x86_64/mm/fault.c        2005/04/29 11:15:05     1.28
@@ -62,21 +62,19 @@
 static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
                                unsigned long error_code)
 { 
-       unsigned char *instr = (unsigned char *)(regs->rip);
+       unsigned char *instr;
        int scan_more = 1;
        int prefetch = 0; 
-       unsigned char *max_instr = instr + 15;
+       unsigned char *max_instr;
 
        /* If it was a exec fault ignore */
        if (error_code & (1<<4))
                return 0;
        
-       /* Code segments in LDT could have a non zero base. Don't check
-          when that's possible */
-       if (regs->cs & (1<<2))
-               return 0;
+       instr = (unsigned char *)convert_rip_to_linear(current, regs);
+       max_instr = instr + 15;
 
-       if ((regs->cs & 3) != 0 && regs->rip >= TASK_SIZE)
+       if ((regs->cs & 3) != 0 && instr >= (unsigned char *)TASK_SIZE)
                return 0;
 
        while (scan_more && instr < max_instr) { 
@@ -458,17 +456,6 @@
        up_read(&mm->mmap_sem);
 
 bad_area_nosemaphore:
-
-#ifdef CONFIG_IA32_EMULATION
-       /* 32bit vsyscall. map on demand. */
-       if (test_thread_flag(TIF_IA32) &&
-           address >= VSYSCALL32_BASE && address < VSYSCALL32_END) {
-               if (map_syscall32(mm, address) < 0)
-                       goto out_of_memory2;
-               return;
-       }
-#endif
-
        /* User mode accesses just cause a SIGSEGV */
        if (error_code & 4) {
                if (is_prefetch(regs, address, error_code))
@@ -550,7 +537,6 @@
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-out_of_memory2:
        if (current->pid == 1) { 
                yield();
                goto again;
diff -urN linux/arch/x86_64/mm/init.c linux/arch/x86_64/mm/init.c
--- linux/arch/x86_64/mm/init.c 2005/01/25 04:28:09     1.31
+++ linux/arch/x86_64/mm/init.c 2005/04/29 11:15:05     1.32
@@ -583,9 +583,9 @@
 __initcall(x8664_sysctl_init);
 #endif
 
-/* Pseudo VMAs to allow ptrace access for the vsyscall pages.  x86-64 has two
-   different ones: one for 32bit and one for 64bit. Use the appropiate
-   for the target task. */
+/* A pseudo VMAs to allow ptrace access for the vsyscall page.   This only
+   covers the 64bit vsyscall page now. 32bit has a real VMA now and does
+   not need special handling anymore. */
 
 static struct vm_area_struct gate_vma = {
        .vm_start = VSYSCALL_START,
@@ -593,22 +593,11 @@
        .vm_page_prot = PAGE_READONLY
 };
 
-static struct vm_area_struct gate32_vma = {
-       .vm_start = VSYSCALL32_BASE,
-       .vm_end = VSYSCALL32_END,
-       .vm_page_prot = PAGE_READONLY
-};
-
 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
 {
 #ifdef CONFIG_IA32_EMULATION
-       if (test_tsk_thread_flag(tsk, TIF_IA32)) {
-               /* lookup code assumes the pages are present. set them up
-                  now */
-               if (__map_syscall32(tsk->mm, VSYSCALL32_BASE) < 0)
-                       return NULL;
-               return &gate32_vma;
-       }
+       if (test_tsk_thread_flag(tsk, TIF_IA32))
+               return NULL;
 #endif
        return &gate_vma;
 }
@@ -616,6 +605,8 @@
 int in_gate_area(struct task_struct *task, unsigned long addr)
 {
        struct vm_area_struct *vma = get_gate_vma(task);
+       if (!vma)
+               return 0;
        return (addr >= vma->vm_start) && (addr < vma->vm_end);
 }
 
@@ -625,6 +616,5 @@
  */
 int in_gate_area_no_task(unsigned long addr)
 {
-       return (((addr >= VSYSCALL_START) && (addr < VSYSCALL_END)) ||
-               ((addr >= VSYSCALL32_BASE) && (addr < VSYSCALL32_END)));
+       return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
 }
diff -urN linux/crypto/deflate.c linux/crypto/deflate.c
--- linux/crypto/deflate.c      2004/07/20 20:21:18     1.3
+++ linux/crypto/deflate.c      2005/04/29 11:15:05     1.4
@@ -93,11 +93,13 @@
 
 static void deflate_comp_exit(struct deflate_ctx *ctx)
 {
+       zlib_deflateEnd(&ctx->comp_stream);
        vfree(ctx->comp_stream.workspace);
 }
 
 static void deflate_decomp_exit(struct deflate_ctx *ctx)
 {
+       zlib_inflateEnd(&ctx->decomp_stream);
        kfree(ctx->decomp_stream.workspace);
 }
 
diff -urN linux/drivers/base/class.c linux/drivers/base/class.c
--- linux/drivers/base/class.c  2005/03/18 17:37:09     1.32
+++ linux/drivers/base/class.c  2005/04/29 11:15:05     1.33
@@ -430,6 +430,7 @@
                sysfs_create_link(&class_dev->kobj,
                                  &class_dev->dev->kobj, "device");
 
+       kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
  register_done:
        if (error && parent)
                class_put(parent);
@@ -461,6 +462,7 @@
                sysfs_remove_link(&class_dev->kobj, "device");
        class_device_remove_attrs(class_dev);
 
+       kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
        kobject_del(&class_dev->kobj);
 
        if (parent)
diff -urN linux/drivers/base/core.c linux/drivers/base/core.c
--- linux/drivers/base/core.c   2004/11/15 11:49:24     1.40
+++ linux/drivers/base/core.c   2005/04/29 11:15:05     1.41
@@ -260,6 +260,8 @@
        /* notify platform of device entry */
        if (platform_notify)
                platform_notify(dev);
+
+       kobject_hotplug(&dev->kobj, KOBJ_ADD);
  Done:
        put_device(dev);
        return error;
@@ -349,6 +351,7 @@
                platform_notify_remove(dev);
        bus_remove_device(dev);
        device_pm_remove(dev);
+       kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
        if (parent)
                put_device(parent);
diff -urN linux/drivers/base/firmware_class.c 
linux/drivers/base/firmware_class.c
--- linux/drivers/base/firmware_class.c 2004/12/04 18:16:02     1.13
+++ linux/drivers/base/firmware_class.c 2005/04/29 11:15:05     1.14
@@ -102,6 +102,9 @@
        if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
                        "FIRMWARE=%s", fw_priv->fw_id))
                return -ENOMEM;
+       if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+                       "TIMEOUT=%i", loading_timeout))
+               return -ENOMEM;
 
        envp[i] = NULL;
 
diff -urN linux/drivers/base/platform.c linux/drivers/base/platform.c
--- linux/drivers/base/platform.c       2005/03/18 17:37:09     1.17
+++ linux/drivers/base/platform.c       2005/04/29 11:15:05     1.18
@@ -341,6 +341,7 @@
 
 EXPORT_SYMBOL_GPL(platform_bus);
 EXPORT_SYMBOL_GPL(platform_bus_type);
+EXPORT_SYMBOL_GPL(platform_add_devices);
 EXPORT_SYMBOL_GPL(platform_device_register);
 EXPORT_SYMBOL_GPL(platform_device_register_simple);
 EXPORT_SYMBOL_GPL(platform_device_unregister);
diff -urN linux/drivers/base/sys.c linux/drivers/base/sys.c
--- linux/drivers/base/sys.c    2005/03/18 17:37:09     1.21
+++ linux/drivers/base/sys.c    2005/04/29 11:15:05     1.22
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/pm.h>
 
 
 extern struct subsystem devices_subsys;
@@ -302,7 +303,7 @@
  *     all synchronization.
  */
 
-int sysdev_suspend(u32 state)
+int sysdev_suspend(pm_message_t state)
 {
        struct sysdev_class * cls;
 
diff -urN linux/drivers/block/Kconfig linux/drivers/block/Kconfig
--- linux/drivers/block/Kconfig 2005/04/08 18:58:10     1.24
+++ linux/drivers/block/Kconfig 2005/04/29 11:15:05     1.25
@@ -6,7 +6,7 @@
 
 config BLK_DEV_FD
        tristate "Normal floppy disk support"
-       depends on (!ARCH_S390 && !M68K && !IA64 && !UML) || Q40 || (SUN3X && 
BROKEN)
+       depends on (!ARCH_S390 && !M68K && !IA64 && !UML) || Q40 || (SUN3X && 
BROKEN) || ARCH_RPC || ARCH_EBSA285
        ---help---
          If you want to use the floppy disk drive(s) of your PC under Linux,
          say Y. Information about this driver, especially important for IBM
diff -urN linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux/drivers/block/ll_rw_blk.c     2005/04/08 18:58:10     1.143
+++ linux/drivers/block/ll_rw_blk.c     2005/04/29 11:15:05     1.144
@@ -1589,7 +1589,8 @@
 
        spin_lock_irqsave(q->queue_lock, flags);
        blk_remove_plug(q);
-       q->request_fn(q);
+       if (!elv_queue_empty(q))
+               q->request_fn(q);
        spin_unlock_irqrestore(q->queue_lock, flags);
 }
 EXPORT_SYMBOL(blk_run_queue);
@@ -1714,6 +1715,15 @@
        if (blk_init_free_list(q))
                goto out_init;
 
+       /*
+        * if caller didn't supply a lock, they get per-queue locking with
+        * our embedded lock
+        */
+       if (!lock) {
+               spin_lock_init(&q->__queue_lock);
+               lock = &q->__queue_lock;
+       }
+
        q->request_fn           = rfn;
        q->back_merge_fn        = ll_back_merge_fn;
        q->front_merge_fn       = ll_front_merge_fn;
@@ -2559,7 +2569,7 @@
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
        struct request *req, *freereq = NULL;
-       int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err;
+       int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
        sector_t sector;
 
        sector = bio->bi_sector;
@@ -2567,6 +2577,7 @@
        cur_nr_sectors = bio_cur_sectors(bio);
 
        rw = bio_data_dir(bio);
+       sync = bio_sync(bio);
 
        /*
         * low level driver can indicate that it wants pages above a
@@ -2698,7 +2709,7 @@
 out:
        if (freereq)
                __blk_put_request(q, freereq);
-       if (bio_sync(bio))
+       if (sync)
                __generic_unplug_device(q);
 
        spin_unlock_irq(q->queue_lock);
diff -urN linux/drivers/block/scsi_ioctl.c linux/drivers/block/scsi_ioctl.c
--- linux/drivers/block/scsi_ioctl.c    2005/01/25 04:28:11     1.30
+++ linux/drivers/block/scsi_ioctl.c    2005/04/29 11:15:05     1.31
@@ -328,11 +328,6 @@
        return 0;
 }
 
-#define FORMAT_UNIT_TIMEOUT            (2 * 60 * 60 * HZ)
-#define START_STOP_TIMEOUT             (60 * HZ)
-#define MOVE_MEDIUM_TIMEOUT            (5 * 60 * HZ)
-#define READ_ELEMENT_STATUS_TIMEOUT    (5 * 60 * HZ)
-#define READ_DEFECT_DATA_TIMEOUT       (60 * HZ )
 #define OMAX_SB_LEN 16          /* For backward compatibility */
 
 static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
diff -urN linux/drivers/block/aoe/aoe.h linux/drivers/block/aoe/aoe.h
--- linux/drivers/block/aoe/aoe.h       2005/03/18 17:37:10     1.3
+++ linux/drivers/block/aoe/aoe.h       2005/04/29 11:15:05     1.4
@@ -1,10 +1,15 @@
 /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
-#define VERSION "5"
+#define VERSION "6"
 #define AOE_MAJOR 152
 #define DEVICE_NAME "aoe"
+
+/* set AOE_PARTITIONS to 1 to use whole-disks only
+ * default is 16, which is 15 partitions plus the whole disk
+ */
 #ifndef AOE_PARTITIONS
 #define AOE_PARTITIONS 16
 #endif
+
 #define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor))
 #define AOEMAJOR(sysminor) ((sysminor) / 10)
 #define AOEMINOR(sysminor) ((sysminor) % 10)
@@ -34,13 +39,13 @@
 struct aoe_hdr {
        unsigned char dst[6];
        unsigned char src[6];
-       unsigned char type[2];
+       __be16 type;
        unsigned char verfl;
        unsigned char err;
-       unsigned char major[2];
+       __be16 major;
        unsigned char minor;
        unsigned char cmd;
-       unsigned char tag[4];
+       __be32 tag;
 };
 
 struct aoe_atahdr {
@@ -58,8 +63,8 @@
 };
 
 struct aoe_cfghdr {
-       unsigned char bufcnt[2];
-       unsigned char fwver[2];
+       __be16 bufcnt;
+       __be16 fwver;
        unsigned char res;
        unsigned char aoeccmd;
        unsigned char cslen[2];
@@ -85,6 +90,7 @@
 
 struct buf {
        struct list_head bufs;
+       ulong start_time;       /* for disk stats */
        ulong flags;
        ulong nframesout;
        char *bufaddr;
@@ -125,7 +131,8 @@
        struct timer_list timer;
        spinlock_t lock;
        struct net_device *ifp; /* interface ed is attached to */
-       struct sk_buff *skblist;/* packets needing to be sent */
+       struct sk_buff *sendq_hd; /* packets needing to be sent, list head */
+       struct sk_buff *sendq_tl;
        mempool_t *bufpool;     /* for deadlock-free Buf allocation */
        struct list_head bufq;  /* queue of bios to work on */
        struct buf *inprocess;  /* the one we're currently working on */
@@ -151,7 +158,7 @@
 
 int aoedev_init(void);
 void aoedev_exit(void);
-struct aoedev *aoedev_bymac(unsigned char *);
+struct aoedev *aoedev_by_aoeaddr(int maj, int min);
 void aoedev_downdev(struct aoedev *d);
 struct aoedev *aoedev_set(ulong, unsigned char *, struct net_device *, ulong);
 int aoedev_busy(void);
diff -urN linux/drivers/block/aoe/aoeblk.c linux/drivers/block/aoe/aoeblk.c
--- linux/drivers/block/aoe/aoeblk.c    2005/03/18 17:37:10     1.4
+++ linux/drivers/block/aoe/aoeblk.c    2005/04/29 11:15:05     1.5
@@ -125,6 +125,7 @@
        }
        memset(buf, 0, sizeof(*buf));
        INIT_LIST_HEAD(&buf->bufs);
+       buf->start_time = jiffies;
        buf->bio = bio;
        buf->resid = bio->bi_size;
        buf->sector = bio->bi_sector;
@@ -146,8 +147,8 @@
        list_add_tail(&buf->bufs, &d->bufq);
        aoecmd_work(d);
 
-       sl = d->skblist;
-       d->skblist = NULL;
+       sl = d->sendq_hd;
+       d->sendq_hd = d->sendq_tl = NULL;
 
        spin_unlock_irqrestore(&d->lock, flags);
 
diff -urN linux/drivers/block/aoe/aoecmd.c linux/drivers/block/aoe/aoecmd.c
--- linux/drivers/block/aoe/aoecmd.c    2005/03/18 17:37:10     1.2
+++ linux/drivers/block/aoe/aoecmd.c    2005/04/29 11:15:05     1.3
@@ -90,19 +90,16 @@
 static int
 aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
 {
-       u16 type = __constant_cpu_to_be16(ETH_P_AOE);
-       u16 aoemajor = __cpu_to_be16(d->aoemajor);
        u32 host_tag = newtag(d);
-       u32 tag = __cpu_to_be32(host_tag);
 
        memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
        memcpy(h->dst, d->addr, sizeof h->dst);
-       memcpy(h->type, &type, sizeof type);
+       h->type = __constant_cpu_to_be16(ETH_P_AOE);
        h->verfl = AOE_HVER;
-       memcpy(h->major, &aoemajor, sizeof aoemajor);
+       h->major = cpu_to_be16(d->aoemajor);
        h->minor = d->aoeminor;
        h->cmd = AOECMD_ATA;
-       memcpy(h->tag, &tag, sizeof tag);
+       h->tag = cpu_to_be32(host_tag);
 
        return host_tag;
 }
@@ -181,8 +178,12 @@
 
        skb = skb_prepare(d, f);
        if (skb) {
-               skb->next = d->skblist;
-               d->skblist = skb;
+               skb->next = NULL;
+               if (d->sendq_hd)
+                       d->sendq_tl->next = skb;
+               else
+                       d->sendq_hd = skb;
+               d->sendq_tl = skb;
        }
 }
 
@@ -215,7 +216,6 @@
        struct aoe_hdr *h;
        char buf[128];
        u32 n;
-       u32 net_tag;
 
        n = newtag(d);
 
@@ -227,13 +227,16 @@
 
        h = (struct aoe_hdr *) f->data;
        f->tag = n;
-       net_tag = __cpu_to_be32(n);
-       memcpy(h->tag, &net_tag, sizeof net_tag);
+       h->tag = cpu_to_be32(n);
 
        skb = skb_prepare(d, f);
        if (skb) {
-               skb->next = d->skblist;
-               d->skblist = skb;
+               skb->next = NULL;
+               if (d->sendq_hd)
+                       d->sendq_tl->next = skb;
+               else
+                       d->sendq_hd = skb;
+               d->sendq_tl = skb;
        }
 }
 
@@ -285,8 +288,8 @@
                }
        }
 
-       sl = d->skblist;
-       d->skblist = NULL;
+       sl = d->sendq_hd;
+       d->sendq_hd = d->sendq_tl = NULL;
        if (sl) {
                n = d->rttavg <<= 1;
                if (n > MAXTIMER)
@@ -308,16 +311,16 @@
        u16 n;
 
        /* word 83: command set supported */
-       n = __le16_to_cpu(*((u16 *) &id[83<<1]));
+       n = le16_to_cpup((__le16 *) &id[83<<1]);
 
        /* word 86: command set/feature enabled */
-       n |= __le16_to_cpu(*((u16 *) &id[86<<1]));
+       n |= le16_to_cpup((__le16 *) &id[86<<1]);
 
        if (n & (1<<10)) {      /* bit 10: LBA 48 */
                d->flags |= DEVFL_EXT;
 
                /* word 100: number lba48 sectors */
-               ssize = __le64_to_cpu(*((u64 *) &id[100<<1]));
+               ssize = le64_to_cpup((__le64 *) &id[100<<1]);
 
                /* set as in ide-disk.c:init_idedisk_capacity */
                d->geo.cylinders = ssize;
@@ -328,12 +331,12 @@
                d->flags &= ~DEVFL_EXT;
 
                /* number lba28 sectors */
-               ssize = __le32_to_cpu(*((u32 *) &id[60<<1]));
+               ssize = le32_to_cpup((__le32 *) &id[60<<1]);
 
                /* NOTE: obsolete in ATA 6 */
-               d->geo.cylinders = __le16_to_cpu(*((u16 *) &id[54<<1]));
-               d->geo.heads = __le16_to_cpu(*((u16 *) &id[55<<1]));
-               d->geo.sectors = __le16_to_cpu(*((u16 *) &id[56<<1]));
+               d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
+               d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
+               d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
        }
        d->ssize = ssize;
        d->geo.start = 0;
@@ -380,29 +383,30 @@
        register long n;
        ulong flags;
        char ebuf[128];
-       
+       u16 aoemajor;
+
        hin = (struct aoe_hdr *) skb->mac.raw;
-       d = aoedev_bymac(hin->src);
+       aoemajor = be16_to_cpu(hin->major);
+       d = aoedev_by_aoeaddr(aoemajor, hin->minor);
        if (d == NULL) {
                snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
                        "for unknown device %d.%d\n",
-                        __be16_to_cpu(*((u16 *) hin->major)),
-                       hin->minor);
+                        aoemajor, hin->minor);
                aoechr_error(ebuf);
                return;
        }
 
        spin_lock_irqsave(&d->lock, flags);
 
-       f = getframe(d, __be32_to_cpu(*((u32 *) hin->tag)));
+       f = getframe(d, be32_to_cpu(hin->tag));
        if (f == NULL) {
                spin_unlock_irqrestore(&d->lock, flags);
                snprintf(ebuf, sizeof ebuf,
                        "%15s e%d.%d    tag=%08x@%08lx\n",
                        "unexpected rsp",
-                       __be16_to_cpu(*((u16 *) hin->major)),
+                       be16_to_cpu(hin->major),
                        hin->minor,
-                       __be32_to_cpu(*((u32 *) hin->tag)),
+                       be32_to_cpu(hin->tag),
                        jiffies);
                aoechr_error(ebuf);
                return;
@@ -452,7 +456,7 @@
                        printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
                               "outbound ata command %2.2Xh for %d.%d\n", 
                               ahout->cmdstat,
-                              __be16_to_cpu(*((u16 *) hin->major)),
+                              be16_to_cpu(hin->major),
                               hin->minor);
                }
        }
@@ -460,6 +464,20 @@
        if (buf) {
                buf->nframesout -= 1;
                if (buf->nframesout == 0 && buf->resid == 0) {
+                       unsigned long duration = jiffies - buf->start_time;
+                       unsigned long n_sect = buf->bio->bi_size >> 9;
+                       struct gendisk *disk = d->gd;
+
+                       if (bio_data_dir(buf->bio) == WRITE) {
+                               disk_stat_inc(disk, writes);
+                               disk_stat_add(disk, write_ticks, duration);
+                               disk_stat_add(disk, write_sectors, n_sect);
+                       } else {
+                               disk_stat_inc(disk, reads);
+                               disk_stat_add(disk, read_ticks, duration);
+                               disk_stat_add(disk, read_sectors, n_sect);
+                       }
+                       disk_stat_add(disk, io_ticks, duration);
                        n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
                        bio_endio(buf->bio, buf->bio->bi_size, n);
                        mempool_free(buf, d->bufpool);
@@ -471,8 +489,8 @@
 
        aoecmd_work(d);
 
-       sl = d->skblist;
-       d->skblist = NULL;
+       sl = d->sendq_hd;
+       d->sendq_hd = d->sendq_tl = NULL;
 
        spin_unlock_irqrestore(&d->lock, flags);
 
@@ -486,8 +504,6 @@
        struct aoe_cfghdr *ch;
        struct sk_buff *skb, *sl;
        struct net_device *ifp;
-       u16 aoe_type = __constant_cpu_to_be16(ETH_P_AOE);
-       u16 net_aoemajor = __cpu_to_be16(aoemajor);
 
        sl = NULL;
 
@@ -507,9 +523,9 @@
 
                memset(h->dst, 0xff, sizeof h->dst);
                memcpy(h->src, ifp->dev_addr, sizeof h->src);
-               memcpy(h->type, &aoe_type, sizeof aoe_type);
+               h->type = __constant_cpu_to_be16(ETH_P_AOE);
                h->verfl = AOE_HVER;
-               memcpy(h->major, &net_aoemajor, sizeof net_aoemajor);
+               h->major = cpu_to_be16(aoemajor);
                h->minor = aoeminor;
                h->cmd = AOECMD_CFG;
 
@@ -523,7 +539,7 @@
  
 /*
  * Since we only call this in one place (and it only prepares one frame)
- * we just return the skb.  Usually we'd chain it up to the d->skblist.
+ * we just return the skb.  Usually we'd chain it up to the aoedev sendq.
  */
 static struct sk_buff *
 aoecmd_ata_id(struct aoedev *d)
@@ -575,9 +591,10 @@
        struct aoedev *d;
        struct aoe_hdr *h;
        struct aoe_cfghdr *ch;
-       ulong flags, bufcnt, sysminor, aoemajor;
+       ulong flags, sysminor, aoemajor;
+       u16 bufcnt;
        struct sk_buff *sl;
-       enum { MAXFRAMES = 8, MAXSYSMINOR = 255 };
+       enum { MAXFRAMES = 8 };
 
        h = (struct aoe_hdr *) skb->mac.raw;
        ch = (struct aoe_cfghdr *) (h+1);
@@ -586,7 +603,7 @@
         * Enough people have their dip switches set backwards to
         * warrant a loud message for this special case.
         */
-       aoemajor = __be16_to_cpu(*((u16 *) h->major));
+       aoemajor = be16_to_cpu(h->major);
        if (aoemajor == 0xfff) {
                printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
                        "address is all ones.  Check shelf dip switches\n");
@@ -594,13 +611,14 @@
        }
 
        sysminor = SYSMINOR(aoemajor, h->minor);
-       if (sysminor > MAXSYSMINOR) {
-               printk(KERN_INFO "aoe: aoecmd_cfg_rsp: sysminor %ld too "
-                       "large\n", sysminor);
+       if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
+               printk(KERN_INFO
+                       "aoe: e%ld.%d: minor number too large\n", 
+                       aoemajor, (int) h->minor);
                return;
        }
 
-       bufcnt = __be16_to_cpu(*((u16 *) ch->bufcnt));
+       bufcnt = be16_to_cpu(ch->bufcnt);
        if (bufcnt > MAXFRAMES) /* keep it reasonable */
                bufcnt = MAXFRAMES;
 
@@ -617,7 +635,7 @@
                return;
        }
 
-       d->fw_ver = __be16_to_cpu(*((u16 *) ch->fwver));
+       d->fw_ver = be16_to_cpu(ch->fwver);
 
        /* we get here only if the device is new */
        sl = aoecmd_ata_id(d);
diff -urN linux/drivers/block/aoe/aoedev.c linux/drivers/block/aoe/aoedev.c
--- linux/drivers/block/aoe/aoedev.c    2005/01/25 04:28:11     1.2
+++ linux/drivers/block/aoe/aoedev.c    2005/04/29 11:15:05     1.3
@@ -13,7 +13,7 @@
 static spinlock_t devlist_lock;
 
 struct aoedev *
-aoedev_bymac(unsigned char *macaddr)
+aoedev_by_aoeaddr(int maj, int min)
 {
        struct aoedev *d;
        ulong flags;
@@ -21,7 +21,7 @@
        spin_lock_irqsave(&devlist_lock, flags);
 
        for (d=devlist; d; d=d->next)
-               if (!memcmp(d->addr, macaddr, 6))
+               if (d->aoemajor == maj && d->aoeminor == min)
                        break;
 
        spin_unlock_irqrestore(&devlist_lock, flags);
@@ -125,7 +125,6 @@
        d->ifp = ifp;
 
        if (d->sysminor != sysminor
-       || memcmp(d->addr, addr, sizeof d->addr)
        || (d->flags & DEVFL_UP) == 0) {
                aoedev_downdev(d); /* flushes outstanding frames */
                memcpy(d->addr, addr, sizeof d->addr);
@@ -147,7 +146,8 @@
                put_disk(d->gd);
        }
        kfree(d->frames);
-       mempool_destroy(d->bufpool);
+       if (d->bufpool)
+               mempool_destroy(d->bufpool);
        kfree(d);
 }
 
diff -urN linux/drivers/block/aoe/aoenet.c linux/drivers/block/aoe/aoenet.c
--- linux/drivers/block/aoe/aoenet.c    2005/01/25 04:28:11     1.2
+++ linux/drivers/block/aoe/aoenet.c    2005/04/29 11:15:05     1.3
@@ -69,7 +69,7 @@
 u64
 mac_addr(char addr[6])
 {
-       u64 n = 0;
+       __be64 n = 0;
        char *p = (char *) &n;
 
        memcpy(p + 2, addr, 6); /* (sizeof addr != 6) */
@@ -108,7 +108,7 @@
 aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
 {
        struct aoe_hdr *h;
-       ulong n;
+       u32 n;
 
        skb = skb_check(skb);
        if (!skb)
@@ -121,7 +121,7 @@
        skb_push(skb, ETH_HLEN);        /* (1) */
 
        h = (struct aoe_hdr *) skb->mac.raw;
-       n = __be32_to_cpu(*((u32 *) h->tag));
+       n = be32_to_cpu(h->tag);
        if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
                goto exit;
 
@@ -132,7 +132,7 @@
                if (net_ratelimit())
                        printk(KERN_ERR "aoe: aoenet_rcv: error packet from 
%d.%d; "
                               "ecode=%d '%s'\n",
-                              __be16_to_cpu(*((u16 *) h->major)), h->minor, 
+                              be16_to_cpu(h->major), h->minor, 
                               h->err, aoe_errlist[n]);
                goto exit;
        }
diff -urN linux/drivers/char/mmtimer.c linux/drivers/char/mmtimer.c
--- linux/drivers/char/mmtimer.c        2005/03/18 17:37:11     1.6
+++ linux/drivers/char/mmtimer.c        2005/04/29 11:15:06     1.7
@@ -485,7 +485,7 @@
                goto out;
        t->it_overrun = 0;
 
-       if (tasklist_lock.write_lock || posix_timer_event(t, 0) != 0) {
+       if (posix_timer_event(t, 0) != 0) {
 
                // printk(KERN_WARNING "mmtimer: cannot deliver signal.\n");
 
diff -urN linux/drivers/char/random.c linux/drivers/char/random.c
--- linux/drivers/char/random.c 2005/03/18 17:37:11     1.64
+++ linux/drivers/char/random.c 2005/04/29 11:15:06     1.65
@@ -1,7 +1,7 @@
 /*
  * random.c -- A strong random number generator
  *
- * Version 1.89, last modified 19-Sep-99
+ * Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
  *
  * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All
  * rights reserved.
diff -urN linux/drivers/char/s3c2410-rtc.c linux/drivers/char/s3c2410-rtc.c
--- linux/drivers/char/s3c2410-rtc.c    2005/03/18 17:37:11     1.4
+++ linux/drivers/char/s3c2410-rtc.c    2005/04/29 11:15:06     1.5
@@ -515,7 +515,7 @@
 
 static int ticnt_save;
 
-static int s3c2410_rtc_suspend(struct device *dev, u32 state, u32 level)
+static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state, u32 
level)
 {
        struct rtc_time tm;
        struct timespec time;
diff -urN linux/drivers/char/sonypi.c linux/drivers/char/sonypi.c
--- linux/drivers/char/sonypi.c 2005/02/13 20:16:21     1.27
+++ linux/drivers/char/sonypi.c 2005/04/29 11:15:06     1.28
@@ -1103,7 +1103,7 @@
 #ifdef CONFIG_PM
 static int old_camera_power;
 
-static int sonypi_suspend(struct device *dev, u32 state, u32 level)
+static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        if (level == SUSPEND_DISABLE) {
                old_camera_power = sonypi_device.camera_power;
diff -urN linux/drivers/char/agp/efficeon-agp.c 
linux/drivers/char/agp/efficeon-agp.c
--- linux/drivers/char/agp/efficeon-agp.c       2005/03/18 17:37:12     1.4
+++ linux/drivers/char/agp/efficeon-agp.c       2005/04/29 11:15:06     1.5
@@ -408,7 +408,7 @@
        agp_put_bridge(bridge);
 }
 
-static int agp_efficeon_suspend(struct pci_dev *dev, u32 state)
+static int agp_efficeon_suspend(struct pci_dev *dev, pm_message_t state)
 {
        return 0;
 }
diff -urN linux/drivers/char/agp/uninorth-agp.c 
linux/drivers/char/agp/uninorth-agp.c
--- linux/drivers/char/agp/uninorth-agp.c       2005/03/18 17:37:12     1.6
+++ linux/drivers/char/agp/uninorth-agp.c       2005/04/29 11:15:06     1.7
@@ -10,6 +10,7 @@
 #include <asm/uninorth.h>
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
+#include <asm/pmac_feature.h>
 #include "agp.h"
 
 /*
@@ -26,6 +27,7 @@
 static int uninorth_rev;
 static int is_u3;
 
+
 static int uninorth_fetch_size(void)
 {
        int i;
@@ -264,7 +266,8 @@
                                       &scratch);
        } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000);
        if ((scratch & PCI_AGP_COMMAND_AGP) == 0)
-               printk(KERN_ERR PFX "failed to write UniNorth AGP command 
reg\n");
+               printk(KERN_ERR PFX "failed to write UniNorth AGP"
+                      " command register\n");
 
        if (uninorth_rev >= 0x30) {
                /* This is an AGP V3 */
@@ -278,13 +281,24 @@
 }
 
 #ifdef CONFIG_PM
-static int agp_uninorth_suspend(struct pci_dev *pdev, pm_message_t state)
+/*
+ * These Power Management routines are _not_ called by the normal PCI PM layer,
+ * but directly by the video driver through function pointers in the device
+ * tree.
+ */
+static int agp_uninorth_suspend(struct pci_dev *pdev)
 {
+       struct agp_bridge_data *bridge;
        u32 cmd;
        u8 agp;
        struct pci_dev *device = NULL;
 
-       if (state != PMSG_SUSPEND)
+       bridge = agp_find_bridge(pdev);
+       if (bridge == NULL)
+               return -ENODEV;
+
+       /* Only one suspend supported */
+       if (bridge->dev_private_data)
                return 0;
 
        /* turn off AGP on the video chip, if it was enabled */
@@ -315,6 +329,7 @@
        /* turn off AGP on the bridge */
        agp = pci_find_capability(pdev, PCI_CAP_ID_AGP);
        pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd);
+       bridge->dev_private_data = (void *)cmd;
        if (cmd & PCI_AGP_COMMAND_AGP) {
                printk("uninorth-agp: disabling AGP on bridge %s\n",
                                pci_name(pdev));
@@ -329,9 +344,23 @@
 
 static int agp_uninorth_resume(struct pci_dev *pdev)
 {
+       struct agp_bridge_data *bridge;
+       u32 command;
+
+       bridge = agp_find_bridge(pdev);
+       if (bridge == NULL)
+               return -ENODEV;
+
+       command = (u32)bridge->dev_private_data;
+       bridge->dev_private_data = NULL;
+       if (!(command & PCI_AGP_COMMAND_AGP))
+               return 0;
+
+       uninorth_agp_enable(bridge, command);
+
        return 0;
 }
-#endif
+#endif /* CONFIG_PM */
 
 static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 {
@@ -575,6 +604,12 @@
                of_node_put(uninorth_node);
        }
 
+#ifdef CONFIG_PM
+       /* Inform platform of our suspend/resume caps */
+       pmac_register_agp_pm(pdev, agp_uninorth_suspend, agp_uninorth_resume);
+#endif
+
+       /* Allocate & setup our driver */
        bridge = agp_alloc_bridge();
        if (!bridge)
                return -ENOMEM;
@@ -599,6 +634,11 @@
 {
        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
+#ifdef CONFIG_PM
+       /* Inform platform of our suspend/resume caps */
+       pmac_register_agp_pm(pdev, NULL, NULL);
+#endif
+
        agp_remove_bridge(bridge);
        agp_put_bridge(bridge);
 }
@@ -622,10 +662,6 @@
        .id_table       = agp_uninorth_pci_table,
        .probe          = agp_uninorth_probe,
        .remove         = agp_uninorth_remove,
-#ifdef CONFIG_PM
-       .suspend        = agp_uninorth_suspend,
-       .resume         = agp_uninorth_resume,
-#endif
 };
 
 static int __init agp_uninorth_init(void)
diff -urN linux/drivers/char/drm/r128_state.c 
linux/drivers/char/drm/r128_state.c
--- linux/drivers/char/drm/r128_state.c 2005/03/18 17:37:13     1.18
+++ linux/drivers/char/drm/r128_state.c 2005/04/29 11:15:06     1.19
@@ -1549,12 +1549,16 @@
        switch ( depth.func ) {
        case R128_WRITE_SPAN:
                ret = r128_cce_dispatch_write_span( dev, &depth );
+               break;
        case R128_WRITE_PIXELS:
                ret = r128_cce_dispatch_write_pixels( dev, &depth );
+               break;
        case R128_READ_SPAN:
                ret = r128_cce_dispatch_read_span( dev, &depth );
+               break;
        case R128_READ_PIXELS:
                ret = r128_cce_dispatch_read_pixels( dev, &depth );
+               break;
        }
 
        COMMIT_RING();
diff -urN linux/drivers/char/tpm/tpm.c linux/drivers/char/tpm/tpm.c
--- linux/drivers/char/tpm/tpm.c        2005/04/08 18:58:12     1.2
+++ linux/drivers/char/tpm/tpm.c        2005/04/29 11:15:06     1.3
@@ -567,7 +567,7 @@
  * We are about to suspend. Save the TPM state
  * so that it can be restored.
  */
-int tpm_pm_suspend(struct pci_dev *pci_dev, u32 pm_state)
+int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
 {
        struct tpm_chip *chip = pci_get_drvdata(pci_dev);
        if (chip == NULL)
diff -urN linux/drivers/char/tpm/tpm.h linux/drivers/char/tpm/tpm.h
--- linux/drivers/char/tpm/tpm.h        2005/04/08 18:58:12     1.2
+++ linux/drivers/char/tpm/tpm.h        2005/04/29 11:15:06     1.3
@@ -89,5 +89,5 @@
                         loff_t *);
 extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
 extern void __devexit tpm_remove(struct pci_dev *);
-extern int tpm_pm_suspend(struct pci_dev *, u32);
+extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
 extern int tpm_pm_resume(struct pci_dev *);
diff -urN linux/drivers/i2c/busses/Kconfig linux/drivers/i2c/busses/Kconfig
--- linux/drivers/i2c/busses/Kconfig    2005/04/08 18:58:13     1.27
+++ linux/drivers/i2c/busses/Kconfig    2005/04/29 11:15:06     1.28
@@ -123,6 +123,7 @@
            6300ESB
            ICH6
            ICH7
+           ESB2
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
diff -urN linux/drivers/i2c/busses/i2c-i801.c 
linux/drivers/i2c/busses/i2c-i801.c
--- linux/drivers/i2c/busses/i2c-i801.c 2005/01/25 04:28:14     1.14
+++ linux/drivers/i2c/busses/i2c-i801.c 2005/04/29 11:15:06     1.15
@@ -31,6 +31,7 @@
     6300ESB            25A4
     ICH6               266A
     ICH7               27DA
+    ESB2               269B
     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
     of Intel's '810' and other chipsets.
@@ -558,6 +559,7 @@
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
        { 0, }
 };
 
diff -urN linux/drivers/i2c/chips/it87.c linux/drivers/i2c/chips/it87.c
--- linux/drivers/i2c/chips/it87.c      2005/04/08 18:58:13     1.21
+++ linux/drivers/i2c/chips/it87.c      2005/04/29 11:15:06     1.22
@@ -668,7 +668,7 @@
        struct it87_data *data = it87_update_device(dev);
        return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
 }
-static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
 static ssize_t
 show_vrm_reg(struct device *dev, char *buf)
diff -urN linux/drivers/i2c/chips/via686a.c linux/drivers/i2c/chips/via686a.c
--- linux/drivers/i2c/chips/via686a.c   2005/04/08 18:58:13     1.21
+++ linux/drivers/i2c/chips/via686a.c   2005/04/29 11:15:06     1.22
@@ -574,7 +574,7 @@
        struct via686a_data *data = via686a_update_device(dev);
        return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
 }
-static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
 /* The driver. I choose to use type i2c_driver, as at is identical to both
    smbus_driver and isa_driver, and clients could be of either kind */
@@ -651,10 +651,9 @@
        new_client->adapter = adapter;
        new_client->driver = &via686a_driver;
        new_client->flags = 0;
-       new_client->dev.parent = &adapter->dev;
 
        /* Fill in the remaining client fields and put into the global list */
-       snprintf(new_client->name, I2C_NAME_SIZE, client_name);
+       strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 
        data->valid = 0;
        init_MUTEX(&data->update_lock);
diff -urN linux/drivers/ide/legacy/hd.c linux/drivers/ide/legacy/hd.c
--- linux/drivers/ide/legacy/hd.c       2005/01/25 04:28:15     1.19
+++ linux/drivers/ide/legacy/hd.c       2005/04/29 11:15:06     1.20
@@ -851,7 +851,7 @@
        goto out;
 }
 
-static int parse_hd_setup (char *line) {
+static int __init parse_hd_setup (char *line) {
        int ints[6];
 
        (void) get_options(line, ARRAY_SIZE(ints), ints);
diff -urN linux/drivers/ide/pci/piix.c linux/drivers/ide/pci/piix.c
--- linux/drivers/ide/pci/piix.c        2005/02/13 20:16:23     1.28
+++ linux/drivers/ide/pci/piix.c        2005/04/29 11:15:06     1.29
@@ -134,6 +134,7 @@
                case PCI_DEVICE_ID_INTEL_ESB_2:
                case PCI_DEVICE_ID_INTEL_ICH6_19:
                case PCI_DEVICE_ID_INTEL_ICH7_21:
+               case PCI_DEVICE_ID_INTEL_ESB2_18:
                        mode = 3;
                        break;
                /* UDMA 66 capable */
@@ -447,6 +448,7 @@
                case PCI_DEVICE_ID_INTEL_ESB_2:
                case PCI_DEVICE_ID_INTEL_ICH6_19:
                case PCI_DEVICE_ID_INTEL_ICH7_21:
+               case PCI_DEVICE_ID_INTEL_ESB2_18:
                {
                        unsigned int extra = 0;
                        pci_read_config_dword(dev, 0x54, &extra);
@@ -572,6 +574,7 @@
        /* 20 */ DECLARE_PIIX_DEV("ICH6"),
        /* 21 */ DECLARE_PIIX_DEV("ICH7"),
        /* 22 */ DECLARE_PIIX_DEV("ICH4"),
+       /* 23 */ DECLARE_PIIX_DEV("ESB2"),
 };
 
 /**
@@ -647,6 +650,7 @@
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, 
PCI_ANY_ID, 0, 0, 20},
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, 
PCI_ANY_ID, 0, 0, 21},
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, 
PCI_ANY_ID, 0, 0, 22},
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, 
PCI_ANY_ID, 0, 0, 23},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
diff -urN linux/drivers/ide/pci/sc1200.c linux/drivers/ide/pci/sc1200.c
--- linux/drivers/ide/pci/sc1200.c      2005/01/13 14:06:00     1.19
+++ linux/drivers/ide/pci/sc1200.c      2005/04/29 11:15:06     1.20
@@ -346,7 +346,7 @@
 } sc1200_saved_state_t;
 
 
-static int sc1200_suspend (struct pci_dev *dev, u32 state)
+static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
 {
        ide_hwif_t              *hwif = NULL;
 
diff -urN linux/drivers/infiniband/core/agent.c 
linux/drivers/infiniband/core/agent.c
--- linux/drivers/infiniband/core/agent.c       2005/03/18 17:37:19     1.2
+++ linux/drivers/infiniband/core/agent.c       2005/04/29 11:15:06     1.3
@@ -129,7 +129,6 @@
                goto out;
        agent_send_wr->mad = mad_priv;
 
-       /* PCI mapping */
        gather_list.addr = dma_map_single(mad_agent->device->dma_device,
                                          &mad_priv->mad,
                                          sizeof(mad_priv->mad),
@@ -261,7 +260,6 @@
        list_del(&agent_send_wr->send_list);
        spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
 
-       /* Unmap PCI */
        dma_unmap_single(mad_agent->device->dma_device,
                         pci_unmap_addr(agent_send_wr, mapping),
                         sizeof(agent_send_wr->mad->mad),
diff -urN linux/drivers/infiniband/core/fmr_pool.c 
linux/drivers/infiniband/core/fmr_pool.c
--- linux/drivers/infiniband/core/fmr_pool.c    2005/01/13 14:06:01     1.1
+++ linux/drivers/infiniband/core/fmr_pool.c    2005/04/29 11:15:06     1.2
@@ -103,9 +103,8 @@
 
 static inline u32 ib_fmr_hash(u64 first_page)
 {
-       return jhash_2words((u32) first_page,
-                           (u32) (first_page >> 32),
-                           0);
+       return jhash_2words((u32) first_page, (u32) (first_page >> 32), 0) &
+               (IB_FMR_HASH_SIZE - 1);
 }
 
 /* Caller must hold pool_lock */
@@ -443,7 +442,7 @@
                list_add(&fmr->list, &pool->free_list);
                spin_unlock_irqrestore(&pool->pool_lock, flags);
 
-               printk(KERN_WARNING "fmr_map returns %d",
+               printk(KERN_WARNING "fmr_map returns %d\n",
                       result);
 
                return ERR_PTR(result);
diff -urN linux/drivers/infiniband/core/mad.c 
linux/drivers/infiniband/core/mad.c
--- linux/drivers/infiniband/core/mad.c 2005/04/08 18:58:15     1.4
+++ linux/drivers/infiniband/core/mad.c 2005/04/29 11:15:06     1.5
@@ -33,9 +33,6 @@
  */
 
 #include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-
-#include <ib_mad.h>
 
 #include "mad_priv.h"
 #include "smi.h"
@@ -1600,7 +1597,8 @@
                         DMA_FROM_DEVICE);
 
        /* Setup MAD receive work completion from "normal" work completion */
-       recv->header.recv_wc.wc = wc;
+       recv->header.wc = *wc;
+       recv->header.recv_wc.wc = &recv->header.wc;
        recv->header.recv_wc.mad_len = sizeof(struct ib_mad);
        recv->header.recv_wc.recv_buf.mad = &recv->mad.mad;
        recv->header.recv_wc.recv_buf.grh = &recv->grh;
@@ -2285,7 +2283,6 @@
                /* Remove from posted receive MAD list */
                list_del(&mad_list->list);
 
-               /* Undo PCI mapping */
                dma_unmap_single(qp_info->port_priv->device->dma_device,
                                 pci_unmap_addr(&recv->header, mapping),
                                 sizeof(struct ib_mad_private) -
diff -urN linux/drivers/infiniband/core/mad_priv.h 
linux/drivers/infiniband/core/mad_priv.h
--- linux/drivers/infiniband/core/mad_priv.h    2005/03/18 17:37:19     1.3
+++ linux/drivers/infiniband/core/mad_priv.h    2005/04/29 11:15:06     1.4
@@ -69,6 +69,7 @@
 struct ib_mad_private_header {
        struct ib_mad_list_head mad_list;
        struct ib_mad_recv_wc recv_wc;
+       struct ib_wc wc;
        DECLARE_PCI_UNMAP_ADDR(mapping)
 } __attribute__ ((packed));
 
diff -urN linux/drivers/infiniband/core/user_mad.c 
linux/drivers/infiniband/core/user_mad.c
--- linux/drivers/infiniband/core/user_mad.c    2005/02/07 02:54:45     1.3
+++ linux/drivers/infiniband/core/user_mad.c    2005/04/29 11:15:06     1.4
@@ -389,15 +389,17 @@
        goto out;
 
 found:
-       req.mgmt_class         = ureq.mgmt_class;
-       req.mgmt_class_version = ureq.mgmt_class_version;
-       memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask);
-       memcpy(req.oui,         ureq.oui,         sizeof req.oui);
+       if (ureq.mgmt_class) {
+               req.mgmt_class         = ureq.mgmt_class;
+               req.mgmt_class_version = ureq.mgmt_class_version;
+               memcpy(req.method_mask, ureq.method_mask, sizeof 
req.method_mask);
+               memcpy(req.oui,         ureq.oui,         sizeof req.oui);
+       }
 
        agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num,
                                      ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
-                                     &req, 0, send_handler, recv_handler,
-                                     file);
+                                     ureq.mgmt_class ? &req : NULL,
+                                     0, send_handler, recv_handler, file);
        if (IS_ERR(agent)) {
                ret = PTR_ERR(agent);
                goto out;
diff -urN linux/drivers/infiniband/hw/mthca/mthca_av.c 
linux/drivers/infiniband/hw/mthca/mthca_av.c
--- linux/drivers/infiniband/hw/mthca/mthca_av.c        2005/03/18 17:37:19     
1.3
+++ linux/drivers/infiniband/hw/mthca/mthca_av.c        2005/04/29 11:15:07     
1.4
@@ -62,8 +62,8 @@
 
        ah->type = MTHCA_AH_PCI_POOL;
 
-       if (dev->hca_type == ARBEL_NATIVE) {
-               ah->av   = kmalloc(sizeof *ah->av, GFP_KERNEL);
+       if (mthca_is_memfree(dev)) {
+               ah->av   = kmalloc(sizeof *ah->av, GFP_ATOMIC);
                if (!ah->av)
                        return -ENOMEM;
 
@@ -77,7 +77,7 @@
                if (index == -1)
                        goto on_hca_fail;
 
-               av = kmalloc(sizeof *av, GFP_KERNEL);
+               av = kmalloc(sizeof *av, GFP_ATOMIC);
                if (!av)
                        goto on_hca_fail;
 
@@ -89,7 +89,7 @@
 on_hca_fail:
        if (ah->type == MTHCA_AH_PCI_POOL) {
                ah->av = pci_pool_alloc(dev->av_table.pool,
-                                       SLAB_KERNEL, &ah->avdma);
+                                       SLAB_ATOMIC, &ah->avdma);
                if (!ah->av)
                        return -ENOMEM;
 
@@ -192,7 +192,7 @@
 {
        int err;
 
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                return 0;
 
        err = mthca_alloc_init(&dev->av_table.alloc,
@@ -231,7 +231,7 @@
 
 void __devexit mthca_cleanup_av_table(struct mthca_dev *dev)
 {
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                return;
 
        if (dev->av_table.av_map)
diff -urN linux/drivers/infiniband/hw/mthca/mthca_cmd.c 
linux/drivers/infiniband/hw/mthca/mthca_cmd.c
--- linux/drivers/infiniband/hw/mthca/mthca_cmd.c       2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_cmd.c       2005/04/29 11:15:07     
1.5
@@ -651,7 +651,7 @@
        mthca_dbg(dev, "FW version %012llx, max commands %d\n",
                  (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                MTHCA_GET(dev->fw.arbel.fw_pages,       outbox, 
QUERY_FW_SIZE_OFFSET);
                MTHCA_GET(dev->fw.arbel.clr_int_base,   outbox, 
QUERY_FW_CLR_INT_BASE_OFFSET);
                MTHCA_GET(dev->fw.arbel.eq_arm_base,    outbox, 
QUERY_FW_EQ_ARM_BASE_OFFSET);
@@ -984,11 +984,11 @@
 
        mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET);
                dev_lim->hca.arbel.resize_srq = field & 1;
-               MTHCA_GET(size, outbox, QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET);
-               dev_lim->mtt_seg_sz = size;
+               MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
+               dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
                MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
                dev_lim->mpt_entry_sz = size;
                MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
@@ -1016,7 +1016,6 @@
        } else {
                MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET);
                dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f);
-               dev_lim->mtt_seg_sz   = MTHCA_MTT_SEG_SIZE;
                dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
        }
 
@@ -1149,7 +1148,7 @@
        /* TPT attributes */
 
        MTHCA_PUT(inbox, param->mpt_base,   INIT_HCA_MPT_BASE_OFFSET);
-       if (dev->hca_type != ARBEL_NATIVE)
+       if (!mthca_is_memfree(dev))
                MTHCA_PUT(inbox, param->mtt_seg_sz, INIT_HCA_MTT_SEG_SZ_OFFSET);
        MTHCA_PUT(inbox, param->log_mpt_sz, INIT_HCA_LOG_MPT_SZ_OFFSET);
        MTHCA_PUT(inbox, param->mtt_base,   INIT_HCA_MTT_BASE_OFFSET);
@@ -1162,7 +1161,7 @@
 
        MTHCA_PUT(inbox, param->uar_scratch_base, 
INIT_HCA_UAR_SCATCH_BASE_OFFSET);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                MTHCA_PUT(inbox, param->log_uarc_sz, INIT_HCA_UARC_SZ_OFFSET);
                MTHCA_PUT(inbox, param->log_uar_sz,  
INIT_HCA_LOG_UAR_SZ_OFFSET);
                MTHCA_PUT(inbox, param->uarc_base,   
INIT_HCA_UAR_CTX_BASE_OFFSET);
@@ -1297,8 +1296,8 @@
        pci_free_consistent(dev->pdev, 16, inbox, indma);
 
        if (!err)
-               mthca_dbg(dev, "Mapped page at %llx for ICM.\n",
-                         (unsigned long long) virt);
+               mthca_dbg(dev, "Mapped page at %llx to %llx for ICM.\n",
+                         (unsigned long long) dma_addr, (unsigned long long) 
virt);
 
        return err;
 }
@@ -1404,6 +1403,11 @@
        return err;
 }
 
+int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status)
+{
+       return mthca_cmd(dev, 0, 0, 0, CMD_SYNC_TPT, CMD_TIME_CLASS_B, status);
+}
+
 int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap,
                 int eq_num, u8 *status)
 {
diff -urN linux/drivers/infiniband/hw/mthca/mthca_cmd.h 
linux/drivers/infiniband/hw/mthca/mthca_cmd.h
--- linux/drivers/infiniband/hw/mthca/mthca_cmd.h       2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_cmd.h       2005/04/29 11:15:07     
1.5
@@ -162,7 +162,6 @@
        int cqc_entry_sz;
        int srq_entry_sz;
        int uar_scratch_entry_sz;
-       int mtt_seg_sz;
        int mpt_entry_sz;
        union {
                struct {
@@ -277,6 +276,7 @@
                    int mpt_index, u8 *status);
 int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry,
                    int num_mtt, u8 *status);
+int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status);
 int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap,
                 int eq_num, u8 *status);
 int mthca_SW2HW_EQ(struct mthca_dev *dev, void *eq_context,
diff -urN linux/drivers/infiniband/hw/mthca/mthca_cq.c 
linux/drivers/infiniband/hw/mthca/mthca_cq.c
--- linux/drivers/infiniband/hw/mthca/mthca_cq.c        2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_cq.c        2005/04/29 11:15:07     
1.5
@@ -180,7 +180,7 @@
 {
        u32 doorbell[2];
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                *cq->set_ci_db = cpu_to_be32(cq->cons_index);
                wmb();
        } else {
@@ -473,7 +473,41 @@
        }
 
        if (is_send) {
-               entry->opcode = IB_WC_SEND; /* XXX */
+               entry->wc_flags = 0;
+               switch (cqe->opcode) {
+               case MTHCA_OPCODE_RDMA_WRITE:
+                       entry->opcode    = IB_WC_RDMA_WRITE;
+                       break;
+               case MTHCA_OPCODE_RDMA_WRITE_IMM:
+                       entry->opcode    = IB_WC_RDMA_WRITE;
+                       entry->wc_flags |= IB_WC_WITH_IMM;
+                       break;
+               case MTHCA_OPCODE_SEND:
+                       entry->opcode    = IB_WC_SEND;
+                       break;
+               case MTHCA_OPCODE_SEND_IMM:
+                       entry->opcode    = IB_WC_SEND;
+                       entry->wc_flags |= IB_WC_WITH_IMM;
+                       break;
+               case MTHCA_OPCODE_RDMA_READ:
+                       entry->opcode    = IB_WC_RDMA_READ;
+                       entry->byte_len  = be32_to_cpu(cqe->byte_cnt);
+                       break;
+               case MTHCA_OPCODE_ATOMIC_CS:
+                       entry->opcode    = IB_WC_COMP_SWAP;
+                       entry->byte_len  = be32_to_cpu(cqe->byte_cnt);
+                       break;
+               case MTHCA_OPCODE_ATOMIC_FA:
+                       entry->opcode    = IB_WC_FETCH_ADD;
+                       entry->byte_len  = be32_to_cpu(cqe->byte_cnt);
+                       break;
+               case MTHCA_OPCODE_BIND_MW:
+                       entry->opcode    = IB_WC_BIND_MW;
+                       break;
+               default:
+                       entry->opcode    = MTHCA_OPCODE_INVALID;
+                       break;
+               }
        } else {
                entry->byte_len = be32_to_cpu(cqe->byte_cnt);
                switch (cqe->opcode & 0x1f) {
@@ -726,7 +760,7 @@
        if (cq->cqn == -1)
                return -ENOMEM;
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                cq->arm_sn = 1;
 
                err = mthca_table_get(dev, dev->cq_table.table, cq->cqn);
@@ -777,7 +811,7 @@
        cq_context->lkey            = cpu_to_be32(cq->mr.ibmr.lkey);
        cq_context->cqn             = cpu_to_be32(cq->cqn);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                cq_context->ci_db    = cpu_to_be32(cq->set_ci_db_index);
                cq_context->state_db = cpu_to_be32(cq->arm_db_index);
        }
@@ -817,10 +851,12 @@
 err_out_mailbox:
        kfree(mailbox);
 
-       mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
+       if (mthca_is_memfree(dev))
+               mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
 
 err_out_ci:
-       mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
+       if (mthca_is_memfree(dev))
+               mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, 
cq->set_ci_db_index);
 
 err_out_icm:
        mthca_table_put(dev, dev->cq_table.table, cq->cqn);
@@ -880,7 +916,7 @@
        mthca_free_mr(dev, &cq->mr);
        mthca_free_cq_buf(dev, cq);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM,    cq->arm_db_index);
                mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, 
cq->set_ci_db_index);
                mthca_table_put(dev, dev->cq_table.table, cq->cqn);
diff -urN linux/drivers/infiniband/hw/mthca/mthca_dev.h 
linux/drivers/infiniband/hw/mthca/mthca_dev.h
--- linux/drivers/infiniband/hw/mthca/mthca_dev.h       2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_dev.h       2005/04/29 11:15:07     
1.5
@@ -49,19 +49,15 @@
 #define DRV_VERSION    "0.06-pre"
 #define DRV_RELDATE    "November 8, 2004"
 
-/* Types of supported HCA */
-enum {
-       TAVOR,                  /* MT23108                        */
-       ARBEL_COMPAT,           /* MT25208 in Tavor compat mode   */
-       ARBEL_NATIVE            /* MT25208 with extended features */
-};
-
 enum {
        MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
        MTHCA_FLAG_SRQ        = 1 << 2,
        MTHCA_FLAG_MSI        = 1 << 3,
        MTHCA_FLAG_MSI_X      = 1 << 4,
-       MTHCA_FLAG_NO_LAM     = 1 << 5
+       MTHCA_FLAG_NO_LAM     = 1 << 5,
+       MTHCA_FLAG_FMR        = 1 << 6,
+       MTHCA_FLAG_MEMFREE    = 1 << 7,
+       MTHCA_FLAG_PCIE       = 1 << 8
 };
 
 enum {
@@ -88,6 +84,19 @@
        MTHCA_NUM_EQ
 };
 
+enum {
+       MTHCA_OPCODE_NOP            = 0x00,
+       MTHCA_OPCODE_RDMA_WRITE     = 0x08,
+       MTHCA_OPCODE_RDMA_WRITE_IMM = 0x09,
+       MTHCA_OPCODE_SEND           = 0x0a,
+       MTHCA_OPCODE_SEND_IMM       = 0x0b,
+       MTHCA_OPCODE_RDMA_READ      = 0x10,
+       MTHCA_OPCODE_ATOMIC_CS      = 0x11,
+       MTHCA_OPCODE_ATOMIC_FA      = 0x12,
+       MTHCA_OPCODE_BIND_MW        = 0x18,
+       MTHCA_OPCODE_INVALID        = 0xff
+};
+
 struct mthca_cmd {
        int                       use_events;
        struct semaphore          hcr_sem;
@@ -121,7 +130,7 @@
        int      reserved_eqs;
        int      num_mpts;
        int      num_mtt_segs;
-       int      mtt_seg_size;
+       int      fmr_reserved_mtts;
        int      reserved_mtts;
        int      reserved_mrws;
        int      reserved_uars;
@@ -158,13 +167,25 @@
        struct mthca_alloc alloc;
 };
 
+struct mthca_buddy {
+       unsigned long **bits;
+       int             max_order;
+       spinlock_t      lock;
+};
+
 struct mthca_mr_table {
        struct mthca_alloc      mpt_alloc;
-       int                     max_mtt_order;
-       unsigned long         **mtt_buddy;
+       struct mthca_buddy      mtt_buddy;
+       struct mthca_buddy     *fmr_mtt_buddy;
        u64                     mtt_base;
+       u64                     mpt_base;
        struct mthca_icm_table *mtt_table;
        struct mthca_icm_table *mpt_table;
+       struct {
+               void __iomem   *mpt_base;
+               void __iomem   *mtt_base;
+               struct mthca_buddy mtt_buddy;
+       } tavor_fmr;
 };
 
 struct mthca_eq_table {
@@ -196,6 +217,7 @@
        struct mthca_array      qp;
        struct mthca_icm_table *qp_table;
        struct mthca_icm_table *eqp_table;
+       struct mthca_icm_table *rdb_table;
 };
 
 struct mthca_av_table {
@@ -363,7 +385,17 @@
                        u64 *buffer_list, int buffer_size_shift,
                        int list_len, u64 iova, u64 total_size,
                        u32 access, struct mthca_mr *mr);
-void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr);
+void mthca_free_mr(struct mthca_dev *dev,  struct mthca_mr *mr);
+
+int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
+                   u32 access, struct mthca_fmr *fmr);
+int mthca_tavor_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
+                            int list_len, u64 iova);
+void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr);
+int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
+                            int list_len, u64 iova);
+void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr);
+int mthca_free_fmr(struct mthca_dev *dev,  struct mthca_fmr *fmr);
 
 int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt);
 void mthca_unmap_eq_icm(struct mthca_dev *dev);
@@ -434,4 +466,9 @@
        return container_of(ibdev, struct mthca_dev, ib_dev);
 }
 
+static inline int mthca_is_memfree(struct mthca_dev *dev)
+{
+       return dev->mthca_flags & MTHCA_FLAG_MEMFREE;
+}
+
 #endif /* MTHCA_DEV_H */
diff -urN linux/drivers/infiniband/hw/mthca/mthca_doorbell.h 
linux/drivers/infiniband/hw/mthca/mthca_doorbell.h
--- linux/drivers/infiniband/hw/mthca/mthca_doorbell.h  2005/03/18 17:37:19     
1.3
+++ linux/drivers/infiniband/hw/mthca/mthca_doorbell.h  2005/04/29 11:15:07     
1.4
@@ -51,6 +51,11 @@
 #define MTHCA_INIT_DOORBELL_LOCK(ptr)    do { } while (0)
 #define MTHCA_GET_DOORBELL_LOCK(ptr)      (NULL)
 
+static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
+{
+       __raw_writeq((__force u64) val, dest);
+}
+
 static inline void mthca_write64(u32 val[2], void __iomem *dest,
                                 spinlock_t *doorbell_lock)
 {
@@ -74,6 +79,12 @@
 #define MTHCA_INIT_DOORBELL_LOCK(ptr)     spin_lock_init(ptr)
 #define MTHCA_GET_DOORBELL_LOCK(ptr)      (ptr)
 
+static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
+{
+       __raw_writel(((__force u32 *) &val)[0], dest);
+       __raw_writel(((__force u32 *) &val)[1], dest + 4);
+}
+
 static inline void mthca_write64(u32 val[2], void __iomem *dest,
                                 spinlock_t *doorbell_lock)
 {
diff -urN linux/drivers/infiniband/hw/mthca/mthca_eq.c 
linux/drivers/infiniband/hw/mthca/mthca_eq.c
--- linux/drivers/infiniband/hw/mthca/mthca_eq.c        2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_eq.c        2005/04/29 11:15:07     
1.5
@@ -198,7 +198,7 @@
 
 static inline void set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 
ci)
 {
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                arbel_set_eq_ci(dev, eq, ci);
        else
                tavor_set_eq_ci(dev, eq, ci);
@@ -223,7 +223,7 @@
 
 static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn)
 {
-       if (dev->hca_type != ARBEL_NATIVE) {
+       if (!mthca_is_memfree(dev)) {
                u32 doorbell[2];
 
                doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn);
@@ -344,10 +344,10 @@
                        break;
 
                case MTHCA_EVENT_TYPE_CQ_ERROR:
-                       mthca_warn(dev, "CQ %s on CQN %08x\n",
+                       mthca_warn(dev, "CQ %s on CQN %06x\n",
                                   eqe->event.cq_err.syndrome == 1 ?
                                   "overrun" : "access violation",
-                                  be32_to_cpu(eqe->event.cq_err.cqn));
+                                  be32_to_cpu(eqe->event.cq_err.cqn) & 
0xffffff);
                        break;
 
                case MTHCA_EVENT_TYPE_EQ_OVERFLOW:
@@ -535,11 +535,11 @@
                                                  MTHCA_EQ_OWNER_HW    |
                                                  MTHCA_EQ_STATE_ARMED |
                                                  MTHCA_EQ_FLAG_TR);
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                eq_context->flags  |= cpu_to_be32(MTHCA_EQ_STATE_ARBEL);
 
        eq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                eq_context->arbel_pd = cpu_to_be32(dev->driver_pd.pd_num);
        } else {
                eq_context->logsize_usrpage |= 
cpu_to_be32(dev->driver_uar.index);
@@ -686,7 +686,7 @@
 
        mthca_base = pci_resource_start(dev->pdev, 0);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                /*
                 * We assume that the EQ arm and EQ set CI registers
                 * fall within the first BAR.  We can't trust the
@@ -756,7 +756,7 @@
 
 static void __devexit mthca_unmap_eq_regs(struct mthca_dev *dev)
 {
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
                                dev->fw.arbel.eq_set_ci_base,
                                MTHCA_EQ_SET_CI_SIZE,
@@ -880,7 +880,7 @@
 
                for (i = 0; i < MTHCA_NUM_EQ; ++i) {
                        err = request_irq(dev->eq_table.eq[i].msi_x_vector,
-                                         dev->hca_type == ARBEL_NATIVE ?
+                                         mthca_is_memfree(dev) ?
                                          mthca_arbel_msi_x_interrupt :
                                          mthca_tavor_msi_x_interrupt,
                                          0, eq_name[i], dev->eq_table.eq + i);
@@ -890,7 +890,7 @@
                }
        } else {
                err = request_irq(dev->pdev->irq,
-                                 dev->hca_type == ARBEL_NATIVE ?
+                                 mthca_is_memfree(dev) ?
                                  mthca_arbel_interrupt :
                                  mthca_tavor_interrupt,
                                  SA_SHIRQ, DRV_NAME, dev);
@@ -918,7 +918,7 @@
                           dev->eq_table.eq[MTHCA_EQ_CMD].eqn, status);
 
        for (i = 0; i < MTHCA_EQ_CMD; ++i)
-               if (dev->hca_type == ARBEL_NATIVE)
+               if (mthca_is_memfree(dev))
                        arbel_eq_req_not(dev, dev->eq_table.eq[i].eqn_mask);
                else
                        tavor_eq_req_not(dev, dev->eq_table.eq[i].eqn);
diff -urN linux/drivers/infiniband/hw/mthca/mthca_main.c 
linux/drivers/infiniband/hw/mthca/mthca_main.c
--- linux/drivers/infiniband/hw/mthca/mthca_main.c      2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_main.c      2005/04/29 11:15:07     
1.5
@@ -73,14 +73,15 @@
        DRV_VERSION " (" DRV_RELDATE ")\n";
 
 static struct mthca_profile default_profile = {
-       .num_qp     = 1 << 16,
-       .rdb_per_qp = 4,
-       .num_cq     = 1 << 16,
-       .num_mcg    = 1 << 13,
-       .num_mpt    = 1 << 17,
-       .num_mtt    = 1 << 20,
-       .num_udav   = 1 << 15,  /* Tavor only */
-       .uarc_size  = 1 << 18,  /* Arbel only */
+       .num_qp            = 1 << 16,
+       .rdb_per_qp        = 4,
+       .num_cq            = 1 << 16,
+       .num_mcg           = 1 << 13,
+       .num_mpt           = 1 << 17,
+       .num_mtt           = 1 << 20,
+       .num_udav          = 1 << 15,   /* Tavor only */
+       .fmr_reserved_mtts = 1 << 18,   /* Tavor only */
+       .uarc_size         = 1 << 18,   /* Arbel only */
 };
 
 static int __devinit mthca_tune_pci(struct mthca_dev *mdev)
@@ -102,7 +103,7 @@
                                  "aborting.\n");
                        return -ENODEV;
                }
-       } else if (mdev->hca_type == TAVOR)
+       } else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE))
                mthca_info(mdev, "No PCI-X capability, not setting RBC.\n");
 
        cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP);
@@ -118,8 +119,7 @@
                                  "register, aborting.\n");
                        return -ENODEV;
                }
-       } else if (mdev->hca_type == ARBEL_NATIVE ||
-                  mdev->hca_type == ARBEL_COMPAT)
+       } else if (mdev->mthca_flags & MTHCA_FLAG_PCIE)
                mthca_info(mdev, "No PCI Express capability, "
                           "not setting Max Read Request Size.\n");
 
@@ -390,7 +390,7 @@
        }
 
        mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, 
init_hca->mtt_base,
-                                                        init_hca->mtt_seg_sz,
+                                                        MTHCA_MTT_SEG_SIZE,
                                                         
mdev->limits.num_mtt_segs,
                                                         
mdev->limits.reserved_mtts, 1);
        if (!mdev->mr_table.mtt_table) {
@@ -429,14 +429,25 @@
                goto err_unmap_qp;
        }
 
-       mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base,
+       mdev->qp_table.rdb_table = mthca_alloc_icm_table(mdev, 
init_hca->rdb_base,
+                                                        MTHCA_RDB_ENTRY_SIZE,
+                                                        mdev->limits.num_qps <<
+                                                        
mdev->qp_table.rdb_shift,
+                                                        0, 0);
+       if (!mdev->qp_table.rdb_table) {
+               mthca_err(mdev, "Failed to map RDB context memory, aborting\n");
+               err = -ENOMEM;
+               goto err_unmap_eqp;
+       }
+
+       mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base,
                                                     dev_lim->cqc_entry_sz,
                                                     mdev->limits.num_cqs,
                                                     mdev->limits.reserved_cqs, 
0);
        if (!mdev->cq_table.table) {
                mthca_err(mdev, "Failed to map CQ context memory, aborting.\n");
                err = -ENOMEM;
-               goto err_unmap_eqp;
+               goto err_unmap_rdb;
        }
 
        /*
@@ -462,6 +473,9 @@
 err_unmap_cq:
        mthca_free_icm_table(mdev, mdev->cq_table.table);
 
+err_unmap_rdb:
+       mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
+
 err_unmap_eqp:
        mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
 
@@ -578,6 +592,7 @@
 
 err_free_icm:
        mthca_free_icm_table(mdev, mdev->cq_table.table);
+       mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
        mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
        mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
        mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
@@ -600,7 +615,7 @@
 
 static int __devinit mthca_init_hca(struct mthca_dev *mdev)
 {
-       if (mdev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(mdev))
                return mthca_init_arbel(mdev);
        else
                return mthca_init_tavor(mdev);
@@ -672,7 +687,10 @@
 
        err = mthca_NOP(dev, &status);
        if (err || status) {
-               mthca_err(dev, "NOP command failed to generate interrupt, 
aborting.\n");
+               mthca_err(dev, "NOP command failed to generate interrupt (IRQ 
%d), aborting.\n",
+                         dev->mthca_flags & MTHCA_FLAG_MSI_X ?
+                         dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector :
+                         dev->pdev->irq);
                if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X))
                        mthca_err(dev, "Try again with MSI/MSI-X disabled.\n");
                else
@@ -831,8 +849,9 @@
 
        mthca_CLOSE_HCA(mdev, 0, &status);
 
-       if (mdev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(mdev)) {
                mthca_free_icm_table(mdev, mdev->cq_table.table);
+               mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
                mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
                mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
                mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
@@ -851,11 +870,32 @@
                mthca_SYS_DIS(mdev, &status);
 }
 
+/* Types of supported HCA */
+enum {
+       TAVOR,                  /* MT23108                        */
+       ARBEL_COMPAT,           /* MT25208 in Tavor compat mode   */
+       ARBEL_NATIVE,           /* MT25208 with extended features */
+       SINAI                   /* MT25204 */
+};
+
+#define MTHCA_FW_VER(major, minor, subminor) \
+       (((u64) (major) << 32) | ((u64) (minor) << 16) | (u64) (subminor))
+
+static struct {
+       u64 latest_fw;
+       int is_memfree;
+       int is_pcie;
+} mthca_hca_table[] = {
+       [TAVOR]        = { .latest_fw = MTHCA_FW_VER(3, 3, 2), .is_memfree = 0, 
.is_pcie = 0 },
+       [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 6, 2), .is_memfree = 0, 
.is_pcie = 1 },
+       [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 0, 1), .is_memfree = 1, 
.is_pcie = 1 },
+       [SINAI]        = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, 
.is_pcie = 1 }
+};
+
 static int __devinit mthca_init_one(struct pci_dev *pdev,
                                    const struct pci_device_id *id)
 {
        static int mthca_version_printed = 0;
-       static int mthca_memfree_warned = 0;
        int ddr_hidden = 0;
        int err;
        struct mthca_dev *mdev;
@@ -868,6 +908,12 @@
        printk(KERN_INFO PFX "Initializing %s (%s)\n",
               pci_pretty_name(pdev), pci_name(pdev));
 
+       if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
+               printk(KERN_ERR PFX "%s (%s) has invalid driver data %lx\n",
+                      pci_pretty_name(pdev), pci_name(pdev), id->driver_data);
+               return -ENODEV;
+       }
+
        err = pci_enable_device(pdev);
        if (err) {
                dev_err(&pdev->dev, "Cannot enable PCI device, "
@@ -932,15 +978,14 @@
                goto err_free_res;
        }
 
-       mdev->pdev     = pdev;
-       mdev->hca_type = id->driver_data;
-
-       if (mdev->hca_type == ARBEL_NATIVE && !mthca_memfree_warned++)
-               mthca_warn(mdev, "Warning: native MT25208 mode support is 
incomplete.  "
-                          "Your HCA may not work properly.\n");
+       mdev->pdev = pdev;
 
        if (ddr_hidden)
                mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN;
+       if (mthca_hca_table[id->driver_data].is_memfree)
+               mdev->mthca_flags |= MTHCA_FLAG_MEMFREE;
+       if (mthca_hca_table[id->driver_data].is_pcie)
+               mdev->mthca_flags |= MTHCA_FLAG_PCIE;
 
        /*
         * Now reset the HCA before we touch the PCI capabilities or
@@ -979,6 +1024,16 @@
        if (err)
                goto err_iounmap;
 
+       if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) {
+               mthca_warn(mdev, "HCA FW version %x.%x.%x is old (%x.%x.%x is 
current).\n",
+                          (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 
16) & 0xffff,
+                          (int) (mdev->fw_ver & 0xffff),
+                          (int) (mthca_hca_table[id->driver_data].latest_fw >> 
32),
+                          (int) (mthca_hca_table[id->driver_data].latest_fw >> 
16) & 0xffff,
+                          (int) (mthca_hca_table[id->driver_data].latest_fw & 
0xffff));
+               mthca_warn(mdev, "If you have problems, try updating your HCA 
FW.\n");
+       }
+
        err = mthca_setup_hca(mdev);
        if (err)
                goto err_close;
@@ -1094,6 +1149,14 @@
          .driver_data = ARBEL_NATIVE },
        { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_ARBEL),
          .driver_data = ARBEL_NATIVE },
+       { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_SINAI),
+         .driver_data = SINAI },
+       { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_SINAI),
+         .driver_data = SINAI },
+       { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_SINAI_OLD),
+         .driver_data = SINAI },
+       { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_SINAI_OLD),
+         .driver_data = SINAI },
        { 0, }
 };
 
diff -urN linux/drivers/infiniband/hw/mthca/mthca_memfree.c 
linux/drivers/infiniband/hw/mthca/mthca_memfree.c
--- linux/drivers/infiniband/hw/mthca/mthca_memfree.c   2005/03/18 17:37:19     
1.3
+++ linux/drivers/infiniband/hw/mthca/mthca_memfree.c   2005/04/29 11:15:07     
1.4
@@ -192,6 +192,72 @@
        up(&table->mutex);
 }
 
+void *mthca_table_find(struct mthca_icm_table *table, int obj)
+{
+       int idx, offset, i;
+       struct mthca_icm_chunk *chunk;
+       struct mthca_icm *icm;
+       struct page *page = NULL;
+
+       if (!table->lowmem)
+               return NULL;
+
+       down(&table->mutex);
+
+       idx = (obj & (table->num_obj - 1)) * table->obj_size;
+       icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE];
+       offset = idx % MTHCA_TABLE_CHUNK_SIZE;
+
+       if (!icm)
+               goto out;
+
+       list_for_each_entry(chunk, &icm->chunk_list, list) {
+               for (i = 0; i < chunk->npages; ++i) {
+                       if (chunk->mem[i].length >= offset) {
+                               page = chunk->mem[i].page;
+                               break;
+                       }
+                       offset -= chunk->mem[i].length;
+               }
+       }
+
+out:
+       up(&table->mutex);
+       return page ? lowmem_page_address(page) + offset : NULL;
+}
+
+int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
+                         int start, int end)
+{
+       int inc = MTHCA_TABLE_CHUNK_SIZE / table->obj_size;
+       int i, err;
+
+       for (i = start; i <= end; i += inc) {
+               err = mthca_table_get(dev, table, i);
+               if (err)
+                       goto fail;
+       }
+
+       return 0;
+
+fail:
+       while (i > start) {
+               i -= inc;
+               mthca_table_put(dev, table, i);
+       }
+
+       return err;
+}
+
+void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table 
*table,
+                          int start, int end)
+{
+       int i;
+
+       for (i = start; i <= end; i += MTHCA_TABLE_CHUNK_SIZE / table->obj_size)
+               mthca_table_put(dev, table, i);
+}
+
 struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
                                              u64 virt, int obj_size,
                                              int nobj, int reserved,
@@ -305,7 +371,8 @@
                break;
 
        default:
-               return -1;
+               ret = -EINVAL;
+               goto out;
        }
 
        for (i = start; i != end; i += dir)
@@ -405,7 +472,7 @@
 {
        int i;
 
-       if (dev->hca_type != ARBEL_NATIVE)
+       if (!mthca_is_memfree(dev))
                return 0;
 
        dev->db_tab = kmalloc(sizeof *dev->db_tab, GFP_KERNEL);
@@ -414,7 +481,7 @@
 
        init_MUTEX(&dev->db_tab->mutex);
 
-       dev->db_tab->npages     = dev->uar_table.uarc_size / PAGE_SIZE;
+       dev->db_tab->npages     = dev->uar_table.uarc_size / 4096;
        dev->db_tab->max_group1 = 0;
        dev->db_tab->min_group2 = dev->db_tab->npages - 1;
 
@@ -437,7 +504,7 @@
        int i;
        u8 status;
 
-       if (dev->hca_type != ARBEL_NATIVE)
+       if (!mthca_is_memfree(dev))
                return;
 
        /*
diff -urN linux/drivers/infiniband/hw/mthca/mthca_memfree.h 
linux/drivers/infiniband/hw/mthca/mthca_memfree.h
--- linux/drivers/infiniband/hw/mthca/mthca_memfree.h   2005/03/18 17:37:19     
1.3
+++ linux/drivers/infiniband/hw/mthca/mthca_memfree.h   2005/04/29 11:15:07     
1.4
@@ -85,6 +85,11 @@
 void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table 
*table);
 int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int 
obj);
 void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int 
obj);
+void *mthca_table_find(struct mthca_icm_table *table, int obj);
+int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
+                         int start, int end);
+void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table 
*table,
+                          int start, int end);
 
 static inline void mthca_icm_first(struct mthca_icm *icm,
                                   struct mthca_icm_iter *iter)
diff -urN linux/drivers/infiniband/hw/mthca/mthca_mr.c 
linux/drivers/infiniband/hw/mthca/mthca_mr.c
--- linux/drivers/infiniband/hw/mthca/mthca_mr.c        2005/03/18 17:37:19     
1.3
+++ linux/drivers/infiniband/hw/mthca/mthca_mr.c        2005/04/29 11:15:07     
1.4
@@ -38,6 +38,7 @@
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
+#include "mthca_memfree.h"
 
 /*
  * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
@@ -65,83 +66,181 @@
 
 #define MTHCA_MTT_FLAG_PRESENT       1
 
+#define MTHCA_MPT_STATUS_SW 0xF0
+#define MTHCA_MPT_STATUS_HW 0x00
+
 /*
  * Buddy allocator for MTT segments (currently not very efficient
  * since it doesn't keep a free list and just searches linearly
  * through the bitmaps)
  */
 
-static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order)
+static u32 mthca_buddy_alloc(struct mthca_buddy *buddy, int order)
 {
        int o;
        int m;
        u32 seg;
 
-       spin_lock(&dev->mr_table.mpt_alloc.lock);
+       spin_lock(&buddy->lock);
 
-       for (o = order; o <= dev->mr_table.max_mtt_order; ++o) {
-               m = 1 << (dev->mr_table.max_mtt_order - o);
-               seg = find_first_bit(dev->mr_table.mtt_buddy[o], m);
+       for (o = order; o <= buddy->max_order; ++o) {
+               m = 1 << (buddy->max_order - o);
+               seg = find_first_bit(buddy->bits[o], m);
                if (seg < m)
                        goto found;
        }
 
-       spin_unlock(&dev->mr_table.mpt_alloc.lock);
+       spin_unlock(&buddy->lock);
        return -1;
 
  found:
-       clear_bit(seg, dev->mr_table.mtt_buddy[o]);
+       clear_bit(seg, buddy->bits[o]);
 
        while (o > order) {
                --o;
                seg <<= 1;
-               set_bit(seg ^ 1, dev->mr_table.mtt_buddy[o]);
+               set_bit(seg ^ 1, buddy->bits[o]);
        }
 
-       spin_unlock(&dev->mr_table.mpt_alloc.lock);
+       spin_unlock(&buddy->lock);
 
        seg <<= order;
 
        return seg;
 }
 
-static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order)
+static void mthca_buddy_free(struct mthca_buddy *buddy, u32 seg, int order)
 {
        seg >>= order;
 
-       spin_lock(&dev->mr_table.mpt_alloc.lock);
+       spin_lock(&buddy->lock);
 
-       while (test_bit(seg ^ 1, dev->mr_table.mtt_buddy[order])) {
-               clear_bit(seg ^ 1, dev->mr_table.mtt_buddy[order]);
+       while (test_bit(seg ^ 1, buddy->bits[order])) {
+               clear_bit(seg ^ 1, buddy->bits[order]);
                seg >>= 1;
                ++order;
        }
 
-       set_bit(seg, dev->mr_table.mtt_buddy[order]);
+       set_bit(seg, buddy->bits[order]);
+
+       spin_unlock(&buddy->lock);
+}
+
+static int __devinit mthca_buddy_init(struct mthca_buddy *buddy, int max_order)
+{
+       int i, s;
+
+       buddy->max_order = max_order;
+       spin_lock_init(&buddy->lock);
+
+       buddy->bits = kmalloc((buddy->max_order + 1) * sizeof (long *),
+                             GFP_KERNEL);
+       if (!buddy->bits)
+               goto err_out;
+
+       memset(buddy->bits, 0, (buddy->max_order + 1) * sizeof (long *));
+
+       for (i = 0; i <= buddy->max_order; ++i) {
+               s = BITS_TO_LONGS(1 << (buddy->max_order - i));
+               buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL);
+               if (!buddy->bits[i])
+                       goto err_out_free;
+               bitmap_zero(buddy->bits[i],
+                           1 << (buddy->max_order - i));
+       }
+
+       set_bit(0, buddy->bits[buddy->max_order]);
+
+       return 0;
+
+err_out_free:
+       for (i = 0; i <= buddy->max_order; ++i)
+               kfree(buddy->bits[i]);
 
-       spin_unlock(&dev->mr_table.mpt_alloc.lock);
+       kfree(buddy->bits);
+
+err_out:
+       return -ENOMEM;
+}
+
+static void __devexit mthca_buddy_cleanup(struct mthca_buddy *buddy)
+{
+       int i;
+
+       for (i = 0; i <= buddy->max_order; ++i)
+               kfree(buddy->bits[i]);
+
+       kfree(buddy->bits);
+}
+
+static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order,
+                          struct mthca_buddy *buddy)
+{
+       u32 seg = mthca_buddy_alloc(buddy, order);
+
+       if (seg == -1)
+               return -1;
+
+       if (mthca_is_memfree(dev))
+               if (mthca_table_get_range(dev, dev->mr_table.mtt_table, seg,
+                                         seg + (1 << order) - 1)) {
+                       mthca_buddy_free(buddy, seg, order);
+                       seg = -1;
+               }
+
+       return seg;
+}
+
+static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order,
+                          struct mthca_buddy* buddy)
+{
+       mthca_buddy_free(buddy, seg, order);
+
+       if (mthca_is_memfree(dev))
+               mthca_table_put_range(dev, dev->mr_table.mtt_table, seg,
+                                     seg + (1 << order) - 1);
+}
+
+static inline u32 tavor_hw_index_to_key(u32 ind)
+{
+       return ind;
+}
+
+static inline u32 tavor_key_to_hw_index(u32 key)
+{
+       return key;
+}
+
+static inline u32 arbel_hw_index_to_key(u32 ind)
+{
+       return (ind >> 24) | (ind << 8);
+}
+
+static inline u32 arbel_key_to_hw_index(u32 key)
+{
+       return (key << 24) | (key >> 8);
 }
 
 static inline u32 hw_index_to_key(struct mthca_dev *dev, u32 ind)
 {
-       if (dev->hca_type == ARBEL_NATIVE)
-               return (ind >> 24) | (ind << 8);
+       if (mthca_is_memfree(dev))
+               return arbel_hw_index_to_key(ind);
        else
-               return ind;
+               return tavor_hw_index_to_key(ind);
 }
 
 static inline u32 key_to_hw_index(struct mthca_dev *dev, u32 key)
 {
-       if (dev->hca_type == ARBEL_NATIVE)
-               return (key << 24) | (key >> 8);
+       if (mthca_is_memfree(dev))
+               return arbel_key_to_hw_index(key);
        else
-               return key;
+               return tavor_key_to_hw_index(key);
 }
 
 int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
                           u32 access, struct mthca_mr *mr)
 {
-       void *mailbox;
+       void *mailbox = NULL;
        struct mthca_mpt_entry *mpt_entry;
        u32 key;
        int err;
@@ -155,11 +254,17 @@
                return -ENOMEM;
        mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
 
+       if (mthca_is_memfree(dev)) {
+               err = mthca_table_get(dev, dev->mr_table.mpt_table, key);
+               if (err)
+                       goto err_out_mpt_free;
+       }
+
        mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA,
                          GFP_KERNEL);
        if (!mailbox) {
-               mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_out_table;
        }
        mpt_entry = MAILBOX_ALIGN(mailbox);
 
@@ -180,16 +285,27 @@
        err = mthca_SW2HW_MPT(dev, mpt_entry,
                              key & (dev->limits.num_mpts - 1),
                              &status);
-       if (err)
+       if (err) {
                mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
-       else if (status) {
+               goto err_out_table;
+       } else if (status) {
                mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
                           status);
                err = -EINVAL;
+               goto err_out_table;
        }
 
        kfree(mailbox);
        return err;
+
+err_out_table:
+       if (mthca_is_memfree(dev))
+               mthca_table_put(dev, dev->mr_table.mpt_table, key);
+
+err_out_mpt_free:
+       mthca_free(&dev->mr_table.mpt_alloc, key);
+       kfree(mailbox);
+       return err;
 }
 
 int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
@@ -213,14 +329,21 @@
                return -ENOMEM;
        mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
 
-       for (i = dev->limits.mtt_seg_size / 8, mr->order = 0;
+       if (mthca_is_memfree(dev)) {
+               err = mthca_table_get(dev, dev->mr_table.mpt_table, key);
+               if (err)
+                       goto err_out_mpt_free;
+       }
+
+       for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0;
             i < list_len;
             i <<= 1, ++mr->order)
                ; /* nothing */
 
-       mr->first_seg = mthca_alloc_mtt(dev, mr->order);
+       mr->first_seg = mthca_alloc_mtt(dev, mr->order,
+                                       &dev->mr_table.mtt_buddy);
        if (mr->first_seg == -1)
-               goto err_out_mpt_free;
+               goto err_out_table;
 
        /*
         * If list_len is odd, we add one more dummy entry for
@@ -236,7 +359,7 @@
        mtt_entry = MAILBOX_ALIGN(mailbox);
 
        mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base +
-                                  mr->first_seg * dev->limits.mtt_seg_size);
+                                  mr->first_seg * MTHCA_MTT_SEG_SIZE);
        mtt_entry[1] = 0;
        for (i = 0; i < list_len; ++i)
                mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] |
@@ -280,7 +403,7 @@
        memset(&mpt_entry->lkey, 0,
               sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey));
        mpt_entry->mtt_seg   = cpu_to_be64(dev->mr_table.mtt_base +
-                                          mr->first_seg * 
dev->limits.mtt_seg_size);
+                                          mr->first_seg * MTHCA_MTT_SEG_SIZE);
 
        if (0) {
                mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
@@ -307,17 +430,35 @@
        kfree(mailbox);
        return err;
 
- err_out_mailbox_free:
+err_out_mailbox_free:
        kfree(mailbox);
 
- err_out_free_mtt:
-       mthca_free_mtt(dev, mr->first_seg, mr->order);
+err_out_free_mtt:
+       mthca_free_mtt(dev, mr->first_seg, mr->order, &dev->mr_table.mtt_buddy);
 
- err_out_mpt_free:
-       mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+err_out_table:
+       if (mthca_is_memfree(dev))
+               mthca_table_put(dev, dev->mr_table.mpt_table, key);
+
+err_out_mpt_free:
+       mthca_free(&dev->mr_table.mpt_alloc, key);
        return err;
 }
 
+/* Free mr or fmr */
+static void mthca_free_region(struct mthca_dev *dev, u32 lkey, int order,
+                             u32 first_seg, struct mthca_buddy *buddy)
+{
+       if (order >= 0)
+               mthca_free_mtt(dev, first_seg, order, buddy);
+
+       if (mthca_is_memfree(dev))
+               mthca_table_put(dev, dev->mr_table.mpt_table,
+                               arbel_key_to_hw_index(lkey));
+
+       mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, lkey));
+}
+
 void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr)
 {
        int err;
@@ -335,16 +476,288 @@
                mthca_warn(dev, "HW2SW_MPT returned status 0x%02x\n",
                           status);
 
-       if (mr->order >= 0)
-               mthca_free_mtt(dev, mr->first_seg, mr->order);
+       mthca_free_region(dev, mr->ibmr.lkey, mr->order, mr->first_seg,
+                         &dev->mr_table.mtt_buddy);
+}
+
+int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
+                   u32 access, struct mthca_fmr *mr)
+{
+       struct mthca_mpt_entry *mpt_entry;
+       void *mailbox;
+       u64 mtt_seg;
+       u32 key, idx;
+       u8 status;
+       int list_len = mr->attr.max_pages;
+       int err = -ENOMEM;
+       int i;
+
+       might_sleep();
+
+       if (mr->attr.page_size < 12 || mr->attr.page_size >= 32)
+               return -EINVAL;
+
+       /* For Arbel, all MTTs must fit in the same page. */
+       if (mthca_is_memfree(dev) &&
+           mr->attr.max_pages * sizeof *mr->mem.arbel.mtts > PAGE_SIZE)
+               return -EINVAL;
+
+       mr->maps = 0;
+
+       key = mthca_alloc(&dev->mr_table.mpt_alloc);
+       if (key == -1)
+               return -ENOMEM;
+
+       idx = key & (dev->limits.num_mpts - 1);
+       mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
+
+       if (mthca_is_memfree(dev)) {
+               err = mthca_table_get(dev, dev->mr_table.mpt_table, key);
+               if (err)
+                       goto err_out_mpt_free;
+
+               mr->mem.arbel.mpt = mthca_table_find(dev->mr_table.mpt_table, 
key);
+               BUG_ON(!mr->mem.arbel.mpt);
+       } else
+               mr->mem.tavor.mpt = dev->mr_table.tavor_fmr.mpt_base +
+                       sizeof *(mr->mem.tavor.mpt) * idx;
+
+       for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0;
+            i < list_len;
+            i <<= 1, ++mr->order)
+               ; /* nothing */
+
+       mr->first_seg = mthca_alloc_mtt(dev, mr->order,
+                                       dev->mr_table.fmr_mtt_buddy);
+       if (mr->first_seg == -1)
+               goto err_out_table;
+
+       mtt_seg = mr->first_seg * MTHCA_MTT_SEG_SIZE;
+
+       if (mthca_is_memfree(dev)) {
+               mr->mem.arbel.mtts = mthca_table_find(dev->mr_table.mtt_table,
+                                                     mr->first_seg);
+               BUG_ON(!mr->mem.arbel.mtts);
+       } else
+               mr->mem.tavor.mtts = dev->mr_table.tavor_fmr.mtt_base + mtt_seg;
+
+       mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA,
+                         GFP_KERNEL);
+       if (!mailbox)
+               goto err_out_free_mtt;
+
+       mpt_entry = MAILBOX_ALIGN(mailbox);
+
+       mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS     |
+                                      MTHCA_MPT_FLAG_MIO         |
+                                      MTHCA_MPT_FLAG_REGION      |
+                                      access);
+
+       mpt_entry->page_size = cpu_to_be32(mr->attr.page_size - 12);
+       mpt_entry->key       = cpu_to_be32(key);
+       mpt_entry->pd        = cpu_to_be32(pd);
+       memset(&mpt_entry->start, 0,
+              sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, start));
+       mpt_entry->mtt_seg   = cpu_to_be64(dev->mr_table.mtt_base + mtt_seg);
+
+       if (0) {
+               mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
+               for (i = 0; i < sizeof (struct mthca_mpt_entry) / 4; ++i) {
+                       if (i % 4 == 0)
+                               printk("[%02x] ", i * 4);
+                       printk(" %08x", be32_to_cpu(((u32 *) mpt_entry)[i]));
+                       if ((i + 1) % 4 == 0)
+                               printk("\n");
+               }
+       }
+
+       err = mthca_SW2HW_MPT(dev, mpt_entry,
+                             key & (dev->limits.num_mpts - 1),
+                             &status);
+       if (err) {
+               mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
+               goto err_out_mailbox_free;
+       }
+       if (status) {
+               mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
+                          status);
+               err = -EINVAL;
+               goto err_out_mailbox_free;
+       }
+
+       kfree(mailbox);
+       return 0;
 
-       mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, 
mr->ibmr.lkey));
+err_out_mailbox_free:
+       kfree(mailbox);
+
+err_out_free_mtt:
+       mthca_free_mtt(dev, mr->first_seg, mr->order,
+                      dev->mr_table.fmr_mtt_buddy);
+
+err_out_table:
+       if (mthca_is_memfree(dev))
+               mthca_table_put(dev, dev->mr_table.mpt_table, key);
+
+err_out_mpt_free:
+       mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+       return err;
+}
+
+int mthca_free_fmr(struct mthca_dev *dev, struct mthca_fmr *fmr)
+{
+       if (fmr->maps)
+               return -EBUSY;
+
+       mthca_free_region(dev, fmr->ibmr.lkey, fmr->order, fmr->first_seg,
+                         dev->mr_table.fmr_mtt_buddy);
+       return 0;
+}
+
+static inline int mthca_check_fmr(struct mthca_fmr *fmr, u64 *page_list,
+                                 int list_len, u64 iova)
+{
+       int i, page_mask;
+
+       if (list_len > fmr->attr.max_pages)
+               return -EINVAL;
+
+       page_mask = (1 << fmr->attr.page_size) - 1;
+
+       /* We are getting page lists, so va must be page aligned. */
+       if (iova & page_mask)
+               return -EINVAL;
+
+       /* Trust the user not to pass misaligned data in page_list */
+       if (0)
+               for (i = 0; i < list_len; ++i) {
+                       if (page_list[i] & ~page_mask)
+                               return -EINVAL;
+               }
+
+       if (fmr->maps >= fmr->attr.max_maps)
+               return -EINVAL;
+
+       return 0;
+}
+
+
+int mthca_tavor_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
+                            int list_len, u64 iova)
+{
+       struct mthca_fmr *fmr = to_mfmr(ibfmr);
+       struct mthca_dev *dev = to_mdev(ibfmr->device);
+       struct mthca_mpt_entry mpt_entry;
+       u32 key;
+       int i, err;
+
+       err = mthca_check_fmr(fmr, page_list, list_len, iova);
+       if (err)
+               return err;
+
+       ++fmr->maps;
+
+       key = tavor_key_to_hw_index(fmr->ibmr.lkey);
+       key += dev->limits.num_mpts;
+       fmr->ibmr.lkey = fmr->ibmr.rkey = tavor_hw_index_to_key(key);
+
+       writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt);
+
+       for (i = 0; i < list_len; ++i) {
+               __be64 mtt_entry = cpu_to_be64(page_list[i] |
+                                              MTHCA_MTT_FLAG_PRESENT);
+               mthca_write64_raw(mtt_entry, fmr->mem.tavor.mtts + i);
+       }
+
+       mpt_entry.lkey   = cpu_to_be32(key);
+       mpt_entry.length = cpu_to_be64(list_len * (1ull << 
fmr->attr.page_size));
+       mpt_entry.start  = cpu_to_be64(iova);
+
+       writel(mpt_entry.lkey, &fmr->mem.tavor.mpt->key);
+       memcpy_toio(&fmr->mem.tavor.mpt->start, &mpt_entry.start,
+                   offsetof(struct mthca_mpt_entry, window_count) -
+                   offsetof(struct mthca_mpt_entry, start));
+
+       writeb(MTHCA_MPT_STATUS_HW, fmr->mem.tavor.mpt);
+
+       return 0;
+}
+
+int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
+                            int list_len, u64 iova)
+{
+       struct mthca_fmr *fmr = to_mfmr(ibfmr);
+       struct mthca_dev *dev = to_mdev(ibfmr->device);
+       u32 key;
+       int i, err;
+
+       err = mthca_check_fmr(fmr, page_list, list_len, iova);
+       if (err)
+               return err;
+
+       ++fmr->maps;
+
+       key = arbel_key_to_hw_index(fmr->ibmr.lkey);
+       key += dev->limits.num_mpts;
+       fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key);
+
+       *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW;
+
+       wmb();
+
+       for (i = 0; i < list_len; ++i)
+               fmr->mem.arbel.mtts[i] = cpu_to_be64(page_list[i] |
+                                                    MTHCA_MTT_FLAG_PRESENT);
+
+       fmr->mem.arbel.mpt->key    = cpu_to_be32(key);
+       fmr->mem.arbel.mpt->lkey   = cpu_to_be32(key);
+       fmr->mem.arbel.mpt->length = cpu_to_be64(list_len * (1ull << 
fmr->attr.page_size));
+       fmr->mem.arbel.mpt->start  = cpu_to_be64(iova);
+
+       wmb();
+
+       *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_HW;
+
+       wmb();
+
+       return 0;
+}
+
+void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
+{
+       u32 key;
+
+       if (!fmr->maps)
+               return;
+
+       key = tavor_key_to_hw_index(fmr->ibmr.lkey);
+       key &= dev->limits.num_mpts - 1;
+       fmr->ibmr.lkey = fmr->ibmr.rkey = tavor_hw_index_to_key(key);
+
+       fmr->maps = 0;
+
+       writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt);
+}
+
+void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
+{
+       u32 key;
+
+       if (!fmr->maps)
+               return;
+
+       key = arbel_key_to_hw_index(fmr->ibmr.lkey);
+       key &= dev->limits.num_mpts - 1;
+       fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key);
+
+       fmr->maps = 0;
+
+       *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW;
 }
 
 int __devinit mthca_init_mr_table(struct mthca_dev *dev)
 {
-       int err;
-       int i, s;
+       int err, i;
 
        err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
                               dev->limits.num_mpts,
@@ -352,53 +765,94 @@
        if (err)
                return err;
 
-       err = -ENOMEM;
+       if (!mthca_is_memfree(dev) &&
+           (dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN))
+               dev->limits.fmr_reserved_mtts = 0;
+       else
+               dev->mthca_flags |= MTHCA_FLAG_FMR;
 
-       for (i = 1, dev->mr_table.max_mtt_order = 0;
-            i < dev->limits.num_mtt_segs;
-            i <<= 1, ++dev->mr_table.max_mtt_order)
-               ; /* nothing */
+       err = mthca_buddy_init(&dev->mr_table.mtt_buddy,
+                              fls(dev->limits.num_mtt_segs - 1));
 
-       dev->mr_table.mtt_buddy = kmalloc((dev->mr_table.max_mtt_order + 1) *
-                                         sizeof (long *),
-                                         GFP_KERNEL);
-       if (!dev->mr_table.mtt_buddy)
-               goto err_out;
+       if (err)
+               goto err_mtt_buddy;
 
-       for (i = 0; i <= dev->mr_table.max_mtt_order; ++i)
-               dev->mr_table.mtt_buddy[i] = NULL;
+       dev->mr_table.tavor_fmr.mpt_base = NULL;
+       dev->mr_table.tavor_fmr.mtt_base = NULL;
 
-       for (i = 0; i <= dev->mr_table.max_mtt_order; ++i) {
-               s = BITS_TO_LONGS(1 << (dev->mr_table.max_mtt_order - i));
-               dev->mr_table.mtt_buddy[i] = kmalloc(s * sizeof (long),
-                                                    GFP_KERNEL);
-               if (!dev->mr_table.mtt_buddy[i])
-                       goto err_out_free;
-               bitmap_zero(dev->mr_table.mtt_buddy[i],
-                           1 << (dev->mr_table.max_mtt_order - i));
-       }
+       if (dev->limits.fmr_reserved_mtts) {
+               i = fls(dev->limits.fmr_reserved_mtts - 1);
 
-       set_bit(0, dev->mr_table.mtt_buddy[dev->mr_table.max_mtt_order]);
+               if (i >= 31) {
+                       mthca_warn(dev, "Unable to reserve 2^31 FMR MTTs.\n");
+                       err = -EINVAL;
+                       goto err_fmr_mpt;
+               }
 
-       for (i = 0; i < dev->mr_table.max_mtt_order; ++i)
-               if (1 << i >= dev->limits.reserved_mtts)
-                       break;
+               dev->mr_table.tavor_fmr.mpt_base =
+                       ioremap(dev->mr_table.mpt_base,
+                               (1 << i) * sizeof (struct mthca_mpt_entry));
+
+               if (!dev->mr_table.tavor_fmr.mpt_base) {
+                       mthca_warn(dev, "MPT ioremap for FMR failed.\n");
+                       err = -ENOMEM;
+                       goto err_fmr_mpt;
+               }
 
-       if (i == dev->mr_table.max_mtt_order) {
-               mthca_err(dev, "MTT table of order %d is "
-                         "too small.\n", i);
-               goto err_out_free;
-       }
+               dev->mr_table.tavor_fmr.mtt_base =
+                       ioremap(dev->mr_table.mtt_base,
+                               (1 << i) * MTHCA_MTT_SEG_SIZE);
+               if (!dev->mr_table.tavor_fmr.mtt_base) {
+                       mthca_warn(dev, "MTT ioremap for FMR failed.\n");
+                       err = -ENOMEM;
+                       goto err_fmr_mtt;
+               }
 
-       (void) mthca_alloc_mtt(dev, i);
+               err = mthca_buddy_init(&dev->mr_table.tavor_fmr.mtt_buddy, i);
+               if (err)
+                       goto err_fmr_mtt_buddy;
+
+               /* Prevent regular MRs from using FMR keys */
+               err = mthca_buddy_alloc(&dev->mr_table.mtt_buddy, i);
+               if (err)
+                       goto err_reserve_fmr;
+
+               dev->mr_table.fmr_mtt_buddy =
+                       &dev->mr_table.tavor_fmr.mtt_buddy;
+       } else
+               dev->mr_table.fmr_mtt_buddy = &dev->mr_table.mtt_buddy;
+
+       /* FMR table is always the first, take reserved MTTs out of there */
+       if (dev->limits.reserved_mtts) {
+               i = fls(dev->limits.reserved_mtts - 1);
+
+               if (mthca_alloc_mtt(dev, i, dev->mr_table.fmr_mtt_buddy) == -1) 
{
+                       mthca_warn(dev, "MTT table of order %d is too small.\n",
+                                 dev->mr_table.fmr_mtt_buddy->max_order);
+                       err = -ENOMEM;
+                       goto err_reserve_mtts;
+               }
+       }
 
        return 0;
 
- err_out_free:
-       for (i = 0; i <= dev->mr_table.max_mtt_order; ++i)
-               kfree(dev->mr_table.mtt_buddy[i]);
+err_reserve_mtts:
+err_reserve_fmr:
+       if (dev->limits.fmr_reserved_mtts)
+               mthca_buddy_cleanup(&dev->mr_table.tavor_fmr.mtt_buddy);
+
+err_fmr_mtt_buddy:
+       if (dev->mr_table.tavor_fmr.mtt_base)
+               iounmap(dev->mr_table.tavor_fmr.mtt_base);
+
+err_fmr_mtt:
+       if (dev->mr_table.tavor_fmr.mpt_base)
+               iounmap(dev->mr_table.tavor_fmr.mpt_base);
+
+err_fmr_mpt:
+       mthca_buddy_cleanup(&dev->mr_table.mtt_buddy);
 
- err_out:
+err_mtt_buddy:
        mthca_alloc_cleanup(&dev->mr_table.mpt_alloc);
 
        return err;
@@ -406,11 +860,16 @@
 
 void __devexit mthca_cleanup_mr_table(struct mthca_dev *dev)
 {
-       int i;
-
        /* XXX check if any MRs are still allocated? */
-       for (i = 0; i <= dev->mr_table.max_mtt_order; ++i)
-               kfree(dev->mr_table.mtt_buddy[i]);
-       kfree(dev->mr_table.mtt_buddy);
+       if (dev->limits.fmr_reserved_mtts)
+               mthca_buddy_cleanup(&dev->mr_table.tavor_fmr.mtt_buddy);
+
+       mthca_buddy_cleanup(&dev->mr_table.mtt_buddy);
+
+       if (dev->mr_table.tavor_fmr.mtt_base)
+               iounmap(dev->mr_table.tavor_fmr.mtt_base);
+       if (dev->mr_table.tavor_fmr.mpt_base)
+               iounmap(dev->mr_table.tavor_fmr.mpt_base);
+
        mthca_alloc_cleanup(&dev->mr_table.mpt_alloc);
 }
diff -urN linux/drivers/infiniband/hw/mthca/mthca_profile.c 
linux/drivers/infiniband/hw/mthca/mthca_profile.c
--- linux/drivers/infiniband/hw/mthca/mthca_profile.c   2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_profile.c   2005/04/29 11:15:07     
1.5
@@ -95,7 +95,7 @@
        profile[MTHCA_RES_RDB].size  = MTHCA_RDB_ENTRY_SIZE;
        profile[MTHCA_RES_MCG].size  = MTHCA_MGM_ENTRY_SIZE;
        profile[MTHCA_RES_MPT].size  = dev_lim->mpt_entry_sz;
-       profile[MTHCA_RES_MTT].size  = dev_lim->mtt_seg_sz;
+       profile[MTHCA_RES_MTT].size  = MTHCA_MTT_SEG_SIZE;
        profile[MTHCA_RES_UAR].size  = dev_lim->uar_scratch_entry_sz;
        profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
        profile[MTHCA_RES_UARC].size = request->uarc_size;
@@ -116,11 +116,11 @@
                profile[i].type     = i;
                profile[i].log_num  = max(ffs(profile[i].num) - 1, 0);
                profile[i].size    *= profile[i].num;
-               if (dev->hca_type == ARBEL_NATIVE)
+               if (mthca_is_memfree(dev))
                        profile[i].size = max(profile[i].size, (u64) PAGE_SIZE);
        }
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                mem_base  = 0;
                mem_avail = dev_lim->hca.arbel.max_icm_sz;
        } else {
@@ -165,7 +165,7 @@
                                  (unsigned long long) profile[i].size);
        }
 
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                mthca_dbg(dev, "HCA context memory: reserving %d KB\n",
                          (int) (total_size >> 10));
        else
@@ -208,8 +208,7 @@
                        break;
                case MTHCA_RES_RDB:
                        for (dev->qp_table.rdb_shift = 0;
-                            profile[MTHCA_RES_QP].num << 
dev->qp_table.rdb_shift <
-                                    profile[i].num;
+                            request->num_qp << dev->qp_table.rdb_shift < 
profile[i].num;
                             ++dev->qp_table.rdb_shift)
                                ; /* nothing */
                        dev->qp_table.rdb_base    = (u32) profile[i].start;
@@ -224,16 +223,16 @@
                        init_hca->mc_hash_sz      = 1 << (profile[i].log_num - 
1);
                        break;
                case MTHCA_RES_MPT:
-                       dev->limits.num_mpts = profile[i].num;
-                       init_hca->mpt_base   = profile[i].start;
-                       init_hca->log_mpt_sz = profile[i].log_num;
+                       dev->limits.num_mpts   = profile[i].num;
+                       dev->mr_table.mpt_base = profile[i].start;
+                       init_hca->mpt_base     = profile[i].start;
+                       init_hca->log_mpt_sz   = profile[i].log_num;
                        break;
                case MTHCA_RES_MTT:
                        dev->limits.num_mtt_segs = profile[i].num;
-                       dev->limits.mtt_seg_size = dev_lim->mtt_seg_sz;
                        dev->mr_table.mtt_base   = profile[i].start;
                        init_hca->mtt_base       = profile[i].start;
-                       init_hca->mtt_seg_sz     = ffs(dev_lim->mtt_seg_sz) - 7;
+                       init_hca->mtt_seg_sz     = ffs(MTHCA_MTT_SEG_SIZE) - 7;
                        break;
                case MTHCA_RES_UAR:
                        dev->limits.num_uars       = profile[i].num;
@@ -261,6 +260,18 @@
         */
        dev->limits.num_pds = MTHCA_NUM_PDS;
 
+       /*
+        * For Tavor, FMRs use ioremapped PCI memory. For 32 bit
+        * systems it may use too much vmalloc space to map all MTT
+        * memory, so we reserve some MTTs for FMR access, taking them
+        * out of the MR pool. They don't use additional memory, but
+        * we assign them as part of the HCA profile anyway.
+        */
+       if (mthca_is_memfree(dev))
+               dev->limits.fmr_reserved_mtts = 0;
+       else
+               dev->limits.fmr_reserved_mtts = request->fmr_reserved_mtts;
+
        kfree(profile);
        return total_size;
 }
diff -urN linux/drivers/infiniband/hw/mthca/mthca_profile.h 
linux/drivers/infiniband/hw/mthca/mthca_profile.h
--- linux/drivers/infiniband/hw/mthca/mthca_profile.h   2005/02/07 02:54:45     
1.3
+++ linux/drivers/infiniband/hw/mthca/mthca_profile.h   2005/04/29 11:15:07     
1.4
@@ -48,6 +48,7 @@
        int num_udav;
        int num_uar;
        int uarc_size;
+       int fmr_reserved_mtts;
 };
 
 u64 mthca_make_profile(struct mthca_dev *mdev,
diff -urN linux/drivers/infiniband/hw/mthca/mthca_provider.c 
linux/drivers/infiniband/hw/mthca/mthca_provider.c
--- linux/drivers/infiniband/hw/mthca/mthca_provider.c  2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_provider.c  2005/04/29 11:15:07     
1.5
@@ -52,6 +52,8 @@
        if (!in_mad || !out_mad)
                goto out;
 
+       memset(props, 0, sizeof props);
+
        props->fw_ver              = mdev->fw_ver;
 
        memset(in_mad, 0, sizeof *in_mad);
@@ -71,14 +73,26 @@
                goto out;
        }
 
-       props->device_cap_flags = mdev->device_cap_flags;
-       props->vendor_id        = be32_to_cpup((u32 *) (out_mad->data + 36)) &
+       props->device_cap_flags    = mdev->device_cap_flags;
+       props->vendor_id           = be32_to_cpup((u32 *) (out_mad->data + 36)) 
&
                0xffffff;
-       props->vendor_part_id   = be16_to_cpup((u16 *) (out_mad->data + 30));
-       props->hw_ver           = be16_to_cpup((u16 *) (out_mad->data + 32));
+       props->vendor_part_id      = be16_to_cpup((u16 *) (out_mad->data + 30));
+       props->hw_ver              = be16_to_cpup((u16 *) (out_mad->data + 32));
        memcpy(&props->sys_image_guid, out_mad->data +  4, 8);
        memcpy(&props->node_guid,      out_mad->data + 12, 8);
 
+       props->max_mr_size         = ~0ull;
+       props->max_qp              = mdev->limits.num_qps - 
mdev->limits.reserved_qps;
+       props->max_qp_wr           = 0xffff;
+       props->max_sge             = mdev->limits.max_sg;
+       props->max_cq              = mdev->limits.num_cqs - 
mdev->limits.reserved_cqs;
+       props->max_cqe             = 0xffff;
+       props->max_mr              = mdev->limits.num_mpts - 
mdev->limits.reserved_mrws;
+       props->max_pd              = mdev->limits.num_pds - 
mdev->limits.reserved_pds;
+       props->max_qp_rd_atom      = 1 << mdev->qp_table.rdb_shift;
+       props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift;
+       props->local_ca_ack_delay  = mdev->limits.local_ca_ack_delay;
+
        err = 0;
  out:
        kfree(in_mad);
@@ -301,7 +315,7 @@
        int err;
        struct mthca_ah *ah;
 
-       ah = kmalloc(sizeof *ah, GFP_KERNEL);
+       ah = kmalloc(sizeof *ah, GFP_ATOMIC);
        if (!ah)
                return ERR_PTR(-ENOMEM);
 
@@ -480,7 +494,7 @@
        mask = 0;
        total_size = 0;
        for (i = 0; i < num_phys_buf; ++i) {
-               if (buffer_list[i].addr & ~PAGE_MASK)
+               if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
                        return ERR_PTR(-EINVAL);
                if (i != 0 && i != num_phys_buf - 1 &&
                    (buffer_list[i].size & ~PAGE_MASK))
@@ -554,8 +568,77 @@
 
 static int mthca_dereg_mr(struct ib_mr *mr)
 {
-       mthca_free_mr(to_mdev(mr->device), to_mmr(mr));
-       kfree(mr);
+       struct mthca_mr *mmr = to_mmr(mr);
+       mthca_free_mr(to_mdev(mr->device), mmr);
+       kfree(mmr);
+       return 0;
+}
+
+static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
+                                     struct ib_fmr_attr *fmr_attr)
+{
+       struct mthca_fmr *fmr;
+       int err;
+
+       fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
+       if (!fmr)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr);
+       err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num,
+                            convert_access(mr_access_flags), fmr);
+
+       if (err) {
+               kfree(fmr);
+               return ERR_PTR(err);
+       }
+
+       return &fmr->ibmr;
+}
+
+static int mthca_dealloc_fmr(struct ib_fmr *fmr)
+{
+       struct mthca_fmr *mfmr = to_mfmr(fmr);
+       int err;
+
+       err = mthca_free_fmr(to_mdev(fmr->device), mfmr);
+       if (err)
+               return err;
+
+       kfree(mfmr);
+       return 0;
+}
+
+static int mthca_unmap_fmr(struct list_head *fmr_list)
+{
+       struct ib_fmr *fmr;
+       int err;
+       u8 status;
+       struct mthca_dev *mdev = NULL;
+
+       list_for_each_entry(fmr, fmr_list, list) {
+               if (mdev && to_mdev(fmr->device) != mdev)
+                       return -EINVAL;
+               mdev = to_mdev(fmr->device);
+       }
+
+       if (!mdev)
+               return 0;
+
+       if (mthca_is_memfree(mdev)) {
+               list_for_each_entry(fmr, fmr_list, list)
+                       mthca_arbel_fmr_unmap(mdev, to_mfmr(fmr));
+
+               wmb();
+       } else
+               list_for_each_entry(fmr, fmr_list, list)
+                       mthca_tavor_fmr_unmap(mdev, to_mfmr(fmr));
+
+       err = mthca_SYNC_TPT(mdev, &status);
+       if (err)
+               return err;
+       if (status)
+               return -EINVAL;
        return 0;
 }
 
@@ -576,11 +659,18 @@
 static ssize_t show_hca(struct class_device *cdev, char *buf)
 {
        struct mthca_dev *dev = container_of(cdev, struct mthca_dev, 
ib_dev.class_dev);
-       switch (dev->hca_type) {
-       case TAVOR:        return sprintf(buf, "MT23108\n");
-       case ARBEL_COMPAT: return sprintf(buf, "MT25208 (MT23108 compat 
mode)\n");
-       case ARBEL_NATIVE: return sprintf(buf, "MT25208\n");
-       default:           return sprintf(buf, "unknown\n");
+       switch (dev->pdev->device) {
+       case PCI_DEVICE_ID_MELLANOX_TAVOR:
+               return sprintf(buf, "MT23108\n");
+       case PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT:
+               return sprintf(buf, "MT25208 (MT23108 compat mode)\n");
+       case PCI_DEVICE_ID_MELLANOX_ARBEL:
+               return sprintf(buf, "MT25208\n");
+       case PCI_DEVICE_ID_MELLANOX_SINAI:
+       case PCI_DEVICE_ID_MELLANOX_SINAI_OLD:
+               return sprintf(buf, "MT25204\n");
+       default:
+               return sprintf(buf, "unknown\n");
        }
 }
 
@@ -622,11 +712,22 @@
        dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
        dev->ib_dev.reg_phys_mr          = mthca_reg_phys_mr;
        dev->ib_dev.dereg_mr             = mthca_dereg_mr;
+
+       if (dev->mthca_flags & MTHCA_FLAG_FMR) {
+               dev->ib_dev.alloc_fmr            = mthca_alloc_fmr;
+               dev->ib_dev.unmap_fmr            = mthca_unmap_fmr;
+               dev->ib_dev.dealloc_fmr          = mthca_dealloc_fmr;
+               if (mthca_is_memfree(dev))
+                       dev->ib_dev.map_phys_fmr = mthca_arbel_map_phys_fmr;
+               else
+                       dev->ib_dev.map_phys_fmr = mthca_tavor_map_phys_fmr;
+       }
+
        dev->ib_dev.attach_mcast         = mthca_multicast_attach;
        dev->ib_dev.detach_mcast         = mthca_multicast_detach;
        dev->ib_dev.process_mad          = mthca_process_mad;
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                dev->ib_dev.req_notify_cq = mthca_arbel_arm_cq;
                dev->ib_dev.post_send     = mthca_arbel_post_send;
                dev->ib_dev.post_recv     = mthca_arbel_post_receive;
diff -urN linux/drivers/infiniband/hw/mthca/mthca_provider.h 
linux/drivers/infiniband/hw/mthca/mthca_provider.h
--- linux/drivers/infiniband/hw/mthca/mthca_provider.h  2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_provider.h  2005/04/29 11:15:07     
1.5
@@ -60,6 +60,24 @@
        u32 first_seg;
 };
 
+struct mthca_fmr {
+       struct ib_fmr ibmr;
+       struct ib_fmr_attr attr;
+       int order;
+       u32 first_seg;
+       int maps;
+       union {
+               struct {
+                       struct mthca_mpt_entry __iomem *mpt;
+                       u64 __iomem *mtts;
+               } tavor;
+               struct {
+                       struct mthca_mpt_entry *mpt;
+                       __be64 *mtts;
+               } arbel;
+       } mem;
+};
+
 struct mthca_pd {
        struct ib_pd    ibpd;
        u32             pd_num;
@@ -218,6 +236,11 @@
        dma_addr_t      header_dma;
 };
 
+static inline struct mthca_fmr *to_mfmr(struct ib_fmr *ibmr)
+{
+       return container_of(ibmr, struct mthca_fmr, ibmr);
+}
+
 static inline struct mthca_mr *to_mmr(struct ib_mr *ibmr)
 {
        return container_of(ibmr, struct mthca_mr, ibmr);
diff -urN linux/drivers/infiniband/hw/mthca/mthca_qp.c 
linux/drivers/infiniband/hw/mthca/mthca_qp.c
--- linux/drivers/infiniband/hw/mthca/mthca_qp.c        2005/03/18 17:37:19     
1.4
+++ linux/drivers/infiniband/hw/mthca/mthca_qp.c        2005/04/29 11:15:07     
1.5
@@ -171,19 +171,6 @@
 };
 
 enum {
-       MTHCA_OPCODE_NOP            = 0x00,
-       MTHCA_OPCODE_RDMA_WRITE     = 0x08,
-       MTHCA_OPCODE_RDMA_WRITE_IMM = 0x09,
-       MTHCA_OPCODE_SEND           = 0x0a,
-       MTHCA_OPCODE_SEND_IMM       = 0x0b,
-       MTHCA_OPCODE_RDMA_READ      = 0x10,
-       MTHCA_OPCODE_ATOMIC_CS      = 0x11,
-       MTHCA_OPCODE_ATOMIC_FA      = 0x12,
-       MTHCA_OPCODE_BIND_MW        = 0x18,
-       MTHCA_OPCODE_INVALID        = 0xff
-};
-
-enum {
        MTHCA_NEXT_DBD       = 1 << 7,
        MTHCA_NEXT_FENCE     = 1 << 6,
        MTHCA_NEXT_CQ_UPDATE = 1 << 3,
@@ -194,6 +181,10 @@
        MTHCA_MLX_SLR        = 1 << 16
 };
 
+enum {
+       MTHCA_INVAL_LKEY = 0x100
+};
+
 struct mthca_next_seg {
        u32 nda_op;             /* [31:6] next WQE [4:0] next opcode */
        u32 ee_nds;             /* [31:8] next EE  [7] DBD [6] F [5:0] next WQE 
size */
@@ -652,7 +643,7 @@
        else if (attr_mask & IB_QP_PATH_MTU)
                qp_context->mtu_msgmax = (attr->path_mtu << 5) | 31;
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                qp_context->rq_size_stride =
                        ((ffs(qp->rq.max) - 1) << 3) | (qp->rq.wqe_shift - 4);
                qp_context->sq_size_stride =
@@ -744,7 +735,7 @@
                qp_context->next_send_psn = cpu_to_be32(attr->sq_psn);
        qp_context->cqn_snd = cpu_to_be32(to_mcq(ibqp->send_cq)->cqn);
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                qp_context->snd_wqe_base_l = cpu_to_be32(qp->send_wqe_offset);
                qp_context->snd_db_index   = cpu_to_be32(qp->sq.db_index);
        }
@@ -835,7 +826,7 @@
 
        qp_context->cqn_rcv = cpu_to_be32(to_mcq(ibqp->recv_cq)->cqn);
 
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                qp_context->rcv_db_index   = cpu_to_be32(qp->rq.db_index);
 
        if (attr_mask & IB_QP_QKEY) {
@@ -910,7 +901,7 @@
                size += 2 * sizeof (struct mthca_data_seg);
                break;
        case UD:
-               if (dev->hca_type == ARBEL_NATIVE)
+               if (mthca_is_memfree(dev))
                        size += sizeof (struct mthca_arbel_ud_seg);
                else
                        size += sizeof (struct mthca_tavor_ud_seg);
@@ -1029,7 +1020,7 @@
 {
        int ret = 0;
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                ret = mthca_table_get(dev, dev->qp_table.qp_table, qp->qpn);
                if (ret)
                        return ret;
@@ -1038,11 +1029,16 @@
                if (ret)
                        goto err_qpc;
 
+               ret = mthca_table_get(dev, dev->qp_table.rdb_table,
+                                     qp->qpn << dev->qp_table.rdb_shift);
+               if (ret)
+                       goto err_eqpc;
+
                qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
                                                 qp->qpn, &qp->rq.db);
                if (qp->rq.db_index < 0) {
                        ret = -ENOMEM;
-                       goto err_eqpc;
+                       goto err_rdb;
                }
 
                qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
@@ -1058,6 +1054,10 @@
 err_rq_db:
        mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
 
+err_rdb:
+       mthca_table_put(dev, dev->qp_table.rdb_table,
+                       qp->qpn << dev->qp_table.rdb_shift);
+
 err_eqpc:
        mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
 
@@ -1070,9 +1070,11 @@
 static void mthca_free_memfree(struct mthca_dev *dev,
                               struct mthca_qp *qp)
 {
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
                mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index);
                mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
+               mthca_table_put(dev, dev->qp_table.rdb_table,
+                               qp->qpn << dev->qp_table.rdb_shift);
                mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
                mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
        }
@@ -1095,7 +1097,6 @@
                                 enum ib_sig_type send_policy,
                                 struct mthca_qp *qp)
 {
-       struct mthca_next_seg *wqe;
        int ret;
        int i;
 
@@ -1117,19 +1118,29 @@
                return ret;
        }
 
-       if (dev->hca_type == ARBEL_NATIVE) {
+       if (mthca_is_memfree(dev)) {
+               struct mthca_next_seg *next;
+               struct mthca_data_seg *scatter;
+               int size = (sizeof (struct mthca_next_seg) +
+                           qp->rq.max_gs * sizeof (struct mthca_data_seg)) / 
16;
+
                for (i = 0; i < qp->rq.max; ++i) {
-                       wqe = get_recv_wqe(qp, i);
-                       wqe->nda_op = cpu_to_be32(((i + 1) & (qp->rq.max - 1)) 
<<
-                                                 qp->rq.wqe_shift);
-                       wqe->ee_nds = cpu_to_be32(1 << (qp->rq.wqe_shift - 4));
+                       next = get_recv_wqe(qp, i);
+                       next->nda_op = cpu_to_be32(((i + 1) & (qp->rq.max - 1)) 
<<
+                                                  qp->rq.wqe_shift);
+                       next->ee_nds = cpu_to_be32(size);
+
+                       for (scatter = (void *) (next + 1);
+                            (void *) scatter < (void *) next + (1 << 
qp->rq.wqe_shift);
+                            ++scatter)
+                               scatter->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
                }
 
                for (i = 0; i < qp->sq.max; ++i) {
-                       wqe = get_send_wqe(qp, i);
-                       wqe->nda_op = cpu_to_be32((((i + 1) & (qp->sq.max - 1)) 
<<
-                                                  qp->sq.wqe_shift) +
-                                                 qp->send_wqe_offset);
+                       next = get_send_wqe(qp, i);
+                       next->nda_op = cpu_to_be32((((i + 1) & (qp->sq.max - 
1)) <<
+                                                   qp->sq.wqe_shift) +
+                                                  qp->send_wqe_offset);
                }
        }
 
@@ -1140,7 +1151,7 @@
 {
        int i;
 
-       if (dev->hca_type != ARBEL_NATIVE)
+       if (!mthca_is_memfree(dev))
                return;
 
        for (i = 0; 1 << i < qp->rq.max; ++i)
@@ -1465,7 +1476,7 @@
                        cpu_to_be32(1);
                if (wr->opcode == IB_WR_SEND_WITH_IMM ||
                    wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
-                       ((struct mthca_next_seg *) wqe)->flags = wr->imm_data;
+                       ((struct mthca_next_seg *) wqe)->imm = wr->imm_data;
 
                wqe += sizeof (struct mthca_next_seg);
                size = sizeof (struct mthca_next_seg) / 16;
@@ -1769,12 +1780,59 @@
                        cpu_to_be32(1);
                if (wr->opcode == IB_WR_SEND_WITH_IMM ||
                    wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
-                       ((struct mthca_next_seg *) wqe)->flags = wr->imm_data;
+                       ((struct mthca_next_seg *) wqe)->imm = wr->imm_data;
 
                wqe += sizeof (struct mthca_next_seg);
                size = sizeof (struct mthca_next_seg) / 16;
 
                switch (qp->transport) {
+               case RC:
+                       switch (wr->opcode) {
+                       case IB_WR_ATOMIC_CMP_AND_SWP:
+                       case IB_WR_ATOMIC_FETCH_AND_ADD:
+                               ((struct mthca_raddr_seg *) wqe)->raddr =
+                                       cpu_to_be64(wr->wr.atomic.remote_addr);
+                               ((struct mthca_raddr_seg *) wqe)->rkey =
+                                       cpu_to_be32(wr->wr.atomic.rkey);
+                               ((struct mthca_raddr_seg *) wqe)->reserved = 0;
+
+                               wqe += sizeof (struct mthca_raddr_seg);
+
+                               if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
+                                       ((struct mthca_atomic_seg *) 
wqe)->swap_add =
+                                               cpu_to_be64(wr->wr.atomic.swap);
+                                       ((struct mthca_atomic_seg *) 
wqe)->compare =
+                                               
cpu_to_be64(wr->wr.atomic.compare_add);
+                               } else {
+                                       ((struct mthca_atomic_seg *) 
wqe)->swap_add =
+                                               
cpu_to_be64(wr->wr.atomic.compare_add);
+                                       ((struct mthca_atomic_seg *) 
wqe)->compare = 0;
+                               }
+
+                               wqe += sizeof (struct mthca_atomic_seg);
+                               size += sizeof (struct mthca_raddr_seg) / 16 +
+                                       sizeof (struct mthca_atomic_seg);
+                               break;
+
+                       case IB_WR_RDMA_WRITE:
+                       case IB_WR_RDMA_WRITE_WITH_IMM:
+                       case IB_WR_RDMA_READ:
+                               ((struct mthca_raddr_seg *) wqe)->raddr =
+                                       cpu_to_be64(wr->wr.rdma.remote_addr);
+                               ((struct mthca_raddr_seg *) wqe)->rkey =
+                                       cpu_to_be32(wr->wr.rdma.rkey);
+                               ((struct mthca_raddr_seg *) wqe)->reserved = 0;
+                               wqe += sizeof (struct mthca_raddr_seg);
+                               size += sizeof (struct mthca_raddr_seg) / 16;
+                               break;
+
+                       default:
+                               /* No extra segments required for sends */
+                               break;
+                       }
+
+                       break;
+
                case UD:
                        memcpy(((struct mthca_arbel_ud_seg *) wqe)->av,
                               to_mah(wr->wr.ud.ah)->av, MTHCA_AV_SIZE);
@@ -1941,7 +1999,7 @@
 
                if (i < qp->rq.max_gs) {
                        ((struct mthca_data_seg *) wqe)->byte_count = 0;
-                       ((struct mthca_data_seg *) wqe)->lkey = 
cpu_to_be32(0x100);
+                       ((struct mthca_data_seg *) wqe)->lkey = 
cpu_to_be32(MTHCA_INVAL_LKEY);
                        ((struct mthca_data_seg *) wqe)->addr = 0;
                }
 
@@ -1977,7 +2035,7 @@
        else
                next = get_recv_wqe(qp, index);
 
-       if (dev->hca_type == ARBEL_NATIVE)
+       if (mthca_is_memfree(dev))
                *dbd = 1;
        else
                *dbd = !!(next->ee_nds & cpu_to_be32(MTHCA_NEXT_DBD));
diff -urN linux/drivers/infiniband/hw/mthca/mthca_reset.c 
linux/drivers/infiniband/hw/mthca/mthca_reset.c
--- linux/drivers/infiniband/hw/mthca/mthca_reset.c     2005/03/18 17:37:19     
1.2
+++ linux/drivers/infiniband/hw/mthca/mthca_reset.c     2005/04/29 11:15:07     
1.3
@@ -63,7 +63,7 @@
         * header as well.
         */
 
-       if (mdev->hca_type == TAVOR) {
+       if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) {
                /* Look for the bridge -- its device ID will be 2 more
                   than HCA's device ID. */
                while ((bridge = pci_get_device(mdev->pdev->vendor,
diff -urN linux/drivers/infiniband/ulp/ipoib/ipoib_fs.c 
linux/drivers/infiniband/ulp/ipoib/ipoib_fs.c
--- linux/drivers/infiniband/ulp/ipoib/ipoib_fs.c       2005/01/13 14:06:02     
1.1
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_fs.c       2005/04/29 11:15:07     
1.2
@@ -32,19 +32,16 @@
  * $Id: ipoib_fs.c 1389 2004-12-27 22:56:47Z roland $
  */
 
-#include <linux/pagemap.h>
+#include <linux/err.h>
 #include <linux/seq_file.h>
 
-#include "ipoib.h"
+struct file_operations;
 
-enum {
-       IPOIB_MAGIC = 0x49504942 /* "IPIB" */
-};
+#include <linux/debugfs.h>
+
+#include "ipoib.h"
 
-static DECLARE_MUTEX(ipoib_fs_mutex);
 static struct dentry *ipoib_root;
-static struct super_block *ipoib_sb;
-static LIST_HEAD(ipoib_device_list);
 
 static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
 {
@@ -145,143 +142,34 @@
        .release = seq_release
 };
 
-static struct inode *ipoib_get_inode(void)
-{
-       struct inode *inode = new_inode(ipoib_sb);
-
-       if (inode) {
-               inode->i_mode    = S_IFREG | S_IRUGO;
-               inode->i_uid     = 0;
-               inode->i_gid     = 0;
-               inode->i_blksize = PAGE_CACHE_SIZE;
-               inode->i_blocks  = 0;
-               inode->i_atime   = inode->i_mtime = inode->i_ctime = 
CURRENT_TIME;
-               inode->i_fop     = &ipoib_fops;
-       }
-
-       return inode;
-}
-
-static int __ipoib_create_debug_file(struct net_device *dev)
+int ipoib_create_debug_file(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       struct dentry *dentry;
-       struct inode *inode;
        char name[IFNAMSIZ + sizeof "_mcg"];
 
        snprintf(name, sizeof name, "%s_mcg", dev->name);
 
-       dentry = d_alloc_name(ipoib_root, name);
-       if (!dentry)
-               return -ENOMEM;
-
-       inode = ipoib_get_inode();
-       if (!inode) {
-               dput(dentry);
-               return -ENOMEM;
-       }
-
-       inode->u.generic_ip = dev;
-       priv->mcg_dentry = dentry;
-
-       d_add(dentry, inode);
-
-       return 0;
-}
-
-int ipoib_create_debug_file(struct net_device *dev)
-{
-       struct ipoib_dev_priv *priv = netdev_priv(dev);
-
-       down(&ipoib_fs_mutex);
-
-       list_add_tail(&priv->fs_list, &ipoib_device_list);
-
-       if (!ipoib_sb) {
-               up(&ipoib_fs_mutex);
-               return 0;
-       }
-
-       up(&ipoib_fs_mutex);
+       priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
+                                              ipoib_root, dev, &ipoib_fops);
 
-       return __ipoib_create_debug_file(dev);
+       return priv->mcg_dentry ? 0 : -ENOMEM;
 }
 
 void ipoib_delete_debug_file(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-       down(&ipoib_fs_mutex);
-       list_del(&priv->fs_list);
-       if (!ipoib_sb) {
-               up(&ipoib_fs_mutex);
-               return;
-       }
-       up(&ipoib_fs_mutex);
-
-       if (priv->mcg_dentry) {
-               d_drop(priv->mcg_dentry);
-               simple_unlink(ipoib_root->d_inode, priv->mcg_dentry);
-       }
-}
-
-static int ipoib_fill_super(struct super_block *sb, void *data, int silent)
-{
-       static struct tree_descr ipoib_files[] = {
-               { "" }
-       };
-       struct ipoib_dev_priv *priv;
-       int ret;
-
-       ret = simple_fill_super(sb, IPOIB_MAGIC, ipoib_files);
-       if (ret)
-               return ret;
-
-       ipoib_root = sb->s_root;
-
-       down(&ipoib_fs_mutex);
-
-       ipoib_sb = sb;
-
-       list_for_each_entry(priv, &ipoib_device_list, fs_list) {
-               ret = __ipoib_create_debug_file(priv->dev);
-               if (ret)
-                       break;
-       }
-
-       up(&ipoib_fs_mutex);
-
-       return ret;
-}
-
-static struct super_block *ipoib_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
-{
-       return get_sb_single(fs_type, flags, data, ipoib_fill_super);
+       if (priv->mcg_dentry)
+               debugfs_remove(priv->mcg_dentry);
 }
 
-static void ipoib_kill_sb(struct super_block *sb)
-{
-       down(&ipoib_fs_mutex);
-       ipoib_sb = NULL;
-       up(&ipoib_fs_mutex);
-
-       kill_litter_super(sb);
-}
-
-static struct file_system_type ipoib_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "ipoib_debugfs",
-       .get_sb         = ipoib_get_sb,
-       .kill_sb        = ipoib_kill_sb,
-};
-
 int ipoib_register_debugfs(void)
 {
-       return register_filesystem(&ipoib_fs_type);
+       ipoib_root = debugfs_create_dir("ipoib", NULL);
+       return ipoib_root ? 0 : -ENOMEM;
 }
 
 void ipoib_unregister_debugfs(void)
 {
-       unregister_filesystem(&ipoib_fs_type);
+       debugfs_remove(ipoib_root);
 }
diff -urN linux/drivers/infiniband/ulp/ipoib/ipoib_ib.c 
linux/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux/drivers/infiniband/ulp/ipoib/ipoib_ib.c       2005/03/18 17:37:20     
1.4
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_ib.c       2005/04/29 11:15:07     
1.5
@@ -201,7 +201,7 @@
                        if (wc->slid != priv->local_lid ||
                            wc->src_qp != priv->qp->qp_num) {
                                skb->protocol = ((struct ipoib_header *) 
skb->data)->proto;
-
+                               skb->mac.raw = skb->data;
                                skb_pull(skb, IPOIB_ENCAP_LEN);
 
                                dev->last_rx = jiffies;
diff -urN linux/drivers/infiniband/ulp/ipoib/ipoib_main.c 
linux/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux/drivers/infiniband/ulp/ipoib/ipoib_main.c     2005/03/18 17:37:20     
1.4
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_main.c     2005/04/29 11:15:07     
1.5
@@ -302,11 +302,10 @@
                        .sl            = pathrec->sl,
                        .port_num      = priv->port
                };
+               int path_rate = ib_sa_rate_enum_to_int(pathrec->rate);
 
-               if (ib_sa_rate_enum_to_int(pathrec->rate) > 0)
-                       av.static_rate = (2 * priv->local_rate -
-                                         ib_sa_rate_enum_to_int(pathrec->rate) 
- 1) /
-                               (priv->local_rate ? priv->local_rate : 1);
+               if (path_rate > 0 && priv->local_rate > path_rate)
+                       av.static_rate = (priv->local_rate - 1) / path_rate;
 
                ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n",
                          av.static_rate, priv->local_rate,
@@ -1083,19 +1082,19 @@
 
        return 0;
 
-err_fs:
-       ipoib_unregister_debugfs();
-
 err_wq:
        destroy_workqueue(ipoib_workqueue);
 
+err_fs:
+       ipoib_unregister_debugfs();
+
        return ret;
 }
 
 static void __exit ipoib_cleanup_module(void)
 {
-       ipoib_unregister_debugfs();
        ib_unregister_client(&ipoib_client);
+       ipoib_unregister_debugfs();
        destroy_workqueue(ipoib_workqueue);
 }
 
diff -urN linux/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 
linux/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
--- linux/drivers/infiniband/ulp/ipoib/ipoib_multicast.c        2005/03/18 
17:37:20     1.3
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_multicast.c        2005/04/29 
11:15:07     1.4
@@ -258,13 +258,12 @@
                                .traffic_class = mcast->mcmember.traffic_class
                        }
                };
+               int path_rate = ib_sa_rate_enum_to_int(mcast->mcmember.rate);
 
                av.grh.dgid = mcast->mcmember.mgid;
 
-               if (ib_sa_rate_enum_to_int(mcast->mcmember.rate) > 0)
-                       av.static_rate = (2 * priv->local_rate -
-                                         
ib_sa_rate_enum_to_int(mcast->mcmember.rate) - 1) /
-                               (priv->local_rate ? priv->local_rate : 1);
+               if (path_rate > 0 && priv->local_rate > path_rate)
+                       av.static_rate = (priv->local_rate - 1) / path_rate;
 
                ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, 
mcmember %dX\n",
                                av.static_rate, priv->local_rate,
diff -urN linux/drivers/macintosh/macio_asic.c 
linux/drivers/macintosh/macio_asic.c
--- linux/drivers/macintosh/macio_asic.c        2005/03/18 17:37:24     1.5
+++ linux/drivers/macintosh/macio_asic.c        2005/04/29 11:15:07     1.6
@@ -106,7 +106,7 @@
                drv->shutdown(macio_dev);
 }
 
-static int macio_device_suspend(struct device *dev, u32 state)
+static int macio_device_suspend(struct device *dev, pm_message_t state)
 {
        struct macio_dev * macio_dev = to_macio_device(dev);
        struct macio_driver * drv = to_macio_driver(dev->driver);
diff -urN linux/drivers/macintosh/mediabay.c linux/drivers/macintosh/mediabay.c
--- linux/drivers/macintosh/mediabay.c  2005/03/18 17:37:24     1.23
+++ linux/drivers/macintosh/mediabay.c  2005/04/29 11:15:07     1.24
@@ -704,7 +704,7 @@
 
 }
 
-static int __pmac media_bay_suspend(struct macio_dev *mdev, u32 state)
+static int __pmac media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
 {
        struct media_bay_info   *bay = macio_get_drvdata(mdev);
 
diff -urN linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- linux/drivers/macintosh/via-pmu.c   2005/04/08 18:58:15     1.46
+++ linux/drivers/macintosh/via-pmu.c   2005/04/29 11:15:07     1.47
@@ -2371,7 +2371,7 @@
         * use this but still... This will take care of sysdev's as well, so
         * we exit from here with local irqs disabled and PIC off.
         */
-       ret = device_power_down(PM_SUSPEND_MEM);
+       ret = device_power_down(PMSG_SUSPEND);
        if (ret) {
                wakeup_decrementer();
                local_irq_enable();
@@ -3052,7 +3052,7 @@
 
 static int pmu_sys_suspended = 0;
 
-static int pmu_sys_suspend(struct sys_device *sysdev, u32 state)
+static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
 {
        if (state != PM_SUSPEND_DISK || pmu_sys_suspended)
                return 0;
diff -urN linux/drivers/md/md.c linux/drivers/md/md.c
--- linux/drivers/md/md.c       2005/03/18 17:37:25     1.81
+++ linux/drivers/md/md.c       2005/04/29 11:15:07     1.82
@@ -332,7 +332,7 @@
 static int sync_page_io(struct block_device *bdev, sector_t sector, int size,
                   struct page *page, int rw)
 {
-       struct bio *bio = bio_alloc(GFP_KERNEL, 1);
+       struct bio *bio = bio_alloc(GFP_NOIO, 1);
        struct completion event;
        int ret;
 
@@ -1387,7 +1387,7 @@
  */
 
 
-static int analyze_sbs(mddev_t * mddev)
+static void analyze_sbs(mddev_t * mddev)
 {
        int i;
        struct list_head *tmp;
@@ -1441,7 +1441,6 @@
                       " -- starting background reconstruction\n",
                       mdname(mddev));
 
-       return 0;
 }
 
 int mdp_major = 0;
@@ -1508,10 +1507,9 @@
        struct gendisk *disk;
        char b[BDEVNAME_SIZE];
 
-       if (list_empty(&mddev->disks)) {
-               MD_BUG();
+       if (list_empty(&mddev->disks))
+               /* cannot run an array with no devices.. */
                return -EINVAL;
-       }
 
        if (mddev->pers)
                return -EBUSY;
@@ -1519,10 +1517,8 @@
        /*
         * Analyze all RAID superblock(s)
         */
-       if (!mddev->raid_disks && analyze_sbs(mddev)) {
-               MD_BUG();
-               return -EINVAL;
-       }
+       if (!mddev->raid_disks)
+               analyze_sbs(mddev);
 
        chunk_size = mddev->chunk_size;
        pnum = level_to_pers(mddev->level);
@@ -1548,7 +1544,7 @@
                 * chunk-size has to be a power of 2 and multiples of PAGE_SIZE
                 */
                if ( (1 << ffz(~chunk_size)) != chunk_size) {
-                       MD_BUG();
+                       printk(KERN_ERR "chunk_size of %d not valid\n", 
chunk_size);
                        return -EINVAL;
                }
                if (chunk_size < PAGE_SIZE) {
@@ -1573,11 +1569,6 @@
                }
        }
 
-       if (pnum >= MAX_PERSONALITY) {
-               MD_BUG();
-               return -EINVAL;
-       }
-
 #ifdef CONFIG_KMOD
        if (!pers[pnum])
        {
@@ -1762,10 +1753,8 @@
        struct list_head *tmp;
        int err;
 
-       if (list_empty(&mddev->disks)) {
-               MD_BUG();
+       if (list_empty(&mddev->disks))
                return;
-       }
 
        printk(KERN_INFO "md: running: ");
 
@@ -2840,16 +2829,6 @@
        return thread;
 }
 
-static void md_interrupt_thread(mdk_thread_t *thread)
-{
-       if (!thread->tsk) {
-               MD_BUG();
-               return;
-       }
-       dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
-       send_sig(SIGKILL, thread->tsk, 1);
-}
-
 void md_unregister_thread(mdk_thread_t *thread)
 {
        struct completion event;
@@ -2857,9 +2836,15 @@
        init_completion(&event);
 
        thread->event = &event;
+
+       /* As soon as ->run is set to NULL, the task could disappear,
+        * so we need to hold tasklist_lock until we have sent the signal
+        */
+       dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+       read_lock(&tasklist_lock);
        thread->run = NULL;
-       thread->name = NULL;
-       md_interrupt_thread(thread);
+       send_sig(SIGKILL, thread->tsk, 1);
+       read_unlock(&tasklist_lock);
        wait_for_completion(&event);
        kfree(thread);
 }
@@ -3132,7 +3117,6 @@
        spin_lock(&pers_lock);
        if (pers[pnum]) {
                spin_unlock(&pers_lock);
-               MD_BUG();
                return -EBUSY;
        }
 
@@ -3144,10 +3128,8 @@
 
 int unregister_md_personality(int pnum)
 {
-       if (pnum >= MAX_PERSONALITY) {
-               MD_BUG();
+       if (pnum >= MAX_PERSONALITY)
                return -EINVAL;
-       }
 
        printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
        spin_lock(&pers_lock);
diff -urN linux/drivers/media/dvb/cinergyT2/cinergyT2.c 
linux/drivers/media/dvb/cinergyT2/cinergyT2.c
--- linux/drivers/media/dvb/cinergyT2/cinergyT2.c       2005/03/18 17:37:26     
1.4
+++ linux/drivers/media/dvb/cinergyT2/cinergyT2.c       2005/04/29 11:15:07     
1.5
@@ -879,7 +879,7 @@
        kfree(cinergyt2);
 }
 
-static int cinergyt2_suspend (struct usb_interface *intf, u32 state)
+static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
 {
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
diff -urN linux/drivers/media/video/bttv-cards.c 
linux/drivers/media/video/bttv-cards.c
--- linux/drivers/media/video/bttv-cards.c      2005/03/18 17:37:28     1.34
+++ linux/drivers/media/video/bttv-cards.c      2005/04/29 11:15:07     1.35
@@ -2785,8 +2785,6 @@
         }
        btv->pll.pll_current = -1;
 
-       bttv_reset_audio(btv);
-
        /* tuner configuration (from card list / autodetect / insmod option) */
        if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
                if(UNSET == btv->tuner_type)
diff -urN linux/drivers/media/video/meye.c linux/drivers/media/video/meye.c
--- linux/drivers/media/video/meye.c    2005/03/18 17:37:28     1.28
+++ linux/drivers/media/video/meye.c    2005/04/29 11:15:07     1.29
@@ -1768,7 +1768,7 @@
 };
 
 #ifdef CONFIG_PM
-static int meye_suspend(struct pci_dev *pdev, u32 state)
+static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        pci_save_state(pdev);
        meye.pm_mchip_mode = meye.mchip_mode;
diff -urN linux/drivers/media/video/msp3400.c 
linux/drivers/media/video/msp3400.c
--- linux/drivers/media/video/msp3400.c 2005/04/08 18:58:18     1.33
+++ linux/drivers/media/video/msp3400.c 2005/04/29 11:15:07     1.34
@@ -1426,7 +1426,7 @@
 static int msp_probe(struct i2c_adapter *adap);
 static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
 
-static int msp_suspend(struct device * dev, u32 state, u32 level);
+static int msp_suspend(struct device * dev, pm_message_t state, u32 level);
 static int msp_resume(struct device * dev, u32 level);
 
 static void msp_wake_thread(struct i2c_client *client);
@@ -1834,7 +1834,7 @@
        return 0;
 }
 
-static int msp_suspend(struct device * dev, u32 state, u32 level)
+static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
 {
        struct i2c_client *c = container_of(dev, struct i2c_client, dev);
 
diff -urN linux/drivers/media/video/tda9887.c 
linux/drivers/media/video/tda9887.c
--- linux/drivers/media/video/tda9887.c 2005/03/18 17:37:28     1.18
+++ linux/drivers/media/video/tda9887.c 2005/04/29 11:15:07     1.19
@@ -478,9 +478,9 @@
 /* ---------------------------------------------------------------------- */
 
 static char pal[] = "-";
-module_param_string(pal, pal, 0644, sizeof(pal));
+module_param_string(pal, pal, sizeof(pal), 0644);
 static char secam[] = "-";
-module_param_string(secam, secam, 0644, sizeof(secam));
+module_param_string(secam, secam, sizeof(secam), 0644);
 
 static int tda9887_fixup_std(struct tda9887 *t)
 {
@@ -741,7 +741,7 @@
        return 0;
 }
 
-static int tda9887_suspend(struct device * dev, u32 state, u32 level)
+static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level)
 {
        dprintk("tda9887: suspend\n");
        return 0;
diff -urN linux/drivers/media/video/tuner-core.c 
linux/drivers/media/video/tuner-core.c
--- linux/drivers/media/video/tuner-core.c      2005/03/18 17:37:28     1.1
+++ linux/drivers/media/video/tuner-core.c      2005/04/29 11:15:07     1.2
@@ -162,7 +162,7 @@
 }
 
 static char pal[] = "-";
-module_param_string(pal, pal, 0644, sizeof(pal));
+module_param_string(pal, pal, sizeof(pal), 0644);
 
 static int tuner_fixup_std(struct tuner *t)
 {
@@ -378,7 +378,7 @@
        return 0;
 }
 
-static int tuner_suspend(struct device * dev, u32 state, u32 level)
+static int tuner_suspend(struct device * dev, pm_message_t state, u32 level)
 {
        struct i2c_client *c = container_of(dev, struct i2c_client, dev);
        struct tuner *t = i2c_get_clientdata(c);
diff -urN linux/drivers/message/fusion/mptbase.c 
linux/drivers/message/fusion/mptbase.c
--- linux/drivers/message/fusion/mptbase.c      2005/03/18 17:37:30     1.25
+++ linux/drivers/message/fusion/mptbase.c      2005/04/29 11:15:08     1.26
@@ -1429,7 +1429,7 @@
  *
  */
 static int
-mptbase_suspend(struct pci_dev *pdev, u32 state)
+mptbase_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        u32 device_state;
        MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
diff -urN linux/drivers/message/fusion/mptbase.h 
linux/drivers/message/fusion/mptbase.h
--- linux/drivers/message/fusion/mptbase.h      2005/04/08 18:58:18     1.24
+++ linux/drivers/message/fusion/mptbase.h      2005/04/29 11:15:08     1.25
@@ -215,7 +215,7 @@
        void (*shutdown) (struct device * dev);
 #ifdef CONFIG_PM
        int  (*resume) (struct pci_dev *dev);
-       int  (*suspend) (struct pci_dev *dev, u32 state);
+       int  (*suspend) (struct pci_dev *dev, pm_message_t state);
 #endif
 };
 
diff -urN linux/drivers/message/fusion/mptscsih.c 
linux/drivers/message/fusion/mptscsih.c
--- linux/drivers/message/fusion/mptscsih.c     2005/04/08 18:58:18     1.38
+++ linux/drivers/message/fusion/mptscsih.c     2005/04/29 11:15:08     1.39
@@ -220,7 +220,7 @@
 static void mptscsih_remove(struct pci_dev *);
 static void mptscsih_shutdown(struct device *);
 #ifdef CONFIG_PM
-static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
+static int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
 static int mptscsih_resume(struct pci_dev *pdev);
 #endif
 
@@ -1389,7 +1389,7 @@
  *
  */
 static int
-mptscsih_suspend(struct pci_dev *pdev, u32 state)
+mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        mptscsih_shutdown(&pdev->dev);
        return 0;
diff -urN linux/drivers/message/i2o/i2o_config.c 
linux/drivers/message/i2o/i2o_config.c
--- linux/drivers/message/i2o/i2o_config.c      2005/01/25 04:28:22     1.17
+++ linux/drivers/message/i2o/i2o_config.c      2005/04/29 11:15:08     1.18
@@ -54,6 +54,9 @@
 
 extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
 
+static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int 
cmd,
+                        unsigned long arg);
+
 static spinlock_t i2o_config_lock;
 
 #define MODINC(x,y) ((x) = ((x) + 1) % (y))
@@ -538,8 +541,7 @@
 }
 
 #ifdef CONFIG_COMPAT
-static int i2o_cfg_passthru32(unsigned fd, unsigned cmnd, unsigned long arg,
-                             struct file *file)
+static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long 
arg)
 {
        struct i2o_cmd_passthru32 __user *cmd;
        struct i2o_controller *c;
@@ -752,7 +754,26 @@
        return rcode;
 }
 
-#else
+static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, unsigned 
long arg)
+{
+       int ret;
+       lock_kernel();          
+       switch (cmd) { 
+       case I2OGETIOPS:
+               ret = i2o_cfg_ioctl(NULL, file, cmd, arg);
+               break;
+       case I2OPASSTHRU32:
+               ret = i2o_cfg_passthru32(file, cmd, arg);
+               break;
+       default:
+               ret = -ENOIOCTLCMD;
+               break;
+       }
+       unlock_kernel();
+       return ret;
+}
+
+#endif
 
 static int i2o_cfg_passthru(unsigned long arg)
 {
@@ -958,7 +979,6 @@
        kfree(reply);
        return rcode;
 }
-#endif
 
 /*
  * IOCTL Handler
@@ -1013,11 +1033,9 @@
                ret = i2o_cfg_evt_get(arg, fp);
                break;
 
-#ifndef CONFIG_COMPAT
        case I2OPASSTHRU:
                ret = i2o_cfg_passthru(arg);
                break;
-#endif
 
        default:
                osm_debug("unknown ioctl called!\n");
@@ -1105,6 +1123,9 @@
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .ioctl = i2o_cfg_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = i2o_cfg_compat_ioctl,
+#endif
        .open = cfg_open,
        .release = cfg_release,
        .fasync = cfg_fasync,
@@ -1134,19 +1155,11 @@
                misc_deregister(&i2o_miscdev);
                return -EBUSY;
        }
-#ifdef CONFIG_COMPAT
-       register_ioctl32_conversion(I2OPASSTHRU32, i2o_cfg_passthru32);
-       register_ioctl32_conversion(I2OGETIOPS, (void *)sys_ioctl);
-#endif
        return 0;
 }
 
 static void i2o_config_exit(void)
 {
-#ifdef CONFIG_COMPAT
-       unregister_ioctl32_conversion(I2OPASSTHRU32);
-       unregister_ioctl32_conversion(I2OGETIOPS);
-#endif
        misc_deregister(&i2o_miscdev);
        i2o_driver_unregister(&i2o_config_driver);
 }
diff -urN linux/drivers/mmc/mmc.c linux/drivers/mmc/mmc.c
--- linux/drivers/mmc/mmc.c     2005/01/13 14:06:08     1.4
+++ linux/drivers/mmc/mmc.c     2005/04/29 11:15:08     1.5
@@ -884,7 +884,7 @@
  *     @host: mmc host
  *     @state: suspend mode (PM_SUSPEND_xxx)
  */
-int mmc_suspend_host(struct mmc_host *host, u32 state)
+int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
 {
        mmc_claim_host(host);
        mmc_deselect_cards(host);
diff -urN linux/drivers/mmc/mmci.c linux/drivers/mmc/mmci.c
--- linux/drivers/mmc/mmci.c    2005/01/13 14:06:08     1.5
+++ linux/drivers/mmc/mmci.c    2005/04/29 11:15:08     1.6
@@ -603,7 +603,7 @@
 }
 
 #ifdef CONFIG_PM
-static int mmci_suspend(struct amba_device *dev, u32 state)
+static int mmci_suspend(struct amba_device *dev, pm_message_t state)
 {
        struct mmc_host *mmc = amba_get_drvdata(dev);
        int ret = 0;
diff -urN linux/drivers/mmc/pxamci.c linux/drivers/mmc/pxamci.c
--- linux/drivers/mmc/pxamci.c  2005/02/28 15:45:15     1.8
+++ linux/drivers/mmc/pxamci.c  2005/04/29 11:15:08     1.9
@@ -558,7 +558,7 @@
 }
 
 #ifdef CONFIG_PM
-static int pxamci_suspend(struct device *dev, u32 state, u32 level)
+static int pxamci_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        struct mmc_host *mmc = dev_get_drvdata(dev);
        int ret = 0;
diff -urN linux/drivers/mmc/wbsd.c linux/drivers/mmc/wbsd.c
--- linux/drivers/mmc/wbsd.c    2005/01/25 04:28:22     1.3
+++ linux/drivers/mmc/wbsd.c    2005/04/29 11:15:08     1.4
@@ -1563,7 +1563,7 @@
  */
 
 #ifdef CONFIG_PM
-static int wbsd_suspend(struct device *dev, u32 state, u32 level)
+static int wbsd_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        DBGF("Not yet supported\n");
 
diff -urN linux/drivers/mtd/maps/sa1100-flash.c 
linux/drivers/mtd/maps/sa1100-flash.c
--- linux/drivers/mtd/maps/sa1100-flash.c       2004/11/15 11:49:28     1.15
+++ linux/drivers/mtd/maps/sa1100-flash.c       2005/04/29 11:15:08     1.16
@@ -403,7 +403,7 @@
 }
 
 #ifdef CONFIG_PM
-static int sa1100_mtd_suspend(struct device *dev, u32 state, u32 level)
+static int sa1100_mtd_suspend(struct device *dev, pm_message_t state, u32 
level)
 {
        struct sa_info *info = dev_get_drvdata(dev);
        int ret = 0;
diff -urN linux/drivers/net/8139cp.c linux/drivers/net/8139cp.c
--- linux/drivers/net/8139cp.c  2005/01/13 14:06:10     1.35
+++ linux/drivers/net/8139cp.c  2005/04/29 11:15:08     1.36
@@ -1824,7 +1824,7 @@
 }
 
 #ifdef CONFIG_PM
-static int cp_suspend (struct pci_dev *pdev, u32 state)
+static int cp_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev;
        struct cp_private *cp;
diff -urN linux/drivers/net/Kconfig linux/drivers/net/Kconfig
--- linux/drivers/net/Kconfig   2005/04/08 18:58:18     1.64
+++ linux/drivers/net/Kconfig   2005/04/29 11:15:08     1.65
@@ -2052,7 +2052,7 @@
 
 config MV643XX_ETH
        tristate "MV-643XX Ethernet support"
-       depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || 
MOMENCO_OCELOT_3
+       depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || 
MOMENCO_OCELOT_3 || PPC_MULTIPLATFORM
        help
          This driver supports the gigabit Ethernet on the Marvell MV643XX
          chipset which is used in the Momenco Ocelot C Ocelot, Jaguar ATX
diff -urN linux/drivers/net/bmac.c linux/drivers/net/bmac.c
--- linux/drivers/net/bmac.c    2005/01/25 04:28:27     1.29
+++ linux/drivers/net/bmac.c    2005/04/29 11:15:08     1.30
@@ -455,7 +455,7 @@
 }
 
 #ifdef CONFIG_PM
-static int bmac_suspend(struct macio_dev *mdev, u32 state)
+static int bmac_suspend(struct macio_dev *mdev, pm_message_t state)
 {
        struct net_device* dev = macio_get_drvdata(mdev);       
        struct bmac_data *bp = netdev_priv(dev);
diff -urN linux/drivers/net/mv643xx_eth.c linux/drivers/net/mv643xx_eth.c
--- linux/drivers/net/mv643xx_eth.c     2005/03/18 17:37:32     1.4
+++ linux/drivers/net/mv643xx_eth.c     2005/04/29 11:15:08     1.5
@@ -668,7 +668,7 @@
        spin_lock_irq(&mp->lock);
 
        err = request_irq(dev->irq, mv643xx_eth_int_handler,
-                       SA_INTERRUPT | SA_SAMPLE_RANDOM, dev->name, dev);
+                       SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
 
        if (err) {
                printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n",
diff -urN linux/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c
--- linux/drivers/net/pci-skeleton.c    2005/01/13 14:06:10     1.24
+++ linux/drivers/net/pci-skeleton.c    2005/04/29 11:15:08     1.25
@@ -1897,7 +1897,7 @@
 
 #ifdef CONFIG_PM
 
-static int netdrv_suspend (struct pci_dev *pdev, u32 state)
+static int netdrv_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
        struct netdrv_private *tp = dev->priv;
diff -urN linux/drivers/net/r8169.c linux/drivers/net/r8169.c
--- linux/drivers/net/r8169.c   2005/03/18 17:37:32     1.24
+++ linux/drivers/net/r8169.c   2005/04/29 11:15:08     1.25
@@ -1449,7 +1449,7 @@
 
 #ifdef CONFIG_PM
 
-static int rtl8169_suspend(struct pci_dev *pdev, u32 state)
+static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
diff -urN linux/drivers/net/smc91x.c linux/drivers/net/smc91x.c
--- linux/drivers/net/smc91x.c  2005/03/18 17:37:32     1.9
+++ linux/drivers/net/smc91x.c  2005/04/29 11:15:08     1.10
@@ -2278,7 +2278,7 @@
        return 0;
 }
 
-static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
+static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        struct net_device *ndev = dev_get_drvdata(dev);
 
diff -urN linux/drivers/net/typhoon.c linux/drivers/net/typhoon.c
--- linux/drivers/net/typhoon.c 2005/03/18 17:37:32     1.17
+++ linux/drivers/net/typhoon.c 2005/04/29 11:15:08     1.18
@@ -1906,7 +1906,7 @@
         */
        netif_carrier_off(tp->dev);
 
-       pci_enable_wake(tp->pdev, state, 1);
+       pci_enable_wake(tp->pdev, pci_choose_state(pdev, state), 1);
        pci_disable_device(pdev);
        return pci_set_power_state(pdev, pci_choose_state(pdev, state));
 }
@@ -2287,7 +2287,7 @@
 }
 
 static int
-typhoon_enable_wake(struct pci_dev *pdev, u32 state, int enable)
+typhoon_enable_wake(struct pci_dev *pdev, pci_power_t state, int enable)
 {
        return pci_enable_wake(pdev, state, enable);
 }
diff -urN linux/drivers/net/irda/Kconfig linux/drivers/net/irda/Kconfig
--- linux/drivers/net/irda/Kconfig      2004/08/06 00:33:27     1.13
+++ linux/drivers/net/irda/Kconfig      2005/04/29 11:15:08     1.14
@@ -310,7 +310,7 @@
 
 config NSC_FIR
        tristate "NSC PC87108/PC87338"
-       depends on IRDA && ISA
+       depends on IRDA
        help
          Say Y here if you want to build support for the NSC PC87108 and
          PC87338 IrDA chipsets.  This driver supports SIR,
@@ -321,7 +321,7 @@
 
 config WINBOND_FIR
        tristate "Winbond W83977AF (IR)"
-       depends on IRDA && ISA
+       depends on IRDA
        help
          Say Y here if you want to build IrDA support for the Winbond
          W83977AF super-io chipset.  This driver should be used for the IrDA
@@ -347,7 +347,7 @@
 
 config SMC_IRCC_FIR
        tristate "SMSC IrCC (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && IRDA && ISA
+       depends on EXPERIMENTAL && IRDA
        help
          Say Y here if you want to build support for the SMC Infrared
          Communications Controller.  It is used in a wide variety of
@@ -357,7 +357,7 @@
 
 config ALI_FIR
        tristate "ALi M5123 FIR (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && IRDA && ISA
+       depends on EXPERIMENTAL && IRDA
        help
          Say Y here if you want to build support for the ALi M5123 FIR
          Controller.  The ALi M5123 FIR Controller is embedded in ALi M1543C,
@@ -385,7 +385,7 @@
 
 config VIA_FIR
        tristate "VIA VT8231/VT1211 SIR/MIR/FIR"
-       depends on IRDA && ISA && PCI
+       depends on IRDA
        help
          Say Y here if you want to build support for the VIA VT8231
          and VIA VT1211 IrDA controllers, found on the motherboards using
diff -urN linux/drivers/net/irda/sa1100_ir.c linux/drivers/net/irda/sa1100_ir.c
--- linux/drivers/net/irda/sa1100_ir.c  2004/12/27 02:15:59     1.13
+++ linux/drivers/net/irda/sa1100_ir.c  2005/04/29 11:15:08     1.14
@@ -291,7 +291,7 @@
 /*
  * Suspend the IrDA interface.
  */
-static int sa1100_irda_suspend(struct device *_dev, u32 state, u32 level)
+static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 
level)
 {
        struct net_device *dev = dev_get_drvdata(_dev);
        struct sa1100_irda *si;
diff -urN linux/drivers/net/irda/stir4200.c linux/drivers/net/irda/stir4200.c
--- linux/drivers/net/irda/stir4200.c   2005/03/18 17:37:37     1.8
+++ linux/drivers/net/irda/stir4200.c   2005/04/29 11:15:08     1.9
@@ -1128,8 +1128,8 @@
 }
 
 #ifdef CONFIG_PM
-/* Power management suspend, so power off the transmitter/receiver */
-static int stir_suspend(struct usb_interface *intf, u32 state)
+/* USB suspend, so power off the transmitter/receiver */
+static int stir_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct stir_cb *stir = usb_get_intfdata(intf);
 
diff -urN linux/drivers/net/irda/vlsi_ir.c linux/drivers/net/irda/vlsi_ir.c
--- linux/drivers/net/irda/vlsi_ir.c    2005/04/08 18:58:20     1.26
+++ linux/drivers/net/irda/vlsi_ir.c    2005/04/29 11:15:08     1.27
@@ -1744,7 +1744,7 @@
  */
 
 
-static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state)
+static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *ndev = pci_get_drvdata(pdev);
        vlsi_irda_dev_t *idev;
diff -urN linux/drivers/net/tulip/de2104x.c linux/drivers/net/tulip/de2104x.c
--- linux/drivers/net/tulip/de2104x.c   2005/03/18 17:37:38     1.27
+++ linux/drivers/net/tulip/de2104x.c   2005/04/29 11:15:09     1.28
@@ -2107,7 +2107,7 @@
 
 #ifdef CONFIG_PM
 
-static int de_suspend (struct pci_dev *pdev, u32 state)
+static int de_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
        struct de_private *de = dev->priv;
diff -urN linux/drivers/net/tulip/winbond-840.c 
linux/drivers/net/tulip/winbond-840.c
--- linux/drivers/net/tulip/winbond-840.c       2005/01/25 04:28:36     1.25
+++ linux/drivers/net/tulip/winbond-840.c       2005/04/29 11:15:09     1.26
@@ -1620,7 +1620,7 @@
  * Detach must occur under spin_unlock_irq(), interrupts from a detached
  * device would cause an irq storm.
  */
-static int w840_suspend (struct pci_dev *pdev, u32 state)
+static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
        struct netdev_private *np = netdev_priv(dev);
diff -urN linux/drivers/net/tulip/xircom_tulip_cb.c 
linux/drivers/net/tulip/xircom_tulip_cb.c
--- linux/drivers/net/tulip/xircom_tulip_cb.c   2005/01/13 14:06:15     1.15
+++ linux/drivers/net/tulip/xircom_tulip_cb.c   2005/04/29 11:15:09     1.16
@@ -1655,7 +1655,7 @@
 
 
 #ifdef CONFIG_PM
-static int xircom_suspend(struct pci_dev *pdev, u32 state)
+static int xircom_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct xircom_private *tp = netdev_priv(dev);
diff -urN linux/drivers/net/wireless/airo.c linux/drivers/net/wireless/airo.c
--- linux/drivers/net/wireless/airo.c   2005/04/08 18:58:20     1.53
+++ linux/drivers/net/wireless/airo.c   2005/04/29 11:15:09     1.54
@@ -61,7 +61,7 @@
 
 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
 static void airo_pci_remove(struct pci_dev *);
-static int airo_pci_suspend(struct pci_dev *pdev, u32 state);
+static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
 static int airo_pci_resume(struct pci_dev *pdev);
 
 static struct pci_driver airo_driver = {
@@ -5464,7 +5464,7 @@
 {
 }
 
-static int airo_pci_suspend(struct pci_dev *pdev, u32 state)
+static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct airo_info *ai = dev->priv;
diff -urN linux/drivers/net/wireless/airport.c 
linux/drivers/net/wireless/airport.c
--- linux/drivers/net/wireless/airport.c        2005/03/18 17:37:39     1.20
+++ linux/drivers/net/wireless/airport.c        2005/04/29 11:15:09     1.21
@@ -50,7 +50,7 @@
 };
 
 static int
-airport_suspend(struct macio_dev *mdev, u32 state)
+airport_suspend(struct macio_dev *mdev, pm_message_t state)
 {
        struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
        struct orinoco_private *priv = netdev_priv(dev);
diff -urN linux/drivers/net/wireless/orinoco_pci.c 
linux/drivers/net/wireless/orinoco_pci.c
--- linux/drivers/net/wireless/orinoco_pci.c    2005/03/18 17:37:39     1.15
+++ linux/drivers/net/wireless/orinoco_pci.c    2005/04/29 11:15:09     1.16
@@ -294,7 +294,7 @@
        pci_disable_device(pdev);
 }
 
-static int orinoco_pci_suspend(struct pci_dev *pdev, u32 state)
+static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct orinoco_private *priv = netdev_priv(dev);
@@ -323,7 +323,7 @@
        orinoco_unlock(priv, &flags);
 
        pci_save_state(pdev);
-       pci_set_power_state(pdev, 3);
+       pci_set_power_state(pdev, PCI_D3hot);
 
        return 0;
 }
diff -urN linux/drivers/net/wireless/prism54/islpci_hotplug.c 
linux/drivers/net/wireless/prism54/islpci_hotplug.c
--- linux/drivers/net/wireless/prism54/islpci_hotplug.c 2005/03/02 19:58:01     
1.9
+++ linux/drivers/net/wireless/prism54/islpci_hotplug.c 2005/04/29 11:15:09     
1.10
@@ -81,7 +81,7 @@
 
 static int prism54_probe(struct pci_dev *, const struct pci_device_id *);
 static void prism54_remove(struct pci_dev *);
-static int prism54_suspend(struct pci_dev *, u32 state);
+static int prism54_suspend(struct pci_dev *, pm_message_t state);
 static int prism54_resume(struct pci_dev *);
 
 static struct pci_driver prism54_driver = {
@@ -261,7 +261,7 @@
 }
 
 int
-prism54_suspend(struct pci_dev *pdev, u32 state)
+prism54_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *ndev = pci_get_drvdata(pdev);
        islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
diff -urN linux/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- linux/drivers/pci/quirks.c  2005/04/08 18:58:21     1.62
+++ linux/drivers/pci/quirks.c  2005/04/29 11:15:09     1.63
@@ -1189,6 +1189,7 @@
        case 0x2651:
        case 0x2652:
        case 0x2653:
+       case 0x2680:    /* ESB2 */
                ich = 6;
                break;
        case 0x27c0:
diff -urN linux/drivers/pci/hotplug/pciehp_core.c 
linux/drivers/pci/hotplug/pciehp_core.c
--- linux/drivers/pci/hotplug/pciehp_core.c     2005/01/25 04:28:38     1.7
+++ linux/drivers/pci/hotplug/pciehp_core.c     2005/04/29 11:15:09     1.8
@@ -578,7 +578,7 @@
 }
 
 #ifdef CONFIG_PM
-static int pciehp_suspend (struct pcie_device *dev, u32 state)
+static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
 {
        printk("%s ENTRY\n", __FUNCTION__);     
        return 0;
diff -urN linux/drivers/pci/pcie/portdrv.h linux/drivers/pci/pcie/portdrv.h
--- linux/drivers/pci/pcie/portdrv.h    2005/02/13 20:16:25     1.2
+++ linux/drivers/pci/pcie/portdrv.h    2005/04/29 11:15:09     1.3
@@ -31,7 +31,7 @@
 extern int pcie_port_device_probe(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
 #ifdef CONFIG_PM
-extern int pcie_port_device_suspend(struct pci_dev *dev, u32 state);
+extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state);
 extern int pcie_port_device_resume(struct pci_dev *dev);
 #endif
 extern void pcie_port_device_remove(struct pci_dev *dev);
diff -urN linux/drivers/pci/pcie/portdrv_bus.c 
linux/drivers/pci/pcie/portdrv_bus.c
--- linux/drivers/pci/pcie/portdrv_bus.c        2005/02/13 20:16:25     1.2
+++ linux/drivers/pci/pcie/portdrv_bus.c        2005/04/29 11:15:09     1.3
@@ -15,7 +15,7 @@
 #include <linux/pcieport_if.h>
 
 static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
-static int pcie_port_bus_suspend(struct device *dev, u32 state);
+static int pcie_port_bus_suspend(struct device *dev, pm_message_t state);
 static int pcie_port_bus_resume(struct device *dev);
 
 struct bus_type pcie_port_bus_type = {
@@ -46,7 +46,7 @@
        return 1;
 }
 
-static int pcie_port_bus_suspend(struct device *dev, u32 state)
+static int pcie_port_bus_suspend(struct device *dev, pm_message_t state)
 {
        struct pcie_device *pciedev;
        struct pcie_port_service_driver *driver;
diff -urN linux/drivers/pci/pcie/portdrv_core.c 
linux/drivers/pci/pcie/portdrv_core.c
--- linux/drivers/pci/pcie/portdrv_core.c       2005/02/13 20:16:25     1.2
+++ linux/drivers/pci/pcie/portdrv_core.c       2005/04/29 11:15:09     1.3
@@ -61,7 +61,7 @@
 
 static void pcie_port_shutdown_service(struct device *dev) {}
 
-static int pcie_port_suspend_service(struct device *dev, u32 state, u32 level)
+static int pcie_port_suspend_service(struct device *dev, pm_message_t state, 
u32 level)
 {
        struct pcie_device *pciedev;
        struct pcie_port_service_driver *driver;
@@ -76,7 +76,7 @@
        return 0;
 }
 
-static int pcie_port_resume_service(struct device *dev, u32 state)
+static int pcie_port_resume_service(struct device *dev, u32 level)
 {
        struct pcie_device *pciedev;
        struct pcie_port_service_driver *driver;
@@ -317,7 +317,7 @@
 }
 
 #ifdef CONFIG_PM
-int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
+int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
 {
        struct list_head                *head, *tmp;
        struct device                   *parent, *child;
diff -urN linux/drivers/pci/pcie/portdrv_pci.c 
linux/drivers/pci/pcie/portdrv_pci.c
--- linux/drivers/pci/pcie/portdrv_pci.c        2005/03/18 17:37:42     1.3
+++ linux/drivers/pci/pcie/portdrv_pci.c        2005/04/29 11:15:09     1.4
@@ -67,7 +67,7 @@
 }
 
 #ifdef CONFIG_PM
-static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
+static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
 {
        return pcie_port_device_suspend(dev, state);
 }
diff -urN linux/drivers/pcmcia/au1000_generic.c 
linux/drivers/pcmcia/au1000_generic.c
--- linux/drivers/pcmcia/au1000_generic.c       2005/04/08 18:58:22     1.19
+++ linux/drivers/pcmcia/au1000_generic.c       2005/04/29 11:15:09     1.20
@@ -518,7 +518,7 @@
 }
 
 
-static int au1x00_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
+static int au1x00_drv_pcmcia_suspend(struct device *dev, pm_message_t state, 
u32 level)
 {
        int ret = 0;
        if (level == SUSPEND_SAVE_STATE)
diff -urN linux/drivers/pcmcia/hd64465_ss.c linux/drivers/pcmcia/hd64465_ss.c
--- linux/drivers/pcmcia/hd64465_ss.c   2005/04/08 18:58:22     1.19
+++ linux/drivers/pcmcia/hd64465_ss.c   2005/04/29 11:15:09     1.20
@@ -845,7 +845,7 @@
        local_irq_restore(flags);
 }
 
-static int hd64465_suspend(struct device *dev, u32 state, u32 level)
+static int hd64465_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        int ret = 0;
        if (level == SUSPEND_SAVE_STATE)
diff -urN linux/drivers/pcmcia/m32r_cfc.c linux/drivers/pcmcia/m32r_cfc.c
--- linux/drivers/pcmcia/m32r_cfc.c     2005/04/08 18:58:22     1.6
+++ linux/drivers/pcmcia/m32r_cfc.c     2005/04/29 11:15:09     1.7
@@ -743,7 +743,7 @@
 
 /*====================================================================*/
 
-static int m32r_pcc_suspend(struct device *dev, u32 state, u32 level)
+static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        int ret = 0;
        if (level == SUSPEND_SAVE_STATE)
diff -urN linux/drivers/pcmcia/m32r_pcc.c linux/drivers/pcmcia/m32r_pcc.c
--- linux/drivers/pcmcia/m32r_pcc.c     2005/04/08 18:58:22     1.6
+++ linux/drivers/pcmcia/m32r_pcc.c     2005/04/29 11:15:09     1.7
@@ -696,7 +696,7 @@
 
 /*====================================================================*/
 
-static int m32r_pcc_suspend(struct device *dev, u32 state, u32 level)
+static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        int ret = 0;
        if (level == SUSPEND_SAVE_STATE)
diff -urN linux/drivers/pcmcia/pxa2xx_base.c linux/drivers/pcmcia/pxa2xx_base.c
--- linux/drivers/pcmcia/pxa2xx_base.c  2004/12/27 02:15:59     1.4
+++ linux/drivers/pcmcia/pxa2xx_base.c  2005/04/29 11:15:09     1.5
@@ -205,7 +205,7 @@
 }
 EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
 
-static int pxa2xx_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
+static int pxa2xx_drv_pcmcia_suspend(struct device *dev, pm_message_t state, 
u32 level)
 {
        int ret = 0;
        if (level == SUSPEND_SAVE_STATE)
diff -urN linux/drivers/pcmcia/sa1100_generic.c 
linux/drivers/pcmcia/sa1100_generic.c
--- linux/drivers/pcmcia/sa1100_generic.c       2004/11/15 11:49:30     1.22
+++ linux/drivers/pcmcia/sa1100_generic.c       2005/04/29 11:15:09     1.23
@@ -75,7 +75,7 @@
        return ret;
 }
 
-static int sa11x0_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
+static int sa11x0_drv_pcmcia_suspend(struct device *dev, pm_message_t state, 
u32 level)
 {
        int ret = 0;
        if (level == SUSPEND_SAVE_STATE)
diff -urN linux/drivers/pcmcia/sa1111_generic.c 
linux/drivers/pcmcia/sa1111_generic.c
--- linux/drivers/pcmcia/sa1111_generic.c       2004/11/15 11:49:30     1.16
+++ linux/drivers/pcmcia/sa1111_generic.c       2005/04/29 11:15:09     1.17
@@ -158,7 +158,7 @@
        return 0;
 }
 
-static int pcmcia_suspend(struct sa1111_dev *dev, u32 state)
+static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
 {
        return pcmcia_socket_dev_suspend(&dev->dev, state);
 }
diff -urN linux/drivers/pnp/pnpbios/core.c linux/drivers/pnp/pnpbios/core.c
--- linux/drivers/pnp/pnpbios/core.c    2005/04/08 18:58:22     1.28
+++ linux/drivers/pnp/pnpbios/core.c    2005/04/29 11:15:09     1.29
@@ -512,7 +512,7 @@
        return 0;
 }
 
-static struct dmi_system_id pnpbios_dmi_table[] = {
+static struct dmi_system_id pnpbios_dmi_table[] __initdata = {
        {       /* PnPBIOS GPF on boot */
                .callback = exploding_pnp_bios,
                .ident = "Higraded P14H",
diff -urN linux/drivers/s390/scsi/zfcp_aux.c linux/drivers/s390/scsi/zfcp_aux.c
--- linux/drivers/s390/scsi/zfcp_aux.c  2005/04/08 18:58:23     1.12
+++ linux/drivers/s390/scsi/zfcp_aux.c  2005/04/29 11:15:10     1.13
@@ -52,19 +52,18 @@
 static inline int zfcp_sg_list_copy_to_user(void __user *,
                                            struct zfcp_sg_list *, size_t);
 
-static int zfcp_cfdc_dev_ioctl(struct inode *, struct file *,
-       unsigned int, unsigned long);
+static int zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long);
 
 #define ZFCP_CFDC_IOC_MAGIC                     0xDD
 #define ZFCP_CFDC_IOC \
        _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_sense_data)
 
-#ifdef CONFIG_COMPAT
-static struct ioctl_trans zfcp_ioctl_trans = {ZFCP_CFDC_IOC, (void*) 
sys_ioctl};
-#endif
 
 static struct file_operations zfcp_cfdc_fops = {
-       .ioctl = zfcp_cfdc_dev_ioctl
+       .unlocked_ioctl = zfcp_cfdc_dev_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = zfcp_cfdc_dev_ioctl
+#endif
 };
 
 static struct miscdevice zfcp_cfdc_misc = {
@@ -89,10 +88,10 @@
     ("FCP (SCSI over Fibre Channel) HBA driver for IBM eServer zSeries");
 MODULE_LICENSE("GPL");
 
-module_param(device, charp, 0);
+module_param(device, charp, 0400);
 MODULE_PARM_DESC(device, "specify initial device");
 
-module_param(loglevel, uint, 0);
+module_param(loglevel, uint, 0400);
 MODULE_PARM_DESC(loglevel,
                 "log levels, 8 nibbles: "
                 "FC ERP QDIO CIO Config FSF SCSI Other, "
@@ -308,23 +307,16 @@
        if (!zfcp_transport_template)
                return -ENODEV;
 
-       retval = register_ioctl32_conversion(zfcp_ioctl_trans.cmd,
-                                            zfcp_ioctl_trans.handler);
-       if (retval != 0) {
-               ZFCP_LOG_INFO("registration of ioctl32 conversion failed\n");
-               goto out;
-       }
-
        retval = misc_register(&zfcp_cfdc_misc);
        if (retval != 0) {
                ZFCP_LOG_INFO("registration of misc device "
                              "zfcp_cfdc failed\n");
-               goto out_misc_register;
-       } else {
-               ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n",
-                              ZFCP_CFDC_DEV_MAJOR, zfcp_cfdc_misc.minor);
+               goto out;
        }
 
+       ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n",
+                      ZFCP_CFDC_DEV_MAJOR, zfcp_cfdc_misc.minor);
+
        /* Initialise proc semaphores */
        sema_init(&zfcp_data.config_sema, 1);
 
@@ -348,8 +340,6 @@
 
  out_ccw_register:
        misc_deregister(&zfcp_cfdc_misc);
- out_misc_register:
-       unregister_ioctl32_conversion(zfcp_ioctl_trans.cmd);
  out:
        return retval;
 }
@@ -370,9 +360,9 @@
  *              -EPERM      - Cannot create or queue FSF request or create 
SBALs
  *              -ERESTARTSYS- Received signal (is mapped to EAGAIN by VFS)
  */
-static int
-zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file,
-                    unsigned int command, unsigned long buffer)
+static long
+zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
+                   unsigned long buffer)
 {
        struct zfcp_cfdc_sense_data *sense_data, __user *sense_data_user;
        struct zfcp_adapter *adapter = NULL;
diff -urN linux/drivers/s390/scsi/zfcp_def.h linux/drivers/s390/scsi/zfcp_def.h
--- linux/drivers/s390/scsi/zfcp_def.h  2004/12/27 02:15:59     1.14
+++ linux/drivers/s390/scsi/zfcp_def.h  2005/04/29 11:15:10     1.15
@@ -70,7 +70,7 @@
 /********************* GENERAL DEFINES *********************************/
 
 /* zfcp version number, it consists of major, minor, and patch-level number */
-#define ZFCP_VERSION           "4.2.0"
+#define ZFCP_VERSION           "4.3.0"
 
 /**
  * zfcp_sg_to_address - determine kernel address from struct scatterlist
@@ -851,6 +851,9 @@
        wwn_t                   wwnn;              /* WWNN */
        wwn_t                   wwpn;              /* WWPN */
        fc_id_t                 s_id;              /* N_Port ID */
+       wwn_t                   peer_wwnn;         /* P2P peer WWNN */
+       wwn_t                   peer_wwpn;         /* P2P peer WWPN */
+       fc_id_t                 peer_d_id;         /* P2P peer D_ID */
        struct ccw_device       *ccw_device;       /* S/390 ccw device */
        u8                      fc_service_class;
        u32                     fc_topology;       /* FC topology */
diff -urN linux/drivers/s390/scsi/zfcp_erp.c linux/drivers/s390/scsi/zfcp_erp.c
--- linux/drivers/s390/scsi/zfcp_erp.c  2005/02/13 20:16:26     1.15
+++ linux/drivers/s390/scsi/zfcp_erp.c  2005/04/29 11:15:10     1.16
@@ -2568,6 +2568,23 @@
        case ZFCP_ERP_STEP_UNINITIALIZED:
        case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
        case ZFCP_ERP_STEP_PORT_CLOSING:
+               if (adapter->fc_topology == FSF_TOPO_P2P) {
+                       if (port->wwpn != adapter->peer_wwpn) {
+                               ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "
+                                               "on adapter %s.\nPeer WWPN "
+                                               "0x%016Lx does not match\n",
+                                               port->wwpn,
+                                               
zfcp_get_busid_by_adapter(adapter),
+                                               adapter->peer_wwpn);
+                               zfcp_erp_port_failed(port);
+                               retval = ZFCP_ERP_FAILED;
+                               break;
+                       }
+                       port->d_id = adapter->peer_d_id;
+                       atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, 
&port->status);
+                       retval = zfcp_erp_port_strategy_open_port(erp_action);
+                       break;
+               }
                if (!(adapter->nameserver_port)) {
                        retval = zfcp_nameserver_enqueue(adapter);
                        if (retval != 0) {
@@ -3516,8 +3533,9 @@
        debug_text_event(adapter->erp_dbf, 3, "a_access_unblock");
        debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
 
-       zfcp_erp_port_access_changed(adapter->nameserver_port);
        read_lock_irqsave(&zfcp_data.config_lock, flags);
+       if (adapter->nameserver_port)
+               zfcp_erp_port_access_changed(adapter->nameserver_port);
        list_for_each_entry(port, &adapter->port_list_head, list)
                if (port != adapter->nameserver_port)
                        zfcp_erp_port_access_changed(port);
diff -urN linux/drivers/s390/scsi/zfcp_fsf.c linux/drivers/s390/scsi/zfcp_fsf.c
--- linux/drivers/s390/scsi/zfcp_fsf.c  2005/02/13 20:16:26     1.14
+++ linux/drivers/s390/scsi/zfcp_fsf.c  2005/04/29 11:15:10     1.15
@@ -2107,6 +2107,9 @@
                       bottom->low_qtcb_version, bottom->high_qtcb_version);
        adapter->fsf_lic_version = bottom->lic_version;
        adapter->supported_features = bottom->supported_features;
+       adapter->peer_wwpn = 0;
+       adapter->peer_wwnn = 0;
+       adapter->peer_d_id = 0;
 
        if (xchg_ok) {
                adapter->wwnn = bottom->nport_serv_param.wwnn;
@@ -2124,13 +2127,19 @@
                adapter->hydra_version = 0;
        }
 
+       if (adapter->fc_topology == FSF_TOPO_P2P) {
+               adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
+               adapter->peer_wwpn = bottom->plogi_payload.wwpn;
+               adapter->peer_wwnn = bottom->plogi_payload.wwnn;
+       }
+
        if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){
                adapter->hardware_version = bottom->hardware_version;
                memcpy(adapter->serial_number, bottom->serial_number, 17);
                EBCASC(adapter->serial_number, sizeof(adapter->serial_number));
        }
 
-       ZFCP_LOG_INFO("The adapter %s reported the following characteristics:\n"
+       ZFCP_LOG_NORMAL("The adapter %s reported the following 
characteristics:\n"
                      "WWNN 0x%016Lx, "
                      "WWPN 0x%016Lx, "
                      "S_ID 0x%08x,\n"
@@ -2194,14 +2203,18 @@
                switch (adapter->fc_topology) {
                case FSF_TOPO_P2P:
                        ZFCP_LOG_FLAGS(1, "FSF_TOPO_P2P\n");
-                       ZFCP_LOG_NORMAL("error: Point-to-point fibrechannel "
-                                       "configuration detected at adapter %s "
-                                       "unsupported, shutting down adapter\n",
-                                       zfcp_get_busid_by_adapter(adapter));
+                       ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
+                                       "configuration detected at adapter %s\n"
+                                       "Peer WWNN 0x%016llx, "
+                                       "peer WWPN 0x%016llx, "
+                                       "peer d_id 0x%06x\n",
+                                       zfcp_get_busid_by_adapter(adapter),
+                                       adapter->peer_wwnn,
+                                       adapter->peer_wwpn,
+                                       adapter->peer_d_id);
                        debug_text_event(fsf_req->adapter->erp_dbf, 0,
                                         "top-p-to-p");
-                       zfcp_erp_adapter_shutdown(adapter, 0);
-                       return -EIO;
+                       break;
                case FSF_TOPO_AL:
                        ZFCP_LOG_FLAGS(1, "FSF_TOPO_AL\n");
                        ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
@@ -2226,6 +2239,7 @@
                                        "of a type known to the zfcp "
                                        "driver, shutting down adapter\n",
                                        zfcp_get_busid_by_adapter(adapter));
+                       adapter->fc_topology = FSF_TOPO_ERROR;
                        debug_text_exception(fsf_req->adapter->erp_dbf, 0,
                                             "unknown-topo");
                        zfcp_erp_adapter_shutdown(adapter, 0);
@@ -4281,6 +4295,7 @@
                                      bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
                        zfcp_cmd_dbf_event_fsf("undeffcp", fsf_req, NULL, 0);
                        set_host_byte(&scpnt->result, DID_ERROR);
+                       goto skip_fsfstatus;
                }
        }
 
@@ -4334,7 +4349,7 @@
 
                scpnt->resid = fcp_rsp_iu->fcp_resid;
                if (scpnt->request_bufflen - scpnt->resid < scpnt->underflow)
-                       scpnt->result |= DID_ERROR << 16;
+                       set_host_byte(&scpnt->result, DID_ERROR);
        }
 
  skip_fsfstatus:
@@ -4607,6 +4622,13 @@
                if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) {
                        switch (header->fsf_status_qual.word[0]) {
 
+                       case FSF_SQ_CFDC_HARDENED_ON_SE:
+                               ZFCP_LOG_NORMAL(
+                                       "CFDC on the adapter %s has being "
+                                       "hardened on primary and secondary 
SE\n",
+                                       zfcp_get_busid_by_adapter(adapter));
+                               break;
+
                        case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE:
                                ZFCP_LOG_NORMAL(
                                        "CFDC of the adapter %s could not "
diff -urN linux/drivers/s390/scsi/zfcp_fsf.h linux/drivers/s390/scsi/zfcp_fsf.h
--- linux/drivers/s390/scsi/zfcp_fsf.h  2004/12/04 18:16:06     1.7
+++ linux/drivers/s390/scsi/zfcp_fsf.h  2005/04/29 11:15:10     1.8
@@ -129,6 +129,7 @@
 #define FSF_SQ_NO_RETRY_POSSIBLE               0x07
 
 /* FSF status qualifier for CFDC commands */
+#define FSF_SQ_CFDC_HARDENED_ON_SE             0x00000000
 #define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE     0x00000001
 #define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2    0x00000002
 /* CFDC subtable codes */
@@ -357,7 +358,6 @@
        u8  class3_serv_param[16];
        u8  class4_serv_param[16];
        u8  vendor_version_level[16];
-       u8  res1[16];
 } __attribute__ ((packed));
 
 struct fsf_plogi {
@@ -415,11 +415,13 @@
        u8 res2[12];
        u32 s_id;
        struct fsf_nport_serv_param nport_serv_param;
+       u8 reserved_nport_serv_param[16];
        u8 res3[8];
        u32 adapter_ports;
        u32 hardware_version;
        u8 serial_number[32];
-       u8 res4[272];
+       struct fsf_nport_serv_param plogi_payload;
+       u8 res4[160];
 } __attribute__ ((packed));
 
 struct fsf_qtcb_bottom_port {
diff -urN linux/drivers/s390/scsi/zfcp_sysfs_adapter.c 
linux/drivers/s390/scsi/zfcp_sysfs_adapter.c
--- linux/drivers/s390/scsi/zfcp_sysfs_adapter.c        2004/10/25 20:44:35     
1.7
+++ linux/drivers/s390/scsi/zfcp_sysfs_adapter.c        2005/04/29 11:15:10     
1.8
@@ -65,6 +65,9 @@
 ZFCP_DEFINE_ADAPTER_ATTR(wwnn, "0x%016llx\n", adapter->wwnn);
 ZFCP_DEFINE_ADAPTER_ATTR(wwpn, "0x%016llx\n", adapter->wwpn);
 ZFCP_DEFINE_ADAPTER_ATTR(s_id, "0x%06x\n", adapter->s_id);
+ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn);
+ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn);
+ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
 ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
 ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
 ZFCP_DEFINE_ADAPTER_ATTR(fc_link_speed, "%d Gb/s\n", adapter->fc_link_speed);
@@ -255,6 +258,9 @@
        &dev_attr_wwnn.attr,
        &dev_attr_wwpn.attr,
        &dev_attr_s_id.attr,
+       &dev_attr_peer_wwnn.attr,
+       &dev_attr_peer_wwpn.attr,
+       &dev_attr_peer_d_id.attr,
        &dev_attr_card_version.attr,
        &dev_attr_lic_version.attr,
        &dev_attr_fc_link_speed.attr,
diff -urN linux/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c
--- linux/drivers/scsi/53c700.c 2005/04/08 18:58:23     1.37
+++ linux/drivers/scsi/53c700.c 2005/04/29 11:15:10     1.38
@@ -389,8 +389,7 @@
        host->max_lun = NCR_700_MAX_LUNS;
        BUG_ON(NCR_700_transport_template == NULL);
        host->transportt = NCR_700_transport_template;
-       host->unique_id = hostdata->base;
-       host->base = hostdata->base;
+       host->unique_id = (unsigned long)hostdata->base;
        hostdata->eh_complete = NULL;
        host->hostdata[0] = (unsigned long)hostdata;
        /* kick the chip */
diff -urN linux/drivers/scsi/53c700.h linux/drivers/scsi/53c700.h
--- linux/drivers/scsi/53c700.h 2005/04/08 18:58:23     1.19
+++ linux/drivers/scsi/53c700.h 2005/04/29 11:15:10     1.20
@@ -14,10 +14,6 @@
 #include <scsi/scsi_device.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
@@ -49,13 +45,6 @@
 /* magic byte identifying an internally generated REQUEST_SENSE command */
 #define NCR_700_INTERNAL_SENSE_MAGIC   0x42
 
-/* WARNING: Leave this in for now: the dependency preprocessor doesn't
- * pick up file specific flags, so must define here if they are not
- * set */
-#if !defined(CONFIG_53C700_IO_MAPPED) && !defined(CONFIG_53C700_MEM_MAPPED)
-#error "Config.in must define either CONFIG_53C700_IO_MAPPED or 
CONFIG_53C700_MEM_MAPPED to use this scsi core."
-#endif
-
 struct NCR_700_Host_Parameters;
 
 /* These are the externally used routines */
@@ -184,7 +173,7 @@
 struct NCR_700_Host_Parameters {
        /* These must be filled in by the calling driver */
        int     clock;                  /* board clock speed in MHz */
-       unsigned long   base;           /* the base for the port (copied to 
host) */
+       void __iomem    *base;          /* the base for the port (copied to 
host) */
        struct device   *dev;
        __u32   dmode_extra;    /* adjustable bus settings */
        __u32   differential:1; /* if we are differential */
@@ -199,9 +188,6 @@
        /* 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 */
@@ -246,12 +232,18 @@
 #ifdef CONFIG_53C700_LE_ON_BE
 #define bE     (hostdata->force_le_on_be ? 0 : 3)
 #define        bSWAP   (hostdata->force_le_on_be)
+/* This is terrible, but there's no raw version of ioread32.  That means
+ * that on a be board we swap twice (once in ioread32 and once again to 
+ * get the value correct) */
+#define bS_to_io(x)    ((hostdata->force_le_on_be) ? (x) : cpu_to_le32(x))
 #elif defined(__BIG_ENDIAN)
 #define bE     3
 #define bSWAP  0
+#define bS_to_io(x)    (x)
 #elif defined(__LITTLE_ENDIAN)
 #define bE     0
 #define bSWAP  0
+#define bS_to_io(x)    (x)
 #else
 #error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include 
byteorder.h?"
 #endif
@@ -455,91 +447,42 @@
 
 
 static inline __u8
-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];
-
-       return readb(host->base + (reg^bE));
-}
-
-static inline __u32
-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))
-               = (struct NCR_700_Host_Parameters *)host->hostdata[0];
-#if 1
-       /* sanity check the register */
-       if((reg & 0x3) != 0)
-               BUG();
-#endif
-
-       return bS_to_cpu(value);
-}
-
-static inline void
-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];
-
-       writeb(value, host->base + (reg^bE));
-}
-
-static inline void
-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];
-
-#if 1
-       /* sanity check the register */
-       if((reg & 0x3) != 0)
-               BUG();
-#endif
-
-       __raw_writel(bS_to_host(value), host->base + reg);
-}
-
-static inline __u8
-NCR_700_io_readb(struct Scsi_Host *host, __u32 reg)
+NCR_700_readb(struct Scsi_Host *host, __u32 reg)
 {
-       const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+       const struct NCR_700_Host_Parameters *hostdata
                = (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
-       return inb(host->base + (reg^bE));
+       return ioread8(hostdata->base + (reg^bE));
 }
 
 static inline __u32
-NCR_700_io_readl(struct Scsi_Host *host, __u32 reg)
+NCR_700_readl(struct Scsi_Host *host, __u32 reg)
 {
-       __u32 value = inl(host->base + reg);
-       const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+       const struct NCR_700_Host_Parameters *hostdata
                = (struct NCR_700_Host_Parameters *)host->hostdata[0];
-
+       __u32 value = ioread32(hostdata->base + reg);
 #if 1
        /* sanity check the register */
        if((reg & 0x3) != 0)
                BUG();
 #endif
 
-       return bS_to_cpu(value);
+       return bS_to_io(value);
 }
 
 static inline void
-NCR_700_io_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
 {
-       const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+       const struct NCR_700_Host_Parameters *hostdata
                = (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
-       outb(value, host->base + (reg^bE));
+       iowrite8(value, hostdata->base + (reg^bE));
 }
 
 static inline void
-NCR_700_io_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
 {
-       const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+       const struct NCR_700_Host_Parameters *hostdata
                = (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
 #if 1
@@ -548,102 +491,7 @@
                BUG();
 #endif
 
-       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;
+       iowrite32(bS_to_io(value), hostdata->base + reg);
 }
 
-
-#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 -urN linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
--- linux/drivers/scsi/53c7xx.c 2004/06/26 15:15:18     1.31
+++ linux/drivers/scsi/53c7xx.c 2005/04/29 11:15:10     1.32
@@ -280,6 +280,7 @@
 #endif
 
 #include "scsi.h"
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
 #include "53c7xx.h"
 #include <linux/stat.h>
@@ -1721,9 +1722,9 @@
                printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
                    host->host_no, i, data + 8);
                printk ("scsi%d : status ", host->host_no);
-               print_status (status);
+               scsi_print_status (status);
                printk ("\nscsi%d : message ", host->host_no);
-               print_msg (&msg);
+               scsi_print_msg (&msg);
                printk ("\n");
            } else if (hostdata->test_completed == 3) {
                printk("scsi%d : test 2 no connection with target %d\n",
@@ -2312,7 +2313,7 @@
            printk ("scsi%d : received message", host->host_no);
            if (c) 
                printk (" from target %d lun %d ", c->device->id, 
c->device->lun);
-           print_msg ((unsigned char *) hostdata->msg_buf);
+           scsi_print_msg ((unsigned char *) hostdata->msg_buf);
            printk("\n");
        }
        
@@ -3204,7 +3205,7 @@
     case WRITE_10:
 #if 0
        printk("scsi%d : command is ", host->host_no);
-       print_command(cmd->cmnd);
+       __scsi_print_command(cmd->cmnd);
 #endif
 #if 0
        printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
@@ -3232,7 +3233,7 @@
      */
     default:
        printk("scsi%d : datain+dataout for command ", host->host_no);
-       print_command(cmd->cmnd);
+       __scsi_print_command(cmd->cmnd);
        datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
     }
 
@@ -3938,7 +3939,7 @@
            if (cmd) {
                printk("scsi%d : target %d, lun %d, command ",
                    host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
-               print_command (cmd->cmd->cmnd);
+               __scsi_print_command (cmd->cmd->cmnd);
                printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
                    NCR53c7x0_read32(DSP_REG),
                    bus_to_virt(NCR53c7x0_read32(DSP_REG)));
@@ -4208,7 +4209,7 @@
        if (hostdata->options & OPTION_DEBUG_INTR) {
            printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 
0x%x ", 
                  host->host_no, tmp->pid, tmp->device->id, tmp->device->lun, 
tmp->result);
-           print_command (tmp->cmnd);
+           __scsi_print_command (tmp->cmnd);
        }
 
        tmp->scsi_done(tmp);
@@ -4297,7 +4298,7 @@
                printk("scsi%d : interrupt for pid %lu, id %d, lun %d ", 
                    host->host_no, cmd->cmd->pid, (int) cmd->cmd->device->id,
                    (int) cmd->cmd->device->lun);
-               print_command (cmd->cmd->cmnd);
+               __scsi_print_command (cmd->cmd->cmnd);
            } else {
                printk("scsi%d : no active command\n", host->host_no);
            }
@@ -5539,7 +5540,7 @@
            i > 0 && !check_address ((unsigned long) ptr, 1);
            ptr += len, i -= len) {
            printk("               ");
-           len = print_msg (ptr);
+           len = scsi_print_msg (ptr);
            printk("\n");
            if (!len)
                break;
@@ -5554,7 +5555,7 @@
     if (cmd) {
        printk("               result = 0x%x, target = %d, lun = %d, cmd = ",
            cmd->result, cmd->device->id, cmd->device->lun);
-       print_command(cmd->cmnd);
+       __scsi_print_command(cmd->cmnd);
     } else
        printk("\n");
     printk("        + %d : dsa_next = 0x%x\n", hostdata->dsa_next,
@@ -6028,7 +6029,7 @@
                    virt_to_bus(event.dsa), event.dsa);
            if (event.pid != -1) {
                printk ("         event for pid %ld ", event.pid);
-               print_command (event.cmnd);
+               __scsi_print_command (event.cmnd);
            }
        }
     }
diff -urN linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- linux/drivers/scsi/BusLogic.c       2004/11/15 11:49:31     1.40
+++ linux/drivers/scsi/BusLogic.c       2005/04/29 11:15:10     1.41
@@ -2958,13 +2958,6 @@
        struct BusLogic_CCB *CCB;
        
BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
        /*
-          If this Command has already completed, then no Abort is necessary.
-        */
-       if (Command->serial_number != Command->serial_number_at_timeout) {
-               BusLogic_Warning("Unable to Abort Command to Target %d - " 
"Already Completed\n", HostAdapter, TargetID);
-               return SUCCESS;
-       }
-       /*
           Attempt to find an Active CCB for this Command.  If no Active CCB 
for this
           Command is found, then no Abort is necessary.
         */
diff -urN linux/drivers/scsi/Kconfig linux/drivers/scsi/Kconfig
--- linux/drivers/scsi/Kconfig  2005/03/18 17:37:44     1.46
+++ linux/drivers/scsi/Kconfig  2005/04/29 11:15:10     1.47
@@ -942,11 +942,6 @@
          Unless you have an NCR manufactured machine, the chances are that
          you do not have this SCSI card, so say N.
 
-config 53C700_IO_MAPPED
-       bool
-       depends on SCSI_NCR_D700
-       default y
-
 config SCSI_LASI700
        tristate "HP Lasi SCSI support for 53c700/710"
        depends on GSC && SCSI
@@ -956,11 +951,6 @@
          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
-       depends on SCSI_LASI700
-       default y
-
 config 53C700_LE_ON_BE
        bool
        depends on SCSI_LASI700
@@ -1324,6 +1314,14 @@
 
 source "drivers/scsi/qla2xxx/Kconfig"
 
+config SCSI_LPFC
+       tristate "Emulex LightPulse Fibre Channel Support"
+       depends on PCI && SCSI
+       select SCSI_FC_ATTRS
+       help
+          This lpfc driver supports the Emulex LightPulse
+          Family of Fibre Channel PCI host adapters.
+
 config SCSI_SEAGATE
        tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support"
        depends on X86 && ISA && SCSI && BROKEN
diff -urN linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- linux/drivers/scsi/Makefile 2005/02/28 15:45:16     1.77
+++ linux/drivers/scsi/Makefile 2005/04/29 11:15:10     1.78
@@ -80,6 +80,7 @@
 obj-$(CONFIG_SCSI_QLOGIC_FC)   += qlogicfc.o 
 obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o 
 obj-$(CONFIG_SCSI_QLA2XXX)     += qla2xxx/
+obj-$(CONFIG_SCSI_LPFC)                += lpfc/
 obj-$(CONFIG_SCSI_PAS16)       += pas16.o
 obj-$(CONFIG_SCSI_SEAGATE)     += seagate.o
 obj-$(CONFIG_SCSI_FD_8xx)      += seagate.o
diff -urN linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c
--- linux/drivers/scsi/NCR5380.c        2005/03/18 17:37:44     1.35
+++ linux/drivers/scsi/NCR5380.c        2005/04/29 11:15:10     1.36
@@ -86,6 +86,7 @@
  * 5.  Test linked command handling code after Eric is ready with 
  *      the high level code.
  */
+#include <scsi/scsi_dbg.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), 
(void*)(y)); if ((x)==(y)) udelay(5); }
@@ -2371,7 +2372,7 @@
  * 3..length+1  arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since print_msg() wants the whole thing.  
+ * byte, since scsi_print_msg() wants the whole thing.  
  */
                                        extended_msg[0] = EXTENDED_MESSAGE;
                                        /* Accept first byte by clearing ACK */
@@ -2418,7 +2419,7 @@
                                default:
                                        if (!tmp) {
                                                printk("scsi%d: rejecting 
message ", instance->host_no);
-                                               print_msg(extended_msg);
+                                               scsi_print_msg(extended_msg);
                                                printk("\n");
                                        } else if (tmp != EXTENDED_MESSAGE)
                                                printk("scsi%d: rejecting 
unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, 
cmd->device->id, cmd->device->lun);
@@ -2552,7 +2553,7 @@
 
        if (!(msg[0] & 0x80)) {
                printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", 
instance->host_no);
-               print_msg(msg);
+               scsi_print_msg(msg);
                abort = 1;
        } else {
                /* Accept message by clearing ACK */
@@ -2677,7 +2678,7 @@
        Scsi_Cmnd *tmp, **prev;
        
        printk(KERN_WARNING "scsi%d : aborting command\n", instance->host_no);
-       print_Scsi_Cmnd(cmd);
+       scsi_print_command(cmd);
 
        NCR5380_print_status(instance);
 
diff -urN linux/drivers/scsi/NCR_D700.c linux/drivers/scsi/NCR_D700.c
--- linux/drivers/scsi/NCR_D700.c       2005/04/08 18:58:23     1.17
+++ linux/drivers/scsi/NCR_D700.c       2005/04/29 11:15:10     1.18
@@ -197,12 +197,10 @@
        }
                
        /* Fill in the three required pieces of hostdata */
-       hostdata->base = region;
+       hostdata->base = ioport_map(region, 64);
        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, p->dev);
        if (!host) {
@@ -214,6 +212,7 @@
        /* FIXME: read this from SUS */
        host->this_id = id_array[slot * 2 + siop];
        host->irq = irq;
+       host->base = region;
        scsi_scan_host(host);
 
        return 0;
diff -urN linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- linux/drivers/scsi/advansys.c       2005/03/18 17:37:44     1.48
+++ linux/drivers/scsi/advansys.c       2005/04/29 11:15:10     1.49
@@ -9198,16 +9198,13 @@
         s->use_sg, s->sglist_len, s->abort_reason);
 
     printk(
-" serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n",
-        (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
-         s->retries, s->allowed);
+" serial_number 0x%x, retries %d, allowed %d\n",
+        (unsigned) s->serial_number, s->retries, s->allowed);
 
     printk(
 " timeout_per_command %d, timeout_total %d, timeout %d\n",
         s->timeout_per_command, s->timeout_total, s->timeout);
 
-    printk(" internal_timeout %u\n", s->internal_timeout);
-
     printk(
 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
         (ulong) s->scsi_done, (ulong) s->done,
diff -urN linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- linux/drivers/scsi/aha152x.c        2005/01/13 14:06:20     1.60
+++ linux/drivers/scsi/aha152x.c        2005/04/29 11:15:10     1.61
@@ -257,6 +257,7 @@
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
 #include "aha152x.h"
 
@@ -986,7 +987,7 @@
        if (HOSTDATA(shpnt)->debug & debug_queue) {
                printk(INFO_LEAD "queue: %p; cmd_len=%d pieces=%d size=%u 
cmnd=",
                       CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len, SCpnt->use_sg, 
SCpnt->request_bufflen);
-               print_command(SCpnt->cmnd);
+               __scsi_print_command(SCpnt->cmnd);
        }
 #endif
 
@@ -1560,7 +1561,7 @@
 #if 0
                        if(HOSTDATA(shpnt)->debug & debug_eh) {
                                printk(ERR_LEAD "received sense: ", 
CMDINFO(DONE_SC));
-                               print_sense("bh", DONE_SC);
+                               scsi_print_sense("bh", DONE_SC);
                        }
 #endif
 
@@ -1846,7 +1847,7 @@
 #if defined(AHA152X_DEBUG)
                if (HOSTDATA(shpnt)->debug & debug_msgi) {
                        printk(INFO_LEAD "inbound message %02x ", 
CMDINFO(CURRENT_SC), MSGI(0));
-                       print_msg(&MSGI(0));
+                       scsi_print_msg(&MSGI(0));
                        printk("\n");
                }
 #endif
@@ -1934,7 +1935,7 @@
                                                break;
 
                                        printk(INFO_LEAD, CMDINFO(CURRENT_SC));
-                                       print_msg(&MSGI(0));
+                                       scsi_print_msg(&MSGI(0));
                                        printk("\n");
 
                                        ticks = (MSGI(3) * 4 + 49) / 50;
@@ -2032,7 +2033,7 @@
                int i;
 
                printk(DEBUG_LEAD "messages( ", CMDINFO(CURRENT_SC));
-               for (i=0; i<MSGOLEN; i+=print_msg(&MSGO(i)), printk(" "))
+               for (i=0; i<MSGOLEN; i+=scsi_print_msg(&MSGO(i)), printk(" "))
                        ;
                printk(")\n");
        }
@@ -2104,7 +2105,7 @@
 #if defined(AHA152X_DEBUG)
        if (HOSTDATA(shpnt)->debug & debug_cmd) {
                printk(DEBUG_LEAD "cmd_init: ", CMDINFO(CURRENT_SC));
-               print_command(CURRENT_SC->cmnd);
+               __scsi_print_command(CURRENT_SC->cmnd);
        }
 #endif
 
@@ -2158,7 +2159,7 @@
 #if defined(AHA152X_DEBUG)
        if (HOSTDATA(shpnt)->debug & debug_status) {
                printk(DEBUG_LEAD "inbound status %02x ", CMDINFO(CURRENT_SC), 
CURRENT_SC->SCp.Status);
-               print_status(CURRENT_SC->SCp.Status);
+               scsi_print_status(CURRENT_SC->SCp.Status);
                printk("\n");
        }
 #endif
@@ -2925,7 +2926,7 @@
        printk(KERN_DEBUG "0x%08x: target=%d; lun=%d; cmnd=(",
               (unsigned int) ptr, ptr->device->id, ptr->device->lun);
 
-       print_command(ptr->cmnd);
+       __scsi_print_command(ptr->cmnd);
 
        printk(KERN_DEBUG "); request_bufflen=%d; resid=%d; phase |",
               ptr->request_bufflen, ptr->resid);
diff -urN linux/drivers/scsi/ahci.c linux/drivers/scsi/ahci.c
--- linux/drivers/scsi/ahci.c   2005/04/08 18:58:23     1.10
+++ linux/drivers/scsi/ahci.c   2005/04/29 11:15:10     1.11
@@ -257,6 +257,12 @@
          board_ahci }, /* ICH7R */
        { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_ahci }, /* ULi M5288 */
+       { PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_ahci }, /* ESB2 */
+       { PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_ahci }, /* ESB2 */
+       { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_ahci }, /* ESB2 */
        { }     /* terminate list */
 };
 
diff -urN linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- linux/drivers/scsi/aic7xxx_old.c    2005/02/07 02:54:51     1.41
+++ linux/drivers/scsi/aic7xxx_old.c    2005/04/29 11:15:10     1.42
@@ -2700,12 +2700,12 @@
     struct scatterlist *sg;
 
     sg = (struct scatterlist *)cmd->request_buffer;
-    pci_unmap_sg(p->pdev, sg, cmd->use_sg, 
scsi_to_pci_dma_dir(cmd->sc_data_direction));
+    pci_unmap_sg(p->pdev, sg, cmd->use_sg, cmd->sc_data_direction);
   }
   else if (cmd->request_bufflen)
     pci_unmap_single(p->pdev, aic7xxx_mapping(cmd),
                     cmd->request_bufflen,
-                     scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                     cmd->sc_data_direction);
   if (scb->flags & SCB_SENSE)
   {
     pci_unmap_single(p->pdev,
@@ -10228,7 +10228,7 @@
 
     sg = (struct scatterlist *)cmd->request_buffer;
     scb->sg_length = 0;
-    use_sg = pci_map_sg(p->pdev, sg, cmd->use_sg, 
scsi_to_pci_dma_dir(cmd->sc_data_direction));
+    use_sg = pci_map_sg(p->pdev, sg, cmd->use_sg, cmd->sc_data_direction);
     /*
      * Copy the segments into the SG array.  NOTE!!! - We used to
      * have the first entry both in the data_pointer area and the first
@@ -10256,7 +10256,7 @@
     {
       unsigned int address = pci_map_single(p->pdev, cmd->request_buffer,
                                            cmd->request_bufflen,
-                                            
scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                                            cmd->sc_data_direction);
       aic7xxx_mapping(cmd) = address;
       scb->sg_list[0].address = cpu_to_le32(address);
       scb->sg_list[0].length = cpu_to_le32(cmd->request_bufflen);
diff -urN linux/drivers/scsi/ata_piix.c linux/drivers/scsi/ata_piix.c
--- linux/drivers/scsi/ata_piix.c       2005/03/18 17:37:44     1.19
+++ linux/drivers/scsi/ata_piix.c       2005/04/29 11:15:10     1.20
@@ -61,6 +61,7 @@
        ich6_sata               = 3,
        ich6_sata_rm            = 4,
        ich7_sata               = 5,
+       esb2_sata               = 6,
 };
 
 static int piix_init_one (struct pci_dev *pdev,
@@ -93,6 +94,7 @@
        { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
        { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
        { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
+       { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata },
 
        { }     /* terminate list */
 };
@@ -256,6 +258,18 @@
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
        },
+
+       /* esb2_sata */
+       {
+               .sht            = &piix_sht,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
+                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
+                                 ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &piix_sata_ops,
+       },
 };
 
 static struct pci_bits piix_enable_bits[] = {
diff -urN linux/drivers/scsi/atari_NCR5380.c linux/drivers/scsi/atari_NCR5380.c
--- linux/drivers/scsi/atari_NCR5380.c  2004/04/23 15:54:16     1.12
+++ linux/drivers/scsi/atari_NCR5380.c  2005/04/29 11:15:10     1.13
@@ -73,6 +73,7 @@
  * 1.  Test linked command handling code after Eric is ready with 
  *     the high level code.
  */
+#include <scsi/scsi_dbg.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) \
@@ -2354,7 +2355,7 @@
  * 3..length+1 arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since print_msg() wants the whole thing.  
+ * byte, since scsi_print_msg() wants the whole thing.  
  */
                    extended_msg[0] = EXTENDED_MESSAGE;
                    /* Accept first byte by clearing ACK */
@@ -2407,7 +2408,7 @@
                default:
                    if (!tmp) {
                        printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-                       print_msg (extended_msg);
+                       scsi_print_msg (extended_msg);
                        printk("\n");
                    } else if (tmp != EXTENDED_MESSAGE)
                        printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2540,7 +2541,7 @@
 
     if (!(msg[0] & 0x80)) {
        printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-       print_msg(msg);
+       scsi_print_msg(msg);
        do_abort(instance);
        return;
     }
@@ -2646,7 +2647,7 @@
     unsigned long flags;
 
     printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO);
-    print_Scsi_Cmnd (cmd);
+    scsi_print_command(cmd);
 
     NCR5380_print_status (instance);
 
diff -urN linux/drivers/scsi/constants.c linux/drivers/scsi/constants.c
--- linux/drivers/scsi/constants.c      2005/01/25 04:28:41     1.24
+++ linux/drivers/scsi/constants.c      2005/04/29 11:15:10     1.25
@@ -372,7 +372,7 @@
 
 /**
  *
- *     print_status - print scsi status description
+ *     scsi_print_status - print scsi status description
  *     @scsi_status: scsi status value
  *
  *     If the status is recognized, the description is printed.
diff -urN linux/drivers/scsi/cpqfcTSinit.c linux/drivers/scsi/cpqfcTSinit.c
--- linux/drivers/scsi/cpqfcTSinit.c    2005/03/18 17:37:44     1.42
+++ linux/drivers/scsi/cpqfcTSinit.c    2005/04/29 11:15:10     1.43
@@ -642,12 +642,12 @@
                                return( -EFAULT);
                        }
                }
-               ScsiPassThruReq->sr_data_direction = SCSI_DATA_WRITE; 
+               ScsiPassThruReq->sr_data_direction = DMA_TO_DEVICE; 
        } else if (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) {
-               ScsiPassThruReq->sr_data_direction = SCSI_DATA_READ; 
+               ScsiPassThruReq->sr_data_direction = DMA_FROM_DEVICE;
        } else
                // maybe this means a bug in the user app
-               ScsiPassThruReq->sr_data_direction = SCSI_DATA_NONE;
+               ScsiPassThruReq->sr_data_direction = DMA_BIDIRECTIONAL;
            
        ScsiPassThruReq->sr_cmd_len = 0; // set correctly by scsi_do_req()
        ScsiPassThruReq->sr_sense_buffer[0] = 0;
diff -urN linux/drivers/scsi/cpqfcTSworker.c linux/drivers/scsi/cpqfcTSworker.c
--- linux/drivers/scsi/cpqfcTSworker.c  2004/06/26 15:15:18     1.19
+++ linux/drivers/scsi/cpqfcTSworker.c  2005/04/29 11:15:10     1.20
@@ -5129,7 +5129,7 @@
        for (i=*sgPages_head; i != NULL ;i = next)
        {
                pci_unmap_single(pcidev, i->busaddr, i->maplen, 
-                       scsi_to_pci_dma_dir(PCI_DMA_TODEVICE));
+                       PCI_DMA_TODEVICE);
                i->busaddr = (dma_addr_t) NULL; 
                i->maplen = 0L; 
                next = i->next;
@@ -5195,7 +5195,7 @@
                        contigaddr = ulBuff = pci_map_single(pcidev, 
                                Cmnd->request_buffer, 
                                Cmnd->request_bufflen,
-                               scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                               Cmnd->sc_data_direction);
                        // printk("ms %p ", ulBuff);
                }
                else {
@@ -5224,7 +5224,7 @@
                unsigned long btg;
                contigaddr = pci_map_single(pcidev, Cmnd->request_buffer, 
                                Cmnd->request_bufflen,
-                               scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                               Cmnd->sc_data_direction);
 
                // printk("contigaddr = %p, len = %d\n", 
                //      (void *) contigaddr, bytes_to_go);
@@ -5247,7 +5247,7 @@
  
        sgl = (struct scatterlist*)Cmnd->request_buffer;  
        sg_count = pci_map_sg(pcidev, sgl, Cmnd->use_sg, 
-               scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+               Cmnd->sc_data_direction);
        if( sg_count <= 3 ) {
 
        // we need to be careful here that no individual mapping
@@ -5400,7 +5400,7 @@
 
                cpqfc_undo_SEST_mappings(pcidev, contigaddr, 
                        Cmnd->request_bufflen,
-                       scsi_to_pci_dma_dir(Cmnd->sc_data_direction),
+                       Cmnd->sc_data_direction,
                        sgl, Cmnd->use_sg, sgPages_head, AllocatedPages+1);
 
                // FIXME: testing shows that if we get here, 
@@ -5946,7 +5946,7 @@
        // for each extended scatter gather region needing unmapping... 
        for (i=fcChip->SEST->sgPages[x_ID] ; i != NULL ; i = i->next)
                pci_unmap_single(pcidev, i->busaddr, i->maplen,
-                       scsi_to_pci_dma_dir(PCI_DMA_TODEVICE));
+                       PCI_DMA_TODEVICE);
 }
 
 // Called also from cpqfcTScontrol.o, so can't be static
@@ -5960,14 +5960,14 @@
        if (cmd->use_sg) {      // Used scatter gather list for data buffer?
                cpqfc_pci_unmap_extended_sg(pcidev, fcChip, x_ID);
                pci_unmap_sg(pcidev, cmd->buffer, cmd->use_sg,
-                       scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                       cmd->sc_data_direction);
                // printk("umsg %d\n", cmd->use_sg);
        }
        else if (cmd->request_bufflen) {
                // printk("ums %p ", fcChip->SEST->u[ x_ID ].IWE.GAddr1);
                pci_unmap_single(pcidev, fcChip->SEST->u[ x_ID ].IWE.GAddr1,
                        cmd->request_bufflen,
-                       scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                       cmd->sc_data_direction);
        }        
 }
 
diff -urN linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- linux/drivers/scsi/gdth.c   2005/02/07 02:54:51     1.50
+++ linux/drivers/scsi/gdth.c   2005/04/29 11:15:10     1.51
@@ -4034,7 +4034,7 @@
 }
 
 #ifdef GDTH_STATISTICS
-void gdth_timeout(ulong data)
+static void gdth_timeout(ulong data)
 {
     ulong32 i;
     Scsi_Cmnd *nscp;
@@ -4062,7 +4062,7 @@
 }
 #endif
 
-void __init internal_setup(char *str,int *ints)
+static void __init internal_setup(char *str,int *ints)
 {
     int i, argc;
     char *cur_str, *argv;
@@ -4153,7 +4153,7 @@
     return 1;
 }
 
-int __init gdth_detect(Scsi_Host_Template *shtp)
+static int __init gdth_detect(Scsi_Host_Template *shtp)
 {
     struct Scsi_Host *shp;
     gdth_pci_str pcistr[MAXHA];
@@ -4604,7 +4604,7 @@
 }
 
 
-int gdth_release(struct Scsi_Host *shp)
+static int gdth_release(struct Scsi_Host *shp)
 {
     int hanum;
     gdth_ha_str *ha;
@@ -4691,7 +4691,7 @@
     return("");
 }
 
-const char *gdth_info(struct Scsi_Host *shp)
+static const char *gdth_info(struct Scsi_Host *shp)
 {
     int hanum;
     gdth_ha_str *ha;
@@ -4704,19 +4704,19 @@
 }
 
 /* new error handling */
-int gdth_eh_abort(Scsi_Cmnd *scp)
+static int gdth_eh_abort(Scsi_Cmnd *scp)
 {
     TRACE2(("gdth_eh_abort()\n"));
     return FAILED;
 }
 
-int gdth_eh_device_reset(Scsi_Cmnd *scp)
+static int gdth_eh_device_reset(Scsi_Cmnd *scp)
 {
     TRACE2(("gdth_eh_device_reset()\n"));
     return FAILED;
 }
 
-int gdth_eh_bus_reset(Scsi_Cmnd *scp)
+static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
 {
     int i, hanum;
     gdth_ha_str *ha;
@@ -4770,7 +4770,7 @@
     return SUCCESS;
 }
 
-int gdth_eh_host_reset(Scsi_Cmnd *scp)
+static int gdth_eh_host_reset(Scsi_Cmnd *scp)
 {
     TRACE2(("gdth_eh_host_reset()\n"));
     return FAILED;
@@ -4778,9 +4778,9 @@
 
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-int gdth_bios_param(struct scsi_device *sdev,struct block_device 
*bdev,sector_t cap,int *ip)
+static int gdth_bios_param(struct scsi_device *sdev,struct block_device 
*bdev,sector_t cap,int *ip)
 #else
-int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
+static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
 #endif
 {
     unchar b, t;
@@ -4818,7 +4818,7 @@
 }
 
 
-int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
+static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
 {
     int hanum;
     int priority;
diff -urN linux/drivers/scsi/gdth.h linux/drivers/scsi/gdth.h
--- linux/drivers/scsi/gdth.h   2004/10/12 14:36:37     1.21
+++ linux/drivers/scsi/gdth.h   2005/04/29 11:15:10     1.22
@@ -1029,51 +1029,10 @@
 
 /* function prototyping */
 
-int gdth_detect(Scsi_Host_Template *);
-int gdth_release(struct Scsi_Host *);
-int gdth_queuecommand(Scsi_Cmnd *,void (*done)(Scsi_Cmnd *));
-const char *gdth_info(struct Scsi_Host *);
-
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-int gdth_bios_param(struct scsi_device *,struct block_device *,sector_t,int *);
 int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-int gdth_bios_param(Disk *,kdev_t,int *);
-int gdth_proc_info(char *,char **,off_t,int,int,int);
 #else
-int gdth_bios_param(Disk *,kdev_t,int *);
-extern struct proc_dir_entry proc_scsi_gdth;
 int gdth_proc_info(char *,char **,off_t,int,int,int);
-int gdth_abort(Scsi_Cmnd *);
-int gdth_reset(Scsi_Cmnd *,unsigned int); 
-#define GDTH { proc_dir:        &proc_scsi_gdth,                 \
-               proc_info:       gdth_proc_info,                  \
-               name:            "GDT SCSI Disk Array Controller",\
-               detect:          gdth_detect,                     \
-               release:         gdth_release,                    \
-               info:            gdth_info,                       \
-               command:         NULL,                            \
-               queuecommand:    gdth_queuecommand,               \
-               eh_abort_handler: gdth_eh_abort,                  \
-               eh_device_reset_handler: gdth_eh_device_reset,    \
-               eh_bus_reset_handler: gdth_eh_bus_reset,          \
-               eh_host_reset_handler: gdth_eh_host_reset,        \
-               abort:           gdth_abort,                      \
-               reset:           gdth_reset,                      \
-               bios_param:      gdth_bios_param,                 \
-               can_queue:       GDTH_MAXCMDS,                    \
-               this_id:         -1,                              \
-               sg_tablesize:    GDTH_MAXSG,                      \
-               cmd_per_lun:     GDTH_MAXC_P_L,                   \
-               present:         0,                               \
-               unchecked_isa_dma: 1,                             \
-               use_clustering:  ENABLE_CLUSTERING,               \
-               use_new_eh_code: 1       /* use new error code */ }    
 #endif
 
-int gdth_eh_abort(Scsi_Cmnd *scp);
-int gdth_eh_device_reset(Scsi_Cmnd *scp);
-int gdth_eh_bus_reset(Scsi_Cmnd *scp);
-int gdth_eh_host_reset(Scsi_Cmnd *scp);
-
 #endif
diff -urN linux/drivers/scsi/ips.c linux/drivers/scsi/ips.c
--- linux/drivers/scsi/ips.c    2005/03/18 17:37:44     1.54
+++ linux/drivers/scsi/ips.c    2005/04/29 11:15:10     1.55
@@ -231,9 +231,9 @@
 #endif
 
 #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || 
\
-                         SCSI_DATA_NONE == scb->scsi_cmd->sc_data_direction) ? 
\
+                         DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
                          PCI_DMA_BIDIRECTIONAL : \
-                         scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction))
+                         scb->scsi_cmd->sc_data_direction)
 
 #ifdef IPS_DEBUG
 #define METHOD_TRACE(s, i)    if (ips_debug >= (i+10)) printk(KERN_NOTICE s 
"\n");
@@ -833,13 +833,6 @@
        if (!ha->active)
                return (FAILED);
 
-       if (SC->serial_number != SC->serial_number_at_timeout) {
-               /* HMM, looks like a bogus command */
-               DEBUG(1, "Abort called with bogus scsi command");
-
-               return (FAILED);
-       }
-
        /* See if the command is on the copp queue */
        item = ha->copp_waitlist.head;
        while ((item) && (item->scsi_cmd != SC))
@@ -2856,8 +2849,7 @@
 
                        sg = SC->request_buffer;
                        scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
-                                                  scsi_to_pci_dma_dir(SC->
-                                                                      
sc_data_direction));
+                                                  SC->sc_data_direction);
                        scb->flags |= IPS_SCB_MAP_SG;
                        for (i = 0; i < scb->sg_count; i++) {
                                if (ips_fill_scb_sg_single
@@ -2872,8 +2864,7 @@
                                    pci_map_single(ha->pcidev,
                                                   SC->request_buffer,
                                                   SC->request_bufflen,
-                                                  scsi_to_pci_dma_dir(SC->
-                                                                      
sc_data_direction));
+                                                  SC->sc_data_direction);
                                scb->flags |= IPS_SCB_MAP_SINGLE;
                                ips_fill_scb_sg_single(ha, scb->data_busaddr,
                                                       scb, 0,
diff -urN linux/drivers/scsi/lasi700.c linux/drivers/scsi/lasi700.c
--- linux/drivers/scsi/lasi700.c        2005/04/08 18:58:23     1.18
+++ linux/drivers/scsi/lasi700.c        2005/04/29 11:15:10     1.19
@@ -131,6 +131,7 @@
        if (!host)
                goto out_kfree;
        host->this_id = 7;
+       host->base = base;
        host->irq = dev->irq;
        if(request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, "lasi700", host)) {
                printk(KERN_ERR "lasi700: request_irq failed!\n");
diff -urN linux/drivers/scsi/libata-scsi.c linux/drivers/scsi/libata-scsi.c
--- linux/drivers/scsi/libata-scsi.c    2005/04/08 18:58:23     1.21
+++ linux/drivers/scsi/libata-scsi.c    2005/04/29 11:15:10     1.22
@@ -305,7 +305,7 @@
        sb[0] = 0x70;
        sb[2] = MEDIUM_ERROR;
        sb[7] = 0x0A;
-       if (cmd->sc_data_direction == SCSI_DATA_READ) {
+       if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
                sb[12] = 0x11; /* "unrecovered read error" */
                sb[13] = 0x04;
        } else {
@@ -671,8 +671,8 @@
                return;
 
        /* data is present; dma-map it */
-       if (cmd->sc_data_direction == SCSI_DATA_READ ||
-           cmd->sc_data_direction == SCSI_DATA_WRITE) {
+       if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+           cmd->sc_data_direction == DMA_TO_DEVICE) {
                if (unlikely(cmd->request_bufflen < 1)) {
                        printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w 
req\n",
                               ap->id, dev->devno);
@@ -1304,7 +1304,7 @@
        struct scsi_cmnd *cmd = qc->scsicmd;
        struct ata_device *dev = qc->dev;
        int using_pio = (dev->flags & ATA_DFLAG_PIO);
-       int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE);
+       int nodata = (cmd->sc_data_direction == DMA_NONE);
 
        if (!using_pio)
                /* Check whether ATAPI DMA is safe */
@@ -1316,7 +1316,7 @@
        qc->complete_fn = atapi_qc_complete;
 
        qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       if (cmd->sc_data_direction == SCSI_DATA_WRITE) {
+       if (cmd->sc_data_direction == DMA_TO_DEVICE) {
                qc->tf.flags |= ATA_TFLAG_WRITE;
                DPRINTK("direction: write\n");
        }
@@ -1340,7 +1340,7 @@
 
 #ifdef ATAPI_ENABLE_DMADIR
                /* some SATA bridges need us to indicate data xfer direction */
-               if (cmd->sc_data_direction != SCSI_DATA_WRITE)
+               if (cmd->sc_data_direction != DMA_TO_DEVICE)
                        qc->tf.feature |= ATAPI_DMADIR;
 #endif
        }
diff -urN linux/drivers/scsi/mesh.c linux/drivers/scsi/mesh.c
--- linux/drivers/scsi/mesh.c   2004/12/04 18:16:06     1.24
+++ linux/drivers/scsi/mesh.c   2005/04/29 11:15:10     1.25
@@ -1757,7 +1757,7 @@
 
 
 #ifdef CONFIG_PM
-static int mesh_suspend(struct macio_dev *mdev, u32 state)
+static int mesh_suspend(struct macio_dev *mdev, pm_message_t state)
 {
        struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
        unsigned long flags;
diff -urN linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- linux/drivers/scsi/ncr53c8xx.c      2005/04/08 18:58:23     1.58
+++ linux/drivers/scsi/ncr53c8xx.c      2005/04/29 11:15:10     1.59
@@ -7486,24 +7486,14 @@
        struct scsi_cmnd *done_list;
 
 #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
-       printk("ncr53c8xx_abort: pid=%lu serial_number=%ld 
serial_number_at_timeout=%ld\n",
-               cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
+       printk("ncr53c8xx_abort: pid=%lu serial_number=%ld\n",
+               cmd->pid, cmd->serial_number);
 #else
        printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid);
 #endif
 
        NCR_LOCK_NCB(np, flags);
 
-#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
-       /*
-        * We have to just ignore abort requests in some situations.
-        */
-       if (cmd->serial_number != cmd->serial_number_at_timeout) {
-               sts = SCSI_ABORT_NOT_RUNNING;
-               goto out;
-       }
-#endif
-
        sts = ncr_abort_command(np, cmd);
 out:
        done_list     = np->done_list;
diff -urN linux/drivers/scsi/nsp32.c linux/drivers/scsi/nsp32.c
--- linux/drivers/scsi/nsp32.c  2005/01/13 14:06:20     1.24
+++ linux/drivers/scsi/nsp32.c  2005/04/29 11:15:10     1.25
@@ -3435,7 +3435,7 @@
 #ifdef CONFIG_PM
 
 /* Device suspended */
-static int nsp32_suspend(struct pci_dev *pdev, u32 state)
+static int nsp32_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct Scsi_Host *host = pci_get_drvdata(pdev);
 
@@ -3443,7 +3443,7 @@
 
        pci_save_state     (pdev);
        pci_disable_device (pdev);
-       pci_set_power_state(pdev, state);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
        return 0;
 }
@@ -3457,8 +3457,8 @@
 
        nsp32_msg(KERN_INFO, "pci-resume: pdev=0x%p, slot=%s, host=0x%p", pdev, 
pci_name(pdev), host);
 
-       pci_set_power_state(pdev, 0);
-       pci_enable_wake    (pdev, 0, 0);
+       pci_set_power_state(pdev, PCI_D0);
+       pci_enable_wake    (pdev, PCI_D0, 0);
        pci_restore_state  (pdev);
 
        reg = nsp32_read2(data->BaseAddress, INDEX_REG);
@@ -3479,7 +3479,7 @@
 }
 
 /* Enable wake event */
-static int nsp32_enable_wake(struct pci_dev *pdev, u32 state, int enable)
+static int nsp32_enable_wake(struct pci_dev *pdev, pci_power_t state, int 
enable)
 {
        struct Scsi_Host *host = pci_get_drvdata(pdev);
 
diff -urN linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c
--- linux/drivers/scsi/pci2000.c        2004/06/26 15:15:18     1.34
+++ linux/drivers/scsi/pci2000.c        2005/04/29 11:15:10     1.35
@@ -209,7 +209,7 @@
        if ( SCpnt->use_sg )
                {
                sg = (struct scatterlist *)SCpnt->request_buffer;
-               zc = pci_map_sg (padapter->pdev, sg, SCpnt->use_sg, 
scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
+               zc = pci_map_sg (padapter->pdev, sg, SCpnt->use_sg, 
SCpnt->sc_data_direction);
                for ( z = 0;  z < zc;  z++ )
                        {
                        pdev->scatGath[z].address = cpu_to_le32 (sg_dma_address 
(sg));
@@ -225,7 +225,9 @@
                outl (0, padapter->mb3);
                return TRUE;
                }
-       SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, 
SCpnt->request_buffer, SCpnt->request_bufflen, scsi_to_pci_dma_dir 
(SCpnt->sc_data_direction));
+       SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
+                       SCpnt->request_buffer, SCpnt->request_bufflen,
+                       SCpnt->sc_data_direction);
        outl (SCpnt->SCp.have_data_in, padapter->mb2);
        outl (SCpnt->request_bufflen, padapter->mb3);
        return TRUE;
@@ -340,11 +342,11 @@
                        }
                }
        if ( SCpnt->SCp.have_data_in )
-               pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 
SCpnt->request_bufflen, scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+               pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 
SCpnt->request_bufflen, SCpnt->sc_data_direction);
        else 
                {
                if ( SCpnt->use_sg )
-                       pci_unmap_sg (padapter->pdev, (struct scatterlist 
*)SCpnt->request_buffer, SCpnt->use_sg, 
scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+                       pci_unmap_sg (padapter->pdev, (struct scatterlist 
*)SCpnt->request_buffer, SCpnt->use_sg, SCpnt->sc_data_direction);
                }
 
 irqProceed:;
@@ -438,8 +440,8 @@
        if ( bus )
                {
                DEB (if(*cdb) printk ("\nCDB: %X-  %X %X %X %X %X %X %X %X %X 
%X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], 
cdb[7], cdb[8], cdb[9]));
-               DEB (if(*cdb) printk ("\ntimeout_per_command: %d, 
timeout_total: %d, timeout: %d, internal_timout: %d", 
SCpnt->timeout_per_command,
-                                                         SCpnt->timeout_total, 
SCpnt->timeout, SCpnt->internal_timeout));
+               DEB (if(*cdb) printk ("\ntimeout_per_command: %d, 
timeout_total: %d, timeout: %d", SCpnt->timeout_per_command,
+                                                         SCpnt->timeout_total, 
SCpnt->timeout));
                outl (SCpnt->timeout_per_command, padapter->mb1);
                outb_p (CMD_SCSI_TIMEOUT, padapter->cmd);
                if ( WaitReady (padapter) )
@@ -495,7 +497,7 @@
                                                else
                                                        {
                                                        SCpnt->SCp.have_data_in 
= pci_map_single (padapter->pdev, SCpnt->request_buffer, SCpnt->request_bufflen,
-                                                                               
                          scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+                                                                               
                          SCpnt->sc_data_direction);
                                                        outl 
(SCpnt->SCp.have_data_in, padapter->mb2);
                                                        }
                                                outl (cdb[5], padapter->mb0);
@@ -511,13 +513,13 @@
                                SCpnt->SCp.have_data_in = pci_map_single 
(padapter->pdev,
                                                                          
((struct scatterlist *)SCpnt->request_buffer)->address,
                                                                          
SCpnt->request_bufflen,
-                                                                         
scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
+                                                                         
SCpnt->sc_data_direction);
                                }
                        else
                                {
                                SCpnt->SCp.have_data_in = pci_map_single 
(padapter->pdev, SCpnt->request_buffer,
                                                                          
SCpnt->request_bufflen,
-                                                                         
scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
+                                                                         
SCpnt->sc_data_direction);
                                }
                        outl (SCpnt->SCp.have_data_in, padapter->mb2);
                        outl (SCpnt->request_bufflen, padapter->mb3);
diff -urN linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- linux/drivers/scsi/qlogicfc.c       2005/03/18 17:37:44     1.45
+++ linux/drivers/scsi/qlogicfc.c       2005/04/29 11:15:10     1.46
@@ -1261,7 +1261,7 @@
 
        if (Cmnd->use_sg) {
                sg = (struct scatterlist *) Cmnd->request_buffer;
-               sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, 
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+               sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, 
Cmnd->sc_data_direction);
                cmd->segment_cnt = cpu_to_le16(sg_count);
                ds = cmd->dataseg;
                /* fill in first two sg entries: */
@@ -1307,7 +1307,7 @@
                dma_addr_t busaddr = pci_map_page(hostdata->pci_dev,
                                                  page, offset,
                                                  Cmnd->request_bufflen,
-                                                 
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                 Cmnd->sc_data_direction);
                Cmnd->SCp.dma_handle = busaddr;
 
                cmd->dataseg[0].d_base = cpu_to_le32(pci64_dma_lo32(busaddr));
@@ -1320,7 +1320,7 @@
                cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */
        }
 
-       if (Cmnd->sc_data_direction == SCSI_DATA_WRITE)
+       if (Cmnd->sc_data_direction == DMA_TO_DEVICE)
                cmd->control_flags = cpu_to_le16(CFLAG_WRITE);
        else 
                cmd->control_flags = cpu_to_le16(CFLAG_READ);
@@ -1405,13 +1405,13 @@
                                                 pci_unmap_sg(hostdata->pci_dev,
                                                              (struct 
scatterlist *)Cmnd->buffer,
                                                              Cmnd->use_sg,
-                                                             
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                             
Cmnd->sc_data_direction);
                                         else if (Cmnd->request_bufflen &&
                                                  Cmnd->sc_data_direction != 
PCI_DMA_NONE) {
                                                 
pci_unmap_page(hostdata->pci_dev,
                                                                
Cmnd->SCp.dma_handle,
                                                                
Cmnd->request_bufflen,
-                                                               
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                               
Cmnd->sc_data_direction);
                                         }
 
                                         hostdata->handle_ptrs[i]->result = 
DID_SOFT_ERROR << 16;
@@ -1515,13 +1515,13 @@
                                        pci_unmap_sg(hostdata->pci_dev,
                                                     (struct scatterlist 
*)Cmnd->buffer,
                                                     Cmnd->use_sg,
-                                                    
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                    Cmnd->sc_data_direction);
                                else if (Cmnd->request_bufflen &&
                                         Cmnd->sc_data_direction != 
PCI_DMA_NONE)
                                        pci_unmap_page(hostdata->pci_dev,
                                                       Cmnd->SCp.dma_handle,
                                                       Cmnd->request_bufflen,
-                                                      
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                      Cmnd->sc_data_direction);
                                Cmnd->result = 0x0;
                                (*Cmnd->scsi_done) (Cmnd);
                        } else
@@ -1569,12 +1569,12 @@
                                if (Cmnd->use_sg)
                                        pci_unmap_sg(hostdata->pci_dev,
                                                     (struct scatterlist 
*)Cmnd->buffer, Cmnd->use_sg,
-                                                    
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                    Cmnd->sc_data_direction);
                                else if (Cmnd->request_bufflen && 
Cmnd->sc_data_direction != PCI_DMA_NONE)
                                        pci_unmap_page(hostdata->pci_dev,
                                                       Cmnd->SCp.dma_handle,
                                                       Cmnd->request_bufflen,
-                                                      
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                                      Cmnd->sc_data_direction);
 
                                /* 
                                 * if any of the following are true we do not
diff -urN linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- linux/drivers/scsi/qlogicisp.c      2005/03/18 17:37:44     1.41
+++ linux/drivers/scsi/qlogicisp.c      2005/04/29 11:15:10     1.42
@@ -877,7 +877,7 @@
                ds = cmd->dataseg;
 
                sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg,
-                                     
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                     Cmnd->sc_data_direction);
 
                cmd->segment_cnt = cpu_to_le16(sg_count);
 
@@ -934,7 +934,7 @@
                dma_addr = pci_map_single(hostdata->pci_dev,
                                       Cmnd->request_buffer,
                                       Cmnd->request_bufflen,
-                                      
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                      Cmnd->sc_data_direction);
                Cmnd->SCp.ptr = (char *)(unsigned long) dma_addr;
 
                cmd->dataseg[0].d_base =
@@ -1067,7 +1067,7 @@
                        pci_unmap_sg(hostdata->pci_dev,
                                     (struct scatterlist *)Cmnd->buffer,
                                     Cmnd->use_sg,
-                                    
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                    Cmnd->sc_data_direction);
                else if (Cmnd->request_bufflen)
                        pci_unmap_single(hostdata->pci_dev,
 #ifdef CONFIG_QL_ISP_A64
@@ -1076,7 +1076,7 @@
                                         (u32)((long)Cmnd->SCp.ptr),
 #endif
                                         Cmnd->request_bufflen,
-                                        
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                        Cmnd->sc_data_direction);
 
                isp_outw(out_ptr, host, MBOX5);
                (*Cmnd->scsi_done)(Cmnd);
diff -urN linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux/drivers/scsi/scsi.c   2005/03/18 17:37:44     1.97
+++ linux/drivers/scsi/scsi.c   2005/04/29 11:15:10     1.98
@@ -489,7 +489,7 @@
                        scsi_print_command(cmd);
                        if (status_byte(cmd->result) & CHECK_CONDITION) {
                                /*
-                                * XXX The print_sense formatting/prefix
+                                * XXX The scsi_print_sense formatting/prefix
                                 * doesn't match this function.
                                 */
                                scsi_print_sense("", cmd);
@@ -686,7 +686,6 @@
        cmd->request = sreq->sr_request;
        memcpy(cmd->data_cmnd, sreq->sr_cmnd, sizeof(cmd->data_cmnd));
        cmd->serial_number = 0;
-       cmd->serial_number_at_timeout = 0;
        cmd->bufflen = sreq->sr_bufflen;
        cmd->buffer = sreq->sr_buffer;
        cmd->retries = 0;
@@ -716,7 +715,6 @@
        /*
         * Start the timer ticking.
         */
-       cmd->internal_timeout = NORMAL_TIMEOUT;
        cmd->abort_reason = 0;
        cmd->result = 0;
 
@@ -766,7 +764,6 @@
         * Set the serial numbers back to zero
         */
        cmd->serial_number = 0;
-       cmd->serial_number_at_timeout = 0;
        cmd->state = SCSI_STATE_BHQUEUE;
        cmd->owner = SCSI_OWNER_BH_HANDLER;
 
diff -urN linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- linux/drivers/scsi/scsi.h   2004/06/26 15:15:18     1.64
+++ linux/drivers/scsi/scsi.h   2005/04/29 11:15:10     1.65
@@ -23,7 +23,6 @@
 #include <linux/config.h>          /* for CONFIG_SCSI_LOGGING */
 
 #include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_request.h>
@@ -46,63 +45,6 @@
 struct scsi_target;
 struct scatterlist;
 
-/*
- * Legacy dma direction interfaces.
- *
- * This assumes the pci/sbus dma mapping flags have the same numercial
- * values as the generic dma-mapping ones.  Currently they have but there's
- * no way to check.  Better don't use these interfaces!
- */
-#define SCSI_DATA_UNKNOWN      (DMA_BIDIRECTIONAL)
-#define SCSI_DATA_WRITE                (DMA_TO_DEVICE)
-#define SCSI_DATA_READ         (DMA_FROM_DEVICE)
-#define SCSI_DATA_NONE         (DMA_NONE)
-
-#define scsi_to_pci_dma_dir(scsi_dir)  ((int)(scsi_dir))
-#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
-
-/*
- * Old names for debug prettyprinting functions.
- */
-static inline void print_Scsi_Cmnd(struct scsi_cmnd *cmd)
-{
-       return scsi_print_command(cmd);
-}
-static inline void print_command(unsigned char *cdb)
-{
-       return __scsi_print_command(cdb);
-}
-static inline void print_sense(const char *devclass, struct scsi_cmnd *cmd)
-{
-       return scsi_print_sense(devclass, cmd);
-}
-static inline void print_req_sense(const char *devclass, struct scsi_request 
*req)
-{
-       return scsi_print_req_sense(devclass, req);
-}
-static inline void print_driverbyte(int scsiresult)
-{
-       return scsi_print_driverbyte(scsiresult);
-}
-static inline void print_hostbyte(int scsiresult)
-{
-       return scsi_print_hostbyte(scsiresult);
-}
-static inline void print_status(unsigned char status)
-{
-       return scsi_print_status(status);
-}
-static inline int print_msg(const unsigned char *msg)
-{
-       return scsi_print_msg(msg);
-}
-
-/*
- * 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"
 
diff -urN linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
--- linux/drivers/scsi/scsi_error.c     2005/04/08 18:58:24     1.66
+++ linux/drivers/scsi/scsi_error.c     2005/04/29 11:15:10     1.67
@@ -79,11 +79,6 @@
         */
        scmd->owner = SCSI_OWNER_ERROR_HANDLER;
        scmd->state = SCSI_STATE_FAILED;
-       /*
-        * Set the serial_number_at_timeout to the current
-        * serial_number
-        */
-       scmd->serial_number_at_timeout = scmd->serial_number;
        list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
        set_bit(SHOST_RECOVERY, &shost->shost_state);
        shost->host_failed++;
@@ -481,7 +476,8 @@
  **/
 static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
 {
-       struct Scsi_Host *host = scmd->device->host;
+       struct scsi_device *sdev = scmd->device;
+       struct Scsi_Host *shost = sdev->host;
        DECLARE_MUTEX_LOCKED(sem);
        unsigned long flags;
        int rtn = SUCCESS;
@@ -492,27 +488,27 @@
         */
        scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-       if (scmd->device->scsi_level <= SCSI_2)
+       if (sdev->scsi_level <= SCSI_2)
                scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
-                       (scmd->device->lun << 5 & 0xe0);
+                       (sdev->lun << 5 & 0xe0);
 
        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;
+       shost->eh_action = &sem;
        scmd->request->rq_status = RQ_SCSI_BUSY;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
+       spin_lock_irqsave(shost->host_lock, flags);
        scsi_log_send(scmd);
-       host->hostt->queuecommand(scmd, scsi_eh_done);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+       shost->hostt->queuecommand(scmd, scsi_eh_done);
+       spin_unlock_irqrestore(shost->host_lock, flags);
 
        down(&sem);
        scsi_log_completion(scmd, SUCCESS);
 
-       scmd->device->host->eh_action = NULL;
+       shost->eh_action = NULL;
 
        /*
         * see if timeout.  if so, tell the host to forget about it.
@@ -532,10 +528,10 @@
                 * 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(shost->host_lock, flags);
+               if (shost->hostt->eh_abort_handler)
+                       shost->hostt->eh_abort_handler(scmd);
+               spin_unlock_irqrestore(shost->host_lock, flags);
                        
                scmd->request->rq_status = RQ_SCSI_DONE;
                scmd->owner = SCSI_OWNER_ERROR_HANDLER;
@@ -1061,7 +1057,6 @@
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
                                          __FUNCTION__));
        scmd->owner = SCSI_OWNER_LOWLEVEL;
-       scmd->serial_number_at_timeout = scmd->serial_number;
 
        if (!scmd->device->host->hostt->eh_bus_reset_handler)
                return FAILED;
@@ -1093,7 +1088,6 @@
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
                                          __FUNCTION__));
        scmd->owner = SCSI_OWNER_LOWLEVEL;
-       scmd->serial_number_at_timeout = scmd->serial_number;
 
        if (!scmd->device->host->hostt->eh_host_reset_handler)
                return FAILED;
@@ -1313,6 +1307,9 @@
        case DID_IMM_RETRY:
                return NEEDS_RETRY;
 
+       case DID_REQUEUE:
+               return ADD_TO_MLQUEUE;
+
        case DID_ERROR:
                if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
                    status_byte(scmd->result) == RESERVATION_CONFLICT)
@@ -1839,7 +1836,6 @@
        scmd->bufflen                   = 0;
        scmd->request_buffer            = NULL;
        scmd->request_bufflen           = 0;
-       scmd->internal_timeout          = NORMAL_TIMEOUT;
        scmd->abort_reason              = DID_ABORT;
 
        scmd->cmd_len                   = 0;
diff -urN linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- linux/drivers/scsi/scsi_ioctl.c     2005/03/18 17:37:45     1.50
+++ linux/drivers/scsi/scsi_ioctl.c     2005/04/29 11:15:10     1.51
@@ -27,11 +27,6 @@
 
 #define NORMAL_RETRIES                 5
 #define IOCTL_NORMAL_TIMEOUT                   (10 * HZ)
-#define FORMAT_UNIT_TIMEOUT            (2 * 60 * 60 * HZ)
-#define START_STOP_TIMEOUT             (60 * HZ)
-#define MOVE_MEDIUM_TIMEOUT            (5 * 60 * HZ)
-#define READ_ELEMENT_STATUS_TIMEOUT    (5 * 60 * HZ)
-#define READ_DEFECT_DATA_TIMEOUT       (60 * HZ )  /* ZIP-250 on parallel port 
takes as long! */
 
 #define MAX_BUF PAGE_SIZE
 
diff -urN linux/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c
--- linux/drivers/scsi/scsi_lib.c       2005/04/08 18:58:24     1.75
+++ linux/drivers/scsi/scsi_lib.c       2005/04/29 11:15:10     1.76
@@ -298,7 +298,6 @@
 {
        cmd->owner = SCSI_OWNER_MIDLEVEL;
        cmd->serial_number = 0;
-       cmd->serial_number_at_timeout = 0;
        cmd->abort_reason = 0;
 
        memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
@@ -320,7 +319,6 @@
        memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
        cmd->buffer = cmd->request_buffer;
        cmd->bufflen = cmd->request_bufflen;
-       cmd->internal_timeout = NORMAL_TIMEOUT;
        cmd->abort_reason = 0;
 
        return 1;
@@ -360,9 +358,9 @@
                     shost->host_failed))
                scsi_eh_wakeup(shost);
        spin_unlock(shost->host_lock);
-       spin_lock(&sdev->sdev_lock);
+       spin_lock(sdev->request_queue->queue_lock);
        sdev->device_busy--;
-       spin_unlock_irqrestore(&sdev->sdev_lock, flags);
+       spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
 }
 
 /*
@@ -1425,7 +1423,7 @@
        struct Scsi_Host *shost = sdev->host;
        struct request_queue *q;
 
-       q = blk_init_queue(scsi_request_fn, &sdev->sdev_lock);
+       q = blk_init_queue(scsi_request_fn, NULL);
        if (!q)
                return NULL;
 
diff -urN linux/drivers/scsi/scsi_priv.h linux/drivers/scsi/scsi_priv.h
--- linux/drivers/scsi/scsi_priv.h      2005/02/07 02:54:51     1.16
+++ linux/drivers/scsi/scsi_priv.h      2005/04/29 11:15:10     1.17
@@ -30,11 +30,6 @@
 #define SCSI_REQ_MAGIC         0x75F6D354
 
 /*
- *  Flag bit for the internal_timeout array
- */
-#define NORMAL_TIMEOUT         0
-
-/*
  * Scsi Error Handler Flags
  */
 #define scsi_eh_eflags_chk(scp, flags) \
diff -urN linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- linux/drivers/scsi/scsi_scan.c      2005/04/08 18:58:24     1.75
+++ linux/drivers/scsi/scsi_scan.c      2005/04/29 11:15:10     1.76
@@ -249,7 +249,6 @@
         */
        sdev->borken = 1;
 
-       spin_lock_init(&sdev->sdev_lock);
        sdev->request_queue = scsi_alloc_queue(sdev);
        if (!sdev->request_queue) {
                /* release fn is set up in scsi_sysfs_device_initialise, so
diff -urN linux/drivers/scsi/scsi_sysfs.c linux/drivers/scsi/scsi_sysfs.c
--- linux/drivers/scsi/scsi_sysfs.c     2005/04/08 18:58:24     1.33
+++ linux/drivers/scsi/scsi_sysfs.c     2005/04/29 11:15:10     1.34
@@ -171,6 +171,9 @@
        if (sdev->request_queue) {
                sdev->request_queue->queuedata = NULL;
                scsi_free_queue(sdev->request_queue);
+               /* temporary expedient, try to catch use of queue lock
+                * after free of sdev */
+               sdev->request_queue = NULL;
        }
 
        scsi_target_reap(scsi_target(sdev));
diff -urN linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- linux/drivers/scsi/seagate.c        2004/12/04 18:16:06     1.35
+++ linux/drivers/scsi/seagate.c        2005/04/29 11:15:10     1.36
@@ -103,6 +103,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
 #include "seagate.h"
 
@@ -746,7 +747,7 @@
 
 #if (DEBUG & PRINT_COMMAND)
        printk("scsi%d : target = %d, command = ", hostno, target);
-       print_command((unsigned char *) cmnd);
+       __scsi_print_command((unsigned char *) cmnd);
 #endif
 
 #if (DEBUG & PHASE_RESELECT)
@@ -1553,7 +1554,7 @@
        printk("\n");
 #endif
        printk("scsi%d : status = ", hostno);
-       print_status(status);
+       scsi_print_status(status);
        printk(" message = %02x\n", message);
 #endif
 
diff -urN linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- linux/drivers/scsi/sg.c     2005/03/18 17:37:45     1.81
+++ linux/drivers/scsi/sg.c     2005/04/29 11:15:10     1.82
@@ -18,8 +18,8 @@
  *
  */
 
-static int sg_version_num = 30532;     /* 2 digits for each component */
-#define SG_VERSION_STR "3.5.32"
+static int sg_version_num = 30533;     /* 2 digits for each component */
+#define SG_VERSION_STR "3.5.33"
 
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
@@ -51,6 +51,7 @@
 #include <linux/delay.h>
 
 #include "scsi.h"
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_ioctl.h>
@@ -60,7 +61,7 @@
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20050117";
+static char *sg_version_date = "20050328";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -330,14 +331,13 @@
 static ssize_t
 sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 {
-       int res;
        Sg_device *sdp;
        Sg_fd *sfp;
        Sg_request *srp;
        int req_pack_id = -1;
-       struct sg_header old_hdr;
-       sg_io_hdr_t new_hdr;
        sg_io_hdr_t *hp;
+       struct sg_header *old_hdr = NULL;
+       int retval = 0;
 
        if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
                return -ENXIO;
@@ -346,98 +346,138 @@
        if (!access_ok(VERIFY_WRITE, buf, count))
                return -EFAULT;
        if (sfp->force_packid && (count >= SZ_SG_HEADER)) {
-               if (__copy_from_user(&old_hdr, buf, SZ_SG_HEADER))
-                       return -EFAULT;
-               if (old_hdr.reply_len < 0) {
+               old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL);
+               if (!old_hdr)
+                       return -ENOMEM;
+               if (__copy_from_user(old_hdr, buf, SZ_SG_HEADER)) {
+                       retval = -EFAULT;
+                       goto free_old_hdr;
+               }
+               if (old_hdr->reply_len < 0) {
                        if (count >= SZ_SG_IO_HDR) {
-                               if (__copy_from_user
-                                   (&new_hdr, buf, SZ_SG_IO_HDR))
-                                       return -EFAULT;
-                               req_pack_id = new_hdr.pack_id;
+                               sg_io_hdr_t *new_hdr;
+                               new_hdr = kmalloc(SZ_SG_IO_HDR, GFP_KERNEL);
+                               if (!new_hdr) {
+                                       retval = -ENOMEM;
+                                       goto free_old_hdr;
+                               }
+                               retval =__copy_from_user
+                                   (new_hdr, buf, SZ_SG_IO_HDR);
+                               req_pack_id = new_hdr->pack_id;
+                               kfree(new_hdr);
+                               if (retval) {
+                                       retval = -EFAULT;
+                                       goto free_old_hdr;
+                               }
                        }
                } else
-                       req_pack_id = old_hdr.pack_id;
+                       req_pack_id = old_hdr->pack_id;
        }
        srp = sg_get_rq_mark(sfp, req_pack_id);
        if (!srp) {             /* now wait on packet to arrive */
-               if (sdp->detached)
-                       return -ENODEV;
-               if (filp->f_flags & O_NONBLOCK)
-                       return -EAGAIN;
+               if (sdp->detached) {
+                       retval = -ENODEV;
+                       goto free_old_hdr;
+               }
+               if (filp->f_flags & O_NONBLOCK) {
+                       retval = -EAGAIN;
+                       goto free_old_hdr;
+               }
                while (1) {
-                       res = 0;        /* following is a macro that beats race 
condition */
+                       retval = 0; /* following macro beats race condition */
                        __wait_event_interruptible(sfp->read_wait,
-                               (sdp->detached || (srp = sg_get_rq_mark(sfp, 
req_pack_id))), 
-                                                  res);
-                       if (sdp->detached)
-                               return -ENODEV;
-                       if (0 == res)
+                               (sdp->detached ||
+                               (srp = sg_get_rq_mark(sfp, req_pack_id))), 
+                               retval);
+                       if (sdp->detached) {
+                               retval = -ENODEV;
+                               goto free_old_hdr;
+                       }
+                       if (0 == retval)
                                break;
-                       return res;     /* -ERESTARTSYS because signal hit 
process */
+
+                       /* -ERESTARTSYS as signal hit process */
+                       goto free_old_hdr;
                }
        }
-       if (srp->header.interface_id != '\0')
-               return sg_new_read(sfp, buf, count, srp);
+       if (srp->header.interface_id != '\0') {
+               retval = sg_new_read(sfp, buf, count, srp);
+               goto free_old_hdr;
+       }
 
        hp = &srp->header;
-       memset(&old_hdr, 0, SZ_SG_HEADER);
-       old_hdr.reply_len = (int) hp->timeout;
-       old_hdr.pack_len = old_hdr.reply_len; /* very old, strange behaviour */
-       old_hdr.pack_id = hp->pack_id;
-       old_hdr.twelve_byte =
+       if (old_hdr == NULL) {
+               old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL);
+               if (! old_hdr) {
+                       retval = -ENOMEM;
+                       goto free_old_hdr;
+               }
+       }
+       memset(old_hdr, 0, SZ_SG_HEADER);
+       old_hdr->reply_len = (int) hp->timeout;
+       old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */
+       old_hdr->pack_id = hp->pack_id;
+       old_hdr->twelve_byte =
            ((srp->data.cmd_opcode >= 0xc0) && (12 == hp->cmd_len)) ? 1 : 0;
-       old_hdr.target_status = hp->masked_status;
-       old_hdr.host_status = hp->host_status;
-       old_hdr.driver_status = hp->driver_status;
+       old_hdr->target_status = hp->masked_status;
+       old_hdr->host_status = hp->host_status;
+       old_hdr->driver_status = hp->driver_status;
        if ((CHECK_CONDITION & hp->masked_status) ||
            (DRIVER_SENSE & hp->driver_status))
-               memcpy(old_hdr.sense_buffer, srp->sense_b,
-                      sizeof (old_hdr.sense_buffer));
+               memcpy(old_hdr->sense_buffer, srp->sense_b,
+                      sizeof (old_hdr->sense_buffer));
        switch (hp->host_status) {
        /* This setup of 'result' is for backward compatibility and is best
           ignored by the user who should use target, host + driver status */
        case DID_OK:
        case DID_PASSTHROUGH:
        case DID_SOFT_ERROR:
-               old_hdr.result = 0;
+               old_hdr->result = 0;
                break;
        case DID_NO_CONNECT:
        case DID_BUS_BUSY:
        case DID_TIME_OUT:
-               old_hdr.result = EBUSY;
+               old_hdr->result = EBUSY;
                break;
        case DID_BAD_TARGET:
        case DID_ABORT:
        case DID_PARITY:
        case DID_RESET:
        case DID_BAD_INTR:
-               old_hdr.result = EIO;
+               old_hdr->result = EIO;
                break;
        case DID_ERROR:
-               old_hdr.result = (srp->sense_b[0] == 0 && 
+               old_hdr->result = (srp->sense_b[0] == 0 && 
                                  hp->masked_status == GOOD) ? 0 : EIO;
                break;
        default:
-               old_hdr.result = EIO;
+               old_hdr->result = EIO;
                break;
        }
 
        /* Now copy the result back to the user buffer.  */
        if (count >= SZ_SG_HEADER) {
-               if (__copy_to_user(buf, &old_hdr, SZ_SG_HEADER))
-                       return -EFAULT;
+               if (__copy_to_user(buf, old_hdr, SZ_SG_HEADER)) {
+                       retval = -EFAULT;
+                       goto free_old_hdr;
+               }
                buf += SZ_SG_HEADER;
-               if (count > old_hdr.reply_len)
-                       count = old_hdr.reply_len;
+               if (count > old_hdr->reply_len)
+                       count = old_hdr->reply_len;
                if (count > SZ_SG_HEADER) {
-                       if ((res =
-                            sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)))
-                               return -EFAULT;
+                       if (sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)) {
+                               retval = -EFAULT;
+                               goto free_old_hdr;
+                       }
                }
        } else
-               count = (old_hdr.result == 0) ? 0 : -EIO;
+               count = (old_hdr->result == 0) ? 0 : -EIO;
        sg_finish_rem_req(srp);
-       return count;
+       retval = count;
+free_old_hdr:
+       if (old_hdr)
+               kfree(old_hdr);
+       return retval;
 }
 
 static ssize_t
@@ -707,16 +747,16 @@
        switch (hp->dxfer_direction) {
        case SG_DXFER_TO_FROM_DEV:
        case SG_DXFER_FROM_DEV:
-               SRpnt->sr_data_direction = SCSI_DATA_READ;
+               SRpnt->sr_data_direction = DMA_FROM_DEVICE;
                break;
        case SG_DXFER_TO_DEV:
-               SRpnt->sr_data_direction = SCSI_DATA_WRITE;
+               SRpnt->sr_data_direction = DMA_TO_DEVICE;
                break;
        case SG_DXFER_UNKNOWN:
-               SRpnt->sr_data_direction = SCSI_DATA_UNKNOWN;
+               SRpnt->sr_data_direction = DMA_BIDIRECTIONAL;
                break;
        default:
-               SRpnt->sr_data_direction = SCSI_DATA_NONE;
+               SRpnt->sr_data_direction = DMA_NONE;
                break;
        }
        SRpnt->upper_private_data = srp;
@@ -724,7 +764,7 @@
        srp->data.sglist_len = 0;
        srp->data.bufflen = 0;
        srp->data.buffer = NULL;
-       hp->duration = jiffies; /* unit jiffies now, millisecs after done */
+       hp->duration = jiffies_to_msecs(jiffies);
 /* Now send everything of to mid-level. The next time we hear about this
    packet is when sg_cmd_done() is called (i.e. a callback). */
        scsi_do_req(SRpnt, (void *) cmnd,
@@ -937,8 +977,13 @@
                if (!access_ok(VERIFY_WRITE, p, SZ_SG_REQ_INFO * SG_MAX_QUEUE))
                        return -EFAULT;
                else {
-                       sg_req_info_t rinfo[SG_MAX_QUEUE];
-                       Sg_request *srp;
+                       sg_req_info_t *rinfo;
+                       unsigned int ms;
+
+                       rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
+                                                               GFP_KERNEL);
+                       if (!rinfo)
+                               return -ENOMEM;
                        read_lock_irqsave(&sfp->rq_list_lock, iflags);
                        for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
                             ++val, srp = srp ? srp->nextrp : srp) {
@@ -949,19 +994,30 @@
                                            srp->header.masked_status & 
                                            srp->header.host_status & 
                                            srp->header.driver_status;
-                                       rinfo[val].duration =
-                                           srp->done ? srp->header.duration :
-                                           jiffies_to_msecs(
-                                               jiffies - srp->header.duration);
+                                       if (srp->done)
+                                               rinfo[val].duration =
+                                                       srp->header.duration;
+                                       else {
+                                               ms = jiffies_to_msecs(jiffies);
+                                               rinfo[val].duration =
+                                                   (ms > srp->header.duration) 
?
+                                                   (ms - srp->header.duration) 
: 0;
+                                       }
                                        rinfo[val].orphan = srp->orphan;
-                                       rinfo[val].sg_io_owned = 
srp->sg_io_owned;
-                                       rinfo[val].pack_id = 
srp->header.pack_id;
-                                       rinfo[val].usr_ptr = 
srp->header.usr_ptr;
+                                       rinfo[val].sg_io_owned =
+                                                       srp->sg_io_owned;
+                                       rinfo[val].pack_id =
+                                                       srp->header.pack_id;
+                                       rinfo[val].usr_ptr =
+                                                       srp->header.usr_ptr;
                                }
                        }
                        read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
-                       return (__copy_to_user(p, rinfo,
-                               SZ_SG_REQ_INFO * SG_MAX_QUEUE) ? -EFAULT : 0);
+                       result = __copy_to_user(p, rinfo, 
+                                               SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+                       result = result ? -EFAULT : 0;
+                       kfree(rinfo);
+                       return result;
                }
        case SG_EMULATED_HOST:
                if (sdp->detached)
@@ -1208,11 +1264,12 @@
 sg_mmap(struct file *filp, struct vm_area_struct *vma)
 {
        Sg_fd *sfp;
-       unsigned long req_sz = vma->vm_end - vma->vm_start;
+       unsigned long req_sz;
        Sg_scatter_hold *rsv_schp;
 
        if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
                return -ENXIO;
+       req_sz = vma->vm_end - vma->vm_start;
        SCSI_LOG_TIMEOUT(3, printk("sg_mmap starting, vm_start=%p, len=%d\n",
                                   (void *) vma->vm_start, (int) req_sz));
        if (vma->vm_pgoff)
@@ -1259,6 +1316,7 @@
        Sg_fd *sfp;
        Sg_request *srp = NULL;
        unsigned long iflags;
+       unsigned int ms;
 
        if (SCpnt && (SRpnt = SCpnt->sc_request))
                srp = (Sg_request *) SRpnt->upper_private_data;
@@ -1295,9 +1353,9 @@
        SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
                sdp->disk->disk_name, srp->header.pack_id, (int) 
SRpnt->sr_result));
        srp->header.resid = SCpnt->resid;
-       /* N.B. unit of duration changes here from jiffies to millisecs */
-       srp->header.duration =
-           jiffies_to_msecs(jiffies - srp->header.duration);
+       ms = jiffies_to_msecs(jiffies);
+       srp->header.duration = (ms > srp->header.duration) ?
+                               (ms - srp->header.duration) : 0;
        if (0 != SRpnt->sr_result) {
                struct scsi_sense_hdr sshdr;
 
@@ -1311,7 +1369,7 @@
                if ((sdp->sgdebug > 0) &&
                    ((CHECK_CONDITION == srp->header.masked_status) ||
                     (COMMAND_TERMINATED == srp->header.masked_status)))
-                       print_req_sense("sg_cmd_done", SRpnt);
+                       scsi_print_req_sense("sg_cmd_done", SRpnt);
 
                /* Following if statement is a patch supplied by Eric Youngdale 
*/
                if (driver_byte(SRpnt->sr_result) != 0
@@ -2395,7 +2453,7 @@
        }
        if (resp) {
                resp->nextrp = NULL;
-               resp->header.duration = jiffies;
+               resp->header.duration = jiffies_to_msecs(jiffies);
                resp->my_cmdp = NULL;
        }
        write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
@@ -2990,6 +3048,7 @@
        Sg_fd *fp;
        const sg_io_hdr_t *hp;
        const char * cp;
+       unsigned int ms;
 
        for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) {
                seq_printf(s, "   FD(%d): timeout=%dms bufflen=%d "
@@ -3028,10 +3087,13 @@
                                   srp->header.pack_id, blen);
                        if (srp->done)
                                seq_printf(s, " dur=%d", hp->duration);
-                       else
+                       else {
+                               ms = jiffies_to_msecs(jiffies);
                                seq_printf(s, " t_o/elap=%d/%d",
-                                 new_interface ? hp->timeout : 
jiffies_to_msecs(fp->timeout),
-                                 jiffies_to_msecs(hp->duration ? (jiffies - 
hp->duration) : 0));
+                                       (new_interface ? hp->timeout :
+                                                 
jiffies_to_msecs(fp->timeout)),
+                                       (ms > hp->duration ? ms - hp->duration 
: 0));
+                       }
                        seq_printf(s, "ms sgat=%d op=0x%02x\n", usg,
                                   (int) srp->data.cmd_opcode);
                }
diff -urN linux/drivers/scsi/sim710.c linux/drivers/scsi/sim710.c
--- linux/drivers/scsi/sim710.c 2005/04/08 18:58:24     1.23
+++ linux/drivers/scsi/sim710.c 2005/04/29 11:15:10     1.24
@@ -120,11 +120,10 @@
        }
 
        /* Fill in the three required pieces of hostdata */
-       hostdata->base = base_addr;
+       hostdata->base = ioport_map(base_addr, 64);
        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, dev))
@@ -133,6 +132,7 @@
                goto out_release;
        }
        host->this_id = scsi_id;
+       host->base = base_addr;
        host->irq = irq;
        if (request_irq(irq, NCR_700_intr, SA_SHIRQ, "sim710", host)) {
                printk(KERN_ERR "sim710: request_irq failed\n");
@@ -164,6 +164,7 @@
        NCR_700_release(host);
        kfree(hostdata);
        free_irq(host->irq, host);
+       release_region(host->base, 64);
        return 0;
 }
 
diff -urN linux/drivers/scsi/sun3_NCR5380.c linux/drivers/scsi/sun3_NCR5380.c
--- linux/drivers/scsi/sun3_NCR5380.c   2003/08/26 00:28:56     1.14
+++ linux/drivers/scsi/sun3_NCR5380.c   2005/04/29 11:15:10     1.15
@@ -69,6 +69,7 @@
  *   finally replaced that by the *_PRINTK() macros.
  *
  */
+#include <scsi/scsi_dbg.h>
 
 /*
  * Further development / testing that should be done : 
@@ -2377,7 +2378,7 @@
  * 3..length+1 arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since print_msg() wants the whole thing.  
+ * byte, since scsi_print_msg() wants the whole thing.  
  */
                    extended_msg[0] = EXTENDED_MESSAGE;
                    /* Accept first byte by clearing ACK */
@@ -2430,7 +2431,7 @@
                default:
                    if (!tmp) {
                        printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-                       print_msg (extended_msg);
+                       scsi_print_msg (extended_msg);
                        printk("\n");
                    } else if (tmp != EXTENDED_MESSAGE)
                        printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2565,7 +2566,7 @@
 
     if (!(msg[0] & 0x80)) {
        printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-       print_msg(msg);
+       scsi_print_msg(msg);
        do_abort(instance);
        return;
     }
@@ -2691,7 +2692,7 @@
     unsigned long flags;
 
     printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO);
-    print_Scsi_Cmnd (cmd);
+    scsi_print_command(cmd);
 
     NCR5380_print_status (instance);
 
diff -urN linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- linux/drivers/scsi/ultrastor.c      2005/03/18 17:37:45     1.28
+++ linux/drivers/scsi/ultrastor.c      2005/04/29 11:15:10     1.29
@@ -945,7 +945,7 @@
               config.mscp[mscp_index].SCint, SCpnt);
 #endif
     if (config.mscp[mscp_index].SCint == 0)
-       return SCSI_ABORT_NOT_RUNNING;
+       return FAILURE;
 
     if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
     config.mscp[mscp_index].SCint = NULL;
@@ -1020,7 +1020,7 @@
 #endif
 
     spin_unlock_irqrestore(host->host_lock, flags);
-    return SCSI_RESET_SUCCESS;
+    return SUCCESS;
 
 }
 
diff -urN linux/drivers/scsi/scsi_obsolete.h linux/drivers/scsi/scsi_obsolete.h
--- linux/drivers/scsi/Attic/scsi_obsolete.h    2005-04-29 12:15:12.439402000 
+0100     1.2
+++ linux/drivers/scsi/Attic/scsi_obsolete.h    1970/01/01 00:00:00+0100
@@ -1,106 +0,0 @@
-/*
- *  scsi_obsolete.h Copyright (C) 1997 Eric Youngdale
- *
- */
-
-#ifndef _SCSI_OBSOLETE_H
-#define _SCSI_OBSOLETE_H
-
-/*
- * These are the return codes for the abort and reset functions.  The mid-level
- * code uses these to decide what to do next.  Each of the low level abort
- * and reset functions must correctly indicate what it has done.
- * The descriptions are written from the point of view of the mid-level code,
- * so that the return code is telling the mid-level drivers exactly what
- * the low level driver has already done, and what remains to be done.
- */
-
-/* We did not do anything.  
- * Wait some more for this command to complete, and if this does not work, 
- * try something more serious. */
-#define SCSI_ABORT_SNOOZE 0
-
-/* This means that we were able to abort the command.  We have already
- * called the mid-level done function, and do not expect an interrupt that 
- * will lead to another call to the mid-level done function for this command */
-#define SCSI_ABORT_SUCCESS 1
-
-/* We called for an abort of this command, and we should get an interrupt 
- * when this succeeds.  Thus we should not restore the timer for this
- * command in the mid-level abort function. */
-#define SCSI_ABORT_PENDING 2
-
-/* Unable to abort - command is currently on the bus.  Grin and bear it. */
-#define SCSI_ABORT_BUSY 3
-
-/* The command is not active in the low level code. Command probably
- * finished. */
-#define SCSI_ABORT_NOT_RUNNING 4
-
-/* Something went wrong.  The low level driver will indicate the correct
- * error condition when it calls scsi_done, so the mid-level abort function
- * can simply wait until this comes through */
-#define SCSI_ABORT_ERROR 5
-
-/* We do not know how to reset the bus, or we do not want to.  Bummer.
- * Anyway, just wait a little more for the command in question, and hope that
- * it eventually finishes.  If it never finishes, the SCSI device could
- * hang, so use this with caution. */
-#define SCSI_RESET_SNOOZE 0
-
-/* We do not know how to reset the bus, or we do not want to.  Bummer.
- * We have given up on this ever completing.  The mid-level code will
- * request sense information to decide how to proceed from here. */
-#define SCSI_RESET_PUNT 1
-
-/* This means that we were able to reset the bus.  We have restarted all of
- * the commands that should be restarted, and we should be able to continue
- * on normally from here.  We do not expect any interrupts that will return
- * DID_RESET to any of the other commands in the host_queue, and the mid-level
- * code does not need to do anything special to keep the commands alive. 
- * If a hard reset was performed then all outstanding commands on the
- * bus have been restarted. */
-#define SCSI_RESET_SUCCESS 2
-
-/* We called for a reset of this bus, and we should get an interrupt 
- * when this succeeds.  Each command should get its own status
- * passed up to scsi_done, but this has not happened yet. 
- * If a hard reset was performed, then we expect an interrupt
- * for *each* of the outstanding commands that will have the
- * effect of restarting the commands.
- */
-#define SCSI_RESET_PENDING 3
-
-/* We did a reset, but do not expect an interrupt to signal DID_RESET.
- * This tells the upper level code to request the sense info, and this
- * should keep the command alive. */
-#define SCSI_RESET_WAKEUP 4
-
-/* The command is not active in the low level code. Command probably
-   finished. */
-#define SCSI_RESET_NOT_RUNNING 5
-
-/* Something went wrong, and we do not know how to fix it. */
-#define SCSI_RESET_ERROR 6
-
-#define SCSI_RESET_SYNCHRONOUS         0x01
-#define SCSI_RESET_ASYNCHRONOUS                0x02
-#define SCSI_RESET_SUGGEST_BUS_RESET   0x04
-#define SCSI_RESET_SUGGEST_HOST_RESET  0x08
-/*
- * This is a bitmask that is ored with one of the above codes.
- * It tells the mid-level code that we did a hard reset.
- */
-#define SCSI_RESET_BUS_RESET 0x100
-/*
- * This is a bitmask that is ored with one of the above codes.
- * It tells the mid-level code that we did a host adapter reset.
- */
-#define SCSI_RESET_HOST_RESET 0x200
-/*
- * Used to mask off bits and to obtain the basic action that was
- * performed.  
- */
-#define SCSI_RESET_ACTION   0xff
-
-#endif                         /* SCSI_OBSOLETE_H */
diff -urN linux/drivers/scsi/aic7xxx/Kconfig.aic7xxx 
linux/drivers/scsi/aic7xxx/Kconfig.aic7xxx
--- linux/drivers/scsi/aic7xxx/Kconfig.aic7xxx  2004/09/19 12:30:14     1.8
+++ linux/drivers/scsi/aic7xxx/Kconfig.aic7xxx  2005/04/29 11:15:12     1.9
@@ -5,6 +5,7 @@
 config SCSI_AIC7XXX
        tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
        depends on (PCI || EISA) && SCSI
+       select SCSI_SPI_ATTRS
        ---help---
        This driver supports all of Adaptec's Fast through Ultra 160 PCI
        based SCSI controllers as well as the aic7770 based EISA and VLB
diff -urN linux/drivers/scsi/aic7xxx/aic79xx_osm.c 
linux/drivers/scsi/aic7xxx/aic79xx_osm.c
--- linux/drivers/scsi/aic7xxx/aic79xx_osm.c    2005/01/13 14:06:22     1.21
+++ linux/drivers/scsi/aic7xxx/aic79xx_osm.c    2005/04/29 11:15:12     1.22
@@ -687,7 +687,7 @@
        int direction;
 
        cmd = scb->io_ctx;
-       direction = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+       direction = cmd->sc_data_direction;
        ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
        if (cmd->use_sg != 0) {
                struct scatterlist *sg;
@@ -3338,7 +3338,7 @@
        }
 
        ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_READ;
+       cmd->sc_data_direction = DMA_FROM_DEVICE;
        cmd->cmd_len = 6;
        cmd->cmnd[0] = INQUIRY;
        cmd->cmnd[4] = request_length;
@@ -3363,7 +3363,7 @@
 #endif
        /* Do a TUR to clear out any non-fatal transitional state */
        ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_NONE;
+       cmd->sc_data_direction = DMA_NONE;
        cmd->cmd_len = 6;
        cmd->cmnd[0] = TEST_UNIT_READY;
 }
@@ -3385,7 +3385,7 @@
                free(targ->dv_buffer, M_DEVBUF);
        targ->dv_buffer = malloc(AHD_REBD_LEN, M_DEVBUF, M_WAITOK);
        ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_READ;
+       cmd->sc_data_direction = DMA_FROM_DEVICE;
        cmd->cmd_len = 10;
        cmd->cmnd[0] = READ_BUFFER;
        cmd->cmnd[1] = 0x0b;
@@ -3407,7 +3407,7 @@
        }
 #endif
        ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_WRITE;
+       cmd->sc_data_direction = DMA_TO_DEVICE;
        cmd->cmd_len = 10;
        cmd->cmnd[0] = WRITE_BUFFER;
        cmd->cmnd[1] = 0x0a;
@@ -3429,7 +3429,7 @@
        }
 #endif
        ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_READ;
+       cmd->sc_data_direction = DMA_FROM_DEVICE;
        cmd->cmd_len = 10;
        cmd->cmnd[0] = READ_BUFFER;
        cmd->cmnd[1] = 0x0a;
@@ -3455,7 +3455,7 @@
        }
 #endif
        ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_NONE;
+       cmd->sc_data_direction = DMA_NONE;
        cmd->cmd_len = 6;
        cmd->cmnd[0] = START_STOP_UNIT;
        cmd->cmnd[4] = le | SSS_START;
@@ -4018,7 +4018,7 @@
                        int      dir;
 
                        cur_seg = (struct scatterlist *)cmd->request_buffer;
-                       dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+                       dir = cmd->sc_data_direction;
                        nseg = pci_map_sg(ahd->dev_softc, cur_seg,
                                          cmd->use_sg, dir);
                        scb->platform_data->xfer_len = 0;
@@ -4038,7 +4038,7 @@
                        int dir;
 
                        sg = scb->sg_list;
-                       dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+                       dir = cmd->sc_data_direction;
                        addr = pci_map_single(ahd->dev_softc,
                                              cmd->request_buffer,
                                              cmd->request_bufflen, dir);
diff -urN linux/drivers/scsi/aic7xxx/aic7xxx_osm.c 
linux/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux/drivers/scsi/aic7xxx/aic7xxx_osm.c    2005/01/13 14:06:22     1.25
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.c    2005/04/29 11:15:12     1.26
@@ -122,6 +122,10 @@
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include <scsi/scsicam.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
+
+static struct scsi_transport_template *ahc_linux_transport_template = NULL;
 
 /*
  * Include aiclib.c as part of our
@@ -271,39 +275,6 @@
 };
 
 /*
- * DV option:
- *
- * positive value = DV Enabled
- * zero                  = DV Disabled
- * negative value = DV Default for adapter type/seeprom
- */
-#ifdef CONFIG_AIC7XXX_DV_SETTING
-#define AIC7XXX_CONFIGED_DV CONFIG_AIC7XXX_DV_SETTING
-#else
-#define AIC7XXX_CONFIGED_DV -1
-#endif
-
-static int8_t aic7xxx_dv_settings[] =
-{
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV,
-       AIC7XXX_CONFIGED_DV
-};
-
-/*
  * There should be a specific return value for this in scsi.h, but
  * it seems that most drivers ignore it.
  */
@@ -450,7 +421,6 @@
 "      tag_info:<tag_str>      Set per-target tag depth\n"
 "      global_tag_depth:<int>  Global tag depth for every target\n"
 "                              on every bus\n"
-"      dv:<dv_settings>        Set per-controller Domain Validation Setting.\n"
 "      seltime:<int>           Selection Timeout\n"
 "                              (0/256ms,1/128ms,2/64ms,3/32ms)\n"
 "\n"
@@ -467,7 +437,6 @@
                                         struct scb *);
 static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
                                         Scsi_Cmnd *cmd);
-static void ahc_linux_filter_inquiry(struct ahc_softc*, struct ahc_devinfo*);
 static void ahc_linux_sem_timeout(u_long arg);
 static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
 static void ahc_linux_release_simq(u_long arg);
@@ -476,49 +445,8 @@
 static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
 static void ahc_linux_size_nseg(void);
 static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc);
-static void ahc_linux_start_dv(struct ahc_softc *ahc);
-static void ahc_linux_dv_timeout(struct scsi_cmnd *cmd);
-static int  ahc_linux_dv_thread(void *data);
-static void ahc_linux_kill_dv_thread(struct ahc_softc *ahc);
-static void ahc_linux_dv_target(struct ahc_softc *ahc, u_int target);
-static void ahc_linux_dv_transition(struct ahc_softc *ahc,
-                                   struct scsi_cmnd *cmd,
-                                   struct ahc_devinfo *devinfo,
-                                   struct ahc_linux_target *targ);
-static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc,
-                                 struct scsi_cmnd *cmd,
-                                 struct ahc_devinfo *devinfo);
-static void ahc_linux_dv_inq(struct ahc_softc *ahc,
-                            struct scsi_cmnd *cmd,
-                            struct ahc_devinfo *devinfo,
-                            struct ahc_linux_target *targ,
-                            u_int request_length);
-static void ahc_linux_dv_tur(struct ahc_softc *ahc,
-                            struct scsi_cmnd *cmd,
-                            struct ahc_devinfo *devinfo);
-static void ahc_linux_dv_rebd(struct ahc_softc *ahc,
-                             struct scsi_cmnd *cmd,
-                             struct ahc_devinfo *devinfo,
-                             struct ahc_linux_target *targ);
-static void ahc_linux_dv_web(struct ahc_softc *ahc,
-                            struct scsi_cmnd *cmd,
-                            struct ahc_devinfo *devinfo,
-                            struct ahc_linux_target *targ);
-static void ahc_linux_dv_reb(struct ahc_softc *ahc,
-                            struct scsi_cmnd *cmd,
-                            struct ahc_devinfo *devinfo,
-                            struct ahc_linux_target *targ);
-static void ahc_linux_dv_su(struct ahc_softc *ahc,
-                           struct scsi_cmnd *cmd,
-                           struct ahc_devinfo *devinfo,
-                           struct ahc_linux_target *targ);
-static int ahc_linux_fallback(struct ahc_softc *ahc,
-                             struct ahc_devinfo *devinfo);
-static void ahc_linux_dv_complete(Scsi_Cmnd *cmd);
-static void ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ);
 static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
                                     struct ahc_devinfo *devinfo);
-static u_int ahc_linux_user_dv_setting(struct ahc_softc *ahc);
 static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
                                         struct ahc_linux_device *dev);
 static struct ahc_linux_target*        ahc_linux_alloc_target(struct 
ahc_softc*,
@@ -534,7 +462,6 @@
                                       struct ahc_linux_device*);
 static void ahc_linux_setup_tag_info_global(char *p);
 static aic_option_callback_t ahc_linux_setup_tag_info;
-static aic_option_callback_t ahc_linux_setup_dv;
 static int  aic7xxx_setup(char *s);
 static int  ahc_linux_next_unit(void);
 static void ahc_runq_tasklet(unsigned long data);
@@ -663,8 +590,7 @@
 {
        
        if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0
-        || (ahc->platform_data->qfrozen != 0
-         && AHC_DV_SIMQ_FROZEN(ahc) == 0))
+           || (ahc->platform_data->qfrozen != 0))
                return (NULL);
        return (TAILQ_FIRST(&ahc->platform_data->device_runq));
 }
@@ -693,12 +619,12 @@
 
                sg = (struct scatterlist *)cmd->request_buffer;
                pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
-                            scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                            cmd->sc_data_direction);
        } else if (cmd->request_bufflen != 0) {
                pci_unmap_single(ahc->dev_softc,
                                 scb->platform_data->buf_busaddr,
                                 cmd->request_bufflen,
-                                scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                                cmd->sc_data_direction);
        }
 }
 
@@ -962,8 +888,7 @@
         * DV commands through so long as we are only frozen to
         * perform DV.
         */
-       if (ahc->platform_data->qfrozen != 0
-        && AHC_DV_CMD(cmd) == 0) {
+       if (ahc->platform_data->qfrozen != 0) {
 
                ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
                ahc_linux_queue_cmd_complete(ahc, cmd);
@@ -1030,6 +955,11 @@
                ahc_linux_device_queue_depth(ahc, dev);
        }
        ahc_midlayer_entrypoint_unlock(ahc, &flags);
+
+       /* Initial Domain Validation */
+       if (!spi_initial_dv(device->sdev_target))
+               spi_dv_device(device);
+
        return (0);
 }
 
@@ -1545,18 +1475,6 @@
        }
 }
 
-static void
-ahc_linux_setup_dv(u_long arg, int instance, int targ, int32_t value)
-{
-
-       if ((instance >= 0)
-        && (instance < NUM_ELEMENTS(aic7xxx_dv_settings))) {
-               aic7xxx_dv_settings[instance] = value;
-               if (bootverbose)
-                       printf("dv[%d] = %d\n", instance, value);
-       }
-}
-
 /*
  * Handle Linux boot parameters. This routine allows for assigning a value
  * to a parameter with a ':' between the parameter and the value.
@@ -1616,9 +1534,6 @@
                } else if (strncmp(p, "tag_info", n) == 0) {
                        s = aic_parse_brace_option("tag_info", p + n, end,
                            2, ahc_linux_setup_tag_info, 0);
-               } else if (strncmp(p, "dv", n) == 0) {
-                       s = aic_parse_brace_option("dv", p + n, end, 1,
-                           ahc_linux_setup_dv, 0);
                } else if (p[n] == ':') {
                        *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
                } else if (strncmp(p, "verbose", n) == 0) {
@@ -1641,7 +1556,6 @@
        struct   Scsi_Host *host;
        char    *new_name;
        u_long   s;
-       u_int    targ_offset;
 
        template->name = ahc->description;
        host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
@@ -1677,57 +1591,11 @@
        scsi_set_pci_device(host, ahc->dev_softc);
 #endif
        ahc_linux_initialize_scsi_bus(ahc);
-       ahc_unlock(ahc, &s);
-       ahc->platform_data->dv_pid = kernel_thread(ahc_linux_dv_thread, ahc, 0);
-       ahc_lock(ahc, &s);
-       if (ahc->platform_data->dv_pid < 0) {
-               printf("%s: Failed to create DV thread, error= %d\n",
-                      ahc_name(ahc), ahc->platform_data->dv_pid);
-               return (-ahc->platform_data->dv_pid);
-       }
-       /*
-        * Initially allocate *all* of our linux target objects
-        * so that the DV thread will scan them all in parallel
-        * just after driver initialization.  Any device that
-        * does not exist will have its target object destroyed
-        * by the selection timeout handler.  In the case of a
-        * device that appears after the initial DV scan, async
-        * negotiation will occur for the first command, and DV
-        * will comence should that first command be successful.
-        */
-       for (targ_offset = 0;
-            targ_offset < host->max_id * (host->max_channel + 1);
-            targ_offset++) {
-               u_int channel;
-               u_int target;
-
-               channel = 0;
-               target = targ_offset;
-               if (target > 7
-                && (ahc->features & AHC_TWIN) != 0) {
-                       channel = 1;
-                       target &= 0x7;
-               }
-               /*
-                * Skip our own ID.  Some Compaq/HP storage devices
-                * have enclosure management devices that respond to
-                * single bit selection (i.e. selecting ourselves).
-                * It is expected that either an external application
-                * or a modified kernel will be used to probe this
-                * ID if it is appropriate.  To accommodate these
-                * installations, ahc_linux_alloc_target() will allocate
-                * for our ID if asked to do so.
-                */
-               if ((channel == 0 && target == ahc->our_id)
-                || (channel == 1 && target == ahc->our_id_b))
-                       continue;
-
-               ahc_linux_alloc_target(ahc, channel, target);
-       }
        ahc_intr_enable(ahc, TRUE);
-       ahc_linux_start_dv(ahc);
        ahc_unlock(ahc, &s);
 
+       host->transportt = ahc_linux_transport_template;
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* 
XXX handle failure */
        scsi_scan_host(host);
@@ -1860,8 +1728,6 @@
        ahc->platform_data->completeq_timer.function =
            (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue;
        init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
-       init_MUTEX_LOCKED(&ahc->platform_data->dv_sem);
-       init_MUTEX_LOCKED(&ahc->platform_data->dv_cmd_sem);
        tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet,
                     (unsigned long)ahc);
        ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
@@ -1881,7 +1747,6 @@
 
        if (ahc->platform_data != NULL) {
                del_timer_sync(&ahc->platform_data->completeq_timer);
-               ahc_linux_kill_dv_thread(ahc);
                tasklet_kill(&ahc->platform_data->runq_tasklet);
                if (ahc->platform_data->host != NULL) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
@@ -2120,1571 +1985,200 @@
        ahc_unlock(ahc, &flags);
 }
 
-static void
-ahc_linux_start_dv(struct ahc_softc *ahc)
+static u_int
+ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
 {
+       static int warned_user;
+       u_int tags;
 
-       /*
-        * Freeze the simq and signal ahc_linux_queue to not let any
-        * more commands through.
-        */
-       if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) {
-#ifdef AHC_DEBUG
-               if (ahc_debug & AHC_SHOW_DV)
-                       printf("%s: Waking DV thread\n", ahc_name(ahc));
-#endif
+       tags = 0;
+       if ((ahc->user_discenable & devinfo->target_mask) != 0) {
+               if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) {
+                       if (warned_user == 0) {
 
-               ahc->platform_data->flags |= AHC_DV_ACTIVE;
-               ahc_linux_freeze_simq(ahc);
+                               printf(KERN_WARNING
+"aic7xxx: WARNING: Insufficient tag_info instances\n"
+"aic7xxx: for installed controllers. Using defaults\n"
+"aic7xxx: Please update the aic7xxx_tag_info array in\n"
+"aic7xxx: the aic7xxx_osm..c source file.\n");
+                               warned_user++;
+                       }
+                       tags = AHC_MAX_QUEUE;
+               } else {
+                       adapter_tag_info_t *tag_info;
 
-               /* Wake up the DV kthread */
-               up(&ahc->platform_data->dv_sem);
+                       tag_info = &aic7xxx_tag_info[ahc->unit];
+                       tags = tag_info->tag_commands[devinfo->target_offset];
+                       if (tags > AHC_MAX_QUEUE)
+                               tags = AHC_MAX_QUEUE;
+               }
        }
+       return (tags);
 }
 
+/*
+ * Determines the queue depth for a given device.
+ */
 static void
-ahc_linux_kill_dv_thread(struct ahc_softc *ahc)
+ahc_linux_device_queue_depth(struct ahc_softc *ahc,
+                            struct ahc_linux_device *dev)
 {
-       u_long s;
-
-       ahc_lock(ahc, &s);
-       if (ahc->platform_data->dv_pid != 0) {
-               ahc->platform_data->flags |= AHC_DV_SHUTDOWN;
-               ahc_unlock(ahc, &s);
-               up(&ahc->platform_data->dv_sem);
+       struct  ahc_devinfo devinfo;
+       u_int   tags;
 
-               /*
-                * Use the eh_sem as an indicator that the
-                * dv thread is exiting.  Note that the dv
-                * thread must still return after performing
-                * the up on our semaphore before it has
-                * completely exited this module.  Unfortunately,
-                * there seems to be no easy way to wait for the
-                * exit of a thread for which you are not the
-                * parent (dv threads are parented by init).
-                * Cross your fingers...
-                */
-               down(&ahc->platform_data->eh_sem);
+       ahc_compile_devinfo(&devinfo,
+                           dev->target->channel == 0
+                         ? ahc->our_id : ahc->our_id_b,
+                           dev->target->target, dev->lun,
+                           dev->target->channel == 0 ? 'A' : 'B',
+                           ROLE_INITIATOR);
+       tags = ahc_linux_user_tagdepth(ahc, &devinfo);
+       if (tags != 0
+        && dev->scsi_device != NULL
+        && dev->scsi_device->tagged_supported != 0) {
 
-               /*
-                * Mark the dv thread as already dead.  This
-                * avoids attempting to kill it a second time.
-                * This is necessary because we must kill the
-                * DV thread before calling ahc_free() in the
-                * module shutdown case to avoid bogus locking
-                * in the SCSI mid-layer, but we ahc_free() is
-                * called without killing the DV thread in the
-                * instance detach case, so ahc_platform_free()
-                * calls us again to verify that the DV thread
-                * is dead.
-                */
-               ahc->platform_data->dv_pid = 0;
+               ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
+               ahc_print_devinfo(ahc, &devinfo);
+               printf("Tagged Queuing enabled.  Depth %d\n", tags);
        } else {
-               ahc_unlock(ahc, &s);
+               ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE);
        }
 }
 
-static int
-ahc_linux_dv_thread(void *data)
+static void
+ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
 {
-       struct  ahc_softc *ahc;
-       int     target;
-       u_long  s;
-
-       ahc = (struct ahc_softc *)data;
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV)
-               printf("Launching DV Thread\n");
-#endif
-
-       /*
-        * Complete thread creation.
-        */
-       lock_kernel();
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       /*
-        * Don't care about any signals.
-        */
-       siginitsetinv(&current->blocked, 0);
-
-       daemonize();
-       sprintf(current->comm, "ahc_dv_%d", ahc->unit);
-#else
-       daemonize("ahc_dv_%d", ahc->unit);
-       current->flags |= PF_FREEZE;
-#endif
-       unlock_kernel();
-
-       while (1) {
-               /*
-                * Use down_interruptible() rather than down() to
-                * avoid inclusion in the load average.
-                */
-               down_interruptible(&ahc->platform_data->dv_sem);
+       struct   ahc_cmd *acmd;
+       struct   scsi_cmnd *cmd;
+       struct   scb *scb;
+       struct   hardware_scb *hscb;
+       struct   ahc_initiator_tinfo *tinfo;
+       struct   ahc_tmode_tstate *tstate;
+       uint16_t mask;
 
-               /* Check to see if we've been signaled to exit */
-               ahc_lock(ahc, &s);
-               if ((ahc->platform_data->flags & AHC_DV_SHUTDOWN) != 0) {
-                       ahc_unlock(ahc, &s);
-                       break;
-               }
-               ahc_unlock(ahc, &s);
+       if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
+               panic("running device on run list");
 
-#ifdef AHC_DEBUG
-               if (ahc_debug & AHC_SHOW_DV)
-                       printf("%s: Beginning Domain Validation\n",
-                              ahc_name(ahc));
-#endif
+       while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
+           && dev->openings > 0 && dev->qfrozen == 0) {
 
                /*
-                * Wait for any pending commands to drain before proceeding.
+                * Schedule us to run later.  The only reason we are not
+                * running is because the whole controller Q is frozen.
                 */
-               ahc_lock(ahc, &s);
-               while (LIST_FIRST(&ahc->pending_scbs) != NULL) {
-                       ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_EMPTY;
-                       ahc_unlock(ahc, &s);
-                       down_interruptible(&ahc->platform_data->dv_sem);
-                       ahc_lock(ahc, &s);
+               if (ahc->platform_data->qfrozen != 0) {
+                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
+                                         dev, links);
+                       dev->flags |= AHC_DEV_ON_RUN_LIST;
+                       return;
                }
-
                /*
-                * Wait for the SIMQ to be released so that DV is the
-                * only reason the queue is frozen.
+                * Get an scb to use.
                 */
-               while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
-                       ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
-                       ahc_unlock(ahc, &s);
-                       down_interruptible(&ahc->platform_data->dv_sem);
-                       ahc_lock(ahc, &s);
+               if ((scb = ahc_get_scb(ahc)) == NULL) {
+                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
+                                        dev, links);
+                       dev->flags |= AHC_DEV_ON_RUN_LIST;
+                       ahc->flags |= AHC_RESOURCE_SHORTAGE;
+                       return;
                }
-               ahc_unlock(ahc, &s);
-
-               for (target = 0; target < AHC_NUM_TARGETS; target++)
-                       ahc_linux_dv_target(ahc, target);
-
-               ahc_lock(ahc, &s);
-               ahc->platform_data->flags &= ~AHC_DV_ACTIVE;
-               ahc_unlock(ahc, &s);
+               TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
+               cmd = &acmd_scsi_cmd(acmd);
+               scb->io_ctx = cmd;
+               scb->platform_data->dev = dev;
+               hscb = scb->hscb;
+               cmd->host_scribble = (char *)scb;
 
                /*
-                * Release the SIMQ so that normal commands are
-                * allowed to continue on the bus.
+                * Fill out basics of the HSCB.
                 */
-               ahc_linux_release_simq((u_long)ahc);
-       }
-       up(&ahc->platform_data->eh_sem);
-       return (0);
-}
+               hscb->control = 0;
+               hscb->scsiid = BUILD_SCSIID(ahc, cmd);
+               hscb->lun = cmd->device->lun;
+               mask = SCB_GET_TARGET_MASK(ahc, scb);
+               tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
+                                           SCB_GET_OUR_ID(scb),
+                                           SCB_GET_TARGET(ahc, scb), &tstate);
+               hscb->scsirate = tinfo->scsirate;
+               hscb->scsioffset = tinfo->curr.offset;
+               if ((tstate->ultraenb & mask) != 0)
+                       hscb->control |= ULTRAENB;
 
-#define AHC_LINUX_DV_INQ_SHORT_LEN     36
-#define AHC_LINUX_DV_INQ_LEN           256
-#define AHC_LINUX_DV_TIMEOUT           (HZ / 4)
+               if ((ahc->user_discenable & mask) != 0)
+                       hscb->control |= DISCENB;
 
-#define AHC_SET_DV_STATE(ahc, targ, newstate) \
-       ahc_set_dv_state(ahc, targ, newstate, __LINE__)
+               if ((tstate->auto_negotiate & mask) != 0) {
+                       scb->flags |= SCB_AUTO_NEGOTIATE;
+                       scb->hscb->control |= MK_MESSAGE;
+               }
 
-static __inline void
-ahc_set_dv_state(struct ahc_softc *ahc, struct ahc_linux_target *targ,
-                ahc_dv_state newstate, u_int line)
-{
-       ahc_dv_state oldstate;
+               if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+                       int     msg_bytes;
+                       uint8_t tag_msgs[2];
 
-       oldstate = targ->dv_state;
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV)
-               printf("%s:%d: Going from state %d to state %d\n",
-                      ahc_name(ahc), line, oldstate, newstate);
+                       msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs);
+                       if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) {
+                               hscb->control |= tag_msgs[0];
+                               if (tag_msgs[0] == MSG_ORDERED_TASK)
+                                       dev->commands_since_idle_or_otag = 0;
+                       } else
 #endif
+                       if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
+                        && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
+                               hscb->control |= MSG_ORDERED_TASK;
+                               dev->commands_since_idle_or_otag = 0;
+                       } else {
+                               hscb->control |= MSG_SIMPLE_TASK;
+                       }
+               }
 
-       if (oldstate == newstate)
-               targ->dv_state_retry++;
-       else
-               targ->dv_state_retry = 0;
-       targ->dv_state = newstate;
-}
+               hscb->cdb_len = cmd->cmd_len;
+               if (hscb->cdb_len <= 12) {
+                       memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
+               } else {
+                       memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
+                       scb->flags |= SCB_CDB32_PTR;
+               }
 
-static void
-ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset)
-{
-       struct   ahc_devinfo devinfo;
-       struct   ahc_linux_target *targ;
-       struct   scsi_cmnd *cmd;
-       struct   scsi_device *scsi_dev;
-       struct   scsi_sense_data *sense;
-       uint8_t *buffer;
-       u_long   s;
-       u_int    timeout;
-       int      echo_size;
+               scb->platform_data->xfer_len = 0;
+               ahc_set_residual(scb, 0);
+               ahc_set_sense_residual(scb, 0);
+               scb->sg_count = 0;
+               if (cmd->use_sg != 0) {
+                       struct  ahc_dma_seg *sg;
+                       struct  scatterlist *cur_seg;
+                       struct  scatterlist *end_seg;
+                       int     nseg;
 
-       sense = NULL;
-       buffer = NULL;
-       echo_size = 0;
-       ahc_lock(ahc, &s);
-       targ = ahc->platform_data->targets[target_offset];
-       if (targ == NULL || (targ->flags & AHC_DV_REQUIRED) == 0) {
-               ahc_unlock(ahc, &s);
-               return;
-       }
-       ahc_compile_devinfo(&devinfo,
-                           targ->channel == 0 ? ahc->our_id : ahc->our_id_b,
-                           targ->target, /*lun*/0, targ->channel + 'A',
-                           ROLE_INITIATOR);
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, &devinfo);
-               printf("Performing DV\n");
-       }
-#endif
+                       cur_seg = (struct scatterlist *)cmd->request_buffer;
+                       nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
+                           cmd->sc_data_direction);
+                       end_seg = cur_seg + nseg;
+                       /* Copy the segments into the SG list. */
+                       sg = scb->sg_list;
+                       /*
+                        * The sg_count may be larger than nseg if
+                        * a transfer crosses a 32bit page.
+                        */ 
+                       while (cur_seg < end_seg) {
+                               dma_addr_t addr;
+                               bus_size_t len;
+                               int consumed;
 
-       ahc_unlock(ahc, &s);
+                               addr = sg_dma_address(cur_seg);
+                               len = sg_dma_len(cur_seg);
+                               consumed = ahc_linux_map_seg(ahc, scb,
+                                                            sg, addr, len);
+                               sg += consumed;
+                               scb->sg_count += consumed;
+                               cur_seg++;
+                       }
+                       sg--;
+                       sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
 
-       cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
-       scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK);
-       scsi_dev->host = ahc->platform_data->host;
-       scsi_dev->id = devinfo.target;
-       scsi_dev->lun = devinfo.lun;
-       scsi_dev->channel = devinfo.channel - 'A';
-       ahc->platform_data->dv_scsi_dev = scsi_dev;
-
-       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC);
-
-       while (targ->dv_state != AHC_DV_STATE_EXIT) {
-               timeout = AHC_LINUX_DV_TIMEOUT;
-               switch (targ->dv_state) {
-               case AHC_DV_STATE_INQ_SHORT_ASYNC:
-               case AHC_DV_STATE_INQ_ASYNC:
-               case AHC_DV_STATE_INQ_ASYNC_VERIFY:
                        /*
-                        * Set things to async narrow to reduce the
-                        * chance that the INQ will fail.
-                        */
-                       ahc_lock(ahc, &s);
-                       ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
-                                        AHC_TRANS_GOAL, /*paused*/FALSE);
-                       ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-                                     AHC_TRANS_GOAL, /*paused*/FALSE);
-                       ahc_unlock(ahc, &s);
-                       timeout = 10 * HZ;
-                       targ->flags &= ~AHC_INQ_VALID;
-                       /* FALLTHROUGH */
-               case AHC_DV_STATE_INQ_VERIFY:
-               {
-                       u_int inq_len;
-
-                       if (targ->dv_state == AHC_DV_STATE_INQ_SHORT_ASYNC)
-                               inq_len = AHC_LINUX_DV_INQ_SHORT_LEN;
-                       else
-                               inq_len = targ->inq_data->additional_length + 5;
-                       ahc_linux_dv_inq(ahc, cmd, &devinfo, targ, inq_len);
-                       break;
-               }
-               case AHC_DV_STATE_TUR:
-               case AHC_DV_STATE_BUSY:
-                       timeout = 5 * HZ;
-                       ahc_linux_dv_tur(ahc, cmd, &devinfo);
-                       break;
-               case AHC_DV_STATE_REBD:
-                       ahc_linux_dv_rebd(ahc, cmd, &devinfo, targ);
-                       break;
-               case AHC_DV_STATE_WEB:
-                       ahc_linux_dv_web(ahc, cmd, &devinfo, targ);
-                       break;
-
-               case AHC_DV_STATE_REB:
-                       ahc_linux_dv_reb(ahc, cmd, &devinfo, targ);
-                       break;
-
-               case AHC_DV_STATE_SU:
-                       ahc_linux_dv_su(ahc, cmd, &devinfo, targ);
-                       timeout = 50 * HZ;
-                       break;
-
-               default:
-                       ahc_print_devinfo(ahc, &devinfo);
-                       printf("Unknown DV state %d\n", targ->dv_state);
-                       goto out;
-               }
-
-               /* Queue the command and wait for it to complete */
-               /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */
-               init_timer(&cmd->eh_timeout);
-#ifdef AHC_DEBUG
-               if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
-                       /*
-                        * All of the printfs during negotiation
-                        * really slow down the negotiation.
-                        * Add a bit of time just to be safe.
-                        */
-                       timeout += HZ;
-#endif
-               scsi_add_timer(cmd, timeout, ahc_linux_dv_timeout);
-               /*
-                * In 2.5.X, it is assumed that all calls from the
-                * "midlayer" (which we are emulating) will have the
-                * ahc host lock held.  For other kernels, the
-                * io_request_lock must be held.
-                */
-#if AHC_SCSI_HAS_HOST_LOCK != 0
-               ahc_lock(ahc, &s);
-#else
-               spin_lock_irqsave(&io_request_lock, s);
-#endif
-               ahc_linux_queue(cmd, ahc_linux_dv_complete);
-#if AHC_SCSI_HAS_HOST_LOCK != 0
-               ahc_unlock(ahc, &s);
-#else
-               spin_unlock_irqrestore(&io_request_lock, s);
-#endif
-               down_interruptible(&ahc->platform_data->dv_cmd_sem);
-               /*
-                * Wait for the SIMQ to be released so that DV is the
-                * only reason the queue is frozen.
-                */
-               ahc_lock(ahc, &s);
-               while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
-                       ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
-                       ahc_unlock(ahc, &s);
-                       down_interruptible(&ahc->platform_data->dv_sem);
-                       ahc_lock(ahc, &s);
-               }
-               ahc_unlock(ahc, &s);
-
-               ahc_linux_dv_transition(ahc, cmd, &devinfo, targ);
-       }
-
-out:
-       if ((targ->flags & AHC_INQ_VALID) != 0
-        && ahc_linux_get_device(ahc, devinfo.channel - 'A',
-                                devinfo.target, devinfo.lun,
-                                /*alloc*/FALSE) == NULL) {
-               /*
-                * The DV state machine failed to configure this device.  
-                * This is normal if DV is disabled.  Since we have inquiry
-                * data, filter it and use the "optimistic" negotiation
-                * parameters found in the inquiry string.
-                */
-               ahc_linux_filter_inquiry(ahc, &devinfo);
-               if ((targ->flags & (AHC_BASIC_DV|AHC_ENHANCED_DV)) != 0) {
-                       ahc_print_devinfo(ahc, &devinfo);
-                       printf("DV failed to configure device.  "
-                              "Please file a bug report against "
-                              "this driver.\n");
-               }
-       }
-
-       if (cmd != NULL)
-               free(cmd, M_DEVBUF);
-
-       if (ahc->platform_data->dv_scsi_dev != NULL) {
-               free(ahc->platform_data->dv_scsi_dev, M_DEVBUF);
-               ahc->platform_data->dv_scsi_dev = NULL;
-       }
-
-       ahc_lock(ahc, &s);
-       if (targ->dv_buffer != NULL) {
-               free(targ->dv_buffer, M_DEVBUF);
-               targ->dv_buffer = NULL;
-       }
-       if (targ->dv_buffer1 != NULL) {
-               free(targ->dv_buffer1, M_DEVBUF);
-               targ->dv_buffer1 = NULL;
-       }
-       targ->flags &= ~AHC_DV_REQUIRED;
-       if (targ->refcount == 0)
-               ahc_linux_free_target(ahc, targ);
-       ahc_unlock(ahc, &s);
-}
-
-static void
-ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                       struct ahc_devinfo *devinfo,
-                       struct ahc_linux_target *targ)
-{
-       u_int32_t status;
-
-       status = aic_error_action(cmd, targ->inq_data,
-                                 ahc_cmd_get_transaction_status(cmd),
-                                 ahc_cmd_get_scsi_status(cmd));
-       
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Entering ahc_linux_dv_transition, state= %d, "
-                      "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state,
-                      status, cmd->result);
-       }
-#endif
-
-       switch (targ->dv_state) {
-       case AHC_DV_STATE_INQ_SHORT_ASYNC:
-       case AHC_DV_STATE_INQ_ASYNC:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-               {
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1);
-                       break;
-               }
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_TUR:
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ)
-                               targ->dv_state_retry--;
-                       if ((status & SS_ERRMASK) == EBUSY)
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
-                       if (targ->dv_state_retry < 10)
-                               break;
-                       /* FALLTHROUGH */
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("Failed DV inquiry, skipping\n");
-                       }
-#endif
-                       break;
-               }
-               break;
-       case AHC_DV_STATE_INQ_ASYNC_VERIFY:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-               {
-                       u_int xportflags;
-                       u_int spi3data;
-
-                       if (memcmp(targ->inq_data, targ->dv_buffer,
-                                  AHC_LINUX_DV_INQ_LEN) != 0) {
-                               /*
-                                * Inquiry data must have changed.
-                                * Try from the top again.
-                                */
-                               AHC_SET_DV_STATE(ahc, targ,
-                                                AHC_DV_STATE_INQ_SHORT_ASYNC);
-                               break;
-                       }
-
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1);
-                       targ->flags |= AHC_INQ_VALID;
-                       if (ahc_linux_user_dv_setting(ahc) == 0)
-                               break;
-
-                       xportflags = targ->inq_data->flags;
-                       if ((xportflags & (SID_Sync|SID_WBus16)) == 0)
-                               break;
-
-                       spi3data = targ->inq_data->spi3data;
-                       switch (spi3data & SID_SPI_CLOCK_DT_ST) {
-                       default:
-                       case SID_SPI_CLOCK_ST:
-                               /* Assume only basic DV is supported. */
-                               targ->flags |= AHC_BASIC_DV;
-                               break;
-                       case SID_SPI_CLOCK_DT:
-                       case SID_SPI_CLOCK_DT_ST:
-                               targ->flags |= AHC_ENHANCED_DV;
-                               break;
-                       }
-                       break;
-               }
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_TUR:
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ)
-                               targ->dv_state_retry--;
-
-                       if ((status & SS_ERRMASK) == EBUSY)
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
-                       if (targ->dv_state_retry < 10)
-                               break;
-                       /* FALLTHROUGH */
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("Failed DV inquiry, skipping\n");
-                       }
-#endif
-                       break;
-               }
-               break;
-       case AHC_DV_STATE_INQ_VERIFY:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-               {
-
-                       if (memcmp(targ->inq_data, targ->dv_buffer,
-                                  AHC_LINUX_DV_INQ_LEN) == 0) {
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                               break;
-                       }
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               int i;
-
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("Inquiry buffer mismatch:");
-                               for (i = 0; i < AHC_LINUX_DV_INQ_LEN; i++) {
-                                       if ((i & 0xF) == 0)
-                                               printf("\n        ");
-                                       printf("0x%x:0x0%x ",
-                                              ((uint8_t *)targ->inq_data)[i], 
-                                              targ->dv_buffer[i]);
-                               }
-                               printf("\n");
-                       }
-#endif
-
-                       if (ahc_linux_fallback(ahc, devinfo) != 0) {
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                               break;
-                       }
-                       /*
-                        * Do not count "falling back"
-                        * against our retries.
-                        */
-                       targ->dv_state_retry = 0;
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       break;
-               }
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_TUR:
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ) {
-                               targ->dv_state_retry--;
-                       } else if ((status & SSQ_FALLBACK) != 0) {
-                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
-                                       AHC_SET_DV_STATE(ahc, targ,
-                                                        AHC_DV_STATE_EXIT);
-                                       break;
-                               }
-                               /*
-                                * Do not count "falling back"
-                                * against our retries.
-                                */
-                               targ->dv_state_retry = 0;
-                       } else if ((status & SS_ERRMASK) == EBUSY)
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
-                       if (targ->dv_state_retry < 10)
-                               break;
-                       /* FALLTHROUGH */
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("Failed DV inquiry, skipping\n");
-                       }
-#endif
-                       break;
-               }
-               break;
-
-       case AHC_DV_STATE_TUR:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-                       if ((targ->flags & AHC_BASIC_DV) != 0) {
-                               ahc_linux_filter_inquiry(ahc, devinfo);
-                               AHC_SET_DV_STATE(ahc, targ,
-                                                AHC_DV_STATE_INQ_VERIFY);
-                       } else if ((targ->flags & AHC_ENHANCED_DV) != 0) {
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REBD);
-                       } else {
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       }
-                       break;
-               case SS_RETRY:
-               case SS_TUR:
-                       if ((status & SS_ERRMASK) == EBUSY) {
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
-                               break;
-                       }
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ) {
-                               targ->dv_state_retry--;
-                       } else if ((status & SSQ_FALLBACK) != 0) {
-                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
-                                       AHC_SET_DV_STATE(ahc, targ,
-                                                        AHC_DV_STATE_EXIT);
-                                       break;
-                               }
-                               /*
-                                * Do not count "falling back"
-                                * against our retries.
-                                */
-                               targ->dv_state_retry = 0;
-                       }
-                       if (targ->dv_state_retry >= 10) {
-#ifdef AHC_DEBUG
-                               if (ahc_debug & AHC_SHOW_DV) {
-                                       ahc_print_devinfo(ahc, devinfo);
-                                       printf("DV TUR reties exhausted\n");
-                               }
-#endif
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                               break;
-                       }
-                       if (status & SSQ_DELAY)
-                               ssleep(1);
-
-                       break;
-               case SS_START:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_SU);
-                       break;
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       break;
-               }
-               break;
-
-       case AHC_DV_STATE_REBD:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-               {
-                       uint32_t echo_size;
-
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
-                       echo_size = scsi_3btoul(&targ->dv_buffer[1]);
-                       echo_size &= 0x1FFF;
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("Echo buffer size= %d\n", echo_size);
-                       }
-#endif
-                       if (echo_size == 0) {
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                               break;
-                       }
-
-                       /* Generate the buffer pattern */
-                       targ->dv_echo_size = echo_size;
-                       ahc_linux_generate_dv_pattern(targ);
-                       /*
-                        * Setup initial negotiation values.
-                        */
-                       ahc_linux_filter_inquiry(ahc, devinfo);
-                       break;
-               }
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ)
-                               targ->dv_state_retry--;
-                       if (targ->dv_state_retry <= 10)
-                               break;
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("DV REBD reties exhausted\n");
-                       }
-#endif
-                       /* FALLTHROUGH */
-               case SS_FATAL:
-               default:
-                       /*
-                        * Setup initial negotiation values
-                        * and try level 1 DV.
-                        */
-                       ahc_linux_filter_inquiry(ahc, devinfo);
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_VERIFY);
-                       targ->dv_echo_size = 0;
-                       break;
-               }
-               break;
-
-       case AHC_DV_STATE_WEB:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REB);
-                       break;
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ) {
-                               targ->dv_state_retry--;
-                       } else if ((status & SSQ_FALLBACK) != 0) {
-                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
-                                       AHC_SET_DV_STATE(ahc, targ,
-                                                        AHC_DV_STATE_EXIT);
-                                       break;
-                               }
-                               /*
-                                * Do not count "falling back"
-                                * against our retries.
-                                */
-                               targ->dv_state_retry = 0;
-                       }
-                       if (targ->dv_state_retry <= 10)
-                               break;
-                       /* FALLTHROUGH */
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("DV WEB reties exhausted\n");
-                       }
-#endif
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       break;
-               }
-               break;
-
-       case AHC_DV_STATE_REB:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-                       if (memcmp(targ->dv_buffer, targ->dv_buffer1,
-                                  targ->dv_echo_size) != 0) {
-                               if (ahc_linux_fallback(ahc, devinfo) != 0)
-                                       AHC_SET_DV_STATE(ahc, targ,
-                                                        AHC_DV_STATE_EXIT);
-                               else
-                                       AHC_SET_DV_STATE(ahc, targ,
-                                                        AHC_DV_STATE_WEB);
-                               break;
-                       }
-                       
-                       if (targ->dv_buffer != NULL) {
-                               free(targ->dv_buffer, M_DEVBUF);
-                               targ->dv_buffer = NULL;
-                       }
-                       if (targ->dv_buffer1 != NULL) {
-                               free(targ->dv_buffer1, M_DEVBUF);
-                               targ->dv_buffer1 = NULL;
-                       }
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       break;
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ) {
-                               targ->dv_state_retry--;
-                       } else if ((status & SSQ_FALLBACK) != 0) {
-                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
-                                       AHC_SET_DV_STATE(ahc, targ,
-                                                        AHC_DV_STATE_EXIT);
-                                       break;
-                               }
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
-                       }
-                       if (targ->dv_state_retry <= 10) {
-                               if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0)
-                                       msleep(ahc->our_id*1000/10);
-                               break;
-                       }
-#ifdef AHC_DEBUG
-                       if (ahc_debug & AHC_SHOW_DV) {
-                               ahc_print_devinfo(ahc, devinfo);
-                               printf("DV REB reties exhausted\n");
-                       }
-#endif
-                       /* FALLTHROUGH */
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       break;
-               }
-               break;
-
-       case AHC_DV_STATE_SU:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       break;
-               }
-               break;
-
-       case AHC_DV_STATE_BUSY:
-               switch (status & SS_MASK) {
-               case SS_NOP:
-               case SS_INQ_REFRESH:
-                       AHC_SET_DV_STATE(ahc, targ,
-                                        AHC_DV_STATE_INQ_SHORT_ASYNC);
-                       break;
-               case SS_TUR:
-               case SS_RETRY:
-                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
-                       if (ahc_cmd_get_transaction_status(cmd)
-                        == CAM_REQUEUE_REQ) {
-                               targ->dv_state_retry--;
-                       } else if (targ->dv_state_retry < 60) {
-                               if ((status & SSQ_DELAY) != 0)
-                                       ssleep(1);
-                       } else {
-#ifdef AHC_DEBUG
-                               if (ahc_debug & AHC_SHOW_DV) {
-                                       ahc_print_devinfo(ahc, devinfo);
-                                       printf("DV BUSY reties exhausted\n");
-                               }
-#endif
-                               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       }
-                       break;
-               default:
-                       AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-                       break;
-               }
-               break;
-
-       default:
-               printf("%s: Invalid DV completion state %d\n", ahc_name(ahc),
-                      targ->dv_state);
-               AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
-               break;
-       }
-}
-
-static void
-ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                     struct ahc_devinfo *devinfo)
-{
-       memset(cmd, 0, sizeof(struct scsi_cmnd));
-       cmd->device = ahc->platform_data->dv_scsi_dev;
-       cmd->scsi_done = ahc_linux_dv_complete;
-}
-
-/*
- * Synthesize an inquiry command.  On the return trip, it'll be
- * sniffed and the device transfer settings set for us.
- */
-static void
-ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                struct ahc_devinfo *devinfo, struct ahc_linux_target *targ,
-                u_int request_length)
-{
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Sending INQ\n");
-       }
-#endif
-       if (targ->inq_data == NULL)
-               targ->inq_data = malloc(AHC_LINUX_DV_INQ_LEN,
-                                       M_DEVBUF, M_WAITOK);
-       if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) {
-               if (targ->dv_buffer != NULL)
-                       free(targ->dv_buffer, M_DEVBUF);
-               targ->dv_buffer = malloc(AHC_LINUX_DV_INQ_LEN,
-                                        M_DEVBUF, M_WAITOK);
-       }
-
-       ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_READ;
-       cmd->cmd_len = 6;
-       cmd->cmnd[0] = INQUIRY;
-       cmd->cmnd[4] = request_length;
-       cmd->request_bufflen = request_length;
-       if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC)
-               cmd->request_buffer = targ->dv_buffer;
-       else
-               cmd->request_buffer = targ->inq_data;
-       memset(cmd->request_buffer, 0, AHC_LINUX_DV_INQ_LEN);
-}
-
-static void
-ahc_linux_dv_tur(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                struct ahc_devinfo *devinfo)
-{
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Sending TUR\n");
-       }
-#endif
-       /* Do a TUR to clear out any non-fatal transitional state */
-       ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_NONE;
-       cmd->cmd_len = 6;
-       cmd->cmnd[0] = TEST_UNIT_READY;
-}
-
-#define AHC_REBD_LEN 4
-
-static void
-ahc_linux_dv_rebd(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
-{
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Sending REBD\n");
-       }
-#endif
-       if (targ->dv_buffer != NULL)
-               free(targ->dv_buffer, M_DEVBUF);
-       targ->dv_buffer = malloc(AHC_REBD_LEN, M_DEVBUF, M_WAITOK);
-       ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_READ;
-       cmd->cmd_len = 10;
-       cmd->cmnd[0] = READ_BUFFER;
-       cmd->cmnd[1] = 0x0b;
-       scsi_ulto3b(AHC_REBD_LEN, &cmd->cmnd[6]);
-       cmd->request_bufflen = AHC_REBD_LEN;
-       cmd->underflow = cmd->request_bufflen;
-       cmd->request_buffer = targ->dv_buffer;
-}
-
-static void
-ahc_linux_dv_web(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
-{
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Sending WEB\n");
-       }
-#endif
-       ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_WRITE;
-       cmd->cmd_len = 10;
-       cmd->cmnd[0] = WRITE_BUFFER;
-       cmd->cmnd[1] = 0x0a;
-       scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]);
-       cmd->request_bufflen = targ->dv_echo_size;
-       cmd->underflow = cmd->request_bufflen;
-       cmd->request_buffer = targ->dv_buffer;
-}
-
-static void
-ahc_linux_dv_reb(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-                struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
-{
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Sending REB\n");
-       }
-#endif
-       ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_READ;
-       cmd->cmd_len = 10;
-       cmd->cmnd[0] = READ_BUFFER;
-       cmd->cmnd[1] = 0x0a;
-       scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]);
-       cmd->request_bufflen = targ->dv_echo_size;
-       cmd->underflow = cmd->request_bufflen;
-       cmd->request_buffer = targ->dv_buffer1;
-}
-
-static void
-ahc_linux_dv_su(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
-               struct ahc_devinfo *devinfo,
-               struct ahc_linux_target *targ)
-{
-       u_int le;
-
-       le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0;
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Sending SU\n");
-       }
-#endif
-       ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
-       cmd->sc_data_direction = SCSI_DATA_NONE;
-       cmd->cmd_len = 6;
-       cmd->cmnd[0] = START_STOP_UNIT;
-       cmd->cmnd[4] = le | SSS_START;
-}
-
-static int
-ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-       struct  ahc_linux_target *targ;
-       struct  ahc_initiator_tinfo *tinfo;
-       struct  ahc_transinfo *goal;
-       struct  ahc_tmode_tstate *tstate;
-       struct  ahc_syncrate *syncrate;
-       u_long  s;
-       u_int   width;
-       u_int   period;
-       u_int   offset;
-       u_int   ppr_options;
-       u_int   cur_speed;
-       u_int   wide_speed;
-       u_int   narrow_speed;
-       u_int   fallback_speed;
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               ahc_print_devinfo(ahc, devinfo);
-               printf("Trying to fallback\n");
-       }
-#endif
-       ahc_lock(ahc, &s);
-       targ = ahc->platform_data->targets[devinfo->target_offset];
-       tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
-                                   devinfo->our_scsiid,
-                                   devinfo->target, &tstate);
-       goal = &tinfo->goal;
-       width = goal->width;
-       period = goal->period;
-       offset = goal->offset;
-       ppr_options = goal->ppr_options;
-       if (offset == 0)
-               period = AHC_ASYNC_XFER_PERIOD;
-       if (targ->dv_next_narrow_period == 0)
-               targ->dv_next_narrow_period = MAX(period, AHC_SYNCRATE_ULTRA2);
-       if (targ->dv_next_wide_period == 0)
-               targ->dv_next_wide_period = period;
-       if (targ->dv_max_width == 0)
-               targ->dv_max_width = width;
-       if (targ->dv_max_ppr_options == 0)
-               targ->dv_max_ppr_options = ppr_options;
-       if (targ->dv_last_ppr_options == 0)
-               targ->dv_last_ppr_options = ppr_options;
-
-       cur_speed = aic_calc_speed(width, period, offset, AHC_SYNCRATE_MIN);
-       wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
-                                         targ->dv_next_wide_period,
-                                         MAX_OFFSET,
-                                         AHC_SYNCRATE_MIN);
-       narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
-                                           targ->dv_next_narrow_period,
-                                           MAX_OFFSET,
-                                           AHC_SYNCRATE_MIN);
-       fallback_speed = aic_calc_speed(width, period+1, offset,
-                                       AHC_SYNCRATE_MIN);
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
-                      "fallback_speed= %d\n", cur_speed, wide_speed,
-                      narrow_speed, fallback_speed);
-       }
-#endif
-
-       if (cur_speed > 160000) {
-               /*
-                * Paced/DT/IU_REQ only transfer speeds.  All we
-                * can do is fallback in terms of syncrate.
-                */
-               period++;
-       } else if (cur_speed > 80000) {
-               if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
-                       /*
-                        * Try without IU_REQ as it may be confusing
-                        * an expander.
-                        */
-                       ppr_options &= ~MSG_EXT_PPR_IU_REQ;
-               } else {
-                       /*
-                        * Paced/DT only transfer speeds.  All we
-                        * can do is fallback in terms of syncrate.
-                        */
-                       period++;
-                       ppr_options = targ->dv_max_ppr_options;
-               }
-       } else if (cur_speed > 3300) {
-
-               /*
-                * In this range we the following
-                * options ordered from highest to
-                * lowest desireability:
-                *
-                * o Wide/DT
-                * o Wide/non-DT
-                * o Narrow at a potentally higher sync rate.
-                *
-                * All modes are tested with and without IU_REQ
-                * set since using IUs may confuse an expander.
-                */
-               if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
-
-                       ppr_options &= ~MSG_EXT_PPR_IU_REQ;
-               } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
-                       /*
-                        * Try going non-DT.
-                        */
-                       ppr_options = targ->dv_max_ppr_options;
-                       ppr_options &= ~MSG_EXT_PPR_DT_REQ;
-               } else if (targ->dv_last_ppr_options != 0) {
-                       /*
-                        * Try without QAS or any other PPR options.
-                        * We may need a non-PPR message to work with
-                        * an expander.  We look at the "last PPR options"
-                        * so we will perform this fallback even if the
-                        * target responded to our PPR negotiation with
-                        * no option bits set.
-                        */
-                       ppr_options = 0;
-               } else if (width == MSG_EXT_WDTR_BUS_16_BIT) {
-                       /*
-                        * If the next narrow speed is greater than
-                        * the next wide speed, fallback to narrow.
-                        * Otherwise fallback to the next DT/Wide setting.
-                        * The narrow async speed will always be smaller
-                        * than the wide async speed, so handle this case
-                        * specifically.
-                        */
-                       ppr_options = targ->dv_max_ppr_options;
-                       if (narrow_speed > fallback_speed
-                        || period >= AHC_ASYNC_XFER_PERIOD) {
-                               targ->dv_next_wide_period = period+1;
-                               width = MSG_EXT_WDTR_BUS_8_BIT;
-                               period = targ->dv_next_narrow_period;
-                       } else {
-                               period++;
-                       }
-               } else if ((ahc->features & AHC_WIDE) != 0
-                       && targ->dv_max_width != 0
-                       && wide_speed >= fallback_speed
-                       && (targ->dv_next_wide_period <= AHC_ASYNC_XFER_PERIOD
-                        || period >= AHC_ASYNC_XFER_PERIOD)) {
-
-                       /*
-                        * We are narrow.  Try falling back
-                        * to the next wide speed with 
-                        * all supported ppr options set.
-                        */
-                       targ->dv_next_narrow_period = period+1;
-                       width = MSG_EXT_WDTR_BUS_16_BIT;
-                       period = targ->dv_next_wide_period;
-                       ppr_options = targ->dv_max_ppr_options;
-               } else {
-                       /* Only narrow fallback is allowed. */
-                       period++;
-                       ppr_options = targ->dv_max_ppr_options;
-               }
-       } else {
-               ahc_unlock(ahc, &s);
-               return (-1);
-       }
-       offset = MAX_OFFSET;
-       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
-                                    AHC_SYNCRATE_DT);
-       ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, FALSE);
-       if (period == 0) {
-               period = 0;
-               offset = 0;
-               ppr_options = 0;
-               if (width == MSG_EXT_WDTR_BUS_8_BIT)
-                       targ->dv_next_narrow_period = AHC_ASYNC_XFER_PERIOD;
-               else
-                       targ->dv_next_wide_period = AHC_ASYNC_XFER_PERIOD;
-       }
-       ahc_set_syncrate(ahc, devinfo, syncrate, period, offset,
-                        ppr_options, AHC_TRANS_GOAL, FALSE);
-       targ->dv_last_ppr_options = ppr_options;
-       ahc_unlock(ahc, &s);
-       return (0);
-}
-
-static void
-ahc_linux_dv_timeout(struct scsi_cmnd *cmd)
-{
-       struct  ahc_softc *ahc;
-       struct  scb *scb;
-       u_long  flags;
-
-       ahc = *((struct ahc_softc **)cmd->device->host->hostdata);
-       ahc_lock(ahc, &flags);
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV) {
-               printf("%s: Timeout while doing DV command %x.\n",
-                      ahc_name(ahc), cmd->cmnd[0]);
-               ahc_dump_card_state(ahc);
-       }
-#endif
-       
-       /*
-        * Guard against "done race".  No action is
-        * required if we just completed.
-        */
-       if ((scb = (struct scb *)cmd->host_scribble) == NULL) {
-               ahc_unlock(ahc, &flags);
-               return;
-       }
-
-       /*
-        * Command has not completed.  Mark this
-        * SCB as having failing status prior to
-        * resetting the bus, so we get the correct
-        * error code.
-        */
-       if ((scb->flags & SCB_SENSE) != 0)
-               ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
-       else
-               ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
-       ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE);
-
-       /*
-        * Add a minimal bus settle delay for devices that are slow to
-        * respond after bus resets.
-        */
-       ahc_linux_freeze_simq(ahc);
-       init_timer(&ahc->platform_data->reset_timer);
-       ahc->platform_data->reset_timer.data = (u_long)ahc;
-       ahc->platform_data->reset_timer.expires = jiffies + HZ / 2;
-       ahc->platform_data->reset_timer.function =
-           (ahc_linux_callback_t *)ahc_linux_release_simq;
-       add_timer(&ahc->platform_data->reset_timer);
-       if (ahc_linux_next_device_to_run(ahc) != NULL)
-               ahc_schedule_runq(ahc);
-       ahc_linux_run_complete_queue(ahc);
-       ahc_unlock(ahc, &flags);
-}
-
-static void
-ahc_linux_dv_complete(struct scsi_cmnd *cmd)
-{
-       struct ahc_softc *ahc;
-
-       ahc = *((struct ahc_softc **)cmd->device->host->hostdata);
-
-       /* Delete the DV timer before it goes off! */
-       scsi_delete_timer(cmd);
-
-#ifdef AHC_DEBUG
-       if (ahc_debug & AHC_SHOW_DV)
-               printf("%s:%d:%d: Command completed, status= 0x%x\n",
-                      ahc_name(ahc), cmd->device->channel,
-                      cmd->device->id, cmd->result);
-#endif
-
-       /* Wake up the state machine */
-       up(&ahc->platform_data->dv_cmd_sem);
-}
-
-static void
-ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ)
-{
-       uint16_t b;
-       u_int    i;
-       u_int    j;
-
-       if (targ->dv_buffer != NULL)
-               free(targ->dv_buffer, M_DEVBUF);
-       targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK);
-       if (targ->dv_buffer1 != NULL)
-               free(targ->dv_buffer1, M_DEVBUF);
-       targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK);
-
-       i = 0;
-       b = 0x0001;
-       for (j = 0 ; i < targ->dv_echo_size; j++) {
-               if (j < 32) {
-                       /*
-                        * 32bytes of sequential numbers.
-                        */
-                       targ->dv_buffer[i++] = j & 0xff;
-               } else if (j < 48) {
-                       /*
-                        * 32bytes of repeating 0x0000, 0xffff.
-                        */
-                       targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00;
-               } else if (j < 64) {
-                       /*
-                        * 32bytes of repeating 0x5555, 0xaaaa.
-                        */
-                       targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55;
-               } else {
-                       /*
-                        * Remaining buffer is filled with a repeating
-                        * patter of:
-                        *
-                        *       0xffff
-                        *      ~0x0001 << shifted once in each loop.
-                        */
-                       if (j & 0x02) {
-                               if (j & 0x01) {
-                                       targ->dv_buffer[i++] = ~(b >> 8) & 0xff;
-                                       b <<= 1;
-                                       if (b == 0x0000)
-                                               b = 0x0001;
-                               } else {
-                                       targ->dv_buffer[i++] = (~b & 0xff);
-                               }
-                       } else {
-                               targ->dv_buffer[i++] = 0xff;
-                       }
-               }
-       }
-}
-
-static u_int
-ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-       static int warned_user;
-       u_int tags;
-
-       tags = 0;
-       if ((ahc->user_discenable & devinfo->target_mask) != 0) {
-               if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) {
-                       if (warned_user == 0) {
-
-                               printf(KERN_WARNING
-"aic7xxx: WARNING: Insufficient tag_info instances\n"
-"aic7xxx: for installed controllers. Using defaults\n"
-"aic7xxx: Please update the aic7xxx_tag_info array in\n"
-"aic7xxx: the aic7xxx_osm..c source file.\n");
-                               warned_user++;
-                       }
-                       tags = AHC_MAX_QUEUE;
-               } else {
-                       adapter_tag_info_t *tag_info;
-
-                       tag_info = &aic7xxx_tag_info[ahc->unit];
-                       tags = tag_info->tag_commands[devinfo->target_offset];
-                       if (tags > AHC_MAX_QUEUE)
-                               tags = AHC_MAX_QUEUE;
-               }
-       }
-       return (tags);
-}
-
-static u_int
-ahc_linux_user_dv_setting(struct ahc_softc *ahc)
-{
-       static int warned_user;
-       int dv;
-
-       if (ahc->unit >= NUM_ELEMENTS(aic7xxx_dv_settings)) {
-               if (warned_user == 0) {
-
-                       printf(KERN_WARNING
-"aic7xxx: WARNING: Insufficient dv settings instances\n"
-"aic7xxx: for installed controllers. Using defaults\n"
-"aic7xxx: Please update the aic7xxx_dv_settings array\n"
-"aic7xxx: in the aic7xxx_osm.c source file.\n");
-                       warned_user++;
-               }
-               dv = -1;
-       } else {
-
-               dv = aic7xxx_dv_settings[ahc->unit];
-       }
-
-       if (dv < 0) {
-               u_long s;
-
-               /*
-                * Apply the default.
-                */
-               /*
-                * XXX - Enable DV on non-U160 controllers once it
-                *       has been tested there.
-                */
-               ahc_lock(ahc, &s);
-               dv = (ahc->features & AHC_DT);
-               if (ahc->seep_config != 0
-                && ahc->seep_config->signature >= CFSIGNATURE2)
-                       dv = (ahc->seep_config->adapter_control & CFENABLEDV);
-               ahc_unlock(ahc, &s);
-       }
-       return (dv);
-}
-
-/*
- * Determines the queue depth for a given device.
- */
-static void
-ahc_linux_device_queue_depth(struct ahc_softc *ahc,
-                            struct ahc_linux_device *dev)
-{
-       struct  ahc_devinfo devinfo;
-       u_int   tags;
-
-       ahc_compile_devinfo(&devinfo,
-                           dev->target->channel == 0
-                         ? ahc->our_id : ahc->our_id_b,
-                           dev->target->target, dev->lun,
-                           dev->target->channel == 0 ? 'A' : 'B',
-                           ROLE_INITIATOR);
-       tags = ahc_linux_user_tagdepth(ahc, &devinfo);
-       if (tags != 0
-        && dev->scsi_device != NULL
-        && dev->scsi_device->tagged_supported != 0) {
-
-               ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
-               ahc_print_devinfo(ahc, &devinfo);
-               printf("Tagged Queuing enabled.  Depth %d\n", tags);
-       } else {
-               ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE);
-       }
-}
-
-static void
-ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
-{
-       struct   ahc_cmd *acmd;
-       struct   scsi_cmnd *cmd;
-       struct   scb *scb;
-       struct   hardware_scb *hscb;
-       struct   ahc_initiator_tinfo *tinfo;
-       struct   ahc_tmode_tstate *tstate;
-       uint16_t mask;
-
-       if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
-               panic("running device on run list");
-
-       while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
-           && dev->openings > 0 && dev->qfrozen == 0) {
-
-               /*
-                * Schedule us to run later.  The only reason we are not
-                * running is because the whole controller Q is frozen.
-                */
-               if (ahc->platform_data->qfrozen != 0
-                && AHC_DV_SIMQ_FROZEN(ahc) == 0) {
-                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
-                                         dev, links);
-                       dev->flags |= AHC_DEV_ON_RUN_LIST;
-                       return;
-               }
-               /*
-                * Get an scb to use.
-                */
-               if ((scb = ahc_get_scb(ahc)) == NULL) {
-                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
-                                        dev, links);
-                       dev->flags |= AHC_DEV_ON_RUN_LIST;
-                       ahc->flags |= AHC_RESOURCE_SHORTAGE;
-                       return;
-               }
-               TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
-               cmd = &acmd_scsi_cmd(acmd);
-               scb->io_ctx = cmd;
-               scb->platform_data->dev = dev;
-               hscb = scb->hscb;
-               cmd->host_scribble = (char *)scb;
-
-               /*
-                * Fill out basics of the HSCB.
-                */
-               hscb->control = 0;
-               hscb->scsiid = BUILD_SCSIID(ahc, cmd);
-               hscb->lun = cmd->device->lun;
-               mask = SCB_GET_TARGET_MASK(ahc, scb);
-               tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
-                                           SCB_GET_OUR_ID(scb),
-                                           SCB_GET_TARGET(ahc, scb), &tstate);
-               hscb->scsirate = tinfo->scsirate;
-               hscb->scsioffset = tinfo->curr.offset;
-               if ((tstate->ultraenb & mask) != 0)
-                       hscb->control |= ULTRAENB;
-
-               if ((ahc->user_discenable & mask) != 0)
-                       hscb->control |= DISCENB;
-
-               if (AHC_DV_CMD(cmd) != 0)
-                       scb->flags |= SCB_SILENT;
-
-               if ((tstate->auto_negotiate & mask) != 0) {
-                       scb->flags |= SCB_AUTO_NEGOTIATE;
-                       scb->hscb->control |= MK_MESSAGE;
-               }
-
-               if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-                       int     msg_bytes;
-                       uint8_t tag_msgs[2];
-
-                       msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs);
-                       if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) {
-                               hscb->control |= tag_msgs[0];
-                               if (tag_msgs[0] == MSG_ORDERED_TASK)
-                                       dev->commands_since_idle_or_otag = 0;
-                       } else
-#endif
-                       if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
-                        && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
-                               hscb->control |= MSG_ORDERED_TASK;
-                               dev->commands_since_idle_or_otag = 0;
-                       } else {
-                               hscb->control |= MSG_SIMPLE_TASK;
-                       }
-               }
-
-               hscb->cdb_len = cmd->cmd_len;
-               if (hscb->cdb_len <= 12) {
-                       memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
-               } else {
-                       memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
-                       scb->flags |= SCB_CDB32_PTR;
-               }
-
-               scb->platform_data->xfer_len = 0;
-               ahc_set_residual(scb, 0);
-               ahc_set_sense_residual(scb, 0);
-               scb->sg_count = 0;
-               if (cmd->use_sg != 0) {
-                       struct  ahc_dma_seg *sg;
-                       struct  scatterlist *cur_seg;
-                       struct  scatterlist *end_seg;
-                       int     nseg;
-
-                       cur_seg = (struct scatterlist *)cmd->request_buffer;
-                       nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
-                           scsi_to_pci_dma_dir(cmd->sc_data_direction));
-                       end_seg = cur_seg + nseg;
-                       /* Copy the segments into the SG list. */
-                       sg = scb->sg_list;
-                       /*
-                        * The sg_count may be larger than nseg if
-                        * a transfer crosses a 32bit page.
-                        */ 
-                       while (cur_seg < end_seg) {
-                               dma_addr_t addr;
-                               bus_size_t len;
-                               int consumed;
-
-                               addr = sg_dma_address(cur_seg);
-                               len = sg_dma_len(cur_seg);
-                               consumed = ahc_linux_map_seg(ahc, scb,
-                                                            sg, addr, len);
-                               sg += consumed;
-                               scb->sg_count += consumed;
-                               cur_seg++;
-                       }
-                       sg--;
-                       sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
-
-                       /*
-                        * Reset the sg list pointer.
+                        * Reset the sg list pointer.
                         */
                        scb->hscb->sgptr =
                            ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
@@ -3703,7 +2197,7 @@
                        addr = pci_map_single(ahc->dev_softc,
                               cmd->request_buffer,
                               cmd->request_bufflen,
-                              scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                              cmd->sc_data_direction);
                        scb->platform_data->buf_busaddr = addr;
                        scb->sg_count = ahc_linux_map_seg(ahc, scb,
                                                          sg, addr,
@@ -3805,7 +2299,6 @@
        targ->channel = channel;
        targ->target = target;
        targ->ahc = ahc;
-       targ->flags = AHC_DV_REQUIRED;
        ahc->platform_data->targets[target_offset] = targ;
        return (targ);
 }
@@ -3844,10 +2337,6 @@
        ahc->platform_data->targets[target_offset] = NULL;
        if (targ->inq_data != NULL)
                free(targ->inq_data, M_DEVBUF);
-       if (targ->dv_buffer != NULL)
-               free(targ->dv_buffer, M_DEVBUF);
-       if (targ->dv_buffer1 != NULL)
-               free(targ->dv_buffer1, M_DEVBUF);
        free(targ, M_DEVBUF);
 }
 
@@ -3894,8 +2383,7 @@
        targ->devices[dev->lun] = NULL;
        free(dev, M_DEVBUF);
        targ->refcount--;
-       if (targ->refcount == 0
-        && (targ->flags & AHC_DV_REQUIRED) == 0)
+       if (targ->refcount == 0)
                ahc_linux_free_target(ahc, targ);
 }
 
@@ -4099,16 +2587,7 @@
                ahc_linux_handle_scsi_status(ahc, dev, scb);
        } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
                dev->flags |= AHC_DEV_UNCONFIGURED;
-               if (AHC_DV_CMD(cmd) == FALSE)
-                       dev->target->flags &= ~AHC_DV_REQUIRED;
        }
-       /*
-        * Start DV for devices that require it assuming the first command
-        * sent does not result in a selection timeout.
-        */
-       if (ahc_get_transaction_status(scb) != CAM_SEL_TIMEOUT
-        && (dev->target->flags & AHC_DV_REQUIRED) != 0)
-               ahc_linux_start_dv(ahc);
 
        if (dev->openings == 1
         && ahc_get_transaction_status(scb) == CAM_REQ_CMP
@@ -4152,13 +2631,6 @@
 
        ahc_free_scb(ahc, scb);
        ahc_linux_queue_cmd_complete(ahc, cmd);
-
-       if ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_EMPTY) != 0
-        && LIST_FIRST(&ahc->pending_scbs) == NULL) {
-               ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_EMPTY;
-               up(&ahc->platform_data->dv_sem);
-       }
-               
 }
 
 static void
@@ -4335,7 +2807,7 @@
         * full error information available when making
         * state change decisions.
         */
-       if (AHC_DV_CMD(cmd) == FALSE) {
+       {
                u_int new_status;
 
                switch (ahc_cmd_get_transaction_status(cmd)) {
@@ -4426,115 +2898,6 @@
 }
 
 static void
-ahc_linux_filter_inquiry(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
-{
-       struct  scsi_inquiry_data *sid;
-       struct  ahc_initiator_tinfo *tinfo;
-       struct  ahc_transinfo *user;
-       struct  ahc_transinfo *goal;
-       struct  ahc_transinfo *curr;
-       struct  ahc_tmode_tstate *tstate;
-       struct  ahc_syncrate *syncrate;
-       struct  ahc_linux_device *dev;
-       u_int   maxsync;
-       u_int   width;
-       u_int   period;
-       u_int   offset;
-       u_int   ppr_options;
-       u_int   trans_version;
-       u_int   prot_version;
-
-       /*
-        * Determine if this lun actually exists.  If so,
-        * hold on to its corresponding device structure.
-        * If not, make sure we release the device and
-        * don't bother processing the rest of this inquiry
-        * command.
-        */
-       dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
-                                  devinfo->target, devinfo->lun,
-                                  /*alloc*/TRUE);
-
-       sid = (struct scsi_inquiry_data *)dev->target->inq_data;
-       if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
-
-               dev->flags &= ~AHC_DEV_UNCONFIGURED;
-       } else {
-               dev->flags |= AHC_DEV_UNCONFIGURED;
-               return;
-       }
-
-       /*
-        * Update our notion of this device's transfer
-        * negotiation capabilities.
-        */
-       tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
-                                   devinfo->our_scsiid,
-                                   devinfo->target, &tstate);
-       user = &tinfo->user;
-       goal = &tinfo->goal;
-       curr = &tinfo->curr;
-       width = user->width;
-       period = user->period;
-       offset = user->offset;
-       ppr_options = user->ppr_options;
-       trans_version = user->transport_version;
-       prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid));
-
-       /*
-        * Only attempt SPI3/4 once we've verified that
-        * the device claims to support SPI3/4 features.
-        */
-       if (prot_version < SCSI_REV_2)
-               trans_version = SID_ANSI_REV(sid);
-       else
-               trans_version = SCSI_REV_2;
-
-       if ((sid->flags & SID_WBus16) == 0)
-               width = MSG_EXT_WDTR_BUS_8_BIT;
-       if ((sid->flags & SID_Sync) == 0) {
-               period = 0;
-               offset = 0;
-               ppr_options = 0;
-       }
-       if ((sid->spi3data & SID_SPI_QAS) == 0)
-               ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
-       if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0)
-               ppr_options &= MSG_EXT_PPR_QAS_REQ;
-       if ((sid->spi3data & SID_SPI_IUS) == 0)
-               ppr_options &= (MSG_EXT_PPR_DT_REQ
-                             | MSG_EXT_PPR_QAS_REQ);
-
-       if (prot_version > SCSI_REV_2
-        && ppr_options != 0)
-               trans_version = user->transport_version;
-
-       ahc_validate_width(ahc, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN);
-       if ((ahc->features & AHC_ULTRA2) != 0)
-               maxsync = AHC_SYNCRATE_DT;
-       else if ((ahc->features & AHC_ULTRA) != 0)
-               maxsync = AHC_SYNCRATE_ULTRA;
-       else
-               maxsync = AHC_SYNCRATE_FAST;
-
-       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, maxsync);
-       ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate,
-                           &offset, width, ROLE_UNKNOWN);
-       if (offset == 0 || period == 0) {
-               period = 0;
-               offset = 0;
-               ppr_options = 0;
-       }
-       /* Apply our filtered user settings. */
-       curr->transport_version = trans_version;
-       curr->protocol_version = prot_version;
-       ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, /*paused*/FALSE);
-       ahc_set_syncrate(ahc, devinfo, syncrate, period,
-                        offset, ppr_options, AHC_TRANS_GOAL,
-                        /*paused*/FALSE);
-}
-
-static void
 ahc_linux_sem_timeout(u_long arg)
 {
        struct  ahc_softc *ahc;
@@ -4579,11 +2942,6 @@
                ahc->platform_data->qfrozen--;
        if (ahc->platform_data->qfrozen == 0)
                unblock_reqs = 1;
-       if (AHC_DV_SIMQ_FROZEN(ahc)
-        && ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_RELEASE) != 0)) {
-               ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_RELEASE;
-               up(&ahc->platform_data->dv_sem);
-       }
        ahc_schedule_runq(ahc);
        ahc_unlock(ahc, &s);
        /*
@@ -4990,13 +3348,267 @@
 
 static void ahc_linux_exit(void);
 
+static void ahc_linux_get_period(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_period(starget) = tinfo->curr.period;
+}
+
+static void ahc_linux_set_period(struct scsi_target *starget, int period)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       struct ahc_devinfo devinfo;
+       unsigned int ppr_options = tinfo->curr.ppr_options;
+       unsigned long flags;
+       unsigned long offset = tinfo->curr.offset;
+       struct ahc_syncrate *syncrate;
+
+       if (offset == 0)
+               offset = MAX_OFFSET;
+
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, 
AHC_SYNCRATE_DT);
+       ahc_lock(ahc, &flags);
+       ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
+                        ppr_options, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_offset(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_offset(starget) = tinfo->curr.offset;
+}
+
+static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       struct ahc_devinfo devinfo;
+       unsigned int ppr_options = 0;
+       unsigned int period = 0;
+       unsigned long flags;
+       struct ahc_syncrate *syncrate = NULL;
+
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       if (offset != 0) {
+               syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, 
AHC_SYNCRATE_DT);
+               period = tinfo->curr.period;
+               ppr_options = tinfo->curr.ppr_options;
+       }
+       ahc_lock(ahc, &flags);
+       ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
+                        ppr_options, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_width(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_width(starget) = tinfo->curr.width;
+}
+
+static void ahc_linux_set_width(struct scsi_target *starget, int width)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_devinfo devinfo;
+       unsigned long flags;
+
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       ahc_lock(ahc, &flags);
+       ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_dt(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
+}
+
+static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       struct ahc_devinfo devinfo;
+       unsigned int ppr_options = tinfo->curr.ppr_options
+               & ~MSG_EXT_PPR_DT_REQ;
+       unsigned int period = tinfo->curr.period;
+       unsigned long flags;
+       struct ahc_syncrate *syncrate;
+
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+                                    dt ? AHC_SYNCRATE_DT : 
AHC_SYNCRATE_ULTRA2);
+       ahc_lock(ahc, &flags);
+       ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+                        ppr_options, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_qas(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
+}
+
+static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       struct ahc_devinfo devinfo;
+       unsigned int ppr_options = tinfo->curr.ppr_options
+               & ~MSG_EXT_PPR_QAS_REQ;
+       unsigned int period = tinfo->curr.period;
+       unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
+       unsigned long flags;
+       struct ahc_syncrate *syncrate;
+
+       if (qas)
+               ppr_options |= MSG_EXT_PPR_QAS_REQ;
+
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+                                    dt ? AHC_SYNCRATE_DT : 
AHC_SYNCRATE_ULTRA2);
+       ahc_lock(ahc, &flags);
+       ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+                        ppr_options, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
+}
+
+static void ahc_linux_get_iu(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
+}
+
+static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
+       struct ahc_tmode_tstate *tstate;
+       struct ahc_initiator_tinfo *tinfo 
+               = ahc_fetch_transinfo(ahc,
+                                     starget->channel + 'A',
+                                     shost->this_id, starget->id, &tstate);
+       struct ahc_devinfo devinfo;
+       unsigned int ppr_options = tinfo->curr.ppr_options
+               & ~MSG_EXT_PPR_IU_REQ;
+       unsigned int period = tinfo->curr.period;
+       unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
+       unsigned long flags;
+       struct ahc_syncrate *syncrate;
+
+       if (iu)
+               ppr_options |= MSG_EXT_PPR_IU_REQ;
+
+       ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
+                           starget->channel + 'A', ROLE_INITIATOR);
+       syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
+                                    dt ? AHC_SYNCRATE_DT : 
AHC_SYNCRATE_ULTRA2);
+       ahc_lock(ahc, &flags);
+       ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+                        ppr_options, AHC_TRANS_GOAL, FALSE);
+       ahc_unlock(ahc, &flags);
+}
+
+static struct spi_function_template ahc_linux_transport_functions = {
+       .get_offset     = ahc_linux_get_offset,
+       .set_offset     = ahc_linux_set_offset,
+       .show_offset    = 1,
+       .get_period     = ahc_linux_get_period,
+       .set_period     = ahc_linux_set_period,
+       .show_period    = 1,
+       .get_width      = ahc_linux_get_width,
+       .set_width      = ahc_linux_set_width,
+       .show_width     = 1,
+       .get_dt         = ahc_linux_get_dt,
+       .set_dt         = ahc_linux_set_dt,
+       .show_dt        = 1,
+       .get_iu         = ahc_linux_get_iu,
+       .set_iu         = ahc_linux_set_iu,
+       .show_iu        = 1,
+       .get_qas        = ahc_linux_get_qas,
+       .set_qas        = ahc_linux_set_qas,
+       .show_qas       = 1,
+};
+
+
+
 static int __init
 ahc_linux_init(void)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       ahc_linux_transport_template = 
spi_attach_transport(&ahc_linux_transport_functions);
+       if (!ahc_linux_transport_template)
+               return -ENODEV;
        int rc = ahc_linux_detect(&aic7xxx_driver_template);
        if (rc)
                return rc;
+       spi_release_transport(ahc_linux_transport_template);
        ahc_linux_exit();
        return -ENODEV;
 #else
@@ -5014,19 +3626,6 @@
 static void
 ahc_linux_exit(void)
 {
-       struct ahc_softc *ahc;
-
-       /*
-        * Shutdown DV threads before going into the SCSI mid-layer.
-        * This avoids situations where the mid-layer locks the entire
-        * kernel so that waiting for our DV threads to exit leads
-        * to deadlock.
-        */
-       TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-
-               ahc_linux_kill_dv_thread(ahc);
-       }
-
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
        /*
         * In 2.4 we have to unregister from the PCI core _after_
@@ -5037,6 +3636,7 @@
 #endif
        ahc_linux_pci_exit();
        ahc_linux_eisa_exit();
+       spi_release_transport(ahc_linux_transport_template);
 }
 
 module_init(ahc_linux_init);
diff -urN linux/drivers/scsi/aic7xxx/aic7xxx_osm.h 
linux/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- linux/drivers/scsi/aic7xxx/aic7xxx_osm.h    2005/01/25 04:28:43     1.28
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.h    2005/04/29 11:15:12     1.29
@@ -424,27 +424,9 @@
 };
 
 typedef enum {
-       AHC_DV_REQUIRED          = 0x01,
        AHC_INQ_VALID            = 0x02,
-       AHC_BASIC_DV             = 0x04,
-       AHC_ENHANCED_DV          = 0x08
 } ahc_linux_targ_flags;
 
-/* DV States */
-typedef enum {
-       AHC_DV_STATE_EXIT = 0,
-       AHC_DV_STATE_INQ_SHORT_ASYNC,
-       AHC_DV_STATE_INQ_ASYNC,
-       AHC_DV_STATE_INQ_ASYNC_VERIFY,
-       AHC_DV_STATE_TUR,
-       AHC_DV_STATE_REBD,
-       AHC_DV_STATE_INQ_VERIFY,
-       AHC_DV_STATE_WEB,
-       AHC_DV_STATE_REB,
-       AHC_DV_STATE_SU,
-       AHC_DV_STATE_BUSY
-} ahc_dv_state;
-
 struct ahc_linux_target {
        struct ahc_linux_device  *devices[AHC_NUM_LUNS];
        int                       channel;
@@ -454,19 +436,6 @@
        struct ahc_softc         *ahc;
        ahc_linux_targ_flags      flags;
        struct scsi_inquiry_data *inq_data;
-       /*
-        * The next "fallback" period to use for narrow/wide transfers.
-        */
-       uint8_t                   dv_next_narrow_period;
-       uint8_t                   dv_next_wide_period;
-       uint8_t                   dv_max_width;
-       uint8_t                   dv_max_ppr_options;
-       uint8_t                   dv_last_ppr_options;
-       u_int                     dv_echo_size;
-       ahc_dv_state              dv_state;
-       u_int                     dv_state_retry;
-       char                     *dv_buffer;
-       char                     *dv_buffer1;
 };
 
 /********************* Definitions Required by the Core 
***********************/
@@ -511,10 +480,6 @@
  * this driver.
  */
 typedef enum {
-       AHC_DV_WAIT_SIMQ_EMPTY   = 0x01,
-       AHC_DV_WAIT_SIMQ_RELEASE = 0x02,
-       AHC_DV_ACTIVE            = 0x04,
-       AHC_DV_SHUTDOWN          = 0x08,
        AHC_RUN_CMPLT_Q_TIMER    = 0x10
 } ahc_linux_softc_flags;
 
@@ -937,11 +902,6 @@
 #endif
 
 /*************************** Domain Validation 
********************************/
-#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
-#define AHC_DV_SIMQ_FROZEN(ahc)                                        \
-       ((((ahc)->platform_data->flags & AHC_DV_ACTIVE) != 0)   \
-        && (ahc)->platform_data->qfrozen == 1)
-
 /*********************** Transaction Access Wrappers *************************/
 static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
 static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
diff -urN linux/drivers/scsi/aic7xxx/cam.h linux/drivers/scsi/aic7xxx/cam.h
--- linux/drivers/scsi/aic7xxx/cam.h    2004/10/25 20:44:37     1.5
+++ linux/drivers/scsi/aic7xxx/cam.h    2005/04/29 11:15:12     1.6
@@ -103,9 +103,9 @@
 } ac_code;
 
 typedef enum {
-       CAM_DIR_IN              = SCSI_DATA_READ,
-       CAM_DIR_OUT             = SCSI_DATA_WRITE,
-       CAM_DIR_NONE            = SCSI_DATA_NONE
+       CAM_DIR_IN              = DMA_FROM_DEVICE,
+       CAM_DIR_OUT             = DMA_TO_DEVICE,
+       CAM_DIR_NONE            = DMA_NONE,
 } ccb_flags;
 
 #endif /* _AIC7XXX_CAM_H */
diff -urN linux/drivers/scsi/arm/acornscsi.c linux/drivers/scsi/arm/acornscsi.c
--- linux/drivers/scsi/arm/acornscsi.c  2004/10/25 20:44:37     1.9
+++ linux/drivers/scsi/arm/acornscsi.c  2005/04/29 11:15:12     1.10
@@ -150,6 +150,7 @@
 #include <asm/ecard.h>
 
 #include "../scsi.h"
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
 #include "acornscsi.h"
 #include "msgqueue.h"
@@ -866,7 +867,7 @@
                    default:
                        printk(KERN_ERR "scsi%d.H: incomplete data transfer 
detected: result=%08X command=",
                                host->host->host_no, SCpnt->result);
-                       print_command(SCpnt->cmnd);
+                       __scsi_print_command(SCpnt->cmnd);
                        acornscsi_dumpdma(host, "done");
                        acornscsi_dumplog(host, SCpnt->device->id);
                        SCpnt->result &= 0xffff;
@@ -1369,7 +1370,7 @@
 
        host->scsi.last_message = msg->msg[0];
 #if (DEBUG & DEBUG_MESSAGES)
-       print_msg(msg->msg);
+       scsi_print_msg(msg->msg);
 #endif
        break;
 
@@ -1391,7 +1392,7 @@
        while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
            unsigned int i;
 #if (DEBUG & DEBUG_MESSAGES)
-           print_msg(msg);
+           scsi_print_msg(msg);
 #endif
            i = 0;
            if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
@@ -1487,7 +1488,7 @@
 #if (DEBUG & DEBUG_MESSAGES)
     printk("scsi%d.%c: message in: ",
            host->host->host_no, acornscsi_target(host));
-    print_msg(message);
+    scsi_print_msg(message);
     printk("\n");
 #endif
 
diff -urN linux/drivers/scsi/arm/fas216.c linux/drivers/scsi/arm/fas216.c
--- linux/drivers/scsi/arm/fas216.c     2005/03/18 17:37:46     1.10
+++ linux/drivers/scsi/arm/fas216.c     2005/04/29 11:15:12     1.11
@@ -52,6 +52,7 @@
 #include <asm/ecard.h>
 
 #include "../scsi.h"
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
 #include "fas216.h"
 #include "scsi.h"
@@ -309,7 +310,7 @@
        va_end(args);
 
        printk(" CDB: ");
-       print_command(SCpnt->cmnd);
+       __scsi_print_command(SCpnt->cmnd);
 }
 
 static void
@@ -2081,7 +2082,7 @@
                                info->host->host_no, '0' + SCpnt->device->id,
                                SCpnt->result, info->scsi.SCp.ptr,
                                info->scsi.SCp.this_residual);
-                       print_command(SCpnt->cmnd);
+                       __scsi_print_command(SCpnt->cmnd);
                        SCpnt->result &= ~(255 << 16);
                        SCpnt->result |= DID_BAD_TARGET << 16;
                        goto request_sense;
@@ -2116,7 +2117,7 @@
        SCpnt->SCp.Message = 0;
        SCpnt->SCp.Status = 0;
        SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
-       SCpnt->sc_data_direction = SCSI_DATA_READ;
+       SCpnt->sc_data_direction = DMA_FROM_DEVICE;
        SCpnt->use_sg = 0;
        SCpnt->tag = 0;
        SCpnt->host_scribble = (void *)fas216_rq_sns_done;
@@ -2170,7 +2171,7 @@
                       info->host->host_no, '0' + SCpnt->device->id,
                       info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
                info->scsi.SCp.ptr = NULL;
-               print_command(SCpnt->cmnd);
+               __scsi_print_command(SCpnt->cmnd);
        }
 
        /*
@@ -2426,7 +2427,7 @@
        info->stats.aborts += 1;
 
        printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
-       print_command(SCpnt->data_cmnd);
+       __scsi_print_command(SCpnt->data_cmnd);
 
        print_debug_list();
        fas216_dumpstate(info);
diff -urN linux/drivers/scsi/arm/scsi.h linux/drivers/scsi/arm/scsi.h
--- linux/drivers/scsi/arm/scsi.h       2003/08/26 00:28:56     1.2
+++ linux/drivers/scsi/arm/scsi.h       2005/04/29 11:15:12     1.3
@@ -108,7 +108,7 @@
 #if 0 //def BELT_AND_BRACES
                printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
                       "command ", SCpnt->host->host_no, '0' + SCpnt->target);
-               print_command(SCpnt->cmnd);
+               __scsi_print_command(SCpnt->cmnd);
 #endif
                SCpnt->SCp.ptr = NULL;
        }
diff -urN linux/drivers/scsi/lpfc/Makefile linux/drivers/scsi/lpfc/Makefile
--- linux/drivers/scsi/lpfc/Makefile    1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/Makefile    2005-04-29 12:15:12.988221000 +0100     
1.1
@@ -0,0 +1,32 @@
+#/*******************************************************************
+# * This file is part of the Emulex Linux Device Driver for         *
+# * Enterprise Fibre Channel Host Bus Adapters.                     *
+# * Refer to the README file included with this package for         *
+# * driver version and adapter support.                             *
+# * Copyright (C) 2004 Emulex Corporation.                          *
+# * www.emulex.com                                                  *
+# *                                                                 *
+# * 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, a copy of which    *
+# * can be found in the file COPYING included with this package.    *
+# *******************************************************************/
+######################################################################
+
+#$Id: Makefile 1.58 2005/01/23 19:00:32EST sf_support Exp  $
+
+ifneq ($(GCOV),)
+  EXTRA_CFLAGS += -fprofile-arcs -ftest-coverage
+  EXTRA_CFLAGS += -O0
+endif
+
+obj-$(CONFIG_SCSI_LPFC) := lpfc.o
+
+lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o \
+       lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o
diff -urN linux/drivers/scsi/lpfc/lpfc.h linux/drivers/scsi/lpfc/lpfc.h
--- linux/drivers/scsi/lpfc/lpfc.h      1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/lpfc.h      2005-04-29 12:15:12.999128000 +0100     
1.1
@@ -0,0 +1,384 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Enterprise Fibre Channel Host Bus Adapters.                     *
+ * Refer to the README file included with this package for         *
+ * driver version and adapter support.                             *
+ * Copyright (C) 2004 Emulex Corporation.                          *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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, a copy of which    *
+ * can be found in the file COPYING included with this package.    *
+ *******************************************************************/
+
+/*
+ * $Id: lpfc.h 1.167 2005/04/07 08:47:05EDT sf_support Exp  $
+ */
+
+struct lpfc_sli2_slim;
+
+#define LPFC_MAX_TARGET         256    /* max targets supported */
+#define LPFC_MAX_DISC_THREADS  64      /* max outstanding discovery els req */
+#define LPFC_MAX_NS_RETRY       3      /* max NameServer retries */
+
+#define LPFC_DFT_HBA_Q_DEPTH   2048    /* max cmds per hba */
+#define LPFC_LC_HBA_Q_DEPTH    1024    /* max cmds per low cost hba */
+#define LPFC_LP101_HBA_Q_DEPTH 128     /* max cmds per low cost hba */
+
+#define LPFC_CMD_PER_LUN       30      /* max outstanding cmds per lun */
+#define LPFC_SG_SEG_CNT                64      /* sg element count per scsi 
cmnd */
+#define LPFC_IOCB_LIST_CNT     2250    /* list of IOCBs for fast-path usage. */
+
+/* Define macros for 64 bit support */
+#define putPaddrLow(addr)    ((uint32_t) (0xffffffff & (u64)(addr)))
+#define putPaddrHigh(addr)   ((uint32_t) (0xffffffff & (((u64)(addr))>>32)))
+#define getPaddr(high, low)  ((dma_addr_t)( \
+                            (( (u64)(high)<<16 ) << 16)|( (u64)(low))))
+/* Provide maximum configuration definitions. */
+#define LPFC_DRVR_TIMEOUT      16      /* driver iocb timeout value in sec */
+#define MAX_FCP_TARGET         256     /* max num of FCP targets supported */
+#define FC_MAX_ADPTMSG         64
+
+#define MAX_HBAEVT     32
+
+/* Provide DMA memory definitions the driver uses per port instance. */
+struct lpfc_dmabuf {
+       struct list_head list;
+       void *virt;             /* virtual address ptr */
+       dma_addr_t phys;        /* mapped address */
+};
+
+struct lpfc_dma_pool {
+       struct lpfc_dmabuf   *elements;
+       uint32_t    max_count;
+       uint32_t    current_count;
+};
+
+/* Priority bit.  Set value to exceed low water mark in lpfc_mem. */
+#define MEM_PRI                0x100
+
+
+/****************************************************************************/
+/*      Device VPD save area                                                */
+/****************************************************************************/
+typedef struct lpfc_vpd {
+       uint32_t status;        /* vpd status value */
+       uint32_t length;        /* number of bytes actually returned */
+       struct {
+               uint32_t rsvd1; /* Revision numbers */
+               uint32_t biuRev;
+               uint32_t smRev;
+               uint32_t smFwRev;
+               uint32_t endecRev;
+               uint16_t rBit;
+               uint8_t fcphHigh;
+               uint8_t fcphLow;
+               uint8_t feaLevelHigh;
+               uint8_t feaLevelLow;
+               uint32_t postKernRev;
+               uint32_t opFwRev;
+               uint8_t opFwName[16];
+               uint32_t sli1FwRev;
+               uint8_t sli1FwName[16];
+               uint32_t sli2FwRev;
+               uint8_t sli2FwName[16];
+       } rev;
+} lpfc_vpd_t;
+
+struct lpfc_scsi_buf;
+
+
+/*
+ * lpfc stat counters
+ */
+struct lpfc_stats {
+       /* Statistics for ELS commands */
+       uint32_t elsLogiCol;
+       uint32_t elsRetryExceeded;
+       uint32_t elsXmitRetry;
+       uint32_t elsDelayRetry;
+       uint32_t elsRcvDrop;
+       uint32_t elsRcvFrame;
+       uint32_t elsRcvRSCN;
+       uint32_t elsRcvRNID;
+       uint32_t elsRcvFARP;
+       uint32_t elsRcvFARPR;
+       uint32_t elsRcvFLOGI;
+       uint32_t elsRcvPLOGI;
+       uint32_t elsRcvADISC;
+       uint32_t elsRcvPDISC;
+       uint32_t elsRcvFAN;
+       uint32_t elsRcvLOGO;
+       uint32_t elsRcvPRLO;
+       uint32_t elsRcvPRLI;
+       uint32_t elsRcvRRQ;
+       uint32_t elsXmitFLOGI;
+       uint32_t elsXmitPLOGI;
+       uint32_t elsXmitPRLI;
+       uint32_t elsXmitADISC;
+       uint32_t elsXmitLOGO;
+       uint32_t elsXmitSCR;
+       uint32_t elsXmitRNID;
+       uint32_t elsXmitFARP;
+       uint32_t elsXmitFARPR;
+       uint32_t elsXmitACC;
+       uint32_t elsXmitLSRJT;
+
+       uint32_t frameRcvBcast;
+       uint32_t frameRcvMulti;
+       uint32_t strayXmitCmpl;
+       uint32_t frameXmitDelay;
+       uint32_t xriCmdCmpl;
+       uint32_t xriStatErr;
+       uint32_t LinkUp;
+       uint32_t LinkDown;
+       uint32_t LinkMultiEvent;
+       uint32_t NoRcvBuf;
+       uint32_t fcpCmd;
+       uint32_t fcpCmpl;
+       uint32_t fcpRspErr;
+       uint32_t fcpRemoteStop;
+       uint32_t fcpPortRjt;
+       uint32_t fcpPortBusy;
+       uint32_t fcpError;
+       uint32_t fcpLocalErr;
+};
+
+enum sysfs_mbox_state {
+       SMBOX_IDLE,
+       SMBOX_WRITING,
+       SMBOX_READING
+};
+
+struct lpfc_sysfs_mbox {
+       enum sysfs_mbox_state state;
+       size_t                offset;
+       struct lpfcMboxq *    mbox;
+};
+
+struct lpfc_hba {
+       struct list_head hba_list;      /* List of hbas/ports */
+       struct lpfc_sli sli;
+       struct lpfc_sli2_slim *slim2p;
+       dma_addr_t slim2p_mapping;
+       uint16_t pci_cfg_value;
+
+       uint32_t hba_state;
+
+#define LPFC_INIT_START           1    /* Initial state after board reset */
+#define LPFC_INIT_MBX_CMDS        2    /* Initialize HBA with mbox commands */
+#define LPFC_LINK_DOWN            3    /* HBA initialized, link is down */
+#define LPFC_LINK_UP              4    /* Link is up  - issue READ_LA */
+#define LPFC_LOCAL_CFG_LINK       5    /* local NPORT Id configured */
+#define LPFC_FLOGI                6    /* FLOGI sent to Fabric */
+#define LPFC_FABRIC_CFG_LINK      7    /* Fabric assigned NPORT Id
+                                          configured */
+#define LPFC_NS_REG               8    /* Register with NameServer */
+#define LPFC_NS_QRY               9    /* Query NameServer for NPort ID list */
+#define LPFC_BUILD_DISC_LIST      10   /* Build ADISC and PLOGI lists for
+                                        * device authentication / discovery */
+#define LPFC_DISC_AUTH            11   /* Processing ADISC list */
+#define LPFC_CLEAR_LA             12   /* authentication cmplt - issue
+                                          CLEAR_LA */
+#define LPFC_HBA_READY            32
+#define LPFC_HBA_ERROR            0xff
+
+       uint8_t fc_linkspeed;   /* Link speed after last READ_LA */
+
+       uint32_t fc_eventTag;   /* event tag for link attention */
+       uint32_t fc_prli_sent;  /* cntr for outstanding PRLIs */
+
+       uint32_t num_disc_nodes;        /*in addition to hba_state */
+
+       struct timer_list fc_estabtmo;  /* link establishment timer */
+       struct timer_list fc_disctmo;   /* Discovery rescue timer */
+       struct timer_list fc_fdmitmo;   /* fdmi timer */
+       /* These fields used to be binfo */
+       struct lpfc_name fc_nodename;   /* fc nodename */
+       struct lpfc_name fc_portname;   /* fc portname */
+       uint32_t fc_pref_DID;   /* preferred D_ID */
+       uint8_t fc_pref_ALPA;   /* preferred AL_PA */
+       uint32_t fc_edtov;      /* E_D_TOV timer value */
+       uint32_t fc_arbtov;     /* ARB_TOV timer value */
+       uint32_t fc_ratov;      /* R_A_TOV timer value */
+       uint32_t fc_rttov;      /* R_T_TOV timer value */
+       uint32_t fc_altov;      /* AL_TOV timer value */
+       uint32_t fc_crtov;      /* C_R_TOV timer value */
+       uint32_t fc_citov;      /* C_I_TOV timer value */
+       uint32_t fc_myDID;      /* fibre channel S_ID */
+       uint32_t fc_prevDID;    /* previous fibre channel S_ID */
+
+       struct serv_parm fc_sparam;     /* buffer for our service parameters */
+       struct serv_parm fc_fabparam;   /* fabric service parameters buffer */
+       uint8_t alpa_map[128];  /* AL_PA map from READ_LA */
+
+       uint8_t fc_ns_retry;    /* retries for fabric nameserver */
+       uint32_t fc_nlp_cnt;    /* outstanding NODELIST requests */
+       uint32_t fc_rscn_id_cnt;        /* count of RSCNs payloads in list */
+       struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
+       uint32_t lmt;
+       uint32_t fc_flag;       /* FC flags */
+#define FC_PT2PT                0x1    /* pt2pt with no fabric */
+#define FC_PT2PT_PLOGI          0x2    /* pt2pt initiate PLOGI */
+#define FC_DISC_TMO             0x4    /* Discovery timer running */
+#define FC_PUBLIC_LOOP          0x8    /* Public loop */
+#define FC_LBIT                 0x10   /* LOGIN bit in loopinit set */
+#define FC_RSCN_MODE            0x20   /* RSCN cmd rcv'ed */
+#define FC_NLP_MORE             0x40   /* More node to process in node tbl */
+#define FC_OFFLINE_MODE         0x80   /* Interface is offline for diag */
+#define FC_FABRIC               0x100  /* We are fabric attached */
+#define FC_ESTABLISH_LINK       0x200  /* Reestablish Link */
+#define FC_RSCN_DISCOVERY       0x400  /* Authenticate all devices after RSCN*/
+#define FC_LOADING             0x1000  /* HBA in process of loading drvr */
+#define FC_UNLOADING           0x2000  /* HBA in process of unloading drvr */
+#define FC_SCSI_SCAN_TMO        0x4000 /* scsi scan timer running */
+#define FC_ABORT_DISCOVERY      0x8000 /* we want to abort discovery */
+#define FC_NDISC_ACTIVE         0x10000        /* NPort discovery active */
+
+       uint32_t fc_topology;   /* link topology, from LINK INIT */
+
+       struct lpfc_stats fc_stat;
+
+       /* These are the head/tail pointers for the bind, plogi, adisc, unmap,
+        *  and map lists.  Their counters are immediately following.
+        */
+       struct list_head fc_plogi_list;
+       struct list_head fc_adisc_list;
+       struct list_head fc_reglogin_list;
+       struct list_head fc_prli_list;
+       struct list_head fc_nlpunmap_list;
+       struct list_head fc_nlpmap_list;
+       struct list_head fc_npr_list;
+       struct list_head fc_unused_list;
+
+       /* Keep counters for the number of entries in each list. */
+       uint16_t fc_plogi_cnt;
+       uint16_t fc_adisc_cnt;
+       uint16_t fc_reglogin_cnt;
+       uint16_t fc_prli_cnt;
+       uint16_t fc_unmap_cnt;
+       uint16_t fc_map_cnt;
+       uint16_t fc_npr_cnt;
+       uint16_t fc_unused_cnt;
+       struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */
+       uint32_t nport_event_cnt;       /* timestamp for nlplist entry */
+
+#define LPFC_RPI_HASH_SIZE     64
+#define LPFC_RPI_HASH_FUNC(x)  ((x) & (0x3f))
+       /* ptr to active D_ID / RPIs */
+       struct lpfc_nodelist *fc_nlplookup[LPFC_RPI_HASH_SIZE];
+       uint32_t wwnn[2];
+       uint32_t RandomData[7];
+
+       uint32_t cfg_log_verbose;
+       uint32_t cfg_lun_queue_depth;
+       uint32_t cfg_nodev_tmo;
+       uint32_t cfg_hba_queue_depth;
+       uint32_t cfg_fcp_class;
+       uint32_t cfg_use_adisc;
+       uint32_t cfg_ack0;
+       uint32_t cfg_topology;
+       uint32_t cfg_scan_down;
+       uint32_t cfg_link_speed;
+       uint32_t cfg_cr_delay;
+       uint32_t cfg_cr_count;
+       uint32_t cfg_fdmi_on;
+       uint32_t cfg_fcp_bind_method;
+       uint32_t cfg_discovery_threads;
+       uint32_t cfg_max_luns;
+       uint32_t cfg_sg_seg_cnt;
+       uint32_t cfg_sg_dma_buf_size;
+
+       lpfc_vpd_t vpd;         /* vital product data */
+
+       struct Scsi_Host *host;
+       struct pci_dev *pcidev;
+       struct list_head      work_list;
+       uint32_t              work_ha;      /* Host Attention Bits for WT */
+       uint32_t              work_ha_mask; /* HA Bits owned by WT        */
+       uint32_t              work_hs;      /* HS stored in case of ERRAT */
+       uint32_t              work_status[2]; /* Extra status from SLIM */
+       uint32_t              work_hba_events; /* Timeout to be handled  */
+#define WORKER_DISC_TMO                0x1     /* Discovery timeout */
+#define WORKER_ELS_TMO                 0x2     /* ELS timeout */
+#define WORKER_MBOX_TMO                0x4     /* MBOX timeout */
+#define WORKER_FDMI_TMO                0x8     /* FDMI timeout */
+
+       wait_queue_head_t    *work_wait;
+       struct task_struct   *worker_thread;
+
+       unsigned long pci_bar0_map;     /* Physical address for PCI BAR0 */
+       unsigned long pci_bar2_map;     /* Physical address for PCI BAR2 */
+       void __iomem *slim_memmap_p;    /* Kernel memory mapped address for
+                                          PCI BAR0 */
+       void __iomem *ctrl_regs_memmap_p;/* Kernel memory mapped address for
+                                           PCI BAR2 */
+
+       void __iomem *MBslimaddr;       /* virtual address for mbox cmds */
+       void __iomem *HAregaddr;        /* virtual address for host attn reg */
+       void __iomem *CAregaddr;        /* virtual address for chip attn reg */
+       void __iomem *HSregaddr;        /* virtual address for host status
+                                          reg */
+       void __iomem *HCregaddr;        /* virtual address for host ctl reg */
+
+       int brd_no;                     /* FC board number */
+
+       char SerialNumber[32];          /* adapter Serial Number */
+       char OptionROMVersion[32];      /* adapter BIOS / Fcode version */
+       char ModelDesc[256];            /* Model Description */
+       char ModelName[80];             /* Model Name */
+       char ProgramType[256];          /* Program Type */
+       char Port[20];                  /* Port No */
+       uint8_t vpd_flag;               /* VPD data flag */
+
+#define VPD_MODEL_DESC      0x1         /* valid vpd model description */
+#define VPD_MODEL_NAME      0x2         /* valid vpd model name */
+#define VPD_PROGRAM_TYPE    0x4         /* valid vpd program type */
+#define VPD_PORT            0x8         /* valid vpd port data */
+#define VPD_MASK            0xf         /* mask for any vpd data */
+
+       struct timer_list els_tmofunc;
+
+       void *link_stats;
+
+       /*
+        * stat  counters
+        */
+       uint64_t fc4InputRequests;
+       uint64_t fc4OutputRequests;
+       uint64_t fc4ControlRequests;
+
+       struct lpfc_sysfs_mbox sysfs_mbox;
+
+       /* fastpath list. */
+       struct list_head lpfc_scsi_buf_list;
+       uint32_t total_scsi_bufs;
+       struct list_head lpfc_iocb_list;
+       uint32_t total_iocbq_bufs;
+
+       /* pci_mem_pools */
+       struct pci_pool *lpfc_scsi_dma_buf_pool;
+       struct pci_pool *lpfc_mbuf_pool;
+       struct lpfc_dma_pool lpfc_mbuf_safety_pool;
+
+       mempool_t *mbox_mem_pool;
+       mempool_t *nlp_mem_pool;
+       struct list_head freebufList;
+       struct list_head ctrspbuflist;
+       struct list_head rnidrspbuflist;
+};
+
+
+struct rnidrsp {
+       void *buf;
+       uint32_t uniqueid;
+       struct list_head list;
+       uint32_t data;
+};
diff -urN linux/drivers/scsi/lpfc/lpfc_attr.c 
linux/drivers/scsi/lpfc/lpfc_attr.c
--- linux/drivers/scsi/lpfc/lpfc_attr.c 1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/lpfc_attr.c 2005-04-29 12:15:13.013130000 +0100     
1.1
@@ -0,0 +1,1291 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Enterprise Fibre Channel Host Bus Adapters.                     *
+ * Refer to the README file included with this package for         *
+ * driver version and adapter support.                             *
+ * Copyright (C) 2004 Emulex Corporation.                          *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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, a copy of which    *
+ * can be found in the file COPYING included with this package.    *
+ *******************************************************************/
+
+/*
+ * $Id: lpfc_attr.c 1.24 2005/04/13 11:58:55EDT sf_support Exp  $
+ */
+
+#include <linux/ctype.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport_fc.h>
+
+#include "lpfc_hw.h"
+#include "lpfc_sli.h"
+#include "lpfc_disc.h"
+#include "lpfc_scsi.h"
+#include "lpfc.h"
+#include "lpfc_logmsg.h"
+#include "lpfc_version.h"
+#include "lpfc_compat.h"
+#include "lpfc_crtn.h"
+
+
+static void
+lpfc_jedec_to_ascii(int incr, char hdw[])
+{
+       int i, j;
+       for (i = 0; i < 8; i++) {
+               j = (incr & 0xf);
+               if (j <= 9)
+                       hdw[7 - i] = 0x30 +  j;
+                else
+                       hdw[7 - i] = 0x61 + j - 10;
+               incr = (incr >> 4);
+       }
+       hdw[8] = 0;
+       return;
+}
+
+static ssize_t
+lpfc_drvr_version_show(struct class_device *cdev, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
+}
+
+static ssize_t
+management_version_show(struct class_device *cdev, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n");
+}
+
+static ssize_t
+lpfc_info_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host));
+}
+
+static ssize_t
+lpfc_serialnum_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
+}
+
+static ssize_t
+lpfc_modeldesc_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
+}
+
+static ssize_t
+lpfc_modelname_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
+}
+
+static ssize_t
+lpfc_programtype_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
+}
+
+static ssize_t
+lpfc_portnum_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
+}
+
+static ssize_t
+lpfc_fwrev_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       char fwrev[32];
+       lpfc_decode_firmware_rev(phba, fwrev, 1);
+       return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);
+}
+
+static ssize_t
+lpfc_hdw_show(struct class_device *cdev, char *buf)
+{
+       char hdw[9];
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       lpfc_vpd_t *vp = &phba->vpd;
+       lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
+       return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
+}
+static ssize_t
+lpfc_option_rom_version_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
+}
+static ssize_t
+lpfc_state_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       int len = 0;
+       switch (phba->hba_state) {
+       case LPFC_INIT_START:
+       case LPFC_INIT_MBX_CMDS:
+       case LPFC_LINK_DOWN:
+               len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n");
+               break;
+       case LPFC_LINK_UP:
+       case LPFC_LOCAL_CFG_LINK:
+               len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n");
+               break;
+       case LPFC_FLOGI:
+       case LPFC_FABRIC_CFG_LINK:
+       case LPFC_NS_REG:
+       case LPFC_NS_QRY:
+       case LPFC_BUILD_DISC_LIST:
+       case LPFC_DISC_AUTH:
+       case LPFC_CLEAR_LA:
+               len += snprintf(buf + len, PAGE_SIZE-len,
+                               "Link Up - Discovery\n");
+               break;
+       case LPFC_HBA_READY:
+               len += snprintf(buf + len, PAGE_SIZE-len,
+                               "Link Up - Ready:\n");
+               if (phba->fc_topology == TOPOLOGY_LOOP) {
+                       if (phba->fc_flag & FC_PUBLIC_LOOP)
+                               len += snprintf(buf + len, PAGE_SIZE-len,
+                                               "   Public Loop\n");
+                       else
+                               len += snprintf(buf + len, PAGE_SIZE-len,
+                                               "   Private Loop\n");
+               } else {
+                       if (phba->fc_flag & FC_FABRIC)
+                               len += snprintf(buf + len, PAGE_SIZE-len,
+                                               "   Fabric\n");
+                       else
+                               len += snprintf(buf + len, PAGE_SIZE-len,
+                                               "   Point-2-Point\n");
+               }
+       }
+       return len;
+}
+
+static ssize_t
+lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +
+                                                       phba->fc_unmap_cnt);
+}
+
+
+static ssize_t
+lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
+       int val = 0;
+       LPFC_MBOXQ_t *pmboxq;
+       int mbxstatus = MBXERR_ERROR;
+
+       if ((sscanf(buf, "%d", &val) != 1) ||
+           (val != 1))
+               return -EINVAL;
+
+       if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+           (phba->hba_state != LPFC_HBA_READY))
+               return -EPERM;
+
+       pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
+
+       if (!pmboxq)
+               return -ENOMEM;
+
+       memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+       lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);
+       mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+
+       if (mbxstatus == MBX_TIMEOUT)
+               pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+       else
+               mempool_free( pmboxq, phba->mbox_mem_pool);
+
+       if (mbxstatus == MBXERR_ERROR)
+               return -EIO;
+
+       return strlen(buf);
+}
+
+static ssize_t
+lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
+}
+
+static ssize_t
+lpfc_board_online_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+
+       if (!phba) return 0;
+
+       if (phba->fc_flag & FC_OFFLINE_MODE)
+               return snprintf(buf, PAGE_SIZE, "0\n");
+       else
+               return snprintf(buf, PAGE_SIZE, "1\n");
+}
+
+static ssize_t
+lpfc_board_online_store(struct class_device *cdev, const char *buf,
+                                                               size_t count)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       struct completion online_compl;
+       int val=0, status=0;
+
+       if (sscanf(buf, "%d", &val) != 1)
+               return 0;
+
+       init_completion(&online_compl);
+
+       if (val)
+               lpfc_workq_post_event(phba, &status, &online_compl,
+                                                       LPFC_EVT_ONLINE);
+       else
+               lpfc_workq_post_event(phba, &status, &online_compl,
+                                                       LPFC_EVT_OFFLINE);
+       wait_for_completion(&online_compl);
+       if (!status)
+               return strlen(buf);
+       else
+               return 0;
+}
+
+
+#define lpfc_param_show(attr)  \
+static ssize_t \
+lpfc_##attr##_show(struct class_device *cdev, char *buf) \
+{ \
+       struct Scsi_Host *host = class_to_shost(cdev);\
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
+       int val = 0;\
+       if (phba){\
+               val = phba->cfg_##attr;\
+               return snprintf(buf, PAGE_SIZE, "%d\n",\
+                               phba->cfg_##attr);\
+       }\
+       return 0;\
+}
+
+#define lpfc_param_store(attr, minval, maxval) \
+static ssize_t \
+lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
+{ \
+       struct Scsi_Host *host = class_to_shost(cdev);\
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
+       int val = 0;\
+       if (!isdigit(buf[0]))\
+               return -EINVAL;\
+       if (sscanf(buf, "0x%x", &val) != 1)\
+               if (sscanf(buf, "%d", &val) != 1)\
+                       return -EINVAL;\
+       if (phba){\
+               if (val >= minval && val <= maxval) {\
+                       phba->cfg_##attr = val;\
+                       return strlen(buf);\
+               }\
+       }\
+       return 0;\
+}
+
+#define LPFC_ATTR_R_NOINIT(name, desc) \
+extern int lpfc_##name;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_param_show(name)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+
+#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_param_show(name)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+
+#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_param_show(name)\
+lpfc_param_store(name, minval, maxval)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
+                        lpfc_##name##_show, lpfc_##name##_store)
+
+static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
+static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
+static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
+static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
+static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
+static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL);
+static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
+static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
+static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL);
+static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO,
+                                       lpfc_option_rom_version_show, NULL);
+static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO,
+                                       lpfc_num_discovered_ports_show, NULL);
+static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, 
NULL);
+static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
+                        NULL);
+static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
+                        NULL);
+static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
+static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
+                        lpfc_board_online_show, lpfc_board_online_store);
+
+
+/*
+# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
+# deluged with LOTS of information.
+# You can set a bit mask to record specific types of verbose messages:
+#
+# LOG_ELS                       0x1        ELS events
+# LOG_DISCOVERY                 0x2        Link discovery events
+# LOG_MBOX                      0x4        Mailbox events
+# LOG_INIT                      0x8        Initialization events
+# LOG_LINK_EVENT                0x10       Link events
+# LOG_IP                        0x20       IP traffic history
+# LOG_FCP                       0x40       FCP traffic history
+# LOG_NODE                      0x80       Node table events
+# LOG_MISC                      0x400      Miscellaneous events
+# LOG_SLI                       0x800      SLI events
+# LOG_CHK_COND                  0x1000     FCP Check condition flag
+# LOG_LIBDFC                    0x2000     LIBDFC events
+# LOG_ALL_MSG                   0xffff     LOG all messages
+*/
+LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
+
+/*
+# lun_queue_depth:  This parameter is used to limit the number of outstanding
+# commands per FCP LUN. Value range is [1,128]. Default value is 30.
+*/
+LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
+           "Max number of FCP commands we can queue to a specific LUN");
+
+/*
+# Some disk devices have a "select ID" or "select Target" capability.
+# From a protocol standpoint "select ID" usually means select the
+# Fibre channel "ALPA".  In the FC-AL Profile there is an "informative
+# annex" which contains a table that maps a "select ID" (a number
+# between 0 and 7F) to an ALPA.  By default, for compatibility with
+# older drivers, the lpfc driver scans this table from low ALPA to high
+# ALPA.
+#
+# Turning on the scan-down variable (on  = 1, off = 0) will
+# cause the lpfc driver to use an inverted table, effectively
+# scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
+#
+# (Note: This "select ID" functionality is a LOOP ONLY characteristic
+# and will not work across a fabric. Also this parameter will take
+# effect only in the case when ALPA map is not available.)
+*/
+LPFC_ATTR_R(scan_down, 1, 0, 1,
+            "Start scanning for devices from highest ALPA to lowest");
+
+/*
+# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
+# until the timer expires. Value range is [0,255]. Default value is 20.
+# NOTE: this MUST be less then the SCSI Layer command timeout - 1.
+*/
+LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
+            "Seconds driver will hold I/O waiting for a device to come back");
+
+/*
+# lpfc_topology:  link topology for init link
+#            0x0  = attempt loop mode then point-to-point
+#            0x02 = attempt point-to-point mode only
+#            0x04 = attempt loop mode only
+#            0x06 = attempt point-to-point mode then loop
+# Set point-to-point mode if you want to run as an N_Port.
+# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
+# Default value is 0.
+*/
+LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology");
+
+/*
+# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
+# connection.
+#       0  = auto select (default)
+#       1  = 1 Gigabaud
+#       2  = 2 Gigabaud
+#       4  = 4 Gigabaud
+# Value range is [0,4]. Default value is 0.
+*/
+LPFC_ATTR_R(link_speed, 0, 0, 4, "Select link speed");
+
+/*
+# lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
+# Value range is [2,3]. Default value is 3.
+*/
+LPFC_ATTR_R(fcp_class, 3, 2, 3,
+            "Select Fibre Channel class of service for FCP sequences");
+
+/*
+# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
+# is [0,1]. Default value is 0.
+*/
+LPFC_ATTR_RW(use_adisc, 0, 0, 1,
+            "Use ADISC on rediscovery to authenticate FCP devices");
+
+/*
+# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
+# range is [0,1]. Default value is 0.
+*/
+LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
+
+/*
+# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
+# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
+# value [0,63]. cr_count can take value [0,255]. Default value of cr_delay
+# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
+# cr_delay is set to 0.
+*/
+static int lpfc_cr_delay = 0;
+module_param(lpfc_cr_delay, int , 0);
+MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an "
+               "interrupt response is generated");
+
+static int lpfc_cr_count = 1;
+module_param(lpfc_cr_count, int, 0);
+MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an "
+               "interrupt response is generated");
+
+/*
+# lpfc_fdmi_on: controls FDMI support.
+#       0 = no FDMI support
+#       1 = support FDMI without attribute of hostname
+#       2 = support FDMI with attribute of hostname
+# Value range [0,2]. Default value is 0.
+*/
+LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
+
+/*
+# Specifies the maximum number of ELS cmds we can have outstanding (for
+# discovery). Value range is [1,64]. Default value = 32.
+*/
+static int lpfc_discovery_threads = 32;
+module_param(lpfc_discovery_threads, int, 0);
+MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands "
+                "during discovery");
+
+/*
+# lpfc_max_luns: maximum number of LUNs per target driver will support
+# Value range is [1,32768]. Default value is 256.
+# NOTE: The SCSI layer will scan each target for this many luns
+*/
+LPFC_ATTR_R(max_luns, 256, 1, 32768,
+            "Maximum number of LUNs per target driver will support");
+
+struct class_device_attribute *lpfc_host_attrs[] = {
+       &class_device_attr_info,
+       &class_device_attr_serialnum,
+       &class_device_attr_modeldesc,
+       &class_device_attr_modelname,
+       &class_device_attr_programtype,
+       &class_device_attr_portnum,
+       &class_device_attr_fwrev,
+       &class_device_attr_hdw,
+       &class_device_attr_option_rom_version,
+       &class_device_attr_state,
+       &class_device_attr_num_discovered_ports,
+       &class_device_attr_lpfc_drvr_version,
+       &class_device_attr_lpfc_log_verbose,
+       &class_device_attr_lpfc_lun_queue_depth,
+       &class_device_attr_lpfc_nodev_tmo,
+       &class_device_attr_lpfc_fcp_class,
+       &class_device_attr_lpfc_use_adisc,
+       &class_device_attr_lpfc_ack0,
+       &class_device_attr_lpfc_topology,
+       &class_device_attr_lpfc_scan_down,
+       &class_device_attr_lpfc_link_speed,
+       &class_device_attr_lpfc_fdmi_on,
+       &class_device_attr_lpfc_max_luns,
+       &class_device_attr_nport_evt_cnt,
+       &class_device_attr_management_version,
+       &class_device_attr_issue_lip,
+       &class_device_attr_board_online,
+       NULL,
+};
+
+static ssize_t
+sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       size_t buf_off;
+       struct Scsi_Host *host = class_to_shost(container_of(kobj,
+                                            struct class_device, kobj));
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+
+       if ((off + count) > FF_REG_AREA_SIZE)
+               return -ERANGE;
+
+       if (count == 0) return 0;
+
+       if (off % 4 || count % 4 || (unsigned long)buf % 4)
+               return -EINVAL;
+
+       spin_lock_irq(phba->host->host_lock);
+
+       if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
+               spin_unlock_irq(phba->host->host_lock);
+               return -EPERM;
+       }
+
+       for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t))
+               writel(*((uint32_t *)(buf + buf_off)),
+                      phba->ctrl_regs_memmap_p + off + buf_off);
+
+       spin_unlock_irq(phba->host->host_lock);
+
+       return count;
+}
+
+static ssize_t
+sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       size_t buf_off;
+       uint32_t * tmp_ptr;
+       struct Scsi_Host *host = class_to_shost(container_of(kobj,
+                                            struct class_device, kobj));
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+
+       if (off > FF_REG_AREA_SIZE)
+               return -ERANGE;
+
+       if ((off + count) > FF_REG_AREA_SIZE)
+               count = FF_REG_AREA_SIZE - off;
+
+       if (count == 0) return 0;
+
+       if (off % 4 || count % 4 || (unsigned long)buf % 4)
+               return -EINVAL;
+
+       spin_lock_irq(phba->host->host_lock);
+
+       for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
+               tmp_ptr = (uint32_t *)(buf + buf_off);
+               *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
+       }
+
+       spin_unlock_irq(phba->host->host_lock);
+
+       return count;
+}
+
+static struct bin_attribute sysfs_ctlreg_attr = {
+       .attr = {
+               .name = "ctlreg",
+               .mode = S_IRUSR | S_IWUSR,
+               .owner = THIS_MODULE,
+       },
+       .size = 256,
+       .read = sysfs_ctlreg_read,
+       .write = sysfs_ctlreg_write,
+};
+
+
+static void
+sysfs_mbox_idle (struct lpfc_hba * phba)
+{
+       phba->sysfs_mbox.state = SMBOX_IDLE;
+       phba->sysfs_mbox.offset = 0;
+
+       if (phba->sysfs_mbox.mbox) {
+               mempool_free(phba->sysfs_mbox.mbox,
+                            phba->mbox_mem_pool);
+               phba->sysfs_mbox.mbox = NULL;
+       }
+}
+
+static ssize_t
+sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       struct Scsi_Host * host =
+               class_to_shost(container_of(kobj, struct class_device, kobj));
+       struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0];
+       struct lpfcMboxq * mbox = NULL;
+
+       if ((count + off) > MAILBOX_CMD_SIZE)
+               return -ERANGE;
+
+       if (off % 4 ||  count % 4 || (unsigned long)buf % 4)
+               return -EINVAL;
+
+       if (count == 0)
+               return 0;
+
+       if (off == 0) {
+               mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+               if (!mbox)
+                       return -ENOMEM;
+
+       }
+
+       spin_lock_irq(host->host_lock);
+
+       if (off == 0) {
+               if (phba->sysfs_mbox.mbox)
+                       mempool_free(mbox, phba->mbox_mem_pool);
+               else
+                       phba->sysfs_mbox.mbox = mbox;
+               phba->sysfs_mbox.state = SMBOX_WRITING;
+       } else {
+               if (phba->sysfs_mbox.state  != SMBOX_WRITING ||
+                   phba->sysfs_mbox.offset != off           ||
+                   phba->sysfs_mbox.mbox   == NULL ) {
+                       sysfs_mbox_idle(phba);
+                       spin_unlock_irq(host->host_lock);
+                       return -EINVAL;
+               }
+       }
+
+       memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off,
+              buf, count);
+
+       phba->sysfs_mbox.offset = off + count;
+
+       spin_unlock_irq(host->host_lock);
+
+       return count;
+}
+
+static ssize_t
+sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       struct Scsi_Host *host =
+               class_to_shost(container_of(kobj, struct class_device,
+                                           kobj));
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       int rc;
+
+       if (off > sizeof(MAILBOX_t))
+               return -ERANGE;
+
+       if ((count + off) > sizeof(MAILBOX_t))
+               count = sizeof(MAILBOX_t) - off;
+
+       if (off % 4 ||  count % 4 || (unsigned long)buf % 4)
+               return -EINVAL;
+
+       if (off && count == 0)
+               return 0;
+
+       spin_lock_irq(phba->host->host_lock);
+
+       if (off == 0 &&
+           phba->sysfs_mbox.state  == SMBOX_WRITING &&
+           phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {
+
+               switch (phba->sysfs_mbox.mbox->mb.mbxCommand) {
+                       /* Offline only */
+               case MBX_WRITE_NV:
+               case MBX_INIT_LINK:
+               case MBX_DOWN_LINK:
+               case MBX_CONFIG_LINK:
+               case MBX_CONFIG_RING:
+               case MBX_RESET_RING:
+               case MBX_UNREG_LOGIN:
+               case MBX_CLEAR_LA:
+               case MBX_DUMP_CONTEXT:
+               case MBX_RUN_DIAGS:
+               case MBX_RESTART:
+               case MBX_FLASH_WR_ULA:
+               case MBX_SET_MASK:
+               case MBX_SET_SLIM:
+               case MBX_SET_DEBUG:
+                       if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
+                               printk(KERN_WARNING "mbox_read:Command 0x%x "
+                                      "is illegal in on-line state\n",
+                                      phba->sysfs_mbox.mbox->mb.mbxCommand);
+                               sysfs_mbox_idle(phba);
+                               spin_unlock_irq(phba->host->host_lock);
+                               return -EPERM;
+                       }
+               case MBX_LOAD_SM:
+               case MBX_READ_NV:
+               case MBX_READ_CONFIG:
+               case MBX_READ_RCONFIG:
+               case MBX_READ_STATUS:
+               case MBX_READ_XRI:
+               case MBX_READ_REV:
+               case MBX_READ_LNK_STAT:
+               case MBX_DUMP_MEMORY:
+               case MBX_DOWN_LOAD:
+               case MBX_UPDATE_CFG:
+               case MBX_LOAD_AREA:
+               case MBX_LOAD_EXP_ROM:
+                       break;
+               case MBX_READ_SPARM64:
+               case MBX_READ_LA:
+               case MBX_READ_LA64:
+               case MBX_REG_LOGIN:
+               case MBX_REG_LOGIN64:
+               case MBX_CONFIG_PORT:
+               case MBX_RUN_BIU_DIAG:
+                       printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n",
+                              phba->sysfs_mbox.mbox->mb.mbxCommand);
+                       sysfs_mbox_idle(phba);
+                       spin_unlock_irq(phba->host->host_lock);
+                       return -EPERM;
+               default:
+                       printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n",
+                              phba->sysfs_mbox.mbox->mb.mbxCommand);
+                       sysfs_mbox_idle(phba);
+                       spin_unlock_irq(phba->host->host_lock);
+                       return -EPERM;
+               }
+
+               if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+                   (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){
+
+                       spin_unlock_irq(phba->host->host_lock);
+                       rc = lpfc_sli_issue_mbox (phba,
+                                                 phba->sysfs_mbox.mbox,
+                                                 MBX_POLL);
+                       spin_lock_irq(phba->host->host_lock);
+
+               } else {
+                       spin_unlock_irq(phba->host->host_lock);
+                       rc = lpfc_sli_issue_mbox_wait (phba,
+                                                      phba->sysfs_mbox.mbox,
+                                                      phba->fc_ratov * 2);
+                       spin_lock_irq(phba->host->host_lock);
+               }
+
+               if (rc != MBX_SUCCESS) {
+                       sysfs_mbox_idle(phba);
+                       spin_unlock_irq(host->host_lock);
+                       return -ENODEV;
+               }
+               phba->sysfs_mbox.state = SMBOX_READING;
+       }
+       else if (phba->sysfs_mbox.offset != off ||
+                phba->sysfs_mbox.state  != SMBOX_READING) {
+               printk(KERN_WARNING  "mbox_read: Bad State\n");
+               sysfs_mbox_idle(phba);
+               spin_unlock_irq(host->host_lock);
+               return -EINVAL;
+       }
+
+       memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count);
+
+       phba->sysfs_mbox.offset = off + count;
+
+       if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t))
+               sysfs_mbox_idle(phba);
+
+       spin_unlock_irq(phba->host->host_lock);
+
+       return count;
+}
+
+static struct bin_attribute sysfs_mbox_attr = {
+       .attr = {
+               .name = "mbox",
+               .mode = S_IRUSR | S_IWUSR,
+               .owner = THIS_MODULE,
+       },
+       .size = sizeof(MAILBOX_t),
+       .read = sysfs_mbox_read,
+       .write = sysfs_mbox_write,
+};
+
+int
+lpfc_alloc_sysfs_attr(struct lpfc_hba *phba)
+{
+       struct Scsi_Host *host = phba->host;
+       int error;
+
+       error = sysfs_create_bin_file(&host->shost_classdev.kobj,
+                                                       &sysfs_ctlreg_attr);
+       if (error)
+               goto out;
+
+       error = sysfs_create_bin_file(&host->shost_classdev.kobj,
+                                                       &sysfs_mbox_attr);
+       if (error)
+               goto out_remove_ctlreg_attr;
+
+       return 0;
+out_remove_ctlreg_attr:
+       sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
+out:
+       return error;
+}
+
+void
+lpfc_free_sysfs_attr(struct lpfc_hba *phba)
+{
+       struct Scsi_Host *host = phba->host;
+
+       sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr);
+       sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
+}
+
+
+/*
+ * Dynamic FC Host Attributes Support
+ */
+
+static void
+lpfc_get_host_port_id(struct Scsi_Host *shost)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
+       /* note: fc_myDID already in cpu endianness */
+       fc_host_port_id(shost) = phba->fc_myDID;
+}
+
+static void
+lpfc_get_host_port_type(struct Scsi_Host *shost)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
+
+       spin_lock_irq(shost->host_lock);
+
+       if (phba->hba_state == LPFC_HBA_READY) {
+               if (phba->fc_topology == TOPOLOGY_LOOP) {
+                       if (phba->fc_flag & FC_PUBLIC_LOOP)
+                               fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+                       else
+                               fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
+               } else {
+                       if (phba->fc_flag & FC_FABRIC)
+                               fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+                       else
+                               fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+               }
+       } else
+               fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
+
+       spin_unlock_irq(shost->host_lock);
+}
+
+static void
+lpfc_get_host_port_state(struct Scsi_Host *shost)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
+
+       spin_lock_irq(shost->host_lock);
+
+       if (phba->fc_flag & FC_OFFLINE_MODE)
+               fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+       else {
+               switch (phba->hba_state) {
+               case LPFC_INIT_START:
+               case LPFC_INIT_MBX_CMDS:
+               case LPFC_LINK_DOWN:
+                       fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
+                       break;
+               case LPFC_LINK_UP:
+               case LPFC_LOCAL_CFG_LINK:
+               case LPFC_FLOGI:
+               case LPFC_FABRIC_CFG_LINK:
+               case LPFC_NS_REG:
+               case LPFC_NS_QRY:
+               case LPFC_BUILD_DISC_LIST:
+               case LPFC_DISC_AUTH:
+               case LPFC_CLEAR_LA:
+               case LPFC_HBA_READY:
+                       /* Links up, beyond this port_type reports state */
+                       fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+                       break;
+               case LPFC_HBA_ERROR:
+                       fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
+                       break;
+               default:
+                       fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
+                       break;
+               }
+       }
+
+       spin_unlock_irq(shost->host_lock);
+}
+
+static void
+lpfc_get_host_speed(struct Scsi_Host *shost)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
+
+       spin_lock_irq(shost->host_lock);
+
+       if (phba->hba_state == LPFC_HBA_READY) {
+               switch(phba->fc_linkspeed) {
+                       case LA_1GHZ_LINK:
+                               fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
+                       break;
+                       case LA_2GHZ_LINK:
+                               fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
+                       break;
+                       case LA_4GHZ_LINK:
+                               fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
+                       break;
+                       default:
+                               fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+                       break;
+               }
+       }
+
+       spin_unlock_irq(shost->host_lock);
+}
+
+static void
+lpfc_get_host_fabric_name (struct Scsi_Host *shost)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
+       u64 nodename;
+
+       spin_lock_irq(shost->host_lock);
+
+       if ((phba->fc_flag & FC_FABRIC) ||
+           ((phba->fc_topology == TOPOLOGY_LOOP) &&
+            (phba->fc_flag & FC_PUBLIC_LOOP)))
+               memcpy(&nodename, &phba->fc_fabparam.nodeName, sizeof(u64));
+       else
+               /* fabric is local port if there is no F/FL_Port */
+               memcpy(&nodename, &phba->fc_nodename, sizeof(u64));
+
+       spin_unlock_irq(shost->host_lock);
+
+       fc_host_fabric_name(shost) = be64_to_cpu(nodename);
+}
+
+
+static struct fc_host_statistics *
+lpfc_get_stats(struct Scsi_Host *shost)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
+       struct lpfc_sli *psli = &phba->sli;
+       struct fc_host_statistics *hs =
+                       (struct fc_host_statistics *)phba->link_stats;
+       LPFC_MBOXQ_t *pmboxq;
+       MAILBOX_t *pmb;
+       int rc=0;
+
+       pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!pmboxq)
+               return NULL;
+       memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+
+       pmb = &pmboxq->mb;
+       pmb->mbxCommand = MBX_READ_STATUS;
+       pmb->mbxOwner = OWN_HOST;
+       pmboxq->context1 = NULL;
+
+       if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+           (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){
+               rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+       } else
+               rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+
+       if (rc != MBX_SUCCESS) {
+               if (pmboxq) {
+                       if (rc == MBX_TIMEOUT)
+                               pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+                       else
+                               mempool_free( pmboxq, phba->mbox_mem_pool);
+               }
+               return NULL;
+       }
+
+       hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
+       hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256);
+       hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
+       hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
+
+       memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+       pmb->mbxCommand = MBX_READ_LNK_STAT;
+       pmb->mbxOwner = OWN_HOST;
+       pmboxq->context1 = NULL;
+
+       if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+           (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) {
+               rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+       } else
+               rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+
+       if (rc != MBX_SUCCESS) {
+               if (pmboxq) {
+                       if (rc == MBX_TIMEOUT)
+                               pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+                       else
+                               mempool_free( pmboxq, phba->mbox_mem_pool);
+               }
+               return NULL;
+       }
+
+       hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
+       hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
+       hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
+       hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
+       hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
+       hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
+       hs->error_frames = pmb->un.varRdLnk.crcCnt;
+
+       if (phba->fc_topology == TOPOLOGY_LOOP) {
+               hs->lip_count = (phba->fc_eventTag >> 1);
+               hs->nos_count = -1;
+       } else {
+               hs->lip_count = -1;
+               hs->nos_count = (phba->fc_eventTag >> 1);
+       }
+
+       hs->dumped_frames = -1;
+
+/* FIX ME */
+       /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/
+
+       return hs;
+}
+
+
+/*
+ * The LPFC driver treats linkdown handling as target loss events so there
+ * are no sysfs handlers for link_down_tmo.
+ */
+static void
+lpfc_get_starget_port_id(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
+       uint32_t did = -1;
+       struct lpfc_nodelist *ndlp = NULL;
+
+       spin_lock_irq(shost->host_lock);
+       /* Search the mapped list for this target ID */
+       list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
+               if (starget->id == ndlp->nlp_sid) {
+                       did = ndlp->nlp_DID;
+                       break;
+               }
+       }
+       spin_unlock_irq(shost->host_lock);
+
+       fc_starget_port_id(starget) = did;
+}
+
+static void
+lpfc_get_starget_node_name(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
+       uint64_t node_name = 0;
+       struct lpfc_nodelist *ndlp = NULL;
+
+       spin_lock_irq(shost->host_lock);
+       /* Search the mapped list for this target ID */
+       list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
+               if (starget->id == ndlp->nlp_sid) {
+                       memcpy(&node_name, &ndlp->nlp_nodename,
+                                               sizeof(struct lpfc_name));
+                       break;
+               }
+       }
+       spin_unlock_irq(shost->host_lock);
+
+       fc_starget_node_name(starget) = be64_to_cpu(node_name);
+}
+
+static void
+lpfc_get_starget_port_name(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
+       uint64_t port_name = 0;
+       struct lpfc_nodelist *ndlp = NULL;
+
+       spin_lock_irq(shost->host_lock);
+       /* Search the mapped list for this target ID */
+       list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
+               if (starget->id == ndlp->nlp_sid) {
+                       memcpy(&port_name, &ndlp->nlp_portname,
+                                               sizeof(struct lpfc_name));
+                       break;
+               }
+       }
+       spin_unlock_irq(shost->host_lock);
+
+       fc_starget_port_name(starget) = be64_to_cpu(port_name);
+}
+
+static void
+lpfc_get_rport_loss_tmo(struct fc_rport *rport)
+{
+       /*
+        * Return the driver's global value for device loss timeout plus
+        * five seconds to allow the driver's nodev timer to run.
+        */
+       rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
+}
+
+static void
+lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
+{
+       /*
+        * The driver doesn't have a per-target timeout setting.  Set
+        * this value globally. lpfc_nodev_tmo should be greater then 0.
+        */
+       if (timeout)
+               lpfc_nodev_tmo = timeout;
+       else
+               lpfc_nodev_tmo = 1;
+       rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
+}
+
+
+#define lpfc_rport_show_function(field, format_string, sz, cast)       \
+static ssize_t                                                         \
+lpfc_show_rport_##field (struct class_device *cdev, char *buf)         \
+{                                                                      \
+       struct fc_rport *rport = transport_class_to_rport(cdev);        \
+       struct lpfc_rport_data *rdata = rport->hostdata;                \
+       return snprintf(buf, sz, format_string,                         \
+               (rdata->target) ? cast rdata->target->field : 0);       \
+}
+
+#define lpfc_rport_rd_attr(field, format_string, sz)                   \
+       lpfc_rport_show_function(field, format_string, sz, )            \
+static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
+
+
+struct fc_function_template lpfc_transport_functions = {
+       /* fixed attributes the driver supports */
+       .show_host_node_name = 1,
+       .show_host_port_name = 1,
+       .show_host_supported_classes = 1,
+       .show_host_supported_fc4s = 1,
+       .show_host_symbolic_name = 1,
+       .show_host_supported_speeds = 1,
+       .show_host_maxframe_size = 1,
+
+       /* dynamic attributes the driver supports */
+       .get_host_port_id = lpfc_get_host_port_id,
+       .show_host_port_id = 1,
+
+       .get_host_port_type = lpfc_get_host_port_type,
+       .show_host_port_type = 1,
+
+       .get_host_port_state = lpfc_get_host_port_state,
+       .show_host_port_state = 1,
+
+       /* active_fc4s is shown but doesn't change (thus no get function) */
+       .show_host_active_fc4s = 1,
+
+       .get_host_speed = lpfc_get_host_speed,
+       .show_host_speed = 1,
+
+       .get_host_fabric_name = lpfc_get_host_fabric_name,
+       .show_host_fabric_name = 1,
+
+       /*
+        * The LPFC driver treats linkdown handling as target loss events
+        * so there are no sysfs handlers for link_down_tmo.
+        */
+
+       .get_fc_host_stats = lpfc_get_stats,
+
+       /* the LPFC driver doesn't support resetting stats yet */
+
+       .dd_fcrport_size = sizeof(struct lpfc_rport_data),
+       .show_rport_maxframe_size = 1,
+       .show_rport_supported_classes = 1,
+
+       .get_rport_dev_loss_tmo = lpfc_get_rport_loss_tmo,
+       .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
+       .show_rport_dev_loss_tmo = 1,
+
+       .get_starget_port_id  = lpfc_get_starget_port_id,
+       .show_starget_port_id = 1,
+
+       .get_starget_node_name = lpfc_get_starget_node_name,
+       .show_starget_node_name = 1,
+
+       .get_starget_port_name = lpfc_get_starget_port_name,
+       .show_starget_port_name = 1,
+};
+
+void
+lpfc_get_cfgparam(struct lpfc_hba *phba)
+{
+       phba->cfg_log_verbose = lpfc_log_verbose;
+       phba->cfg_cr_delay = lpfc_cr_delay;
+       phba->cfg_cr_count = lpfc_cr_count;
+       phba->cfg_lun_queue_depth = lpfc_lun_queue_depth;
+       phba->cfg_fcp_class = lpfc_fcp_class;
+       phba->cfg_use_adisc = lpfc_use_adisc;
+       phba->cfg_ack0 = lpfc_ack0;
+       phba->cfg_topology = lpfc_topology;
+       phba->cfg_scan_down = lpfc_scan_down;
+       phba->cfg_nodev_tmo = lpfc_nodev_tmo;
+       phba->cfg_link_speed = lpfc_link_speed;
+       phba->cfg_fdmi_on = lpfc_fdmi_on;
+       phba->cfg_discovery_threads = lpfc_discovery_threads;
+       phba->cfg_max_luns = lpfc_max_luns;
+
+       /*
+        * The total number of segments is the configuration value plus 2
+        * since the IOCB need a command and response bde.
+        */
+       phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2;
+
+       /*
+        * Since the sg_tablesize is module parameter, the sg_dma_buf_size
+        * used to create the sg_dma_buf_pool must be dynamically calculated
+        */
+       phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
+                       sizeof(struct fcp_rsp) +
+                       (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));
+
+       switch (phba->pcidev->device) {
+       case PCI_DEVICE_ID_LP101:
+       case PCI_DEVICE_ID_BSMB:
+       case PCI_DEVICE_ID_ZSMB:
+               phba->cfg_hba_queue_depth = LPFC_LP101_HBA_Q_DEPTH;
+               break;
+       case PCI_DEVICE_ID_RFLY:
+       case PCI_DEVICE_ID_PFLY:
+       case PCI_DEVICE_ID_BMID:
+       case PCI_DEVICE_ID_ZMID:
+       case PCI_DEVICE_ID_TFLY:
+               phba->cfg_hba_queue_depth = LPFC_LC_HBA_Q_DEPTH;
+               break;
+       default:
+               phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH;
+       }
+       return;
+}
diff -urN linux/drivers/scsi/lpfc/lpfc_compat.h 
linux/drivers/scsi/lpfc/lpfc_compat.h
--- linux/drivers/scsi/lpfc/lpfc_compat.h       1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/lpfc_compat.h       2005-04-29 12:15:13.036220000 
+0100     1.1
@@ -0,0 +1,97 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Enterprise Fibre Channel Host Bus Adapters.                     *
+ * Refer to the README file included with this package for         *
+ * driver version and adapter support.                             *
+ * Copyright (C) 2004 Emulex Corporation.                          *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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, a copy of which    *
+ * can be found in the file COPYING included with this package.    *
+ *******************************************************************/
+
+/*
+ * $Id: lpfc_compat.h 1.32 2005/01/25 17:51:45EST sf_support Exp  $
+ *
+ * This file provides macros to aid compilation in the Linux 2.4 kernel
+ * over various platform architectures.
+ */
+
+/*******************************************************************
+Note: HBA's SLI memory contains little-endian LW.
+Thus to access it from a little-endian host,
+memcpy_toio() and memcpy_fromio() can be used.
+However on a big-endian host, copy 4 bytes at a time,
+using writel() and readl().
+ *******************************************************************/
+
+#if __BIG_ENDIAN
+
+static inline void
+lpfc_memcpy_to_slim(void __iomem *dest, void *src, unsigned int bytes)
+{
+       uint32_t __iomem *dest32;
+       uint32_t *src32;
+       unsigned int four_bytes;
+
+
+       dest32  = (uint32_t __iomem *) dest;
+       src32  = (uint32_t *) src;
+
+       /* write input bytes, 4 bytes at a time */
+       for (four_bytes = bytes /4; four_bytes > 0; four_bytes--) {
+               writel( *src32, dest32);
+               readl(dest32); /* flush */
+               dest32++;
+               src32++;
+       }
+
+       return;
+}
+
+static inline void
+lpfc_memcpy_from_slim( void *dest, void __iomem *src, unsigned int bytes)
+{
+       uint32_t *dest32;
+       uint32_t __iomem *src32;
+       unsigned int four_bytes;
+
+
+       dest32  = (uint32_t *) dest;
+       src32  = (uint32_t __iomem *) src;
+
+       /* read input bytes, 4 bytes at a time */
+       for (four_bytes = bytes /4; four_bytes > 0; four_bytes--) {
+               *dest32 = readl( src32);
+               dest32++;
+               src32++;
+       }
+
+       return;
+}
+
+#else
+
+static inline void
+lpfc_memcpy_to_slim( void __iomem *dest, void *src, unsigned int bytes)
+{
+       /* actually returns 1 byte past dest */
+       memcpy_toio( dest, src, bytes);
+}
+
+static inline void
+lpfc_memcpy_from_slim( void *dest, void __iomem *src, unsigned int bytes)
+{
+       /* actually returns 1 byte past dest */
+       memcpy_fromio( dest, src, bytes);
+}
+
+#endif /* __BIG_ENDIAN */
diff -urN linux/drivers/scsi/lpfc/lpfc_crtn.h 
linux/drivers/scsi/lpfc/lpfc_crtn.h
--- linux/drivers/scsi/lpfc/lpfc_crtn.h 1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/lpfc_crtn.h 2005-04-29 12:15:13.047358000 +0100     
1.1
@@ -0,0 +1,216 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Enterprise Fibre Channel Host Bus Adapters.                     *
+ * Refer to the README file included with this package for         *
+ * driver version and adapter support.                             *
+ * Copyright (C) 2004 Emulex Corporation.                          *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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, a copy of which    *
+ * can be found in the file COPYING included with this package.    *
+ *******************************************************************/
+
+/*
+ * $Id: lpfc_crtn.h 1.166 2005/04/07 08:46:47EDT sf_support Exp  $
+ */
+
+void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
+void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
+                struct lpfc_dmabuf *mp);
+void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
+int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *,
+                  uint32_t);
+void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
+void lpfc_unreg_did(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
+void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
+
+
+int lpfc_linkdown(struct lpfc_hba *);
+void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+
+void lpfc_mbx_cmpl_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_nlp_plogi(struct lpfc_hba *, struct lpfc_nodelist *);
+int lpfc_nlp_adisc(struct lpfc_hba *, struct lpfc_nodelist *);
+int lpfc_nlp_unmapped(struct lpfc_hba *, struct lpfc_nodelist *);
+int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int);
+void lpfc_set_disctmo(struct lpfc_hba *);
+int lpfc_can_disctmo(struct lpfc_hba *);
+int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *);
+int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
+                   struct lpfc_iocbq *, struct lpfc_nodelist *);
+int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *);
+void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t);
+struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t);
+struct lpfc_nodelist *lpfc_setup_rscn_node(struct lpfc_hba *, uint32_t);
+void lpfc_disc_list_loopmap(struct lpfc_hba *);
+void lpfc_disc_start(struct lpfc_hba *);
+void lpfc_disc_flush_list(struct lpfc_hba *);
+void lpfc_disc_timeout(unsigned long);
+void lpfc_scan_timeout(unsigned long);
+
+struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
+struct lpfc_nodelist *lpfc_findnode_remove_rpi(struct lpfc_hba * phba,
+                                              uint16_t rpi);
+void lpfc_addnode_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+                     uint16_t rpi);
+
+int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
+int lpfc_do_work(void *);
+int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *,
+                           uint32_t);
+
+uint32_t lpfc_cmpl_prli_reglogin_issue(struct lpfc_hba *,
+                                      struct lpfc_nodelist *, void *,
+                                      uint32_t);
+uint32_t lpfc_cmpl_plogi_prli_issue(struct lpfc_hba *, struct lpfc_nodelist *,
+                                   void *, uint32_t);
+
+int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *,
+                    struct serv_parm *, uint32_t);
+int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp,
+                       int);
+int lpfc_els_abort_flogi(struct lpfc_hba *);
+int lpfc_initial_flogi(struct lpfc_hba *);
+int lpfc_issue_els_plogi(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_scr(struct lpfc_hba *, uint32_t, uint8_t);
+int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
+int lpfc_els_rsp_acc(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *,
+                    struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t);
+int lpfc_els_rsp_reject(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *,
+                       struct lpfc_nodelist *);
+int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *,
+                          struct lpfc_nodelist *);
+int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *,
+                         struct lpfc_nodelist *);
+void lpfc_els_retry_delay(unsigned long);
+void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
+void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
+                         struct lpfc_iocbq *);
+int lpfc_els_handle_rscn(struct lpfc_hba *);
+int lpfc_els_flush_rscn(struct lpfc_hba *);
+int lpfc_rscn_payload_check(struct lpfc_hba *, uint32_t);
+void lpfc_els_flush_cmd(struct lpfc_hba *);
+int lpfc_els_disc_adisc(struct lpfc_hba *);
+int lpfc_els_disc_plogi(struct lpfc_hba *);
+void lpfc_els_timeout(unsigned long);
+void lpfc_els_timeout_handler(struct lpfc_hba *);
+
+void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
+                        struct lpfc_iocbq *);
+int lpfc_ns_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int);
+int lpfc_fdmi_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int);
+void lpfc_fdmi_tmo(unsigned long);
+void lpfc_fdmi_tmo_handler(struct lpfc_hba *);
+
+int lpfc_config_port_prep(struct lpfc_hba *);
+int lpfc_config_port_post(struct lpfc_hba *);
+int lpfc_hba_down_prep(struct lpfc_hba *);
+void lpfc_hba_init(struct lpfc_hba *, uint32_t *);
+int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int);
+void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int);
+uint8_t *lpfc_get_lpfchba_info(struct lpfc_hba *, uint8_t *);
+int lpfc_fcp_abort(struct lpfc_hba *, int, int, int);
+int lpfc_online(struct lpfc_hba *);
+int lpfc_offline(struct lpfc_hba *);
+
+
+int lpfc_sli_setup(struct lpfc_hba *);
+int lpfc_sli_queue_setup(struct lpfc_hba *);
+void lpfc_slim_access(struct lpfc_hba *);
+
+void lpfc_handle_eratt(struct lpfc_hba *);
+void lpfc_handle_latt(struct lpfc_hba *);
+irqreturn_t lpfc_intr_handler(int, void *, struct pt_regs *);
+
+void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
+void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
+LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
+
+int lpfc_mem_alloc(struct lpfc_hba *);
+void lpfc_mem_free(struct lpfc_hba *);
+
+int lpfc_sli_hba_setup(struct lpfc_hba *);
+int lpfc_sli_hba_down(struct lpfc_hba *);
+int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
+int lpfc_sli_handle_mb_event(struct lpfc_hba *);
+int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
+                                   struct lpfc_sli_ring *, uint32_t);
+void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *,
+                       struct lpfc_iocbq *, uint32_t);
+void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
+int lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
+int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
+                            struct lpfc_dmabuf *);
+struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
+                                            struct lpfc_sli_ring *,
+                                            dma_addr_t);
+int lpfc_sli_issue_abort_iotag32(struct lpfc_hba *, struct lpfc_sli_ring *,
+                                struct lpfc_iocbq *);
+int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
+                         uint64_t, lpfc_ctx_cmd);
+int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
+                           uint64_t, uint32_t, lpfc_ctx_cmd);
+
+void lpfc_mbox_timeout(unsigned long);
+void lpfc_mbox_timeout_handler(struct lpfc_hba *);
+void lpfc_map_fcp_cmnd_to_bpl(struct lpfc_hba *, struct lpfc_scsi_buf *);
+void lpfc_free_scsi_cmd(struct lpfc_scsi_buf *);
+uint32_t lpfc_os_timeout_transform(struct lpfc_hba *, uint32_t);
+
+struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order,
+                                       uint32_t did);
+
+int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
+                        uint32_t timeout);
+
+int lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
+                                          struct lpfc_sli_ring * pring,
+                                          struct lpfc_iocbq * piocb,
+                                          uint32_t flag,
+                                          struct lpfc_iocbq * prspiocbq,
+                                          uint32_t timeout);
+void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
+                                     struct lpfc_iocbq * queue1,
+                                     struct lpfc_iocbq * queue2);
+
+void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
+void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
+
+/* Function prototypes. */
+const char* lpfc_info(struct Scsi_Host *);
+void lpfc_get_cfgparam(struct lpfc_hba *);
+int lpfc_alloc_sysfs_attr(struct lpfc_hba *);
+void lpfc_free_sysfs_attr(struct lpfc_hba *);
+extern struct class_device_attribute *lpfc_host_attrs[];
+extern struct scsi_host_template lpfc_template;
+extern struct fc_function_template lpfc_transport_functions;
+
+void lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp);
+
+#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
+#define HBA_EVENT_RSCN                   5
+#define HBA_EVENT_LINK_UP                2
+#define HBA_EVENT_LINK_DOWN              3
diff -urN linux/drivers/scsi/lpfc/lpfc_ct.c linux/drivers/scsi/lpfc/lpfc_ct.c
--- linux/drivers/scsi/lpfc/lpfc_ct.c   1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/lpfc_ct.c   2005-04-29 12:15:13.059492000 +0100     
1.1
@@ -0,0 +1,1237 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Enterprise Fibre Channel Host Bus Adapters.                     *
+ * Refer to the README file included with this package for         *
+ * driver version and adapter support.                             *
+ * Copyright (C) 2004 Emulex Corporation.                          *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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, a copy of which    *
+ * can be found in the file COPYING included with this package.    *
+ *******************************************************************/
+
+/*
+ * $Id: lpfc_ct.c 1.161 2005/04/13 11:59:01EDT sf_support Exp  $
+ *
+ * Fibre Channel SCSI LAN Device Driver CT support
+ */
+
+#include <linux/blkdev.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/utsname.h>
+
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include "lpfc_hw.h"
+#include "lpfc_sli.h"
+#include "lpfc_disc.h"
+#include "lpfc_scsi.h"
+#include "lpfc.h"
+#include "lpfc_logmsg.h"
+#include "lpfc_crtn.h"
+#include "lpfc_version.h"
+
+#define HBA_PORTSPEED_UNKNOWN               0  /* Unknown - transceiver
+                                                * incapable of reporting */
+#define HBA_PORTSPEED_1GBIT                 1  /* 1 GBit/sec */
+#define HBA_PORTSPEED_2GBIT                 2  /* 2 GBit/sec */
+#define HBA_PORTSPEED_4GBIT                 8   /* 4 GBit/sec */
+#define HBA_PORTSPEED_8GBIT                16   /* 8 GBit/sec */
+#define HBA_PORTSPEED_10GBIT                4  /* 10 GBit/sec */
+#define HBA_PORTSPEED_NOT_NEGOTIATED        5  /* Speed not established */
+
+#define FOURBYTES      4
+
+
+static char *lpfc_release_version = LPFC_DRIVER_VERSION;
+
+/*
+ * lpfc_ct_unsol_event
+ */
+void
+lpfc_ct_unsol_event(struct lpfc_hba * phba,
+                   struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocbq)
+{
+
+       struct lpfc_iocbq *next_piocbq;
+       struct lpfc_dmabuf *pmbuf = NULL;
+       struct lpfc_dmabuf *matp, *next_matp;
+       uint32_t ctx = 0, size = 0, cnt = 0;
+       IOCB_t *icmd = &piocbq->iocb;
+       IOCB_t *save_icmd = icmd;
+       int i, go_exit = 0;
+       struct list_head head;
+
+       if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
+               ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
+               /* Not enough posted buffers; Try posting more buffers */
+               phba->fc_stat.NoRcvBuf++;
+               lpfc_post_buffer(phba, pring, 0, 1);
+               return;
+       }
+
+       /* If there are no BDEs associated with this IOCB,
+        * there is nothing to do.
+        */
+       if (icmd->ulpBdeCount == 0)
+               return;
+
+       INIT_LIST_HEAD(&head);
+       list_add_tail(&head, &piocbq->list);
+
+       list_for_each_entry_safe(piocbq, next_piocbq, &head, list) {
+               icmd = &piocbq->iocb;
+               if (ctx == 0)
+                       ctx = (uint32_t) (icmd->ulpContext);
+               if (icmd->ulpBdeCount == 0)
+                       continue;
+
+               for (i = 0; i < icmd->ulpBdeCount; i++) {
+                       matp = lpfc_sli_ringpostbuf_get(phba, pring,
+                                                       getPaddr(icmd->un.
+                                                                cont64[i].
+                                                                addrHigh,
+                                                                icmd->un.
+                                                                cont64[i].
+                                                                addrLow));
+                       if (!matp) {
+                               /* Insert lpfc log message here */
+                               lpfc_post_buffer(phba, pring, cnt, 1);
+                               go_exit = 1;
+                               goto ct_unsol_event_exit_piocbq;
+                       }
+
+                       /* Typically for Unsolicited CT requests */
+                       if (!pmbuf) {
+                               pmbuf = matp;
+                               INIT_LIST_HEAD(&pmbuf->list);
+                       } else
+                               list_add_tail(&matp->list, &pmbuf->list);
+
+                       size += icmd->un.cont64[i].tus.f.bdeSize;
+                       cnt++;
+               }
+
+               icmd->ulpBdeCount = 0;
+       }
+
+       lpfc_post_buffer(phba, pring, cnt, 1);
+       if (save_icmd->ulpStatus) {
+               go_exit = 1;
+       }
+
+ct_unsol_event_exit_piocbq:
+       if (pmbuf) {
+               list_for_each_entry_safe(matp, next_matp, &pmbuf->list, list) {
+                       lpfc_mbuf_free(phba, matp->virt, matp->phys);
+                       list_del(&matp->list);
+                       kfree(matp);
+               }
+               lpfc_mbuf_free(phba, pmbuf->virt, pmbuf->phys);
+               kfree(pmbuf);
+       }
+       return;
+}
+
+static void
+lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist)
+{
+       struct lpfc_dmabuf *mlast, *next_mlast;
+
+       list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) {
+               lpfc_mbuf_free(phba, mlast->virt, mlast->phys);
+               list_del(&mlast->list);
+               kfree(mlast);
+       }
+       lpfc_mbuf_free(phba, mlist->virt, mlist->phys);
+       kfree(mlist);
+       return;
+}
+
+static struct lpfc_dmabuf *
+lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl,
+                 uint32_t size, int *entries)
+{
+       struct lpfc_dmabuf *mlist = NULL;
+       struct lpfc_dmabuf *mp;
+       int cnt, i = 0;
+
+       /* We get chucks of FCELSSIZE */
+       cnt = size > FCELSSIZE ? FCELSSIZE: size;
+
+       while (size) {
+               /* Allocate buffer for rsp payload */
+               mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+               if (!mp) {
+                       if (mlist)
+                               lpfc_free_ct_rsp(phba, mlist);
+                       return NULL;
+               }
+
+               INIT_LIST_HEAD(&mp->list);
+
+               if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT))
+                       mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
+               else
+                       mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
+
+               if (!mp->virt) {
+                       kfree(mp);
+                       lpfc_free_ct_rsp(phba, mlist);
+                       return NULL;
+               }
+
+               /* Queue it to a linked list */
+               if (!mlist)
+                       mlist = mp;
+               else
+                       list_add_tail(&mp->list, &mlist->list);
+
+               bpl->tus.f.bdeFlags = BUFF_USE_RCV;
+               /* build buffer ptr list for IOCB */
+               bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) );
+               bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) );
+               bpl->tus.f.bdeSize = (uint16_t) cnt;
+               bpl->tus.w = le32_to_cpu(bpl->tus.w);
+               bpl++;
+
+               i++;
+               size -= cnt;
+       }
+
+       *entries = i;
+       return mlist;
+}
+
+static int
+lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
+            struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
+            void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
+                    struct lpfc_iocbq *),
+            struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry,
+            uint32_t tmo)
+{
+
+       struct lpfc_sli *psli = &phba->sli;
+       struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
+       struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
+       IOCB_t *icmd;
+       struct lpfc_iocbq *geniocb = NULL;
+
+       /* Allocate buffer for  command iocb */
+       spin_lock_irq(phba->host->host_lock);
+       list_remove_head(lpfc_iocb_list, geniocb, struct lpfc_iocbq, list);
+       spin_unlock_irq(phba->host->host_lock);
+
+       if (geniocb == NULL)
+               return 1;
+       memset(geniocb, 0, sizeof (struct lpfc_iocbq));
+
+       icmd = &geniocb->iocb;
+       icmd->un.genreq64.bdl.ulpIoTag32 = 0;
+       icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+       icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
+       icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
+       icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64));
+
+       if (usr_flg)
+               geniocb->context3 = NULL;
+       else
+               geniocb->context3 = (uint8_t *) bmp;
+
+       /* Save for completion so we can release these resources */
+       geniocb->context1 = (uint8_t *) inp;
+       geniocb->context2 = (uint8_t *) outp;
+
+       /* Fill in payload, bp points to frame payload */
+       icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
+
+       /* Fill in rest of iocb */
+       icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
+       icmd->un.genreq64.w5.hcsw.Dfctl = 0;
+       icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
+       icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+
+       if (!tmo)
+               tmo = (2 * phba->fc_ratov) + 1;
+       icmd->ulpTimeout = tmo;
+       icmd->ulpBdeCount = 1;
+       icmd->ulpLe = 1;
+       icmd->ulpClass = CLASS3;
+       icmd->ulpContext = ndlp->nlp_rpi;
+
+       /* Issue GEN REQ IOCB for NPORT <did> */
+       lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+                       "%d:0119 Issue GEN REQ IOCB for NPORT x%x "
+                       "Data: x%x x%x\n", phba->brd_no, icmd->un.ulpWord[5],
+                       icmd->ulpIoTag, phba->hba_state);
+       geniocb->iocb_cmpl = cmpl;
+       geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
+       spin_lock_irq(phba->host->host_lock);
+       if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) {
+               list_add_tail(&geniocb->list, lpfc_iocb_list);
+               spin_unlock_irq(phba->host->host_lock);
+               return 1;
+       }
+       spin_unlock_irq(phba->host->host_lock);
+
+       return 0;
+}
+
+static int
+lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp,
+           struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
+           void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
+                         struct lpfc_iocbq *),
+           uint32_t rsp_size)
+{
+       struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt;
+       struct lpfc_dmabuf *outmp;
+       int cnt = 0, status;
+       int cmdcode = ((struct lpfc_sli_ct_request *) inmp->virt)->
+               CommandResponse.bits.CmdRsp;
+
+       bpl++;                  /* Skip past ct request */
+
+       /* Put buffer(s) for ct rsp in bpl */
+       outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
+       if (!outmp)
+               return -ENOMEM;
+
+       status = lpfc_gen_req(phba, bmp, inmp, outmp, cmpl, ndlp, 0,
+                             cnt+1, 0);
+       if (status) {
+               lpfc_free_ct_rsp(phba, outmp);
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static int
+lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
+{
+       struct lpfc_sli_ct_request *Response =
+               (struct lpfc_sli_ct_request *) mp->virt;
+       struct lpfc_nodelist *ndlp = NULL;
+       struct lpfc_dmabuf *mlast, *next_mp;
+       uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
+       uint32_t Did;
+       uint32_t CTentry;
+       int Cnt;
+       struct list_head head;
+
+       lpfc_set_disctmo(phba);
+
+       Cnt = Size  > FCELSSIZE ? FCELSSIZE : Size;
+
+       list_add_tail(&head, &mp->list);
+       list_for_each_entry_safe(mp, next_mp, &head, list) {
+               mlast = mp;
+
+               Size -= Cnt;
+
+               if (!ctptr)
+                       ctptr = (uint32_t *) mlast->virt;
+               else
+                       Cnt -= 16;      /* subtract length of CT header */
+
+               /* Loop through entire NameServer list of DIDs */
+               while (Cnt) {
+
+                       /* Get next DID from NameServer List */
+                       CTentry = *ctptr++;
+                       Did = ((be32_to_cpu(CTentry)) & Mask_DID);
+
+                       ndlp = NULL;
+                       if (Did != phba->fc_myDID) {
+                               /* Check for rscn processing or not */
+                               ndlp = lpfc_setup_disc_node(phba, Did);
+                       }
+                       /* Mark all node table entries that are in the
+                          Nameserver */
+                       if (ndlp) {
+                               /* NameServer Rsp */
+                               lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
+                                               "%d:0238 Process x%x NameServer"
+                                               " Rsp Data: x%x x%x x%x\n",
+                                               phba->brd_no,
+                                               Did, ndlp->nlp_flag,
+                                               phba->fc_flag,
+                                               phba->fc_rscn_id_cnt);
+                       } else {
+                               /* NameServer Rsp */
+                               lpfc_printf_log(phba,
+                                               KERN_INFO,
+                                               LOG_DISCOVERY,
+                                               "%d:0239 Skip x%x NameServer "
+                                               "Rsp Data: x%x x%x x%x\n",
+                                               phba->brd_no,
+                                               Did, Size, phba->fc_flag,
+                                               phba->fc_rscn_id_cnt);
+                       }
+
+                       if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY)))
+                               goto nsout1;
+                       Cnt -= sizeof (uint32_t);
+               }
+               ctptr = NULL;
+
+       }
+
+nsout1:
+       list_del(&head);
+
+       /* Here we are finished in the case RSCN */
+       if (phba->hba_state == LPFC_HBA_READY) {
+               lpfc_els_flush_rscn(phba);
+               spin_lock_irq(phba->host->host_lock);
+               phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */
+               spin_unlock_irq(phba->host->host_lock);
+       }
+       return 0;
+}
+
+
+
+
+static void
+lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+                       struct lpfc_iocbq * rspiocb)
+{
+       IOCB_t *irsp;
+       struct lpfc_sli *psli;
+       struct lpfc_dmabuf *bmp;
+       struct lpfc_dmabuf *inp;
+       struct lpfc_dmabuf *outp;
+       struct lpfc_nodelist *ndlp;
+       struct lpfc_sli_ct_request *CTrsp;
+
+       psli = &phba->sli;
+       /* we pass cmdiocb to state machine which needs rspiocb as well */
+       cmdiocb->context_un.rsp_iocb = rspiocb;
+
+       inp = (struct lpfc_dmabuf *) cmdiocb->context1;
+       outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+       bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
+
+       irsp = &rspiocb->iocb;
+       if (irsp->ulpStatus) {
+               if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
+                       ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
+                        (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) {
+                       goto out;
+               }
+
+               /* Check for retry */
+               if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {
+                       phba->fc_ns_retry++;
+                       /* CT command is being retried */
+                       ndlp =
+                           lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED,
+                                             NameServer_DID);
+                       if (ndlp) {
+                               if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) ==
+                                   0) {
+                                       goto out;
+                               }
+                       }
+               }
+       } else {
+               /* Good status, continue checking */
+               CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+               if (CTrsp->CommandResponse.bits.CmdRsp ==
+                   be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
+                       lpfc_ns_rsp(phba, outp,
+                                   (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
+               } else if (CTrsp->CommandResponse.bits.CmdRsp ==
+                          be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
+                       /* NameServer Rsp Error */
+                       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
+                                       "%d:0240 NameServer Rsp Error "
+                                       "Data: x%x x%x x%x x%x\n",
+                                       phba->brd_no,
+                                       CTrsp->CommandResponse.bits.CmdRsp,
+                                       (uint32_t) CTrsp->ReasonCode,
+                                       (uint32_t) CTrsp->Explanation,
+                                       phba->fc_flag);
+               } else {
+                       /* NameServer Rsp Error */
+                       lpfc_printf_log(phba,
+                                       KERN_INFO,
+                                       LOG_DISCOVERY,
+                                       "%d:0241 NameServer Rsp Error "
+                                       "Data: x%x x%x x%x x%x\n",
+                                       phba->brd_no,
+                                       CTrsp->CommandResponse.bits.CmdRsp,
+                                       (uint32_t) CTrsp->ReasonCode,
+                                       (uint32_t) CTrsp->Explanation,
+                                       phba->fc_flag);
+               }
+       }
+       /* Link up / RSCN discovery */
+       lpfc_disc_start(phba);
+out:
+       lpfc_free_ct_rsp(phba, outp);
+       lpfc_mbuf_free(phba, inp->virt, inp->phys);
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+       kfree(inp);
+       kfree(bmp);
+       spin_lock_irq(phba->host->host_lock);
+       list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+       spin_unlock_irq(phba->host->host_lock);
+       return;
+}
+
+static void
+lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+                       struct lpfc_iocbq * rspiocb)
+{
+       struct lpfc_sli *psli;
+       struct lpfc_dmabuf *bmp;
+       struct lpfc_dmabuf *inp;
+       struct lpfc_dmabuf *outp;
+       IOCB_t *irsp;
+       struct lpfc_sli_ct_request *CTrsp;
+
+       psli = &phba->sli;
+       /* we pass cmdiocb to state machine which needs rspiocb as well */
+       cmdiocb->context_un.rsp_iocb = rspiocb;
+
+       inp = (struct lpfc_dmabuf *) cmdiocb->context1;
+       outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+       bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
+       irsp = &rspiocb->iocb;
+
+       CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+
+       /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
+       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
+                       "%d:0209 RFT request completes ulpStatus x%x "
+                       "CmdRsp x%x\n", phba->brd_no, irsp->ulpStatus,
+                       CTrsp->CommandResponse.bits.CmdRsp);
+
+       lpfc_free_ct_rsp(phba, outp);
+       lpfc_mbuf_free(phba, inp->virt, inp->phys);
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+       kfree(inp);
+       kfree(bmp);
+       spin_lock_irq(phba->host->host_lock);
+       list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+       spin_unlock_irq(phba->host->host_lock);
+       return;
+}
+
+static void
+lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+                       struct lpfc_iocbq * rspiocb)
+{
+       lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+       return;
+}
+
+static void
+lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+                        struct lpfc_iocbq * rspiocb)
+{
+       lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+       return;
+}
+
+void
+lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp)
+{
+       char fwrev[16];
+
+       lpfc_decode_firmware_rev(phba, fwrev, 0);
+
+       if (phba->Port[0]) {
+               sprintf(symbp, "Emulex %s Port %s FV%s DV%s", phba->ModelName,
+                       phba->Port, fwrev, lpfc_release_version);
+       } else {
+               sprintf(symbp, "Emulex %s FV%s DV%s", phba->ModelName,
+                       fwrev, lpfc_release_version);
+       }
+}
+
+/*
+ * lpfc_ns_cmd
+ * Description:
+ *    Issue Cmd to NameServer
+ *       SLI_CTNS_GID_FT
+ *       LI_CTNS_RFT_ID
+ */
+int
+lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
+{
+       struct lpfc_dmabuf *mp, *bmp;
+       struct lpfc_sli_ct_request *CtReq;
+       struct ulp_bde64 *bpl;
+       void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
+                     struct lpfc_iocbq *) = NULL;
+       uint32_t rsp_size = 1024;
+
+       /* fill in BDEs for command */
+       /* Allocate buffer for command payload */
+       mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
+       if (!mp)
+               goto ns_cmd_exit;
+
+       INIT_LIST_HEAD(&mp->list);
+       mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
+       if (!mp->virt)
+               goto ns_cmd_free_mp;
+
+       /* Allocate buffer for Buffer ptr list */
+       bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
+       if (!bmp)
+               goto ns_cmd_free_mpvirt;
+
+       INIT_LIST_HEAD(&bmp->list);
+       bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));
+       if (!bmp->virt)
+               goto ns_cmd_free_bmp;
+
+       /* NameServer Req */
+       lpfc_printf_log(phba,
+                       KERN_INFO,
+                       LOG_DISCOVERY,
+                       "%d:0236 NameServer Req Data: x%x x%x x%x\n",
+                       phba->brd_no, cmdcode, phba->fc_flag,
+                       phba->fc_rscn_id_cnt);
+
+       bpl = (struct ulp_bde64 *) bmp->virt;
+       memset(bpl, 0, sizeof(struct ulp_bde64));
+       bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) );
+       bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) );
+       bpl->tus.f.bdeFlags = 0;
+       if (cmdcode == SLI_CTNS_GID_FT)
+               bpl->tus.f.bdeSize = GID_REQUEST_SZ;
+       else if (cmdcode == SLI_CTNS_RFT_ID)
+               bpl->tus.f.bdeSize = RFT_REQUEST_SZ;
+       else if (cmdcode == SLI_CTNS_RNN_ID)
+               bpl->tus.f.bdeSize = RNN_REQUEST_SZ;
+       else if (cmdcode == SLI_CTNS_RSNN_NN)
+               bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
+       else
+               bpl->tus.f.bdeSize = 0;
+       bpl->tus.w = le32_to_cpu(bpl->tus.w);
+
+       CtReq = (struct lpfc_sli_ct_request *) mp->virt;
+       memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request));
+       CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
+       CtReq->RevisionId.bits.InId = 0;
+       CtReq->FsType = SLI_CT_DIRECTORY_SERVICE;
+       CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
+       CtReq->CommandResponse.bits.Size = 0;
+       switch (cmdcode) {
+       case SLI_CTNS_GID_FT:
+               CtReq->CommandResponse.bits.CmdRsp =
+                   be16_to_cpu(SLI_CTNS_GID_FT);
+               CtReq->un.gid.Fc4Type = SLI_CTPT_FCP;
+               if (phba->hba_state < LPFC_HBA_READY)
+                       phba->hba_state = LPFC_NS_QRY;
+               lpfc_set_disctmo(phba);
+               cmpl = lpfc_cmpl_ct_cmd_gid_ft;
+               rsp_size = FC_MAX_NS_RSP;
+               break;
+
+       case SLI_CTNS_RFT_ID:
+               CtReq->CommandResponse.bits.CmdRsp =
+                   be16_to_cpu(SLI_CTNS_RFT_ID);
+               CtReq->un.rft.PortId = be32_to_cpu(phba->fc_myDID);
+               CtReq->un.rft.fcpReg = 1;
+               cmpl = lpfc_cmpl_ct_cmd_rft_id;
+               break;
+
+       case SLI_CTNS_RNN_ID:
+               CtReq->CommandResponse.bits.CmdRsp =
+                   be16_to_cpu(SLI_CTNS_RNN_ID);
+               CtReq->un.rnn.PortId = be32_to_cpu(phba->fc_myDID);
+               memcpy(CtReq->un.rnn.wwnn,  &phba->fc_nodename,
+                      sizeof (struct lpfc_name));
+               cmpl = lpfc_cmpl_ct_cmd_rnn_id;
+               break;
+
+       case SLI_CTNS_RSNN_NN:
+               CtReq->CommandResponse.bits.CmdRsp =
+                   be16_to_cpu(SLI_CTNS_RSNN_NN);
+               memcpy(CtReq->un.rsnn.wwnn, &phba->fc_nodename,
+                      sizeof (struct lpfc_name));
+               lpfc_get_hba_sym_node_name(phba, CtReq->un.rsnn.symbname);
+               CtReq->un.rsnn.len = strlen(CtReq->un.rsnn.symbname);
+               cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
+               break;
+       }
+
+       if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, rsp_size))
+               /* On success, The cmpl function will free the buffers */
+               return 0;
+
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+ns_cmd_free_bmp:
+       kfree(bmp);
+ns_cmd_free_mpvirt:
+       lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ns_cmd_free_mp:
+       kfree(mp);
+ns_cmd_exit:
+       return 1;
+}
+
+static void
+lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
+                     struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb)
+{
+       struct lpfc_dmabuf *bmp = cmdiocb->context3;
+       struct lpfc_dmabuf *inp = cmdiocb->context1;
+       struct lpfc_dmabuf *outp = cmdiocb->context2;
+       struct lpfc_sli_ct_request *CTrsp = outp->virt;
+       struct lpfc_sli_ct_request *CTcmd = inp->virt;
+       struct lpfc_nodelist *ndlp;
+       uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
+       uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
+
+       ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
+       if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
+               /* FDMI rsp failed */
+               lpfc_printf_log(phba,
+                               KERN_INFO,
+                               LOG_DISCOVERY,
+                               "%d:0220 FDMI rsp failed Data: x%x\n",
+                               phba->brd_no,
+                              be16_to_cpu(fdmi_cmd));
+       }
+
+       switch (be16_to_cpu(fdmi_cmd)) {
+       case SLI_MGMT_RHBA:
+               lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RPA);
+               break;
+
+       case SLI_MGMT_RPA:
+               break;
+
+       case SLI_MGMT_DHBA:
+               lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DPRT);
+               break;
+
+       case SLI_MGMT_DPRT:
+               lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RHBA);
+               break;
+       }
+
+       lpfc_free_ct_rsp(phba, outp);
+       lpfc_mbuf_free(phba, inp->virt, inp->phys);
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+       kfree(inp);
+       kfree(bmp);
+       spin_lock_irq(phba->host->host_lock);
+       list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+       spin_unlock_irq(phba->host->host_lock);
+       return;
+}
+int
+lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
+{
+       struct lpfc_dmabuf *mp, *bmp;
+       struct lpfc_sli_ct_request *CtReq;
+       struct ulp_bde64 *bpl;
+       uint32_t size;
+       REG_HBA *rh;
+       PORT_ENTRY *pe;
+       REG_PORT_ATTRIBUTE *pab;
+       ATTRIBUTE_BLOCK *ab;
+       ATTRIBUTE_ENTRY *ae;
+       void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
+                     struct lpfc_iocbq *);
+
+
+       /* fill in BDEs for command */
+       /* Allocate buffer for command payload */
+       mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
+       if (!mp)
+               goto fdmi_cmd_exit;
+
+       mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
+       if (!mp->virt)
+               goto fdmi_cmd_free_mp;
+
+       /* Allocate buffer for Buffer ptr list */
+       bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
+       if (!bmp)
+               goto fdmi_cmd_free_mpvirt;
+
+       bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys));
+       if (!bmp->virt)
+               goto fdmi_cmd_free_bmp;
+
+       INIT_LIST_HEAD(&mp->list);
+       INIT_LIST_HEAD(&bmp->list);
+
+       /* FDMI request */
+       lpfc_printf_log(phba,
+                       KERN_INFO,
+                       LOG_DISCOVERY,
+                       "%d:0218 FDMI Request Data: x%x x%x x%x\n",
+                       phba->brd_no,
+                      phba->fc_flag, phba->hba_state, cmdcode);
+
+       CtReq = (struct lpfc_sli_ct_request *) mp->virt;
+
+       memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
+       CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
+       CtReq->RevisionId.bits.InId = 0;
+
+       CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;
+       CtReq->FsSubType = SLI_CT_FDMI_Subtypes;
+       size = 0;
+
+       switch (cmdcode) {
+       case SLI_MGMT_RHBA:
+               {
+                       lpfc_vpd_t *vp = &phba->vpd;
+                       uint32_t i, j, incr;
+                       int len;
+
+                       CtReq->CommandResponse.bits.CmdRsp =
+                           be16_to_cpu(SLI_MGMT_RHBA);
+                       CtReq->CommandResponse.bits.Size = 0;
+                       rh = (REG_HBA *) & CtReq->un.PortID;
+                       memcpy(&rh->hi.PortName, &phba->fc_sparam.portName,
+                              sizeof (struct lpfc_name));
+                       /* One entry (port) per adapter */
+                       rh->rpl.EntryCnt = be32_to_cpu(1);
+                       memcpy(&rh->rpl.pe, &phba->fc_sparam.portName,
+                              sizeof (struct lpfc_name));
+
+                       /* point to the HBA attribute block */
+                       size = 2 * sizeof (struct lpfc_name) + FOURBYTES;
+                       ab = (ATTRIBUTE_BLOCK *) ((uint8_t *) rh + size);
+                       ab->EntryCnt = 0;
+
+                       /* Point to the beginning of the first HBA attribute
+                          entry */
+                       /* #1 HBA attribute entry */
+                       size += FOURBYTES;
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME);
+                       ae->ad.bits.AttrLen =  be16_to_cpu(FOURBYTES
+                                               + sizeof (struct lpfc_name));
+                       memcpy(&ae->un.NodeName, &phba->fc_sparam.nodeName,
+                              sizeof (struct lpfc_name));
+                       ab->EntryCnt++;
+                       size += FOURBYTES + sizeof (struct lpfc_name);
+
+                       /* #2 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(MANUFACTURER);
+                       strcpy(ae->un.Manufacturer, "Emulex Corporation");
+                       len = strlen(ae->un.Manufacturer);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #3 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(SERIAL_NUMBER);
+                       strcpy(ae->un.SerialNumber, phba->SerialNumber);
+                       len = strlen(ae->un.SerialNumber);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #4 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(MODEL);
+                       strcpy(ae->un.Model, phba->ModelName);
+                       len = strlen(ae->un.Model);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #5 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(MODEL_DESCRIPTION);
+                       strcpy(ae->un.ModelDescription, phba->ModelDesc);
+                       len = strlen(ae->un.ModelDescription);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #6 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(HARDWARE_VERSION);
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 8);
+                       /* Convert JEDEC ID to ascii for hardware version */
+                       incr = vp->rev.biuRev;
+                       for (i = 0; i < 8; i++) {
+                               j = (incr & 0xf);
+                               if (j <= 9)
+                                       ae->un.HardwareVersion[7 - i] =
+                                           (char)((uint8_t) 0x30 +
+                                                  (uint8_t) j);
+                               else
+                                       ae->un.HardwareVersion[7 - i] =
+                                           (char)((uint8_t) 0x61 +
+                                                  (uint8_t) (j - 10));
+                               incr = (incr >> 4);
+                       }
+                       ab->EntryCnt++;
+                       size += FOURBYTES + 8;
+
+                       /* #7 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(DRIVER_VERSION);
+                       strcpy(ae->un.DriverVersion, lpfc_release_version);
+                       len = strlen(ae->un.DriverVersion);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #8 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(OPTION_ROM_VERSION);
+                       strcpy(ae->un.OptionROMVersion, phba->OptionROMVersion);
+                       len = strlen(ae->un.OptionROMVersion);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #9 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(FIRMWARE_VERSION);
+                       lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion,
+                               1);
+                       len = strlen(ae->un.FirmwareVersion);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #10 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION);
+                       sprintf(ae->un.OsNameVersion, "%s %s %s",
+                               system_utsname.sysname, system_utsname.release,
+                               system_utsname.version);
+                       len = strlen(ae->un.OsNameVersion);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       /* #11 HBA attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(MAX_CT_PAYLOAD_LEN);
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
+                       ae->un.MaxCTPayloadLen = (65 * 4096);
+                       ab->EntryCnt++;
+                       size += FOURBYTES + 4;
+
+                       ab->EntryCnt = be32_to_cpu(ab->EntryCnt);
+                       /* Total size */
+                       size = GID_REQUEST_SZ - 4 + size;
+               }
+               break;
+
+       case SLI_MGMT_RPA:
+               {
+                       lpfc_vpd_t *vp;
+                       struct serv_parm *hsp;
+                       int len;
+
+                       vp = &phba->vpd;
+
+                       CtReq->CommandResponse.bits.CmdRsp =
+                           be16_to_cpu(SLI_MGMT_RPA);
+                       CtReq->CommandResponse.bits.Size = 0;
+                       pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID;
+                       size = sizeof (struct lpfc_name) + FOURBYTES;
+                       memcpy((uint8_t *) & pab->PortName,
+                              (uint8_t *) & phba->fc_sparam.portName,
+                              sizeof (struct lpfc_name));
+                       pab->ab.EntryCnt = 0;
+
+                       /* #1 Port attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_FC4_TYPES);
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 32);
+                       ae->un.SupportFC4Types[2] = 1;
+                       ae->un.SupportFC4Types[7] = 1;
+                       pab->ab.EntryCnt++;
+                       size += FOURBYTES + 32;
+
+                       /* #2 Port attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED);
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
+                       if (FC_JEDEC_ID(vp->rev.biuRev) == VIPER_JEDEC_ID)
+                               ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
+                       else if (FC_JEDEC_ID(vp->rev.biuRev) == HELIOS_JEDEC_ID)
+                               ae->un.SupportSpeed = HBA_PORTSPEED_4GBIT;
+                       else if ((FC_JEDEC_ID(vp->rev.biuRev) ==
+                                 CENTAUR_2G_JEDEC_ID)
+                                || (FC_JEDEC_ID(vp->rev.biuRev) ==
+                                    PEGASUS_JEDEC_ID)
+                                || (FC_JEDEC_ID(vp->rev.biuRev) ==
+                                    THOR_JEDEC_ID))
+                               ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT;
+                       else
+                               ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT;
+                       pab->ab.EntryCnt++;
+                       size += FOURBYTES + 4;
+
+                       /* #3 Port attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED);
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
+                       switch(phba->fc_linkspeed) {
+                               case LA_1GHZ_LINK:
+                                       ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
+                               break;
+                               case LA_2GHZ_LINK:
+                                       ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
+                               break;
+                               case LA_4GHZ_LINK:
+                                       ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
+                               break;
+                               default:
+                                       ae->un.PortSpeed =
+                                               HBA_PORTSPEED_UNKNOWN;
+                               break;
+                       }
+                       pab->ab.EntryCnt++;
+                       size += FOURBYTES + 4;
+
+                       /* #4 Port attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE);
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
+                       hsp = (struct serv_parm *) & phba->fc_sparam;
+                       ae->un.MaxFrameSize =
+                           (((uint32_t) hsp->cmn.
+                             bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn.
+                           bbRcvSizeLsb;
+                       pab->ab.EntryCnt++;
+                       size += FOURBYTES + 4;
+
+                       /* #5 Port attribute entry */
+                       ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
+                       ae->ad.bits.AttrType = be16_to_cpu(OS_DEVICE_NAME);
+                       strcpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME);
+                       len = strlen((char *)ae->un.OsDeviceName);
+                       len += (len & 3) ? (4 - (len & 3)) : 4;
+                       ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
+                       pab->ab.EntryCnt++;
+                       size += FOURBYTES + len;
+
+                       if (phba->cfg_fdmi_on == 2) {
+                               /* #6 Port attribute entry */
+                               ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab +
+                                                         size);
+                               ae->ad.bits.AttrType = be16_to_cpu(HOST_NAME);
+                               sprintf(ae->un.HostName, "%s",
+                                       system_utsname.nodename);
+                               len = strlen(ae->un.HostName);
+                               len += (len & 3) ? (4 - (len & 3)) : 4;
+                               ae->ad.bits.AttrLen =
+                                   be16_to_cpu(FOURBYTES + len);
+                               pab->ab.EntryCnt++;
+                               size += FOURBYTES + len;
+                       }
+
+                       pab->ab.EntryCnt = be32_to_cpu(pab->ab.EntryCnt);
+                       /* Total size */
+                       size = GID_REQUEST_SZ - 4 + size;
+               }
+               break;
+
+       case SLI_MGMT_DHBA:
+               CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_DHBA);
+               CtReq->CommandResponse.bits.Size = 0;
+               pe = (PORT_ENTRY *) & CtReq->un.PortID;
+               memcpy((uint8_t *) & pe->PortName,
+                      (uint8_t *) & phba->fc_sparam.portName,
+                      sizeof (struct lpfc_name));
+               size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
+               break;
+
+       case SLI_MGMT_DPRT:
+               CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_DPRT);
+               CtReq->CommandResponse.bits.Size = 0;
+               pe = (PORT_ENTRY *) & CtReq->un.PortID;
+               memcpy((uint8_t *) & pe->PortName,
+                      (uint8_t *) & phba->fc_sparam.portName,
+                      sizeof (struct lpfc_name));
+               size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
+               break;
+       }
+
+       bpl = (struct ulp_bde64 *) bmp->virt;
+       bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) );
+       bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) );
+       bpl->tus.f.bdeFlags = 0;
+       bpl->tus.f.bdeSize = size;
+       bpl->tus.w = le32_to_cpu(bpl->tus.w);
+
+       cmpl = lpfc_cmpl_ct_cmd_fdmi;
+
+       if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP))
+               return 0;
+
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+fdmi_cmd_free_bmp:
+       kfree(bmp);
+fdmi_cmd_free_mpvirt:
+       lpfc_mbuf_free(phba, mp->virt, mp->phys);
+fdmi_cmd_free_mp:
+       kfree(mp);
+fdmi_cmd_exit:
+       /* Issue FDMI request failed */
+       lpfc_printf_log(phba,
+                       KERN_INFO,
+                       LOG_DISCOVERY,
+                       "%d:0244 Issue FDMI request failed Data: x%x\n",
+                       phba->brd_no,
+                       cmdcode);
+       return 1;
+}
+
+void
+lpfc_fdmi_tmo(unsigned long ptr)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+       unsigned long iflag;
+
+       spin_lock_irqsave(phba->host->host_lock, iflag);
+       if (!(phba->work_hba_events & WORKER_FDMI_TMO)) {
+               phba->work_hba_events |= WORKER_FDMI_TMO;
+               if (phba->work_wait)
+                       wake_up(phba->work_wait);
+       }
+       spin_unlock_irqrestore(phba->host->host_lock,iflag);
+}
+
+void
+lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
+{
+       struct lpfc_nodelist *ndlp;
+
+       spin_lock_irq(phba->host->host_lock);
+       if (!(phba->work_hba_events & WORKER_FDMI_TMO)) {
+               spin_unlock_irq(phba->host->host_lock);
+               return;
+       }
+       ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
+       if (ndlp) {
+               if (system_utsname.nodename[0] != '\0') {
+                       lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
+               } else {
+                       mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
+               }
+       }
+       spin_unlock_irq(phba->host->host_lock);
+       return;
+}
+
+
+void
+lpfc_decode_firmware_rev(struct lpfc_hba * phba, char *fwrevision, int flag)
+{
+       struct lpfc_sli *psli = &phba->sli;
+       lpfc_vpd_t *vp = &phba->vpd;
+       uint32_t b1, b2, b3, b4, i, rev;
+       char c;
+       uint32_t *ptr, str[4];
+       uint8_t *fwname;
+
+       if (vp->rev.rBit) {
+               if (psli->sli_flag & LPFC_SLI2_ACTIVE)
+                       rev = vp->rev.sli2FwRev;
+               else
+                       rev = vp->rev.sli1FwRev;
+
+               b1 = (rev & 0x0000f000) >> 12;
+               b2 = (rev & 0x00000f00) >> 8;
+               b3 = (rev & 0x000000c0) >> 6;
+               b4 = (rev & 0x00000030) >> 4;
+
+               switch (b4) {
+               case 0:
+                       c = 'N';
+                       break;
+               case 1:
+                       c = 'A';
+                       break;
+               case 2:
+                       c = 'B';
+                       break;
+               default:
+                       c = 0;
+                       break;
+               }
+               b4 = (rev & 0x0000000f);
+
+               if (psli->sli_flag & LPFC_SLI2_ACTIVE)
+                       fwname = vp->rev.sli2FwName;
+               else
+                       fwname = vp->rev.sli1FwName;
+
+               for (i = 0; i < 16; i++)
+                       if (fwname[i] == 0x20)
+                               fwname[i] = 0;
+
+               ptr = (uint32_t*)fwname;
+
+               for (i = 0; i < 3; i++)
+                       str[i] = be32_to_cpu(*ptr++);
+
+               if (c == 0) {
+                       if (flag)
+                               sprintf(fwrevision, "%d.%d%d (%s)",
+                                       b1, b2, b3, (char *)str);
+                       else
+                               sprintf(fwrevision, "%d.%d%d", b1,
+                                       b2, b3);
+               } else {
+                       if (flag)
+                               sprintf(fwrevision, "%d.%d%d%c%d (%s)",
+                                       b1, b2, b3, c,
+                                       b4, (char *)str);
+                       else
+                               sprintf(fwrevision, "%d.%d%d%c%d",
+                                       b1, b2, b3, c, b4);
+               }
+       } else {
+               rev = vp->rev.smFwRev;
+
+               b1 = (rev & 0xff000000) >> 24;
+               b2 = (rev & 0x00f00000) >> 20;
+               b3 = (rev & 0x000f0000) >> 16;
+               c  = (rev & 0x0000ff00) >> 8;
+               b4 = (rev & 0x000000ff);
+
+               if (flag)
+                       sprintf(fwrevision, "%d.%d%d%c%d ", b1,
+                               b2, b3, c, b4);
+               else
+                       sprintf(fwrevision, "%d.%d%d%c%d ", b1,
+                               b2, b3, c, b4);
+       }
+       return;
+}
diff -urN linux/drivers/scsi/lpfc/lpfc_disc.h 
linux/drivers/scsi/lpfc/lpfc_disc.h
--- linux/drivers/scsi/lpfc/lpfc_disc.h 1970/01/01 00:00:00
+++ linux/drivers/scsi/lpfc/lpfc_disc.h 2005-04-29 12:15:13.082178000 +0100     
1.1
@@ -0,0 +1,206 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Enterprise Fibre Channel Host Bus Adapters.                     *
+ * Refer to the README file included with this package for         *
+ * driver version and adapter support.                             *
+ * Copyright (C) 2004 Emulex Corporation.                          *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * 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, a copy of which    *
+ * can be found in the file COPYING included with this package.    *
+ *******************************************************************/
+
+/*
+ * $Id: lpfc_disc.h 1.61 2005/04/07 08:46:52EDT sf_support Exp  $
+ */
+
+#define FC_MAX_HOLD_RSCN     32              /* max number of deferred RSCNs */
+#define FC_MAX_NS_RSP        65536    /* max size NameServer rsp */
+#define FC_MAXLOOP           126      /* max devices supported on a fc loop */
+#define LPFC_DISC_FLOGI_TMO  10              /* Discovery FLOGI ratov */
+
+
+/* This is the protocol dependent definition for a Node List Entry.
+ * This is used by Fibre Channel protocol to support FCP.
+ */
+
+/* structure used to queue event to the discovery tasklet */
+struct lpfc_work_evt {
+       struct list_head      evt_listp;
+       void                * evt_arg1;
+       void                * evt_arg2;
+       uint32_t              evt;
+};
+
+#define LPFC_EVT_NODEV_TMO     0x1
+#define LPFC_EVT_ONLINE                0x2
+#define LPFC_EVT_OFFLINE       0x3
+#define LPFC_EVT_ELS_RETRY     0x4
+
+struct lpfc_nodelist {
+       struct list_head nlp_listp;
+       struct lpfc_name nlp_portname;          /* port name */
+       struct lpfc_name nlp_nodename;          /* node name */
+       uint32_t         nlp_flag