[parisc-linux-cvs] linux grundler
Grant Grundler
grundler@dsl2.external.hp.com
Mon, 19 Aug 2002 23:55:21 -0600
Grant Grundler wrote:
> Log message:
> 2.4.19-pa4 cpqfc fixes
> loads as module now on parisc, still doesn't see NVRAM or GBIC.
Still needs more work. Does fix bugs like missing pci_enable_device().
I think the "NVRAM Read Failed" is the next problem that needs to be solved.
Likely a posted PCI write issue. Console output is before the diff below.
I'm committing this intermediate version for the usual reasons:
o the system no longer crashes (HPMC) when loading the module
o remaining problems are most likely posted PCI write problems
o enabled someone else can work on them.
Anyone interested in working on the a500 + Agilent XL2 should
contact me off list. I'll poke at this off/on again but
not as much as I'd like.
grant
a500:/usr/src/linux# modprobe cpqfc
scsi_register allocating 6656 bytes for FC HBA
HBA found!
HostAdapter->PciDev->irq = 256
PciDev->baseaddress[0]= 0
PciDev->baseaddress[1]= 20000
PciDev->baseaddress[2]= 20100
PciDev->baseaddress[3]= fffffffffa040000
cpqfcHBAdata->fcChip.Registers. :
IOBaseL = 20000
IOBaseU = 20100
ioremap'd Membase: fffffffffa040000
SFQconsumerIndex.address = fffffffffa040058
ERQproducerIndex.address = fffffffffa040008
TYconfig.address = fffffffffa040184
FMconfig.address = fffffffffa0401c0
FMcontrol.address = fffffffffa0401c4
Requesting 255 I/O addresses @ 20000
Requesting 255 I/O addresses @ 20100
starting TimerTask
InitializeTachyon
ResetTachyon
HBA Tachyon RevId 2.2
Allocating 129024 for 576 Exchanges @ 0000000058fc0000
Allocating 112904 for LinkQ @ 0000000075160000 (576 elements)
Allocating 106504 for TachSEST for 512 Exchanges
cpqfcTS: writing IMQ BASE E960000h PI E964000h
cpqfcTS: SEST 00000000595a0000(virt): Wrote base E980000h @ fffffffffa040140
cpqfcTS: NVRAM read failed
WARNING! HBA NVRAM WWN read failed - make alias
WWN 57681D3D44556677
Waiting for broken Brocade switch...
scsi4 : Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.2: WWN 57681D3D44556677
on PCI bus 32 device 0x1029 irq 256 IObaseL 0x20000, MEMBASE 0xfa040000
PCI bus width 64 bits, bus speed 66 MHz
FCP-SCSI Driver v2.1.1
GBIC detected: NONE! LPSM 0h Monitor
a500:/usr/src/linux#
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 20 Aug 2002 05:22: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 20 Aug 2002 05:22: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 20 Aug 2002 05:22: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,41 +395,37 @@ 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);
-
-
- // start our TimerTask...
-
- cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer;
-
- init_timer( cpqfcTStimer); // Linux clears next/prev values
- cpqfcTStimer->expires = jiffies + HZ; // one second
- cpqfcTStimer->data = (unsigned long)cpqfcHBAdata; // this adapter
- cpqfcTStimer->function = cpqfcTSheartbeat; // handles timeouts, housekeeping
-
- add_timer( cpqfcTStimer); // give it to Linux
-
-
- // now initialize our hardware...
- if (cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1)) {
- printk(KERN_WARNING "cpqfc: initialization of HBA hardware failed.\n");
- // FIXME: might want to do something better than nothing here.
- }
+ // 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);
+
+ launch_FCworker_thread(HostAdapter);
+
+ cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer;
+
+ init_timer( cpqfcTStimer); /* Linux clears next/prev values */
+ cpqfcTStimer->expires = jiffies + HZ; /* one second */
+ cpqfcTStimer->data = (unsigned long)cpqfcHBAdata;
+ cpqfcTStimer->function = cpqfcTSheartbeat;
+
+ add_timer( cpqfcTStimer); /* start timer */
+
+ /* now initialize our hardware... */
+ if (cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1)) {
+ printk(KERN_WARNING "cpqfc: initialization of HBA hardware failed.\n");
+ BUG();
+ }
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:
@@ -1126,24 +1122,23 @@ Original code from M. McGowen, Compaq
void cpqfcTS_print_scsi_cmd(Scsi_Cmnd * cmd)
{
-printk("cpqfcTS: (%s) chnl 0x%02x, trgt = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
- ScsiToAscii( cmd->cmnd[0]), cmd->channel, cmd->target, cmd->lun, cmd->cmd_len);
-
-if( cmd->cmnd[0] == 0) // Test Unit Ready?
-{
- int i;
-
- printk("Cmnd->request_bufflen = 0x%X, ->use_sg = %d, ->bufflen = %d\n",
- cmd->request_bufflen, cmd->use_sg, cmd->bufflen);
- printk("Cmnd->request_buffer = %p, ->sglist_len = %d, ->buffer = %p\n",
- cmd->request_buffer, cmd->sglist_len, cmd->buffer);
- for (i = 0; i < cmd->cmd_len; i++)
- printk("0x%02x ", cmd->cmnd[i]);
- printk("\n");
-}
-
+ printk("cpqfcTS: (%s) chnl 0x%02x, trgt = 0x%02x,"
+ " lun = 0x%02x, cmd_len = 0x%02x\n",
+ ScsiToAscii( cmd->cmnd[0]), cmd->channel,
+ cmd->target, cmd->lun, cmd->cmd_len);
+
+ if( cmd->cmnd[0] == TEST_UNIT_READY) {
+ int i;
+
+ printk("Cmnd request_bufflen 0x%X, use_sg %d, bufflen %d\n",
+ cmd->request_bufflen, cmd->use_sg, cmd->bufflen);
+ printk("Cmnd->request_buffer 0x%p, sglist_len %d, buffer %p\n",
+ cmd->request_buffer, cmd->sglist_len, cmd->buffer);
+ for (i = 0; i < cmd->cmd_len; i++)
+ printk("0x%02x ", cmd->cmnd[i]);
+ printk("\n");
+ }
}
-
#endif /* DEBUG_CMND */
Index: drivers/scsi/cpqfcTSstructs.h
===================================================================
RCS file: /var/cvs/linux/drivers/scsi/cpqfcTSstructs.h,v
retrieving revision 1.5
diff -u -p -r1.5 cpqfcTSstructs.h
--- drivers/scsi/cpqfcTSstructs.h 4 Aug 2002 22:58:50 -0000 1.5
+++ drivers/scsi/cpqfcTSstructs.h 20 Aug 2002 05:22: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 20 Aug 2002 05:22: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;
}