patch-2.2.15 linux/drivers/scsi/megaraid.c
Next file: linux/drivers/scsi/megaraid.h
Previous file: linux/drivers/scsi/hosts.h
Back to the patch index
Back to the overall index
- Lines: 410
- Date:
Fri Apr 21 12:46:30 2000
- Orig file:
v2.2.14/drivers/scsi/megaraid.c
- Orig date:
Tue Jan 4 21:18:57 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
@@ -2,14 +2,14 @@
*
* Linux MegaRAID device driver
*
- * Copyright 1998 American Megatrends Inc.
+ * Copyright 1999 American Megatrends 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 the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version : 1.05
+ * Version : 1.07b
*
* Description: Linux device driver for AMI MegaRAID controller
*
@@ -120,6 +120,14 @@
* also enables the driver to handle large amount of I/O requests for
* long duration of time.
*
+ * Version 1.07
+ * Removed the usage of uaccess.h file for kernel versions less than
+ * 2.0.36, as this file is not present in those versions.
+ *
+ * Version 1.07b
+ * The MegaRAID 466 cards with 3.00 firmware lockup and seem to very
+ * occasionally hang. We check such cards and report them. You can
+ * get firmware upgrades to flash the board to 3.10 for free.
*
* BUGS:
* Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
@@ -135,7 +143,7 @@
#define CRLFSTR "\n"
#define IOCTL_CMD_NEW 0x81
-#define MEGARAID_VERSION "v1.05 (October 27, 1999)"
+#define MEGARAID_VERSION "v107 (December 22, 1999)"
#include <linux/config.h>
@@ -178,7 +186,9 @@
#include <asm/io.h>
#include <asm/irq.h>
+#if LINUX_VERSION_CODE > 0x020024
#include <asm/uaccess.h>
+#endif
#include "sd.h"
#include "scsi.h"
@@ -265,7 +275,6 @@
-
#if LINUX_VERSION_CODE > 0x020100
# include <asm/spinlock.h>
# include <linux/smp.h>
@@ -304,6 +313,7 @@
cli();
# define DRIVER_UNLOCK(p) \
restore_flags(cpu_flags);
+# define IO_LOCK_T unsigned long io_flags = 0;
# define IO_LOCK(p) DRIVER_LOCK(p)
# define IO_UNLOCK(p) DRIVER_UNLOCK(p)
# define le32_to_cpu(x) (x)
@@ -329,6 +339,7 @@
/* Use "megaraid=skipXX" as LILO option to prohibit driver from scanning
XX scsi id on each channel. Used for Madrona motherboard, where SAF_TE
processor id cannot be scanned */
+
static char *megaraid;
#if LINUX_VERSION_CODE > 0x20100
#ifdef MODULE
@@ -350,7 +361,6 @@
#if SERDEBUG
volatile static spinlock_t serial_lock;
#endif
-//volatile static spinlock_t mega_lock;
struct proc_dir_entry proc_scsi_megaraid =
{
@@ -593,7 +603,6 @@
}
SCpnt = pScb->SCpnt;
- /*freeSCB(megaCfg, pScb);*/ /*delay this to the end of this func.*/
pthru = &pScb->pthru;
mbox = (mega_mailbox *) &pScb->mboxData;
@@ -708,13 +717,11 @@
if ( islogical ) {
lun = (SCpnt->target * 8) + lun;
-#if 1
if ( lun > FC_MAX_LOGICAL_DRIVES ){
SCpnt->result = (DID_BAD_TARGET << 16);
callDone (SCpnt);
return NULL;
}
-#endif
}
/*-----------------------------------------------------
*
@@ -878,7 +885,6 @@
return NULL;
}
-
mboxdata = (u8 *) & pScb->mboxData;
mbox = (mega_ioctl_mbox *) & pScb->mboxData;
mailbox = (mega_mailbox *) & pScb->mboxData;
@@ -913,6 +919,14 @@
}
/* else normal (nonpassthru) command */
+#if LINUX_VERSION_CODE > 0x020024
+/*
+ * usage of the function copy from user is used in case of data more than
+ * 4KB. This is used only with adapters which supports more than 8 logical
+ * drives. This feature is disabled on kernels earlier or same as 2.0.36
+ * as the uaccess.h file is not available with those kernels.
+ */
+
if (SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
/* use external data area for large xfers */
/* If cmnd[0] is set to IOCTL_CMD_NEW then *
@@ -938,6 +952,7 @@
copy_from_user(kern_area,user_area,xfer_size);
pScb->kern_area = kern_area;
}
+#endif
mbox->cmd = data[0];
mbox->channel = data[1];
@@ -998,7 +1013,9 @@
*--------------------------------------------------------------------*/
static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
{
+#if LINUX_VERSION_CODE >= 0x20100
IO_LOCK_T
+#endif
mega_host_config *megaCfg;
u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
u32 dword=0;
@@ -1011,7 +1028,6 @@
megaCfg = (mega_host_config *) devp;
mbox = (mega_mailbox *)tmpBox;
-
if (megaCfg->host->irq == irq) {
if (megaCfg->flag & IN_ISR) {
@@ -1031,10 +1047,6 @@
if (dword != 0x10001234) {
/* Spurious interrupt */
megaCfg->flag &= ~IN_ISR;
-//#if LINUX_VERSION_CODE >= 0x20100
-// IO_UNLOCK;
-//#endif
-// break;
return;
}
}
@@ -1043,10 +1055,6 @@
if ((byte & VALID_INTR_BYTE) == 0) {
/* Spurious interrupt */
megaCfg->flag &= ~IN_ISR;
-//#if LINUX_VERSION_CODE >= 0x20100
-// IO_UNLOCK;
-//#endif
-// break;
return;
}
WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
@@ -1110,9 +1118,6 @@
*/
if (pScb->state == SCB_ABORTED) {
SCpnt = pScb->SCpnt;
-#if DEBUG
-printk("megaraid_isr:fcnt=%d, pcnt=%d, qcnt=%d\n",megaCfg->qFcnt, megaCfg->qPcnt, megaCfg->qCcnt);
-#endif
}
if (pScb->state == SCB_RESET) {
SCpnt = pScb->SCpnt;
@@ -1211,9 +1216,6 @@
#endif
/* Wait until mailbox is free */
-#if 0
- while (mega_busyWaitMbox (megaCfg))
-#endif
if (mega_busyWaitMbox (megaCfg)) {
printk("Blocked mailbox......!!\n");
udelay(1000);
@@ -1266,7 +1268,6 @@
if (pScb) {
mega_cmd_done (megaCfg, pScb, mbox->status);
-// mega_rundoneq (megaCfg);
}
WRINDOOR (megaCfg, phys_mbox | 0x2);
@@ -1285,7 +1286,6 @@
if (pScb) {
mega_cmd_done (megaCfg, pScb, mbox->status);
-// mega_rundoneq (megaCfg);
}
else {
TRACE (("Error: NULL pScb!\n"));
@@ -1424,7 +1424,6 @@
u32 paddr;
u8 retval;
-
/* Initialize adapter inquiry mailbox*/
paddr = virt_to_bus (megaCfg->mega_buffer);
mbox = (mega_mailbox *) mboxData;
@@ -1496,25 +1495,6 @@
megaCfg->host->can_queue = MAX_COMMANDS-1;
}
-#if 0
- int i;
- printk (KERN_DEBUG "---- Logical drive info from enquiry3 struct----\n");
- for (i = 0; i < megaCfg->numldrv; i++) {
- printk ("%d: size: %d prop: %x state: %x\n", i,
- enquiry3Pnt->lDrvSize[i],
- enquiry3Pnt->lDrvProp[i],
- enquiry3Pnt->lDrvState[i]);
- }
-
- printk (KERN_DEBUG "---- Physical drive info ----\n");
- for (i = 0; i < FC_MAX_PHYSICAL_DEVICES; i++) {
- if (i && !(i % 8))
- printk ("\n");
- printk ("%d: %x ", i, enquiry3Pnt->pDrvState[i]);
- }
- printk ("\n");
-#endif
-
#ifdef HP /* use HP firmware and bios version encoding */
sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
megaCfg->productInfo.FwVer[2],
@@ -1573,10 +1553,6 @@
#if LINUX_VERSION_CODE < 0x20100
while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
-
-#if 0
- } /* keep auto-indenters happy */
-#endif
#else
struct pci_dev *pdev = pci_devices;
@@ -1587,10 +1563,14 @@
#endif
if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
u16 magic;
+#if LINUX_VERSION_CODE < 0x20100
pcibios_read_config_word (pciBus, pciDevFun,
PCI_CONF_AMISIG,
&magic);
- if (magic != AMI_SIGNATURE) {
+#else
+ pci_read_config_word (pdev, PCI_CONF_AMISIG, &magic);
+#endif
+ if ((magic != AMI_SIGNATURE) && (magic != AMI_SIGNATURE_471) ){
pciIdx++;
continue; /* not an AMI board */
}
@@ -1673,10 +1653,43 @@
mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox64));
mega_i_query_adapter (megaCfg);
-
+
+ if (flag == BOARD_QUARTZ) {
+ /* Check to see if this is a Dell PERC RAID controller model 466 */
+ u16 subsysid, subsysvid;
+#if LINUX_VERSION_CODE < 0x20100
+ pcibios_read_config_word (pciBus, pciDevFun,
+ PCI_SUBSYSTEM_VENDOR_ID,
+ &subsysvid);
+ pcibios_read_config_word (pciBus, pciDevFun,
+ PCI_SUBSYSTEM_ID,
+ &subsysid);
+#else
+ pci_read_config_word (pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
+ pci_read_config_word (pdev, PCI_SUBSYSTEM_ID, &subsysid);
+#endif
+ if ( (subsysid == 0x1111) && (subsysvid == 0x1111) &&
+ (!strcmp(megaCfg->fwVer,"3.00") || !strcmp(megaCfg->fwVer,"3.01"))) {
+ printk(KERN_WARNING
+"megaraid: Your card is a Dell PERC 2/SC RAID controller with firmware\n"
+"megaraid: 3.00 or 3.01. This driver is known to have corruption issues\n"
+"megaraid: with those firmware versions on this specific card. In order\n"
+"megaraid: to protect your data, please upgrade your firmware to version\n"
+"megaraid: 3.10 or later, available from the Dell Technical Support web\n"
+"megaraid: site at\n"
+"http://support.dell.com/us/en/filelib/download/index.asp?fileid=2489\n");
+ megaraid_release (host);
+#ifdef MODULE
+ continue;
+#else
+ while(1) schedule_timeout(1 * HZ);
+#endif
+ }
+ }
+
/* Initialize SCBs */
if (mega_initSCB (megaCfg)) {
- scsi_unregister (host);
+ megaraid_release (host);
continue;
}
@@ -1824,9 +1837,6 @@
/* If driver in abort or reset.. cancel this command */
if (megaCfg->flag & IN_ABORT) {
-#if DEBUG
-printk("mq: got a request while in abort\n");
-#endif
SCpnt->result = (DID_ABORT << 16);
/* Add Scsi_Command to end of completed queue */
if( megaCfg->qCompletedH == NULL ) {
@@ -1843,9 +1853,6 @@
return 0;
}
else if (megaCfg->flag & IN_RESET) {
-#if DEBUG
-printk("mq: got a request while in reset\n");
-#endif
SCpnt->result = (DID_RESET << 16);
/* Add Scsi_Command to end of completed queue */
if( megaCfg->qCompletedH == NULL ) {
@@ -1878,16 +1885,9 @@
megaCfg->qPendingT->next = NULL;
megaCfg->qPcnt++;
-
- /* Issue any pending command to the card if not in ISR */
-// if (!(megaCfg->flag & IN_ISR)) {
mega_runpendq(megaCfg);
-// }
-/*
- * try running the pend queue, irrespective of the driver's context.
- * -cn
- */
+#if LINUX_VERSION_CODE > 0x020024
if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW )
{ /* user data from external user buffer */
char *user_area;
@@ -1905,6 +1905,7 @@
mega_freeSCB(megaCfg, pScb);
}
+#endif
}
megaCfg->flag &= ~IN_QUEUE;
@@ -1959,9 +1960,6 @@
megaCfg->flag |= IN_ABORT;
-#if DEBUG
-printk("ma:fcnt=%d, pcnt=%d, qcnt=%d\n",megaCfg->qFcnt, megaCfg->qPcnt, megaCfg->qCcnt);
-#endif
for(pScb=megaCfg->qPendingH; pScb; pScb=pScb->next) {
if (pScb->SCpnt == SCpnt) {
/* Found an aborting command */
@@ -2013,20 +2011,6 @@
}
}
-#if 0
- TRACE (("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
- SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
- SCpnt->lun));
- for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
- if (pScb->SCpnt == SCpnt) {
- ser_printk("** %d<%x> %c\n", pScb->SCpnt->pid, pScb->idx+1,
- pScb->state == SCB_ACTIVE ? 'A' : 'I');
-#if DEBUG
- showMbox(pScb);
-#endif
- }
- }
-#endif
megaCfg->flag &= ~IN_ABORT;
#if DEBUG
@@ -2044,12 +2028,11 @@
megaCfg->qCompletedH = (Scsi_Cmnd *)SCpnt->host_scribble;
megaCfg->qCcnt--;
- SCpnt->host_scribble = (unsigned char *) NULL ; // XC : sep 14
+ SCpnt->host_scribble = (unsigned char *) NULL ;
/* Callback */
callDone (SCpnt);
}
mega_rundoneq(megaCfg);
-
return rc;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)