Index: drivers/scsi/cpqfcTScontrol.c
===================================================================
RCS file: /var/cvs/linux/drivers/scsi/cpqfcTScontrol.c,v
retrieving revision 1.4
diff -u -p -r1.4 cpqfcTScontrol.c
--- drivers/scsi/cpqfcTScontrol.c	9 Nov 2001 23:36:21 -0000	1.4
+++ drivers/scsi/cpqfcTScontrol.c	3 Aug 2002 08:04:32 -0000
@@ -383,14 +383,11 @@ int CpqTsResetTachLite(void *pHBA, int t
       {
         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 );
         }
       }
@@ -406,7 +403,9 @@ int CpqTsResetTachLite(void *pHBA, int t
                               // However, CPQ 64-bit HBAs have a "health
                               // circuit" which keeps laser ON for a brief
                               // period after it is turned off ( < 1s)
-      
+
+      readb( fcChip->Registers.ReMapMemBase + IINTEN); /* flush posted write */
+
       fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 0);
   
 
@@ -424,9 +423,10 @@ int CpqTsResetTachLite(void *pHBA, int t
         ulBuff = readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST);
 
         // clear the soft reset
-      for( i=0; i<8; i++)
+      for( i=0; i<8; i++) {
   	writel( 0, (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
-
+        (void) readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST);
+	}
                
 
 			       // clear out our copy of Tach regs,
@@ -457,22 +457,19 @@ int CpqTsResetTachLite(void *pHBA, int t
 
 
 
-
-
-
-// 'addrBase' is IOBaseU for both TachLite and (older) Tachyon
 int CpqTsLaserControl( void* addrBase, int opcode )
 {
-  ULONG dwBuff;
+	u32 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;
+	dwBuff = readl(addrBase + TL_MEM_TACH_CONTROL);
+
+	dwBuff &= ~0x10;	/* assume Laser OFF - clear */
+	if( opcode == 1)
+		dwBuff |= 0x10; /* nope - really want it ON - set */
+
+	writel( dwBuff, (addrBase + TL_MEM_TACH_CONTROL));
+	readl((addrBase + TL_MEM_TACH_CONTROL) ); /* flush posted PCI write */
+	return 0;
 }
 
 
@@ -1669,17 +1666,12 @@ int CpqTsInitializeTachLite( void *pHBA,
   {
     case 1:       // restore hardware to power-on (hard) restart
 
+	DEBUG_PCI(printk(" ResetTachyon\n"));
 
       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;
 
@@ -1690,17 +1682,11 @@ int CpqTsInitializeTachLite( void *pHBA,
 
       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 );
+	writel( ulBuff, fcChip->Registers.TYconfig.address);
+
+	// 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,
@@ -1735,7 +1721,11 @@ int CpqTsInitializeTachLite( void *pHBA,
 	}
 	else if( (Major == 2) && (Minor == 1) )
         {
-	  sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2_21);
+	  sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2 "/2.1");
+	}
+	else if( (Major == 2) && (Minor == 2) )
+        {
+	  sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2 "/2.2");
 	}
 	else
 	  sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE_UNKNOWN);
Index: drivers/scsi/cpqfcTSi2c.c
===================================================================
RCS file: /var/cvs/linux/drivers/scsi/cpqfcTSi2c.c,v
retrieving revision 1.1
diff -u -p -r1.1 cpqfcTSi2c.c
--- drivers/scsi/cpqfcTSi2c.c	9 Nov 2000 18:56:48 -0000	1.1
+++ drivers/scsi/cpqfcTSi2c.c	3 Aug 2002 08:04:32 -0000
@@ -136,6 +136,7 @@ static void tl_write_i2c_reg( void* gpio
 
 	// Now or in the new data and send it back out
   writel( temp | value, gpioregOUT);
+  readl( gpioregOUT );	/* flush posted PCI write */
 }
 //-----------------------------------------------------------------------------
 //
@@ -327,6 +328,7 @@ static void tl_set_clock(void* gpioreg)
   ret_val = readl( gpioreg );
   ret_val &= 0xffffffFBL;  // clear GPIO2 (SCL)
   writel( ret_val, gpioreg);
