diff --git a/drivers/scsi/cpqfcTScontrol.c b/drivers/scsi/cpqfcTScontrol.c
new file mode 100644
index 0000000..bd94c70
--- /dev/null
+++ b/drivers/scsi/cpqfcTScontrol.c
@@ -0,0 +1,2231 @@
+/* Copyright 2000, Compaq Computer Corporation 
+ * Fibre Channel Host Bus Adapter 
+ * 64-bit, 66MHz PCI 
+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2  L2C1090 ...
+ *          SP# P225CXCBFIEL6T, Rev XC
+ *          SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * 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.
+ * Written by Don Zimmerman
+*/
+/* These functions control the host bus adapter (HBA) hardware.  The main chip
+   control takes place in the interrupt handler where we process the IMQ 
+   (Inbound Message Queue).  The IMQ is Tachyon's way of communicating FC link
+   events and state information to the driver.  The Single Frame Queue (SFQ)
+   buffers incoming FC frames for processing by the driver.  References to 
+   "TL/TS UG" are for:
+   "HP HPFC-5100/5166 Tachyon TL/TS ICs User Guide", August 16, 1999, 1st Ed.
+   Hewlitt Packard Manual Part Number 5968-1083E.
+*/
+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#include <linux/blkdev.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>  // request_region() prototype
+#include <linux/sched.h>
+#include <linux/slab.h>  // need "kfree" for ext. S/G pages
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/unistd.h>
+#include <asm/io.h>  // struct pt_regs for IRQ handler & Port I/O
+#include <asm/irq.h>
+#include <linux/spinlock.h>
+
+#include "scsi.h"
+#include <scsi/scsi_host.h>   // Scsi_Host definition for INT handler
+#include "cpqfcTSchip.h"
+#include "cpqfcTSstructs.h"
+
+//#define IMQ_DEBUG 1
+
+static void fcParseLinkStatusCounters(TACHYON * fcChip);
+static void CpqTsGetSFQEntry(TACHYON * fcChip, 
+	      USHORT pi, ULONG * buffr, BOOLEAN UpdateChip); 
+
+static void 
+cpqfc_free_dma_consistent(CPQFCHBA *cpqfcHBAdata)
+{
+  	// free up the primary EXCHANGES struct and Link Q
+	PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+
+	if (fcChip->Exchanges != NULL)
+		pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_EXCHANGES),
+			fcChip->Exchanges, fcChip->exch_dma_handle);
+	fcChip->Exchanges = NULL;
+	if (cpqfcHBAdata->fcLQ != NULL)
+		pci_free_consistent(cpqfcHBAdata->PciDev, sizeof(FC_LINK_QUE),
+			cpqfcHBAdata->fcLQ, cpqfcHBAdata->fcLQ_dma_handle);
+	cpqfcHBAdata->fcLQ = NULL;
+}
+
+// Note special requirements for Q alignment!  (TL/TS UG pg. 190)
+// We place critical index pointers at end of QUE elements to assist
+// in non-symbolic (i.e. memory dump) debugging
+// opcode defines placement of Queues (e.g. local/external RAM)
+
+int CpqTsCreateTachLiteQues( void* pHBA, int opcode)
+{
+  CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+  PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+
+  int iStatus=0;
+  unsigned long ulAddr;
+  dma_addr_t ERQdma, IMQdma, SPQdma, SESTdma;
+  int i;
+
+  // NOTE! fcMemManager() will return system virtual addresses.
+  // System (kernel) virtual addresses, though non-paged, still
+  // aren't physical addresses.  Convert to PHYSICAL_ADDRESS for Tachyon's
+  // DMA use.
+  ENTER("CreateTachLiteQues");
+
+
+  // Allocate primary EXCHANGES array...
+  fcChip->Exchanges = NULL;
+  cpqfcHBAdata->fcLQ = NULL;
+  
+  /* printk("Allocating %u for %u Exchanges ", 
+	  (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID); */
+  fcChip->Exchanges = pci_alloc_consistent(cpqfcHBAdata->PciDev, 
+			sizeof(FC_EXCHANGES), &fcChip->exch_dma_handle);
+  /* printk("@ %p\n", fcChip->Exchanges); */
+
+  if( fcChip->Exchanges == NULL ) // fatal error!!
+  {
+    printk("pci_alloc_consistent failure on Exchanges: fatal error\n");
+    return -1;
+  }
+  // zero out the entire EXCHANGE space
+  memset( fcChip->Exchanges, 0, sizeof( FC_EXCHANGES));  
+
+
+  /* printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE)); */
+  cpqfcHBAdata->fcLQ = pci_alloc_consistent(cpqfcHBAdata->PciDev,
+				 sizeof( FC_LINK_QUE), &cpqfcHBAdata->fcLQ_dma_handle);
+  /* printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH); */
+
+  if( cpqfcHBAdata->fcLQ == NULL ) // fatal error!!
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk("pci_alloc_consistent() failure on fc Link Que: fatal error\n");
+    return -1;
+  }
+  // zero out the entire EXCHANGE space
+  memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE));  
+  
+  // Verify that basic Tach I/O registers are not NULL  
+  if( !fcChip->Registers.ReMapMemBase )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk("HBA base address NULL: fatal error\n");
+    return -1;
+  }
+
+
+  // Initialize the fcMemManager memory pairs (stores allocated/aligned
+  // pairs for future freeing)
+  memset( cpqfcHBAdata->dynamic_mem, 0, sizeof(cpqfcHBAdata->dynamic_mem));
+  
+
+  // Allocate Tach's Exchange Request Queue (each ERQ entry 32 bytes)
+  
+  fcChip->ERQ = fcMemManager( cpqfcHBAdata->PciDev, 
+			&cpqfcHBAdata->dynamic_mem[0], 
+			sizeof( TachLiteERQ ), 32*(ERQ_LEN), 0L, &ERQdma);
+  if( !fcChip->ERQ )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk("pci_alloc_consistent/alignment failure on ERQ: fatal error\n");
+    return -1;
+  }
+  fcChip->ERQ->length = ERQ_LEN-1;
+  ulAddr = (ULONG) ERQdma; 
+#if BITS_PER_LONG > 32
+  if( (ulAddr >> 32) )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk(" FATAL! ERQ ptr %p exceeds Tachyon's 32-bit register size\n",
+		    (void*)ulAddr);
+    return -1;  // failed
+  }
+#endif
+  fcChip->ERQ->base = (ULONG)ulAddr;  // copy for quick reference
+
+
+  // Allocate Tach's Inbound Message Queue (32 bytes per entry)
+  
+  fcChip->IMQ = fcMemManager( cpqfcHBAdata->PciDev, 
+		  &cpqfcHBAdata->dynamic_mem[0],
+		  sizeof( TachyonIMQ ), 32*(IMQ_LEN), 0L, &IMQdma );
+  if( !fcChip->IMQ )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk("pci_alloc_consistent/alignment failure on IMQ: fatal error\n");
+    return -1;
+  }
+  fcChip->IMQ->length = IMQ_LEN-1;
+
+  ulAddr = IMQdma;
+#if BITS_PER_LONG > 32
+  if( (ulAddr >> 32) )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
+		    (void*)ulAddr);
+    return -1;  // failed
+  }
+#endif
+  fcChip->IMQ->base = (ULONG)ulAddr;  // copy for quick reference
+
+
+  // Allocate Tach's  Single Frame Queue (64 bytes per entry)
+  fcChip->SFQ = fcMemManager( cpqfcHBAdata->PciDev, 
+		  &cpqfcHBAdata->dynamic_mem[0],
+		  sizeof( TachLiteSFQ ), 64*(SFQ_LEN),0L, &SPQdma );
+  if( !fcChip->SFQ )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk("pci_alloc_consistent/alignment failure on SFQ: fatal error\n");
+    return -1;
+  }
+  fcChip->SFQ->length = SFQ_LEN-1;      // i.e. Que length [# entries -
+                                       // min. 32; max.  4096 (0xffff)]
+  
+  ulAddr = SPQdma;
+#if BITS_PER_LONG > 32
+  if( (ulAddr >> 32) )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
+		    (void*)ulAddr);
+    return -1;  // failed
+  }
+#endif
+  fcChip->SFQ->base = (ULONG)ulAddr;  // copy for quick reference
+
+
+  // Allocate SCSI Exchange State Table; aligned nearest @sizeof
+  // power-of-2 boundary
+  // LIVE DANGEROUSLY!  Assume the boundary for SEST mem will
+  // be on physical page (e.g. 4k) boundary.
+  /* printk("Allocating %u for TachSEST for %u Exchanges\n", 
+		 (ULONG)sizeof(TachSEST), TACH_SEST_LEN); */
+  fcChip->SEST = fcMemManager( cpqfcHBAdata->PciDev,
+		  &cpqfcHBAdata->dynamic_mem[0],
+		  sizeof(TachSEST),  4, 0L, &SESTdma );
+//		  sizeof(TachSEST),  64*TACH_SEST_LEN, 0L );
+  if( !fcChip->SEST )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk("pci_alloc_consistent/alignment failure on SEST: fatal error\n");
+    return -1;
+  }
+
+  for( i=0; i < TACH_SEST_LEN; i++)  // for each exchange
+      fcChip->SEST->sgPages[i] = NULL;
+
+  fcChip->SEST->length = TACH_SEST_LEN;  // e.g. DON'T subtract one 
+                                       // (TL/TS UG, pg 153)
+
+  ulAddr = SESTdma; 
+#if BITS_PER_LONG > 32
+  if( (ulAddr >> 32) )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
+		    (void*)ulAddr);
+    return -1;  // failed
+  }
+#endif
+  fcChip->SEST->base = (ULONG)ulAddr;  // copy for quick reference
+
+
+			      // Now that structures are defined,
+			      // fill in Tachyon chip registers...
+
+			      // EEEEEEEE  EXCHANGE REQUEST QUEUE
+
+  writel( fcChip->ERQ->base, 
+    (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
+      
+  writel( fcChip->ERQ->length,
+    (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_LENGTH));
+     
+
+  fcChip->ERQ->producerIndex = 0L;
+  writel( fcChip->ERQ->producerIndex,
+    (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX));
+      
+
+		// NOTE! write consumer index last, since the write
+		// causes Tachyon to process the other registers
+
+  ulAddr = ((unsigned long)&fcChip->ERQ->consumerIndex - 
+		(unsigned long)fcChip->ERQ) + (unsigned long) ERQdma;
+
+  // NOTE! Tachyon DMAs to the ERQ consumer Index host
+		// address; must be correctly aligned
+  writel( (ULONG)ulAddr,
+    (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_CONSUMER_INDEX_ADR));
+
+
+
+				 // IIIIIIIIIIIII  INBOUND MESSAGE QUEUE
+				 // Tell Tachyon where the Que starts
+
+  // set the Host's pointer for Tachyon to access
+
+  /* printk("  cpqfcTS: writing IMQ BASE %Xh  ", fcChip->IMQ->base ); */
+  writel( fcChip->IMQ->base, 
+    (fcChip->Registers.ReMapMemBase + IMQ_BASE));
+
+  writel( fcChip->IMQ->length,
+    (fcChip->Registers.ReMapMemBase + IMQ_LENGTH));
+
+  writel( fcChip->IMQ->consumerIndex,
+    (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
+
+
+		// NOTE: TachLite DMAs to the producerIndex host address
+		// must be correctly aligned with address bits 1-0 cleared
+    // Writing the BASE register clears the PI register, so write it last
+  ulAddr = ((unsigned long)&fcChip->IMQ->producerIndex - 
+		(unsigned long)fcChip->IMQ) + (unsigned long) IMQdma;
+
+#if BITS_PER_LONG > 32
+  if( (ulAddr >> 32) )
+  {
+    cpqfc_free_dma_consistent(cpqfcHBAdata);
+    printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
+		    (void*)ulAddr);
+    return -1;  // failed
+  }
+#endif
+#if DBG
+  printk("  PI %Xh\n", (ULONG)ulAddr );
+#endif
+  writel( (ULONG)ulAddr, 
+    (fcChip->Registers.ReMapMemBase + IMQ_PRODUCER_INDEX));
+
+
+
+				 // SSSSSSSSSSSSSSS SINGLE FRAME SEQUENCE
+				 // Tell TachLite where the Que starts
+
+  writel( fcChip->SFQ->base, 
+    (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_BASE));
+
+  writel( fcChip->SFQ->length,
+    (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_LENGTH));
+
+
+         // tell TachLite where SEST table is & how long
+  writel( fcChip->SEST->base,
+    (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE));
+
+  /* printk("  cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n",
+    fcChip->SEST, fcChip->SEST->base, 
+    fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE); */
+
+  writel( fcChip->SEST->length,
+    (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_LENGTH));
+      
+  writel( (TL_EXT_SG_PAGE_COUNT-1),
+    (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_SG_PAGE));
+
+
+  LEAVE("CreateTachLiteQues");
+
+  return iStatus;
+}
+
+
+
+// function to return TachLite to Power On state
+// 1st - reset tachyon ('SOFT' reset)
+// others - future
+
+int CpqTsResetTachLite(void *pHBA, int type)
+{
+  CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+  PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+  ULONG ulBuff, i;
+  int ret_status=0; // def. success
+
+  ENTER("ResetTach");
+  
+  switch(type)
+  {
+
+    case CLEAR_FCPORTS:
+
+      // in case he was running previously, mask Tach's interrupt
+      writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
+      
+     // de-allocate mem for any Logged in ports
+      // (e.g., our module is unloading)
+      // search the forward linked list, de-allocating
+      // the memory we allocated when the port was initially logged in
+      {
+        PFC_LOGGEDIN_PORT pLoggedInPort = fcChip->fcPorts.pNextPort;
+        PFC_LOGGEDIN_PORT ptr;
+//        printk("checking for allocated LoggedInPorts...\n");
+			
+        while( pLoggedInPort )
+        {
+          ptr = pLoggedInPort;
+          pLoggedInPort = ptr->pNextPort;
+//	  printk("kfree(%p) on FC LoggedInPort port_id 0x%06lX\n",
+//			  ptr, ptr->port_id);
+          kfree( ptr );
+        }
+      }
+      // (continue resetting hardware...)
+
+    case 1:                   // RESTART Tachyon (power-up state)
+
+      // in case he was running previously, mask Tach's interrupt
+      writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
+			      // turn OFF laser (NOTE: laser is turned
+                              // off during reset, because GPIO4 is cleared
+                              // to 0 by reset action - see TLUM, sec 7.22)
+                              // However, CPQ 64-bit HBAs have a "health
+                              // circuit" which keeps laser ON for a brief
+                              // period after it is turned off ( < 1s)
+      
+      fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 0);
+  
+
+
+            // soft reset timing constraints require:
+            //   1. set RST to 1
+            //   2. read SOFTRST register 
+            //      (128 times per R. Callison code)
+            //   3. clear PCI ints
+            //   4. clear RST to 0
+      writel( 0xff000001L,
+        (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
+        
+      for( i=0; i<128; i++)
+        ulBuff = readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST);
+
+        // clear the soft reset
+      for( i=0; i<8; i++)
+  	writel( 0, (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
+
+               
+
+			       // clear out our copy of Tach regs,
+			       // because they must be invalid now,
+			       // since TachLite reset all his regs.
+      CpqTsDestroyTachLiteQues(cpqfcHBAdata,0); // remove Host-based Que structs
+      cpqfcTSClearLinkStatusCounters(fcChip);  // clear our s/w accumulators
+                               // lower bits give GBIC info
+      fcChip->Registers.TYstatus.value = 
+	              readl( fcChip->Registers.TYstatus.address );
+      break;
+
+/*
+    case 2:                   // freeze SCSI
+    case 3:                   // reset Outbound command que (ERQ)
+    case 4:                   // unfreeze OSM (Outbound Seq. Man.) 'er'
+    case 5:                   // report status
+
+    break;
+*/
+    default:
+      ret_status = -1;  // invalid option passed to RESET function
+      break;
+  }
+  LEAVE("ResetTach");
+  return ret_status;
+}
+
+
+
+
+
+
+// 'addrBase' is IOBaseU for both TachLite and (older) Tachyon
+int CpqTsLaserControl( void* addrBase, int opcode )
+{
+  ULONG dwBuff;
+
+  dwBuff = readl((addrBase + TL_MEM_TACH_CONTROL) ); // read TL Control reg
+                                                    // (change only bit 4)
+  if( opcode == 1)
+    dwBuff |= ~0xffffffefL; // set - ON
+  else
+    dwBuff &= 0xffffffefL;  // clear - OFF
+  writel( dwBuff, (addrBase + TL_MEM_TACH_CONTROL)); // write TL Control reg
+  return 0;
+}
+
+
+
+
+
+// Use controller's "Options" field to determine loopback mode (if any)
+//   internal loopback (silicon - no GBIC)
+//   external loopback (GBIC - no FC loop)
+//   no loopback: L_PORT, external cable from GBIC required
+
+int CpqTsInitializeFrameManager( void *pChip, int opcode)
+{
+  PTACHYON fcChip;
+  int iStatus;
+  ULONG wwnLo, wwnHi; // for readback verification
+
+  ENTER("InitializeFrameManager");
+  fcChip = (PTACHYON)pChip;
+  if( !fcChip->Registers.ReMapMemBase )   // undefined controller?
+    return -1;
+
+  // TL/TS UG, pg. 184
+  // 0x0065 = 100ms for RT_TOV
+  // 0x01f5 = 500ms for ED_TOV
+  // 0x07D1 = 2000ms 
+  fcChip->Registers.ed_tov.value = 0x006507D1; 
+  writel( fcChip->Registers.ed_tov.value,
+    (fcChip->Registers.ed_tov.address));
+      
+
+  // Set LP_TOV to the FC-AL2 specified 2 secs.
+  // TL/TS UG, pg. 185
+  writel( 0x07d00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
+
+
+  // Now try to read the WWN from the adapter's NVRAM
+  iStatus = CpqTsReadWriteWWN( fcChip, 1); // '1' for READ
+
+  if( iStatus )   // NVRAM read failed?
+  {
+    printk(" WARNING! HBA NVRAM WWN read failed - make alias\n");
+    // make up a WWN.  If NULL or duplicated on loop, FC loop may hang!
+
+
+    fcChip->Registers.wwn_hi = (__u32)jiffies;
+    fcChip->Registers.wwn_hi |= 0x50000000L;
+    fcChip->Registers.wwn_lo = 0x44556677L;
+  }
+
+  
+  writel( fcChip->Registers.wwn_hi, 
+	  fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI);
+  
+  writel( fcChip->Registers.wwn_lo, 
+	  fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
+	  
+
+  // readback for verification:
+  wwnHi = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI ); 
+          
+  wwnLo = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
+  // test for correct chip register WRITE/READ
+  DEBUG_PCI( printk("  WWN %08X%08X\n",
+    fcChip->Registers.wwn_hi, fcChip->Registers.wwn_lo ) );
+    
+  if( wwnHi != fcChip->Registers.wwn_hi ||
+      wwnLo != fcChip->Registers.wwn_lo )
+  {
+    printk( "cpqfcTS: WorldWideName register load failed\n");
+    return -1; // FAILED!
+  }
+
+
+
+			// set Frame Manager Initialize command
+  fcChip->Registers.FMcontrol.value = 0x06;
+
+  // Note: for test/debug purposes, we may use "Hard" address,
+  // but we completely support "soft" addressing, including
+  // dynamically changing our address.
+  if( fcChip->Options.intLoopback == 1 )            // internal loopback
+    fcChip->Registers.FMconfig.value = 0x0f002080L;
+  else if( fcChip->Options.extLoopback == 1 )            // internal loopback
+    fcChip->Registers.FMconfig.value = 0x0f004080L;
+  else                  // L_Port
+    fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
+//    fcChip->Registers.FMconfig.value = 0x01000080L; // soft address (can't pick)
+//    fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
+		
+  // write config to FM
+
+  if( !fcChip->Options.intLoopback && !fcChip->Options.extLoopback )
+                               // (also need LASER for real LOOP)
+    fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 1); // turn on LASER
+
+  writel( fcChip->Registers.FMconfig.value,
+    fcChip->Registers.FMconfig.address);
+    
+
+			       // issue INITIALIZE command to FM - ACTION!
+  writel( fcChip->Registers.FMcontrol.value,
+    fcChip->Registers.FMcontrol.address);
+    
+  LEAVE("InitializeFrameManager");
+  
+  return 0;
+}
+
+
+
+
+
+// This "look ahead" function examines the IMQ for occurrence of
+// "type".  Returns 1 if found, 0 if not.
+static int PeekIMQEntry( PTACHYON fcChip, ULONG type)
+{
+  ULONG CI = fcChip->IMQ->consumerIndex;
+  ULONG PI = fcChip->IMQ->producerIndex; // snapshot of IMQ indexes
+  
+  while( CI != PI )
+  {                             // proceed with search
+    if( (++CI) >= IMQ_LEN ) CI = 0; // rollover check
+    
+    switch( type )
+    {
+      case ELS_LILP_FRAME:
+      {
+      // first, we need to find an Inbound Completion message,
+      // If we find it, check the incoming frame payload (1st word)
+      // for LILP frame
+        if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 )
+        { 
+          TachFCHDR_GCMND* fchs;
+#error This is too much stack
+          ULONG ulFibreFrame[2048/4];  // max DWORDS in incoming FC Frame
+	  USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL);
+
+	  CpqTsGetSFQEntry( fcChip,
+            SFQpi,        // SFQ producer ndx         
+	    ulFibreFrame, // contiguous dest. buffer
+	    FALSE);       // DON'T update chip--this is a "lookahead"
+          
+	  fchs = (TachFCHDR_GCMND*)&ulFibreFrame;
+          if( fchs->pl[0] == ELS_LILP_FRAME)
+	  {
+            return 1; // found the LILP frame!
+	  }
+	  else
+	  {
+	    // keep looking...
+	  }
+	}  
+      }
+      break;
+
+      case OUTBOUND_COMPLETION:
+        if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x00 )
+	{
+
+          // any OCM errors?
+          if( fcChip->IMQ->QEntry[CI].word[2] & 0x7a000000L )
+            return 1;   	    // found OCM error
+	}
+      break;
+
+
+      
+      default:
+      break;
+    }
+  }
+  return 0; // failed to find "type"
+}
+
+			
+static void SetTachTOV( CPQFCHBA* cpqfcHBAdata)
+{
+  PTACHYON fcChip = &cpqfcHBAdata->fcChip; 
+  
+  // TL/TS UG, pg. 184
+  // 0x0065 = 100ms for RT_TOV
+  // 0x01f5 = 500ms for ED_TOV
+  // 0x07d1 = 2000ms for ED_TOV
+
+  // SANMark Level 1 requires an "initialization backoff"
+  // (See "SANMark Test Suite Level 1":
+  // initialization_timeout.fcal.SANMark-1.fc)
+  // We have to use 2sec, 24sec, then 128sec when login/
+  // port discovery processes fail to complete.
+  
+  // when port discovery completes (logins done), we set
+  // ED_TOV to 500ms -- this is the normal operational case
+  // On the first Link Down, we'll move to 2 secs (7D1 ms)
+  if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x1f5)
+    fcChip->Registers.ed_tov.value = 0x006507D1; 
+  
+  // If we get another LST after we moved TOV to 2 sec,
+  // increase to 24 seconds (5DC1 ms) per SANMark!
+  else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x7D1)
+    fcChip->Registers.ed_tov.value = 0x00655DC1; 
+
+  // If we get still another LST, set the max TOV (Tachyon
+  // has only 16 bits for ms timer, so the max is 65.5 sec)
+  else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x5DC1)
+    fcChip->Registers.ed_tov.value = 0x0065FFFF; 
+
+  writel( fcChip->Registers.ed_tov.value,
+    (fcChip->Registers.ed_tov.address));
+  // keep the same 2sec LP_TOV 
+  writel( 0x07D00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
+}	
+
+
+// The IMQ is an array with IMQ_LEN length, each element (QEntry)
+// with eight 32-bit words.  Tachyon PRODUCES a QEntry with each
+// message it wants to send to the host.  The host CONSUMES IMQ entries
+
+// This function copies the current
+// (or oldest not-yet-processed) QEntry to
+// the caller, clears/ re-enables the interrupt, and updates the
+// (Host) Consumer Index.
+// Return value:
+//  0   message processed, none remain (producer and consumer
+//        indexes match)
+//  1   message processed, more messages remain
+// -1   no message processed - none were available to process
+// Remarks:
+//   TL/TS UG specifices that the following actions for
+//   INTA_L handling:
+//   1. read PCI Interrupt Status register (0xff)
+//   2. all IMQ messages should be processed before writing the
+//      IMQ consumer index.
+
+
+int CpqTsProcessIMQEntry(void *host)
+{
+  struct Scsi_Host *HostAdapter = (struct Scsi_Host *)host;
+  CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+  PTACHYON fcChip = &cpqfcHBAdata->fcChip; 
+  FC_EXCHANGES *Exchanges = fcChip->Exchanges;
+  int iStatus;
+  USHORT i, RPCset, DPCset;
+  ULONG x_ID;
+  ULONG ulBuff, dwStatus;
+  TachFCHDR_GCMND* fchs;
+#error This is too much stack
+  ULONG ulFibreFrame[2048/4];  // max number of DWORDS in incoming Fibre Frame
+  UCHAR ucInboundMessageType;  // Inbound CM, dword 3 "type" field
+
+  ENTER("ProcessIMQEntry");
+   
+
+				// check TachLite's IMQ producer index -
+				// is a new message waiting for us?
+				// equal indexes means empty que
+
+  if( fcChip->IMQ->producerIndex != fcChip->IMQ->consumerIndex )
+  {                             // need to process message
+
+
+#ifdef IMQ_DEBUG
+    printk("PI %X, CI %X  type: %X\n", 
+      fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex,
+      fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type);
+#endif                                
+    // Examine Completion Messages in IMQ
+    // what CM_Type?
+    switch( (UCHAR)(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type
+                    & 0xffL) )
+    {
+    case OUTBOUND_COMPLETION:
+
+      // Remarks:
+      // x_IDs (OX_ID, RX_ID) are partitioned by SEST entries
+      // (starting at 0), and SFS entries (starting at
+      // SEST_LEN -- outside the SEST space).
+      // Psuedo code:
+      // x_ID (OX_ID or RX_ID) from message is Trans_ID or SEST index
+      // range check - x_ID
+      //   if x_ID outside 'Transactions' length, error - exit
+      // if any OCM error, copy error status to Exchange slot
+      // if FCP ASSIST transaction (x_ID within SEST),
+      //   call fcComplete (to App)
+      // ...
+
+
+      ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1];
+      x_ID = ulBuff & 0x7fffL;     // lower 14 bits SEST_Index/Trans_ID
+                                     // Range check CM OX/RX_ID value...
+      if( x_ID < TACH_MAX_XID )   // don't go beyond array space
+      {
+
+
+	if( ulBuff & 0x20000000L ) // RPC -Response Phase Complete?
+          RPCset = 1;              // (SEST transactions only)
+        else
+          RPCset = 0;
+
+        if( ulBuff & 0x40000000L ) // DPC -Data Phase Complete?
+          DPCset = 1;              // (SEST transactions only)
+        else
+          DPCset = 0;
+                // set the status for this Outbound transaction's ID
+        dwStatus = 0L;
+        if( ulBuff & 0x10000000L ) // SPE? (SEST Programming Error)
+            dwStatus |= SESTPROG_ERR;
+
+        ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2];
+        if( ulBuff & 0x7a000000L ) // any other errs?
+        {
+          if( ulBuff & 0x40000000L )
+            dwStatus |= INV_ENTRY;
+          if( ulBuff & 0x20000000L )
+            dwStatus |= FRAME_TO;        // FTO
+          if( ulBuff & 0x10000000L )
+            dwStatus |= HOSTPROG_ERR;
+          if( ulBuff & 0x08000000L )
+            dwStatus |= LINKFAIL_TX;
+          if( ulBuff & 0x02000000L )
+            dwStatus |= ABORTSEQ_NOTIFY;  // ASN
+        }
+
+	  
+	if( dwStatus )          // any errors?
+        {
+                  // set the Outbound Completion status
+          Exchanges->fcExchange[ x_ID ].status |= dwStatus;
+
+          // if this Outbound frame was for a SEST entry, automatically
+          // reque it in the case of LINKFAIL (it will restart on PDISC)
+          if( x_ID < TACH_SEST_LEN )
+          {
+
+            printk(" #OCM error %Xh x_ID %X# ", 
+		    dwStatus, x_ID);
+
+	    Exchanges->fcExchange[x_ID].timeOut = 30000; // seconds default
+                                                 
+
+	    // We Q ABTS for each exchange.
+	    // NOTE: We can get FRAME_TO on bad alpa (device gone).  Since
+	    // bad alpa is reported before FRAME_TO, examine the status
+	    // flags to see if the device is removed.  If so, DON'T
+	    // post an ABTS, since it will be terminated by the bad alpa
+	    // message.
+	    if( dwStatus & FRAME_TO ) // check for device removed...
+	    {
+	      if( !(Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED) )
+	      { 
+		// presumes device is still there: send ABTS.
+  
+                cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
+	      }
+	    }
+	    else  // Abort all other errors
+	    {
+              cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
+	    }
+
+            // if the HPE bit is set, we have to CLose the LOOP
+            // (see TL/TS UG, pg. 239)
+
+            if( dwStatus &= HOSTPROG_ERR )
+            // set CL bit (see TL/TS UG, pg. 172)
+              writel( 4, fcChip->Registers.FMcontrol.address);
+          }
+        }
+          // NOTE: we don't necessarily care about ALL completion messages...
+                                      // SCSI resp. complete OR
+        if( ((x_ID < TACH_SEST_LEN) && RPCset)|| 
+             (x_ID >= TACH_SEST_LEN) )  // non-SCSI command
+        {
+              // exchange done; complete to upper levels with status
+              // (if necessary) and free the exchange slot
+            
+
+          if( x_ID >= TACH_SEST_LEN ) // Link Service Outbound frame?
+                                    // A Request or Reply has been sent
+          {                         // signal waiting WorkerThread
+
+            up( cpqfcHBAdata->TYOBcomplete);   // frame is OUT of Tach
+
+                                    // WorkerThread will complete Xchng
+          }
+          else  // X_ID is for FCP assist (SEST)
+          {
+              // TBD (target mode)
+//            fcCompleteExchange( fcChip, x_ID); // TRE completed
+          }
+        }
+      }
+      else  // ERROR CONDITION!  bogus x_ID in completion message
+      {
+
+        printk(" ProcessIMQ (OBCM) x_id out of range %Xh\n", x_ID);
+
+      }
+
+
+
+          // Load the Frame Manager's error counters.  We check them here
+          // because presumably the link is up and healthy enough for the
+          // counters to be meaningful (i.e., don't check them while loop
+          // is initializing).
+      fcChip->Registers.FMLinkStatus1.value =    // get TL's counter
+        readl(fcChip->Registers.FMLinkStatus1.address);
+                  
+      fcChip->Registers.FMLinkStatus2.value =    // get TL's counter
+        readl(fcChip->Registers.FMLinkStatus2.address);
+            
+
+      fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
+    break;
+
+
+
+    case ERROR_IDLE_COMPLETION:  // TachLite Error Idle...
+    
+    // We usually get this when the link goes down during heavy traffic.
+    // For now, presume that if SEST Exchanges are open, we will
+    // get this as our cue to INVALIDATE all SEST entries
+    // (and we OWN all the SEST entries).
+    // See TL/TS UG, pg. 53
+    
+      for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
+      {
+
+        // Does this VALid SEST entry need to be invalidated for Abort?
+        fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF; 
+      }
+      
+      CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachyon, if Link OK
+
+    break;
+
+
+    case INBOUND_SFS_COMPLETION:  //0x04
+          // NOTE! we must process this SFQ message to avoid SFQ filling
+          // up and stopping TachLite.  Incoming commands are placed here,
+          // as well as 'unknown' frames (e.g. LIP loop position data)
+          // write this CM's producer index to global...
+          // TL/TS UG, pg 234:
+          // Type: 0 - reserved
+          //       1 - Unassisted FCP
+          //       2 - BAD FCP
+          //       3 - Unkown Frame
+          //       4-F reserved
+
+
+      fcChip->SFQ->producerIndex = (USHORT)
+        (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] & 0x0fffL);
+
+
+      ucInboundMessageType = 0;  // default to useless frame
+
+        // we can only process two Types: 1, Unassisted FCP, and 3, Unknown
+        // Also, we aren't interested in processing frame fragments
+        // so don't Que anything with 'LKF' bit set
+      if( !(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] 
+        & 0x40000000) )  // 'LKF' link failure bit clear?
+      {
+        ucInboundMessageType = (UCHAR)  // ICM DWord3, "Type"
+        (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] & 0x0fL);
+      }
+      else
+      {
+	fcChip->fcStats.linkFailRX++;
+//        printk("LKF (link failure) bit set on inbound message\n");
+      }
+
+          // clears SFQ entry from Tachyon buffer; copies to contiguous ulBuff
+      CpqTsGetSFQEntry(
+        fcChip,                  // i.e. this Device Object
+        (USHORT)fcChip->SFQ->producerIndex,  // SFQ producer ndx         
+        ulFibreFrame, TRUE);    // contiguous destination buffer, update chip
+                     
+        // analyze the incoming frame outside the INT handler...
+        // (i.e., Worker)
+
+      if( ucInboundMessageType == 1 )
+      {
+        fchs = (TachFCHDR_GCMND*)ulFibreFrame; // cast to examine IB frame
+        // don't fill up our Q with garbage - only accept FCP-CMND  
+        // or XRDY frames
+        if( (fchs->d_id & 0xFF000000) == 0x06000000 ) // CMND
+        {
+	  // someone sent us a SCSI command
+	  
+//          fcPutScsiQue( cpqfcHBAdata, 
+//                        SFQ_UNASSISTED_FCP, ulFibreFrame); 
+	}
+	else if( ((fchs->d_id & 0xFF000000) == 0x07000000) || // RSP (status)
+            (fchs->d_id & 0xFF000000) == 0x05000000 )  // XRDY  
+	{
+	  ULONG x_ID;
+	  // Unfortunately, ABTS requires a Freeze on the chip so
+	  // we can modify the shared memory SEST.  When frozen,
+	  // any received Exchange frames cannot be processed by
+	  // Tachyon, so they will be dumped in here.  It is too
+	  // complex to attempt the reconstruct these frames in
+	  // the correct Exchange context, so we simply seek to
+	  // find status or transfer ready frames, and cause the
+	  // exchange to complete with errors before the timeout
+	  // expires.  We use a Linux Scsi Cmnd result code that
+	  // causes immediate retry.
+	  
+
+	  // Do we have an open exchange that matches this s_id
+	  // and ox_id?
+	  for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
+	  {
+            if( (fchs->s_id & 0xFFFFFF) == 
+                 (Exchanges->fcExchange[x_ID].fchs.d_id & 0xFFFFFF) 
+		       &&
+                (fchs->ox_rx_id & 0xFFFF0000) == 
+                 (Exchanges->fcExchange[x_ID].fchs.ox_rx_id & 0xFFFF0000) )
+	    {
+    //          printk(" #R/X frame x_ID %08X# ", fchs->ox_rx_id );
+              // simulate the anticipated error - since the
+	      // SEST was frozen, frames were lost...
+              Exchanges->fcExchange[ x_ID ].status |= SFQ_FRAME;
+              
+	      // presumes device is still there: send ABTS.
+              cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
+	      break;  // done
+	    }
+	  }
+	}
+	  
+      }
+          
+      else if( ucInboundMessageType == 3)
+      {
+        // FC Link Service frames (e.g. PLOGI, ACC) come in here.  
+        cpqfcTSPutLinkQue( cpqfcHBAdata, SFQ_UNKNOWN, ulFibreFrame); 
+                          
+      }
+
+      else if( ucInboundMessageType == 2 ) // "bad FCP"?
+      {
+#ifdef IMQ_DEBUG
+        printk("Bad FCP incoming frame discarded\n");
+#endif
+      }
+
+      else // don't know this type
+      {
+#ifdef IMQ_DEBUG 
+        printk("Incoming frame discarded, type: %Xh\n", ucInboundMessageType);
+#endif
+      }
+        
+        // Check the Frame Manager's error counters.  We check them here
+        // because presumably the link is up and healthy enough for the
+        // counters to be meaningful (i.e., don't check them while loop
+        // is initializing).
+      fcChip->Registers.FMLinkStatus1.value =    // get TL's counter
+        readl(fcChip->Registers.FMLinkStatus1.address);
+                  
+
+      fcChip->Registers.FMLinkStatus2.value =    // get TL's counter
+        readl(fcChip->Registers.FMLinkStatus2.address);
+                
+
+      break;
+
+
+
+
+                    // We get this CM because we issued a freeze
+                    // command to stop outbound frames.  We issue the
+                    // freeze command at Link Up time; when this message
+                    // is received, the ERQ base can be switched and PDISC
+                    // frames can be sent.
+
+      
+    case ERQ_FROZEN_COMPLETION:  // note: expect ERQ followed immediately
+                                 // by FCP when freezing TL
+      fcChip->Registers.TYstatus.value =         // read what's frozen
+        readl(fcChip->Registers.TYstatus.address);
+      // (do nothing; wait for FCP frozen message)
+      break;
+    case FCP_FROZEN_COMPLETION:
+      
+      fcChip->Registers.TYstatus.value =         // read what's frozen
+        readl(fcChip->Registers.TYstatus.address);
+      
+      // Signal the kernel thread to proceed with SEST modification
+      up( cpqfcHBAdata->TachFrozen);
+
+      break;
+
+
+
+    case INBOUND_C1_TIMEOUT:
+    case MFS_BUF_WARN:
+    case IMQ_BUF_WARN:
+    break;
+
+
+
+
+
+        // In older Tachyons, we 'clear' the internal 'core' interrupt state
+        // by reading the FMstatus register.  In newer TachLite (Tachyon),
+        // we must WRITE the register
+        // to clear the condition (TL/TS UG, pg 179)
+    case FRAME_MGR_INTERRUPT:
+    {
+      PFC_LOGGEDIN_PORT pLoggedInPort; 
+
+      fcChip->Registers.FMstatus.value = 
+        readl( fcChip->Registers.FMstatus.address );
+                
+      // PROBLEM: It is possible, especially with "dumb" hubs that
+      // don't automatically LIP on by-pass of ports that are going
+      // away, for the hub by-pass process to destroy critical 
+      // ordered sets of a frame.  The result of this is a hung LPSM
+      // (Loop Port State Machine), which on Tachyon results in a
+      // (default 2 sec) Loop State Timeout (LST) FM message.  We 
+      // want to avoid this relatively huge timeout by detecting
+      // likely scenarios which will result in LST.
+      // To do this, we could examine FMstatus for Loss of Synchronization
+      // and/or Elastic Store (ES) errors.  Of these, Elastic Store is better
+      // because we get this indication more quickly than the LOS.
+      // Not all ES errors are harmfull, so we don't want to LIP on every
+      // ES.  Instead, on every ES, detect whether our LPSM in in one
+      // of the LST states: ARBITRATING, OPEN, OPENED, XMITTED CLOSE,
+      // or RECEIVED CLOSE.  (See TL/TS UG, pg. 181)
+      // If any of these LPSM states are detected
+      // in combination with the LIP while LDn is not set, 
+      // send an FM init (LIP F7,F7 for loops)!
+      // It is critical to the physical link stability NOT to reset (LIP)
+      // more than absolutely necessary; this is a basic premise of the
+      // SANMark level 1 spec.
+      {
+	ULONG Lpsm = (fcChip->Registers.FMstatus.value & 0xF0) >>4;
+	
+	if( (fcChip->Registers.FMstatus.value & 0x400)  // ElasticStore?
+                      &&
+            !(fcChip->Registers.FMstatus.value & 0x100) // NOT LDn
+	              &&
+            !(fcChip->Registers.FMstatus.value & 0x1000)) // NOT LF
+	{
+	  if( (Lpsm != 0) || // not MONITORING? or
+	      !(Lpsm & 0x8) )// not already offline?
+	  {
+	  // now check the particular LST states...
+            if( (Lpsm == ARBITRATING) || (Lpsm == OPEN) ||
+	      (Lpsm == OPENED)      || (Lpsm == XMITTD_CLOSE) ||
+	      (Lpsm == RCVD_CLOSE) )
+	    {
+	      // re-init the loop before it hangs itself!
+              printk(" #req FMinit on E-S: LPSM %Xh# ",Lpsm);
+
+
+	      fcChip->fcStats.FMinits++;
+              writel( 6, fcChip->Registers.FMcontrol.address); // LIP
+	    }
+	  }
+	}
+	else if( fcChip->Registers.FMstatus.value & 0x40000 ) // LST?
+	{
+          printk(" #req FMinit on LST, LPSM %Xh# ",Lpsm);
+	 
+          fcChip->fcStats.FMinits++;
+          writel( 6, fcChip->Registers.FMcontrol.address);  // LIP
+	}  
+      }
+
+
+      // clear only the 'interrupting' type bits for this REG read
+      writel( (fcChip->Registers.FMstatus.value & 0xff3fff00L),
+        fcChip->Registers.FMstatus.address);
+                          
+
+               // copy frame manager status to unused ULONG slot
+      fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] =
+          fcChip->Registers.FMstatus.value; // (for debugging)
+
+
+          // Load the Frame Manager's error counters.  We check them here
+          // because presumably the link is up and healthy enough for the
+          // counters to be meaningful (i.e., don't check them while loop
+          // is initializing).
+      fcChip->Registers.FMLinkStatus1.value =   // get TL's counter
+        readl(fcChip->Registers.FMLinkStatus1.address);
+            
+      fcChip->Registers.FMLinkStatus2.value =   // get TL's counter
+        readl(fcChip->Registers.FMLinkStatus2.address);
+          
+          // Get FM BB_Credit Zero Reg - does not clear on READ
+      fcChip->Registers.FMBB_CreditZero.value =   // get TL's counter
+        readl(fcChip->Registers.FMBB_CreditZero.address);
+            
+
+
+      fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
+
+
+               // LINK DOWN
+
+      if( fcChip->Registers.FMstatus.value & 0x100L ) // Link DOWN bit
+      {                                 
+	
+#ifdef IMQ_DEBUG
+        printk("LinkDn\n");
+#endif
+        printk(" #LDn# ");
+        
+        fcChip->fcStats.linkDown++;
+        
+	SetTachTOV( cpqfcHBAdata);  // must set according to SANMark
+
+	// Check the ERQ - force it to be "empty" to prevent Tach
+	// from sending out frames before we do logins.
+
+
+  	if( fcChip->ERQ->producerIndex != fcChip->ERQ->consumerIndex)
+	{
+//	  printk("#ERQ PI != CI#");
+          CpqTsFreezeTachlite( fcChip, 1); // freeze ERQ only	  
+	  fcChip->ERQ->producerIndex = fcChip->ERQ->consumerIndex = 0;
+ 	  writel( fcChip->ERQ->base, 
+	    (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
+          // re-writing base forces ERQ PI to equal CI
+  
+	}
+		
+	// link down transition occurred -- port_ids can change
+        // on next LinkUp, so we must invalidate current logins
+        // (and any I/O in progress) until PDISC or PLOGI/PRLI
+        // completes
+        {
+          pLoggedInPort = &fcChip->fcPorts; 
+          while( pLoggedInPort ) // for all ports which are expecting
+                                 // PDISC after the next LIP, set the
+                                 // logoutTimer
+          {
+
+	    if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
+            {
+              pLoggedInPort->LOGO_timer = 3;  // we want 2 seconds
+                                              // but Timer granularity
+                                              // is 1 second
+            }
+                                // suspend any I/O in progress until
+                                // PDISC received...
+            pLoggedInPort->prli = FALSE;   // block FCP-SCSI commands
+	    
+            pLoggedInPort = pLoggedInPort->pNextPort;
+          }  // ... all Previously known ports checked
+        }
+        
+	// since any hot plugging device may NOT support LILP frames
+	// (such as early Tachyon chips), clear this flag indicating
+	// we shouldn't use (our copy of) a LILP map.
+	// If we receive an LILP frame, we'll set it again.
+	fcChip->Options.LILPin = 0; // our LILPmap is invalid
+        cpqfcHBAdata->PortDiscDone = 0; // must re-validate FC ports!
+
+          // also, we want to invalidate (i.e. INITIATOR_ABORT) any
+          // open Login exchanges, in case the LinkDown happened in the
+          // middle of logins.  It's possible that some ports already
+          // ACCepted login commands which we have not processed before
+          // another LinkDown occurred.  Any accepted Login exhanges are
+          // invalidated by LinkDown, even before they are acknowledged.
+          // It's also possible for a port to have a Queued Reply or Request
+          // for login which was interrupted by LinkDown; it may come later,
+          // but it will be unacceptable to us.
+
+          // we must scan the entire exchange space, find every Login type
+          // originated by us, and abort it. This is NOT an abort due to
+          // timeout, so we don't actually send abort to the other port -
+          // we just complete it to free up the fcExchange slot.
+
+        for( i=TACH_SEST_LEN; i< TACH_MAX_XID; i++)
+        {                     // looking for Extended Link Serv.Exchanges
+          if( Exchanges->fcExchange[i].type == ELS_PDISC ||
+              Exchanges->fcExchange[i].type == ELS_PLOGI ||
+              Exchanges->fcExchange[i].type == ELS_PRLI ) 
+          {
+              // ABORT the exchange!
+#ifdef IMQ_DEBUG
+            printk("Originator ABORT x_id %Xh, type %Xh, port_id %Xh on LDn\n",
+              i, Exchanges->fcExchange[i].type,
+            Exchanges->fcExchange[i].fchs.d_id);
+#endif
+
+            Exchanges->fcExchange[i].status |= INITIATOR_ABORT;
+            cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev, fcChip, i); // abort on LDn
+          }
+        }
+
+      }
+
+             // ################   LINK UP   ##################
+      if( fcChip->Registers.FMstatus.value & 0x200L ) // Link Up bit
+      {                                 // AL_PA could have changed
+
+          // We need the following code, duplicated from LinkDn condition,
+          // because it's possible for the Tachyon to re-initialize (hard
+          // reset) without ever getting a LinkDn indication.
+        pLoggedInPort = &fcChip->fcPorts; 
+        while( pLoggedInPort )   // for all ports which are expecting
+                                 // PDISC after the next LIP, set the
+                                 // logoutTimer
+        {
+          if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
+          {
+            pLoggedInPort->LOGO_timer = 3;  // we want 2 seconds
+                                              // but Timer granularity
+                                              // is 1 second
+             
+                                  // suspend any I/O in progress until
+                                  // PDISC received...
+
+          }
+          pLoggedInPort = pLoggedInPort->pNextPort;
+        }  // ... all Previously known ports checked
+ 
+          // CpqTs acquired AL_PA in register AL_PA (ACQ_ALPA)
+        fcChip->Registers.rcv_al_pa.value = 
+          readl(fcChip->Registers.rcv_al_pa.address);
+ 
+	// Now, if our acquired address is DIFFERENT from our
+        // previous one, we are not allow to do PDISC - we
+        // must go back to PLOGI, which will terminate I/O in
+        // progress for ALL logged in FC devices...
+	// (This is highly unlikely).
+
+	if( (fcChip->Registers.my_al_pa & 0xFF) != 
+	    ((fcChip->Registers.rcv_al_pa.value >> 16) &0xFF) )
+	{
+
+//	  printk(" #our HBA port_id changed!# "); // FC port_id changed!!	
+
+	  pLoggedInPort = &fcChip->fcPorts; 
+          while( pLoggedInPort ) // for all ports which are expecting
+                                 // PDISC after the next LIP, set the
+                                 // logoutTimer
+          {
+	    pLoggedInPort->pdisc  = FALSE;
+            pLoggedInPort->prli = FALSE;
+            pLoggedInPort = pLoggedInPort->pNextPort;
+          }  // ... all Previously known ports checked
+
+	  // when the port_id changes, we must terminate
+	  // all open exchanges.
+          cpqfcTSTerminateExchange( cpqfcHBAdata, NULL, PORTID_CHANGED);
+
+	}
+	               
+	// Replace the entire 24-bit port_id.  We only know the
+	// lower 8 bits (alpa) from Tachyon; if a FLOGI is done,
+	// we'll get the upper 16-bits from the FLOGI ACC frame.
+	// If someone plugs into Fabric switch, we'll do FLOGI and
+	// get full 24-bit port_id; someone could then remove and
+	// hot-plug us into a dumb hub.  If we send a 24-bit PLOGI
+	// to a "private" loop device, it might blow up.
+	// Consequently, we force the upper 16-bits of port_id to
+	// be re-set on every LinkUp transition
+        fcChip->Registers.my_al_pa =
+          (fcChip->Registers.rcv_al_pa.value >> 16) & 0xFF;
+
+              
+              // copy frame manager status to unused ULONG slot
+        fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
+          fcChip->Registers.my_al_pa; // (for debugging)
+
+              // for TachLite, we need to write the acquired al_pa
+              // back into the FMconfig register, because after
+              // first initialization, the AQ (prev. acq.) bit gets
+              // set, causing TL FM to use the AL_PA field in FMconfig.
+              // (In Tachyon, FM writes the acquired AL_PA for us.)
+        ulBuff = readl( fcChip->Registers.FMconfig.address);
+        ulBuff &= 0x00ffffffL;  // mask out current al_pa
+        ulBuff |= ( fcChip->Registers.my_al_pa << 24 ); // or in acq. al_pa
+        fcChip->Registers.FMconfig.value = ulBuff; // copy it back
+        writel( fcChip->Registers.FMconfig.value,  // put in TachLite
+          fcChip->Registers.FMconfig.address);
+            
+
+#ifdef IMQ_DEBUG
+        printk("#LUp %Xh, FMstat 0x%08X#", 
+		fcChip->Registers.my_al_pa, fcChip->Registers.FMstatus.value);
+#endif
+
+              // also set the WRITE-ONLY My_ID Register (for Fabric
+              // initialization)
+        writel( fcChip->Registers.my_al_pa,
+          fcChip->Registers.ReMapMemBase +TL_MEM_TACH_My_ID);
+          
+
+        fcChip->fcStats.linkUp++;
+
+                                     // reset TL statistics counters
+                                     // (we ignore these error counters
+                                     // while link is down)
+        ulBuff =                     // just reset TL's counter
+                 readl( fcChip->Registers.FMLinkStatus1.address);
+          
+        ulBuff =                     // just reset TL's counter
+                 readl( fcChip->Registers.FMLinkStatus2.address);
+
+          // for initiator, need to start verifying ports (e.g. PDISC)
+
+
+
+         
+      
+      
+	CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachlite, if Link OK
+	
+	// Tachyon creates an interesting problem for us on LILP frames.
+	// Instead of writing the incoming LILP frame into the SFQ before
+	// indicating LINK UP (the actual order of events), Tachyon tells
+	// us LINK UP, and later us the LILP.  So we delay, then examine the
+	// IMQ for an Inbound CM (x04); if found, we can set
+	// LINKACTIVE after processing the LILP.  Otherwise, just proceed.
+	// Since Tachyon imposes this time delay (and doesn't tell us
+	// what it is), we have to impose a delay before "Peeking" the IMQ
+	// for Tach hardware (DMA) delivery.
+	// Processing LILP is required by SANMark
+	udelay( 1000);  // microsec delay waiting for LILP (if it comes)
+        if( PeekIMQEntry( fcChip, ELS_LILP_FRAME) )
+	{  // found SFQ LILP, which will post LINKACTIVE	  
+//	  printk("skipping LINKACTIVE post\n");
+
+	}
+	else
+          cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, ulFibreFrame);  
+      }
+
+
+
+      // ******* Set Fabric Login indication ********
+      if( fcChip->Registers.FMstatus.value & 0x2000 )
+      {
+	printk(" #Fabric# ");
+        fcChip->Options.fabric = 1;
+      }
+      else
+        fcChip->Options.fabric = 0;
+
+      
+      
+                             // ******* LIP(F8,x) or BAD AL_PA? ********
+      if( fcChip->Registers.FMstatus.value & 0x30000L )
+      {
+                        // copy the error AL_PAs
+        fcChip->Registers.rcv_al_pa.value = 
+          readl(fcChip->Registers.rcv_al_pa.address);
+            
+                        // Bad AL_PA?
+        if( fcChip->Registers.FMstatus.value & 0x10000L )
+        {
+          PFC_LOGGEDIN_PORT pLoggedInPort;
+        
+                       // copy "BAD" al_pa field
+          fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
+              (fcChip->Registers.rcv_al_pa.value & 0xff00L) >> 8;
+
+	  pLoggedInPort = fcFindLoggedInPort( fcChip,
+            NULL,     // DON'T search Scsi Nexus
+            fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1], // port id
+            NULL,     // DON'T search linked list for FC WWN
+            NULL);    // DON'T care about end of list
+ 
+	  if( pLoggedInPort )
+	  {
+            // Just in case we got this BAD_ALPA because a device
+	    // quietly disappeared (can happen on non-managed hubs such 
+	    // as the Vixel Rapport 1000),
+	    // do an Implicit Logout.  We never expect this on a Logged
+	    // in port (but do expect it on port discovery).
+	    // (As a reasonable alternative, this could be changed to 
+	    // simply start the implicit logout timer, giving the device
+	    // several seconds to "come back".)
+	    // 
+	    printk(" #BAD alpa %Xh# ",
+		   fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1]);
+            cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort);
+	  }
+        }
+                        // LIP(f8,x)?
+        if( fcChip->Registers.FMstatus.value & 0x20000L )
+        {
+                        // for debugging, copy al_pa field
+          fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] =
+              (fcChip->Registers.rcv_al_pa.value & 0xffL);
+                        // get the other port's al_pa
+                        // (one that sent LIP(F8,?) )
+        }
+      }
+
+                             // Elastic store err
+      if( fcChip->Registers.FMstatus.value & 0x400L )
+      {
+            // don't count e-s if loop is down!
+        if( !(USHORT)(fcChip->Registers.FMstatus.value & 0x80) )
+          fcChip->fcStats.e_stores++;
+          
+      }
+    }
+    break;
+
+
+    case INBOUND_FCP_XCHG_COMPLETION:  // 0x0C
+
+    // Remarks:
+    // On Tachlite TL/TS, we get this message when the data phase
+    // of a SEST inbound transfer is complete.  For example, if a WRITE command
+    // was received with OX_ID 0, we might respond with XFER_RDY with
+    // RX_ID 8001.  This would start the SEST controlled data phases.  When
+    // all data frames are received, we get this inbound completion. This means
+    // we should send a status frame to complete the status phase of the 
+    // FCP-SCSI exchange, using the same OX_ID,RX_ID that we used for data
+    // frames.
+    // See Outbound CM discussion of x_IDs
+    // Psuedo Code
+    //   Get SEST index (x_ID)
+    //     x_ID out of range, return (err condition)
+    //   set status bits from 2nd dword
+    //   free transactionID & SEST entry
+    //   call fcComplete with transactionID & status
+
+      ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0];
+      x_ID = ulBuff & 0x7fffL;  // lower 14 bits SEST_Index/Trans_ID
+                                // (mask out MSB "direction" bit)
+                                // Range check CM OX/RX_ID value...
+      if( x_ID < TACH_SEST_LEN )  // don't go beyond SEST array space
+      {
+
+//#define FCP_COMPLETION_DBG 1
+#ifdef FCP_COMPLETION_DBG
+        printk(" FCP_CM x_ID %Xh, status %Xh, Cmnd %p\n", 
+          x_ID, ulBuff, Exchanges->fcExchange[x_ID].Cmnd);
+#endif
+        if( ulBuff & 0x08000000L ) // RPC -Response Phase Complete - or -
+                                   // time to send response frame?
+          RPCset = 1;             // (SEST transaction)
+        else
+          RPCset = 0;
+                // set the status for this Inbound SCSI transaction's ID
+        dwStatus = 0L;
+        if( ulBuff & 0x70000000L ) // any errs?
+        {
+          
+          if( ulBuff & 0x40000000L )
+            dwStatus |= LINKFAIL_RX;
+          
+	  if( ulBuff & 0x20000000L )
+            dwStatus |= COUNT_ERROR;
+          
+          if( ulBuff & 0x10000000L )
+            dwStatus |= OVERFLOW;
+        }
+      
+	
+	  // FCP transaction done - copy status
+        Exchanges->fcExchange[ x_ID ].status = dwStatus;
+
+
+        // Did the exchange get an FCP-RSP response frame?
+        // (Note the little endian/big endian FC payload difference)
+
+        if( RPCset )             // SEST transaction Response frame rec'd
+        {
+    	  // complete the command in our driver...
+          cpqfcTSCompleteExchange( cpqfcHBAdata->PciDev,fcChip, x_ID);
+
+        }  // end "RPCset"
+	
+        else  // ("target" logic)
+        {
+            // Tachlite says all data frames have been received - now it's time
+            // to analyze data transfer (successful?), then send a response 
+            // frame for this exchange
+
+          ulFibreFrame[0] = x_ID; // copy for later reference
+
+          // if this was a TWE, we have to send satus response
+          if( Exchanges->fcExchange[ x_ID].type == SCSI_TWE )
+	  {
+//            fcPutScsiQue( cpqfcHBAdata, 
+//                NEED_FCP_RSP, ulFibreFrame);  // (ulFibreFrame not used here)
+	  }
+        }
+      }
+      else  // ERROR CONDITION!  bogus x_ID in completion message
+      {
+        printk("IN FCP_XCHG: bad x_ID: %Xh\n", x_ID);
+      }
+
+    break;
+
+
+
+
+    case INBOUND_SCSI_DATA_COMMAND:
+    case BAD_SCSI_FRAME:
+    case INB_SCSI_STATUS_COMPLETION:
+    case BUFFER_PROCESSED_COMPLETION:
+    break;
+    }
+
+					   // Tachyon is producing;
+					   // we are consuming
+    fcChip->IMQ->consumerIndex++;             // increment OUR consumerIndex
+    if( fcChip->IMQ->consumerIndex >= IMQ_LEN)// check for rollover
+      fcChip->IMQ->consumerIndex = 0L;        // reset it
+
+
+    if( fcChip->IMQ->producerIndex == fcChip->IMQ->consumerIndex )
+    {                           // all Messages are processed -
+      iStatus = 0;              // no more messages to process
+
+    }
+    else
+      iStatus = 1;              // more messages to process
+
+    // update TachLite's ConsumerIndex... (clears INTA_L)
+    // NOTE: according to TL/TS UG, the 
+    // "host must return completion messages in sequential order".
+    // Does this mean one at a time, in the order received?  We
+    // presume so.
+
+    writel( fcChip->IMQ->consumerIndex,
+      (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
+		    
+#if IMQ_DEBUG
+    printk("Process IMQ: writing consumer ndx %d\n ", 
+      fcChip->IMQ->consumerIndex);
+    printk("PI %X, CI %X\n", 
+    fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex );
+#endif
+  
+
+
+  }
+  else
+  {
+   // hmmm... why did we get interrupted/called with no message?
+    iStatus = -1;               // nothing to process
+#if IMQ_DEBUG
+    printk("Process IMQ: no message PI %Xh  CI %Xh", 
+      fcChip->IMQ->producerIndex,
+      fcChip->IMQ->consumerIndex);
+#endif
+  }
+
+  LEAVE("ProcessIMQEntry");
+  
+  return iStatus;
+}
+
+
+
+
+
+// This routine initializes Tachyon according to the following
+// options (opcode1):
+// 1 - RESTART Tachyon, simulate power on condition by shutting
+//     down laser, resetting the hardware, de-allocating all buffers;
+//     continue
+// 2 - Config Tachyon / PCI registers;
+//     continue
+// 3 - Allocating memory and setting Tachyon queues (write Tachyon regs);
+//     continue
+// 4 - Config frame manager registers, initialize, turn on laser
+//
+// Returns:
+//  -1 on fatal error
+//   0 on success
+
+int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2)
+{
+  CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+  PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+  ULONG ulBuff;
+  UCHAR bBuff;
+  int iStatus=-1;  // assume failure
+
+  ENTER("InitializeTachLite");
+
+  // verify board's base address (sanity check)
+
+  if( !fcChip->Registers.ReMapMemBase)                // NULL address for card?
+    return -1;                         // FATAL error!
+
+
+
+  switch( opcode1 )
+  {
+    case 1:       // restore hardware to power-on (hard) restart
+
+
+      iStatus = fcChip->ResetTachyon( 
+		  cpqfcHBAdata, opcode2); // laser off, reset hardware
+				      // de-allocate aligned buffers
+
+
+/* TBD      // reset FC link Q (producer and consumer = 0)
+      fcLinkQReset(cpqfcHBAdata); 
+
+*/
+
+      if( iStatus )
+        break;
+
+    case 2:       // Config PCI/Tachyon registers
+      // NOTE: For Tach TL/TS, bit 31 must be set to 1.  For TS chips, a read
+      // of bit 31 indicates state of M66EN signal; if 1, chip may run at 
+      // 33-66MHz  (see TL/TS UG, pg 159)
+
+      ulBuff = 0x80000000;  // TachLite Configuration Register
+
+      writel( ulBuff, fcChip->Registers.TYconfig.address);
+//      ulBuff = 0x0147L;  // CpqTs PCI CFGCMD register
+//      WritePCIConfiguration( fcChip->Backplane.bus,
+//                           fcChip->Backplane.slot, TLCFGCMD, ulBuff, 4);
+//      ulBuff = 0x0L;  // test!
+//      ReadPCIConfiguration( fcChip->Backplane.bus,
+//                           fcChip->Backplane.slot, TLCFGCMD, &ulBuff, 4);
+
+      // read back for reference...
+      fcChip->Registers.TYconfig.value = 
+         readl( fcChip->Registers.TYconfig.address );
+
+      // what is the PCI bus width?
+      pci_read_config_byte( cpqfcHBAdata->PciDev,
+                                0x43, // PCIMCTR offset
+                                &bBuff);
+      
+      fcChip->Registers.PCIMCTR = bBuff;
+
+      // set string identifying the chip on the circuit board
+
+      fcChip->Registers.TYstatus.value =
+        readl( fcChip->Registers.TYstatus.address);
+      
+      {
+// Now that we are supporting multiple boards, we need to change
+// this logic to check for PCI vendor/device IDs...
+// for now, quick & dirty is simply checking Chip rev
+	
+	ULONG RevId = (fcChip->Registers.TYstatus.value &0x3E0)>>5;
+	UCHAR Minor = (UCHAR)(RevId & 0x3);
+	UCHAR Major = (UCHAR)((RevId & 0x1C) >>2);
+  
+	/* printk("  HBA Tachyon RevId %d.%d\n", Major, Minor); */
+  	if( (Major == 1) && (Minor == 2) )
+        {
+	  sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS12);
+
+	}
+	else if( (Major == 1) && (Minor == 3) )
+        {
+	  sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS13);
+	}
+	else if( (Major == 2) && (Minor == 1) )
+        {
+	  sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2_21);
+	}
+	else
+	  sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE_UNKNOWN);
+      }
+
+
+
+    case 3:       // allocate mem, set Tachyon Que registers
+      iStatus = CpqTsCreateTachLiteQues( cpqfcHBAdata, opcode2);
+
+      if( iStatus )
+        break;
+
+      // now that the Queues exist, Tach can DMA to them, so
+      // we can begin processing INTs
+      // INTEN register - enable INT (TachLite interrupt)
+      writeb( 0x1F, fcChip->Registers.ReMapMemBase + IINTEN);
+
+	// Fall through
+    case 4:       // Config Fame Manager, Init Loop Command, laser on
+
+                 // L_PORT or loopback
+                 // depending on Options
+      iStatus = CpqTsInitializeFrameManager( fcChip,0 );
+      if( iStatus )
+      {
+           // failed to initialize Frame Manager
+	      break;
+      }
+
+    default:
+      break;
+  }
+  LEAVE("InitializeTachLite");
+  
+  return iStatus;
+}
+
+
+
+
+// Depending on the type of platform memory allocation (e.g. dynamic),
+// it's probably best to free memory in opposite order as it was allocated.
+// Order of allocation: see other function
+
+
+int CpqTsDestroyTachLiteQues( void *pHBA, int opcode)
+{
+  CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+  PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+  USHORT i, iStatus=0;
+  void* vPtr;  // mem Align manager sets this to the freed address on success
+  unsigned long ulPtr;  // for 64-bit pointer cast (e.g. Alpa machine)
+  FC_EXCHANGES *Exchanges = fcChip->Exchanges;
+  PSGPAGES j, next;
+
+  ENTER("DestroyTachLiteQues");
+
+  if( fcChip->SEST )
+  {
+                // search out and free Pool for Extended S/G list pages
+
+    for( i=0; i < TACH_SEST_LEN; i++)  // for each exchange
+    {
+      // It's possible that extended S/G pages were allocated, mapped, and
+      // not cleared due to error conditions or O/S driver termination.
+      // Make sure they're all gone.
+      if (Exchanges->fcExchange[i].Cmnd != NULL) 
+      	cpqfc_pci_unmap(cpqfcHBAdata->PciDev, Exchanges->fcExchange[i].Cmnd, 
+			fcChip, i); // undo DMA mappings.
+
+      for (j=fcChip->SEST->sgPages[i] ; j != NULL ; j = next) {
+		next = j->next;
+		kfree(j);
+      }
+      fcChip->SEST->sgPages[i] = NULL;
+    }
+    ulPtr = (unsigned long)fcChip->SEST;
+    vPtr = fcMemManager( cpqfcHBAdata->PciDev, 
+		    &cpqfcHBAdata->dynamic_mem[0],
+		    0,0, (ULONG)ulPtr, NULL ); // 'free' mem
+    fcChip->SEST = 0L;  // null invalid ptr
+    if( !vPtr )
+    {
+      printk("SEST mem not freed\n");
+      iStatus = -1;
+    }
+  }
+
+  if( fcChip->SFQ )
+  {
+
+    ulPtr = (unsigned long)fcChip->SFQ;
+    vPtr = fcMemManager( cpqfcHBAdata->PciDev, 
+		    &cpqfcHBAdata->dynamic_mem[0],
+		    0,0, (ULONG)ulPtr, NULL ); // 'free' mem
+    fcChip->SFQ = 0L;  // null invalid ptr
+    if( !vPtr )
+    {
+      printk("SFQ mem not freed\n");
+      iStatus = -2;
+    }
+  }
+
+
+  if( fcChip->IMQ )
+  {
+      // clear Indexes to show empty Queue
+    fcChip->IMQ->producerIndex = 0;
+    fcChip->IMQ->consumerIndex = 0;
+
+    ulPtr = (unsigned long)fcChip->IMQ;
+    vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0],
+		    0,0, (ULONG)ulPtr, NULL ); // 'free' mem
+    fcChip->IMQ = 0L;  // null invalid ptr
+    if( !vPtr )
+    {
+      printk("IMQ mem not freed\n");
+      iStatus = -3;
+    }
+  }
+
+  if( fcChip->ERQ )         // release memory blocks used by the queues
+  {
+    ulPtr = (unsigned long)fcChip->ERQ;
+    vPtr = fcMemManager( cpqfcHBAdata->PciDev, &cpqfcHBAdata->dynamic_mem[0],
+		    0,0, (ULONG)ulPtr, NULL ); // 'free' mem
+    fcChip->ERQ = 0L;  // null invalid ptr
+    if( !vPtr )
+    {
+      printk("ERQ mem not freed\n");
+      iStatus = -4;
+    }
+  }
+    
+  // free up the primary EXCHANGES struct and Link Q
+  cpqfc_free_dma_consistent(cpqfcHBAdata);
+  
+  LEAVE("DestroyTachLiteQues");
+  
+  return iStatus;     // non-zero (failed) if any memory not freed
+}
+
+
+
+
+
+// The SFQ is an array with SFQ_LEN length, each element (QEntry)
+// with eight 32-bit words.  TachLite places incoming FC frames (i.e.
+// a valid FC frame with our AL_PA ) in contiguous SFQ entries
+// and sends a completion message telling the host where the frame is
+// in the que.
+// This function copies the current (or oldest not-yet-processed) QEntry to
+// a caller's contiguous buffer and updates the Tachyon chip's consumer index
+//
+// NOTE:
+//   An FC frame may consume one or many SFQ entries.  We know the total
+//   length from the completion message.  The caller passes a buffer large
+//   enough for the complete message (max 2k).
+
+static void CpqTsGetSFQEntry(
+         PTACHYON fcChip,
+         USHORT producerNdx,
+         ULONG *ulDestPtr,            // contiguous destination buffer
+	 BOOLEAN UpdateChip)
+{
+  ULONG total_bytes=0;
+  ULONG consumerIndex = fcChip->SFQ->consumerIndex;
+  
+				// check passed copy of SFQ producer index -
+				// is a new message waiting for us?
+				// equal indexes means SFS is copied
+
+  while( producerNdx != consumerIndex )
+  {                             // need to process message
+    total_bytes += 64;   // maintain count to prevent writing past buffer
+                   // don't allow copies over Fibre Channel defined length!
+    if( total_bytes <= 2048 )
+    {
+      memcpy( ulDestPtr, 
+              &fcChip->SFQ->QEntry[consumerIndex],
+              64 );  // each SFQ entry is 64 bytes
+      ulDestPtr += 16;   // advance pointer to next 64 byte block
+    }
+		         // Tachyon is producing,
+                         // and we are consuming
+
+    if( ++consumerIndex >= SFQ_LEN)// check for rollover
+      consumerIndex = 0L;        // reset it
+  }
+
+  // if specified, update the Tachlite chip ConsumerIndex...
+  if( UpdateChip )
+  {
+    fcChip->SFQ->consumerIndex = consumerIndex;
+    writel( fcChip->SFQ->consumerIndex,
+      fcChip->Registers.SFQconsumerIndex.address);
+  }
+}
+
+
+
+// TachLite routinely freezes it's core ques - Outbound FIFO, Inbound FIFO,
+// and Exchange Request Queue (ERQ) on error recover - 
+// (e.g. whenever a LIP occurs).  Here
+// we routinely RESUME by clearing these bits, but only if the loop is up
+// to avoid ERROR IDLE messages forever.
+
+void CpqTsUnFreezeTachlite( void *pChip, int type )
+{
+  PTACHYON fcChip = (PTACHYON)pChip;
+  fcChip->Registers.TYcontrol.value = 
+    readl(fcChip->Registers.TYcontrol.address);
+            
+  // (bit 4 of value is GBIC LASER)
+  // if we 'unfreeze' the core machines before the loop is healthy
+  // (i.e. FLT, OS, LS failure bits set in FMstatus)
+  // we can get 'error idle' messages forever.  Verify that
+  // FMstatus (Link Status) is OK before unfreezing.
+
+  if( !(fcChip->Registers.FMstatus.value & 0x07000000L) && // bits clear?
+      !(fcChip->Registers.FMstatus.value & 0x80  ))  // Active LPSM?
+  {
+    fcChip->Registers.TYcontrol.value &=  ~0x300L; // clear FEQ, FFA
+    if( type == 1 )  // unfreeze ERQ only
+    {
+//      printk("Unfreezing ERQ\n");
+      fcChip->Registers.TYcontrol.value |= 0x10000L; // set REQ
+    }
+    else             // unfreeze both ERQ and FCP-ASSIST (SEST)
+    {
+//      printk("Unfreezing ERQ & FCP-ASSIST\n");
+
+                     // set ROF, RIF, REQ - resume Outbound FCP, Inbnd FCP, ERQ
+      fcChip->Registers.TYcontrol.value |= 0x70000L; // set ROF, RIF, REQ
+    }
+
+    writel( fcChip->Registers.TYcontrol.value,
+      fcChip->Registers.TYcontrol.address);
+              
+  }
+          // readback for verify (TachLite still frozen?)
+  fcChip->Registers.TYstatus.value = 
+    readl(fcChip->Registers.TYstatus.address);
+}
+
+
+// Whenever an FC Exchange Abort is required, we must manipulate the
+// Host/Tachyon shared memory SEST table.  Before doing this, we
+// must freeze Tachyon, which flushes certain buffers and ensure we
+// can manipulate the SEST without contention.
+// This freeze function will result in FCP & ERQ FROZEN completion
+// messages (per argument "type").
+
+void CpqTsFreezeTachlite( void *pChip, int type )
+{
+  PTACHYON fcChip = (PTACHYON)pChip;
+  fcChip->Registers.TYcontrol.value = 
+    readl(fcChip->Registers.TYcontrol.address);
+    
+                     //set FFA, FEQ - freezes SCSI assist and ERQ
+  if( type == 1)    // freeze ERQ only
+    fcChip->Registers.TYcontrol.value |= 0x100L; // (bit 4 is laser)
+  else              // freeze both FCP assists (SEST) and ERQ
+    fcChip->Registers.TYcontrol.value |= 0x300L; // (bit 4 is laser)
+  
+  writel( fcChip->Registers.TYcontrol.value,
+    fcChip->Registers.TYcontrol.address);
+              
+}
+
+
+
+
+// TL has two Frame Manager Link Status Registers, with three 8-bit
+// fields each. These eight bit counters are cleared after each read,
+// so we define six 32-bit accumulators for these TL counters. This
+// function breaks out each 8-bit field and adds the value to the existing
+// sum.  (s/w counters cleared independently)
+
+void fcParseLinkStatusCounters(PTACHYON fcChip)
+{
+  UCHAR bBuff;
+  ULONG ulBuff;
+
+
+// The BB0 timer usually increments when TL is initialized, resulting
+// in an initially bogus count.  If our own counter is ZERO, it means we
+// are reading this thing for the first time, so we ignore the first count.
+// Also, reading the register does not clear it, so we have to keep an
+// additional static counter to detect rollover (yuk).
+
+  if( fcChip->fcStats.lastBB0timer == 0L)  // TL was reset? (ignore 1st values)
+  {
+                           // get TL's register counter - the "last" count
+    fcChip->fcStats.lastBB0timer = 
+      fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
+  }
+  else  // subsequent pass - check for rollover
+  {
+                              // "this" count
+    ulBuff = fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
+    if( fcChip->fcStats.lastBB0timer > ulBuff ) // rollover happened
+    {
+                                // counter advanced to max...
+      fcChip->fcStats.BB0_Timer += (0x00FFFFFFL - fcChip->fcStats.lastBB0timer);
+      fcChip->fcStats.BB0_Timer += ulBuff;  // plus some more
+
+
+    }
+    else // no rollover -- more counts or no change
+    {
+      fcChip->fcStats.BB0_Timer +=  (ulBuff - fcChip->fcStats.lastBB0timer);
+
+    }
+
+    fcChip->fcStats.lastBB0timer = ulBuff;
+  }
+
+
+
+  bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 24);
+  fcChip->fcStats.LossofSignal += bBuff;
+
+  bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 16);
+  fcChip->fcStats.BadRXChar += bBuff;
+
+  bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 8);
+  fcChip->fcStats.LossofSync += bBuff;
+
+
+  bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 24);
+  fcChip->fcStats.Rx_EOFa += bBuff;
+
+  bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 16);
+  fcChip->fcStats.Dis_Frm += bBuff;
+
+  bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 8);
+  fcChip->fcStats.Bad_CRC += bBuff;
+}
+
+
+void cpqfcTSClearLinkStatusCounters(PTACHYON fcChip)
+{
+  ENTER("ClearLinkStatusCounters");
+  memset( &fcChip->fcStats, 0, sizeof( FCSTATS));
+  LEAVE("ClearLinkStatusCounters");
+
+}
+
+
+
+
+// The following function reads the I2C hardware to get the adapter's
+// World Wide Name (WWN).
+// If the WWN is "500805f1fadb43e8" (as printed on the card), the
+// Tachyon WWN_hi (32-bit) register is 500805f1, and WWN_lo register
+// is fadb43e8.
+// In the NVRAM, the bytes appear as:
+// [2d] ..
+// [2e] .. 
+// [2f] 50
+// [30] 08
+// [31] 05
+// [32] f1
+// [33] fa
+// [34] db
+// [35] 43
+// [36] e8
+//
+// In the Fibre Channel (Big Endian) format, the FC-AL LISM frame will
+// be correctly loaded by Tachyon silicon.  In the login payload, bytes
+// must be correctly swapped for Big Endian format.
+
+int CpqTsReadWriteWWN( PVOID pChip, int Read)
+{
+  PTACHYON fcChip = (PTACHYON)pChip;
+#define NVRAM_SIZE 512
+  unsigned short i, count = NVRAM_SIZE;
+  UCHAR nvRam[NVRAM_SIZE], WWNbuf[8];
+  ULONG ulBuff;
+  int iStatus=-1;  // assume failure
+  int WWNoffset;
+
+  ENTER("ReadWriteWWN");
+  // Now try to read the WWN from the adapter's NVRAM
+
+  if( Read )  // READing NVRAM WWN?
+  {
+    ulBuff = cpqfcTS_ReadNVRAM( fcChip->Registers.TYstatus.address,
+                              fcChip->Registers.TYcontrol.address,
+                              count, &nvRam[0] );
+
+    if( ulBuff )   // NVRAM read successful?
+    {
+      iStatus = 0; // success!
+      
+                   // for engineering/ prototype boards, the data may be
+                   // invalid (GIGO, usually all "FF"); this prevents the
+                   // parse routine from working correctly, which means
+                   // nothing will be written to our passed buffer.
+
+      WWNoffset = cpqfcTS_GetNVRAM_data( WWNbuf, nvRam );
+
+      if( !WWNoffset ) // uninitialized NVRAM -- copy bytes directly
+      {
+        printk( "CAUTION: Copying NVRAM data on fcChip\n");
+        for( i= 0; i < 8; i++)
+          WWNbuf[i] = nvRam[i +0x2f]; // dangerous! some formats won't work
+      }
+      
+      fcChip->Registers.wwn_hi = 0L;
+      fcChip->Registers.wwn_lo = 0L;
+      for( i=0; i<4; i++)  // WWN bytes are big endian in NVRAM
+      {
+        ulBuff = 0L;
+        ulBuff = (ULONG)(WWNbuf[i]) << (8 * (3-i));
+        fcChip->Registers.wwn_hi |= ulBuff;
+      }
+      for( i=0; i<4; i++)  // WWN bytes are big endian in NVRAM
+      {
+        ulBuff = 0L;
+        ulBuff = (ULONG)(WWNbuf[i+4]) << (8 * (3-i));
+        fcChip->Registers.wwn_lo |= ulBuff;
+      }
+    }  // done reading
+    else
+    {
+
+      printk( "cpqfcTS: NVRAM read failed\n");
+
+    }
+  }
+
+  else  // WRITE
+  {
+
+    // NOTE: WRITE not supported & not used in released driver.
+
+   
+    printk("ReadWriteNRAM: can't write NVRAM; aborting write\n");
+  }
+  
+  LEAVE("ReadWriteWWN");
+  return iStatus;
+}
+
+
+
+
+
+// The following function reads or writes the entire "NVRAM" contents of 
+// the I2C hardware (i.e. the NM24C03).  Note that HP's 5121A (TS 66Mhz)
+// adapter does not use the NM24C03 chip, so this function only works on
+// Compaq's adapters.
+
+int CpqTsReadWriteNVRAM( PVOID pChip, PVOID buf, int Read)
+{
+  PTACHYON fcChip = (PTACHYON)pChip;
+#define NVRAM_SIZE 512
+  ULONG ulBuff;
+  UCHAR *ucPtr = buf; // cast caller's void ptr to UCHAR array
+  int iStatus=-1;  // assume failure
+
+     
+  if( Read )  // READing NVRAM?
+  {
+    ulBuff = cpqfcTS_ReadNVRAM(   // TRUE on success
+                fcChip->Registers.TYstatus.address,
+                fcChip->Registers.TYcontrol.address,
+                256,            // bytes to write
+                ucPtr );        // source ptr
+
+
+    if( ulBuff )
+      iStatus = 0; // success
+    else
+    {
+#ifdef DBG
+      printk( "CAUTION: NVRAM read failed\n");
+#endif
+    }
+  }  // done reading
+
+  else  // WRITING NVRAM 
+  {
+
+    printk("cpqfcTS: WRITE of FC Controller's NVRAM disabled\n");
+  }
+    
+  return iStatus;
+}
