patch-2.2.4 linux/drivers/scsi/pci2000.c
Next file: linux/drivers/scsi/pci2000.h
Previous file: linux/drivers/scsi/fcal.h
Back to the patch index
Back to the overall index
- Lines: 245
- Date:
Mon Mar 22 13:05:53 1999
- Orig file:
v2.2.3/linux/drivers/scsi/pci2000.c
- Orig date:
Wed Sep 9 14:51:08 1998
diff -u --recursive --new-file v2.2.3/linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c
@@ -1,7 +1,7 @@
/*+M*************************************************************************
* Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
*
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
*
* 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
@@ -20,13 +20,24 @@
*
* File Name: pci2000i.c
*
+ * Revisions 1.10 Jan-21-1999
+ * - Fixed sign on message to reflect proper controller name.
+ * - Added support for RAID status monitoring and control.
+ *
+ * Revisions 1.11 Mar-22-1999
+ * - Fixed control timeout to not lock up the entire system if
+ * controller goes offline completely.
+ *
*-M*************************************************************************/
+#define PCI2000_VERSION "1.11"
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/head.h>
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/bios32.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
@@ -34,7 +45,6 @@
#include <linux/proc_fs.h>
#include <asm/dma.h>
#include <asm/system.h>
-#include <asm/spinlock.h>
#include <asm/io.h>
#include <linux/blk.h>
#include "scsi.h"
@@ -89,7 +99,6 @@
static struct Scsi_Host *PsiHost[MAXADAPTER] = {NULL,}; // One for each adapter
static int NumAdapters = 0;
-
/****************************************************************
* Name: WaitReady :LOCAL
*
@@ -102,13 +111,14 @@
****************************************************************/
static int WaitReady (PADAPTER2000 padapter)
{
- ULONG timer;
+ ULONG z;
- timer = jiffies + TIMEOUT_COMMAND; // calculate the timeout value
- do {
+ for ( z = 0; z < (TIMEOUT_COMMAND * 4); z++ )
+ {
if ( !inb_p (padapter->cmd) )
return FALSE;
- } while ( timer > jiffies ); // test for timeout
+ udelay (250);
+ };
return TRUE;
}
/****************************************************************
@@ -180,6 +190,26 @@
outl (SCpnt->request_bufflen, padapter->mb3);
return TRUE;
}
+/*********************************************************************
+ * Name: PsiRaidCmd
+ *
+ * Description: Execute a simple command.
+ *
+ * Parameters: padapter - Pointer to adapter control structure.
+ * cmd - Roy command byte.
+ *
+ * Returns: Return error status.
+ *
+ ********************************************************************/
+static int PsiRaidCmd (PADAPTER2000 padapter, char cmd)
+ {
+ if ( WaitReady (padapter) ) // test for command register ready
+ return DID_TIME_OUT;
+ outb_p (cmd, padapter->cmd); // issue command
+ if ( WaitReady (padapter) ) // wait for adapter ready
+ return DID_TIME_OUT;
+ return DID_OK;
+ }
/****************************************************************
* Name: Irq_Handler :LOCAL
*
@@ -366,7 +396,35 @@
switch ( *cdb )
{
case SCSIOP_INQUIRY: // inquiry CDB
- {
+ if ( cdb[2] == SC_MY_RAID )
+ {
+ switch ( cdb[3] )
+ {
+ case MY_SCSI_REBUILD:
+ OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_REBUILD) << 16);
+ return 0;
+ case MY_SCSI_ALARMMUTE:
+ OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_MUTE) << 16);
+ return 0;
+ case MY_SCSI_DEMOFAIL:
+ OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_FAIL) << 16);
+ return 0;
+ default:
+ if ( SCpnt->use_sg )
+ {
+ rc = DID_ERROR;
+ goto finished;
+ }
+ else
+ outl (virt_to_bus (SCpnt->request_buffer), padapter->mb2);
+ outl (cdb[5], padapter->mb0);
+ outl (cdb[3], padapter->mb3);
+ cmd = CMD_DASD_RAID_RQ;
+ break;
+ }
+ break;
+ }
+
if ( SCpnt->use_sg )
{
outl (virt_to_bus (((struct scatterlist *)(SCpnt->request_buffer))->address), padapter->mb2);
@@ -378,7 +436,6 @@
outl (SCpnt->request_bufflen, padapter->mb3);
cmd = CMD_DASD_SCSI_INQ;
break;
- }
case SCSIOP_TEST_UNIT_READY: // test unit ready CDB
outl (virt_to_bus (SCpnt->sense_buffer), padapter->mb2);
@@ -466,14 +523,6 @@
OpDone (SCpnt, rc << 16);
return 0;
}
-static void do_Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
- {
- unsigned long flags;
-
- spin_lock_irqsave(&io_request_lock, flags);
- Irq_Handler(irq, dev_id, regs);
- spin_unlock_irqrestore(&io_request_lock, flags);
- }
/****************************************************************
* Name: internal_done :LOCAL
*
@@ -524,17 +573,23 @@
int pci_index = 0;
struct Scsi_Host *pshost;
PADAPTER2000 padapter;
- int z;
+ int z, zz;
int setirq;
- struct pci_dev *pdev = NULL;
- if ( pci_present () )
- while ((pdev = pci_find_device(VENDOR_PSI, DEVICE_ROY_1, pdev)))
+ if ( pcibios_present () )
+ {
+ for ( pci_index = 0; pci_index <= MAXADAPTER; ++pci_index )
{
+ UCHAR pci_bus, pci_device_fn;
+
+ if ( pcibios_find_device (VENDOR_PSI, DEVICE_ROY_1, pci_index, &pci_bus, &pci_device_fn) != 0 )
+ break;
+
pshost = scsi_register (tpnt, sizeof(ADAPTER2000));
padapter = HOSTDATA(pshost);
- padapter->basePort = pdev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;
+ pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &padapter->basePort);
+ padapter->basePort &= 0xFFFE;
DEB (printk ("\nBase Regs = %#04X", padapter->basePort)); // get the base I/O port address
padapter->mb0 = padapter->basePort + RTR_MAILBOX; // get the 32 bit mail boxes
padapter->mb1 = padapter->basePort + RTR_MAILBOX + 4;
@@ -551,35 +606,40 @@
if ( WaitReady (padapter) )
goto unregister;
- pshost->irq = pdev->irq;
+ pcibios_read_config_byte (pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pshost->irq);
setirq = 1;
- for ( z = 0; z < pci_index; z++ ) // scan for shared interrupts
+ for ( z = 0; z < pci_index; z++ ) // scan for shared interrupts
{
- if ( PsiHost[z]->irq == pshost->irq ) // if shared then, don't posses
+ if ( PsiHost[z]->irq == pshost->irq ) // if shared then, don't posses
setirq = 0;
}
- if ( setirq ) // if not shared, posses
+ if ( setirq ) // if not shared, posses
{
- if ( request_irq (pshost->irq, do_Irq_Handler, 0, "pci2000", NULL) )
+ if ( request_irq (pshost->irq, Irq_Handler, 0, "pci2000", NULL) )
{
printk ("Unable to allocate IRQ for PSI-2000 controller.\n");
goto unregister;
}
}
- PsiHost[pci_index] = pshost; // save SCSI_HOST pointer
+ PsiHost[pci_index] = pshost; // save SCSI_HOST pointer
pshost->unique_id = padapter->basePort;
pshost->max_id = 16;
pshost->max_channel = 1;
- printk("\nPSI-2000 EIDE CONTROLLER: at I/O = %X IRQ = %d\n", padapter->basePort, pshost->irq);
- printk("(C) 1997 Perceptive Solutions, Inc. All rights reserved\n\n");
- NumAdapters++;
+ for ( zz = 0; zz < MAX_BUS; zz++ )
+ for ( z = 0; z < MAX_UNITS; z++ )
+ padapter->dev[zz][z].tag = 0;
+
+ printk("\nPSI-2000 Intelligent Storage SCSI CONTROLLER: at I/O = %X IRQ = %d\n", padapter->basePort, pshost->irq);
+ printk("Version %s, Compiled %s %s\n\n", PCI2000_VERSION, __DATE__, __TIME__);
continue;
unregister:;
scsi_unregister (pshost);
}
- return NumAdapters;
+ }
+ NumAdapters = pci_index;
+ return pci_index;
}
/****************************************************************
* Name: Pci2220i_Abort
@@ -653,7 +713,7 @@
#ifdef MODULE
/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = PCI2000;
+Scsi_Host_Template driver_template = PCI2220I;
#include "scsi_module.c"
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)