+  readl(gpioreg);	/* flush posted PCI write */
 }
 
 static void tl_clr_clock(void* gpioreg)
@@ -336,6 +338,7 @@ static void tl_clr_clock(void* gpioreg)
   ret_val = readl( gpioreg );
   ret_val |= SET_CLOCK_LO;
   writel( ret_val, gpioreg);
+  readl( gpioreg ); /* flush posted PCI write */
 }
 
 //*****************************************************************
@@ -366,6 +369,7 @@ static void tl_i2c_clock_pulse( UCHAR va
   ret_val |= value;           // the data
   ret_val |= SET_CLOCK_LO;    // the clock
   writel( ret_val, GPIOout );
+  readl( GPIOout );	/* flush posted PCI write */
 
   i2c_delay(0);
 
@@ -463,30 +467,19 @@ int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf
 
 
 
-// define a short 5 micro sec delay, and longer (ms) delay
 
-static void i2c_delay(ULONG mstime)
-{
-  ULONG i;
-  
-// NOTE: we only expect to use these delays when reading
+// We only expect to use these delays when reading
 // our adapter's NVRAM, which happens only during adapter reset.
 // Delay technique from "Linux Device Drivers", A. Rubini 
 // (1st Ed.) pg 137.
 
+static void i2c_delay(ULONG mstime)
+{
 //  printk(" delay %lx  ", mstime);
-  if( mstime ) // ms delay?
-  {
-    // delay technique
-    for( i=0; i < mstime; i++)
-      udelay(1000); // 1ms per loop
-	
-  }
-  else  // 5 micro sec delay
-  
-    udelay( 5 ); // micro secs
-  
-//  printk("done\n");
+	if( mstime ) {
+		mdelay(mstime);
+	} else
+		udelay(5);
 }
 
 
Index: drivers/scsi/cpqfcTSinit.c
===================================================================
RCS file: /var/cvs/linux/drivers/scsi/cpqfcTSinit.c,v
retrieving revision 1.7
diff -u -p -r1.7 cpqfcTSinit.c
--- drivers/scsi/cpqfcTSinit.c	9 Nov 2001 23:36:21 -0000	1.7
+++ drivers/scsi/cpqfcTSinit.c	3 Aug 2002 08:04:32 -0000
@@ -137,7 +137,7 @@ static void Cpqfc_initHBAdata( CPQFCHBA 
   
   cpqfcHBAdata->fcChip.Registers.SROMBase =  // NULL for HP TS adapter
     PciDev->resource[5].start;
-  
+
   // now the Tachlite chip registers
   // the REGISTER struct holds both the physical address & last
   // written value (some TL registers are WRITE ONLY)
@@ -395,23 +395,20 @@ int cpqfcTS_detect(Scsi_Host_Template *S
 	continue;
       }	
       
-      // OK, we should be able to grab everything we need now.
-      request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff, DEV_NAME);
-      request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff, DEV_NAME);
-      DEBUG_PCI(printk("  Requesting 255 I/O addresses @ %x\n",
-        cpqfcHBAdata->fcChip.Registers.IOBaseL ));
-      DEBUG_PCI(printk("  Requesting 255 I/O addresses @ %x\n",
-        cpqfcHBAdata->fcChip.Registers.IOBaseU ));
-
-      
-      // start our kernel worker thread
-
-      launch_FCworker_thread(HostAdapter);
-
+	// OK, we should be able to grab everything we need now.
+	DEBUG_PCI(printk("  Requesting 255 I/O addresses @ %x\n",
+				cpqfcHBAdata->fcChip.Registers.IOBaseL ));
+	request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff, DEV_NAME);
+
+	DEBUG_PCI(printk("  Requesting 255 I/O addresses @ %x\n",
+				cpqfcHBAdata->fcChip.Registers.IOBaseU ));
+	request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff, DEV_NAME);
+	pci_enable_device(PciDev);
 
-      // start our TimerTask...
+	launch_FCworker_thread(HostAdapter);
 
-      cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer;
+printk("  starting TimerTask\n");
+	cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer;
 
       init_timer( cpqfcTStimer); // Linux clears next/prev values
       cpqfcTStimer->expires = jiffies + HZ; // one second
@@ -421,6 +418,7 @@ int cpqfcTS_detect(Scsi_Host_Template *S
       add_timer( cpqfcTStimer);  // give it to Linux
 
 
+printk("  InitializeTachyon\n");
       // now initialize our hardware...
       if (cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1)) {
 	printk(KERN_WARNING "cpqfc: initialization of HBA hardware failed.\n");
@@ -430,6 +428,7 @@ int cpqfcTS_detect(Scsi_Host_Template *S
       cpqfcHBAdata->fcStatsTime = jiffies;  // (for FC Statistics delta)
       
       // give our HBA time to initialize and login current devices...
+	DEBUG_PCI(printk("  Waiting for broken Brocade switch...\n"));
       {
 	// The Brocade switch (e.g. 2400, 2010, etc.) as of March 2000,
 	// has the following algorithm for FL_Port startup:
Index: drivers/scsi/cpqfcTSstructs.h
===================================================================
RCS file: /var/cvs/linux/drivers/scsi/cpqfcTSstructs.h,v
retrieving revision 1.4
diff -u -p -r1.4 cpqfcTSstructs.h
--- drivers/scsi/cpqfcTSstructs.h	9 Nov 2001 23:36:21 -0000	1.4
+++ drivers/scsi/cpqfcTSstructs.h	3 Aug 2002 08:04:32 -0000
@@ -63,7 +63,7 @@
 #define DEBUG(x)
 #endif				/* DEBUG_CPQFCTS */
 
-//#define DEBUG_CPQFCTS_PCI 1
+#define DEBUG_CPQFCTS_PCI 1
 //#undef DEBUG_CPQFCTS_PCI
 #if DEBUG_CPQFCTS_PCI
 #define DEBUG_PCI(x)	x
@@ -74,7 +74,7 @@
 #define STACHLITE66_TS12  "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2"
 #define STACHLITE66_TS13  "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.3"
 #define STACHLITE_UNKNOWN "Compaq FibreChannel HBA Tachyon Chip/Board Ver??"
-#define SAGILENT_XL2_21   "Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.1"
+#define SAGILENT_XL2      "Agilent FC HBA, Tachyon XL2 HPFC-5200B"
 
 // PDA is Peripheral Device Address, VSA is Volume Set Addressing
 // Linux SCSI parameters
@@ -416,7 +416,7 @@ typedef struct           // TachLite pla
 } TachLiteERQ;
 
 // for now, just 32 bit DMA, eventually 40something, with code changes
-#define CPQFCTS_DMA_MASK ((unsigned long) (0x00000000FFFFFFFF))
+#define CPQFCTS_DMA_MASK 0xFFFFFFFFUL
 
 #define TL_MAX_SG_ELEM_LEN 0x7ffff  // Max buffer length a single S/G entry
 				// may represent (a hardware limitation).  The
Index: drivers/scsi/cpqfcTSworker.c
===================================================================
RCS file: /var/cvs/linux/drivers/scsi/cpqfcTSworker.c,v
retrieving revision 1.5
diff -u -p -r1.5 cpqfcTSworker.c
--- drivers/scsi/cpqfcTSworker.c	9 Nov 2001 23:36:21 -0000	1.5
+++ drivers/scsi/cpqfcTSworker.c	3 Aug 2002 08:04:32 -0000
@@ -5111,13 +5111,6 @@ cpqfc_pci_map_sg_page(
 				*maplen, PCI_DMA_TODEVICE);
 	*hw_paddr = (ULONG) *umap_paddr;
 
-#       if BITS_PER_LONG > 32
-       		if( *umap_paddr >>32 ) {
-       	  		printk("cqpfcTS:Tach SG DMA addr %p>32 bits\n", 
-	  			(void*)umap_paddr);
-       			return 0;
-       		}
-#       endif
 	return *umap_paddr;
 }
 
