* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version : 1.01
+ * Version : 1.04
*
* Description: Linux device driver for AMI MegaRAID controller
*
- * Supported controllers: MegaRAID 418, 428, 438, 466, 762
+ * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 490
*
- * Maintainer: Jeff L Jones <jeffreyj@ami.com>
- * Xi Shine Chen <xic@ami.com>
* History:
*
* Version 0.90:
* Fixed bug in mega_cmd_done() for megamgr control commands,
* the host_byte in the result code from the scsi request to
* scsi midlayer is set to DID_BAD_TARGET when adapter's
- * returned codes are 0xF0 and oxF4.
+ * returned codes are 0xF0 and 0xF4.
+ *
+ * Version 1.02:
+ * Fixed the tape drive bug by extending the adapter timeout value
+ * for passthrough command to 60 seconds in mega_build_cmd().
+ *
+ * Version 1.03:
+ * Fixed Madrona support.
+ * Changed the adapter timeout value from 60 sec in 1.02 to 10 min
+ * for bigger and slower tape drive.
+ * Added driver version printout at driver loadup time
+ *
+ * Version 1.04
+ * Added code for 40 ld FW support.
+ * Added new ioctl command 0x81 to support NEW_READ/WRITE_CONFIG with
+ * data area greater than 4 KB, which is the upper bound for data
+ * tranfer through scsi_ioctl interface.
+ * The addtional 32 bit field for 64bit address in the newly defined
+ * mailbox64 structure is set to 0 at this point.
*
* BUGS:
* Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
* fails to detect the controller as a pci device on the system.
*
- * Timeout period for mid scsi layer is too short for
- * this controller. Must be increased or Aborts will occur.
+ * Timeout period for upper scsi layer, i.e. SD_TIMEOUT in
+ * /drivers/scsi/sd.c, is too short for this controller. SD_TIMEOUT
+ * value must be increased to (30 * HZ) otherwise false timeouts
+ * will occur in the upper layer.
*
*===================================================================*/
#define CRLFSTR "\n"
+#define IOCTL_CMD_NEW 0x81
+
+#define MEGARAID_VERSION "v1.04 (August 16, 1999)"
#include <linux/config.h>
#include <linux/version.h>
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/uaccess.h>
#include "sd.h"
#include "scsi.h"
spin_unlock_irqrestore(&mega_lock,cpuflag);\
};
-u_long RDINDOOR (mega_host_config * megaCfg)
+u32 RDINDOOR (mega_host_config * megaCfg)
{
return readl (megaCfg->base + 0x20);
}
-void WRINDOOR (mega_host_config * megaCfg, u_long value)
+void WRINDOOR (mega_host_config * megaCfg, u32 value)
{
writel (value, megaCfg->base + 0x20);
}
-u_long RDOUTDOOR (mega_host_config * megaCfg)
+u32 RDOUTDOOR (mega_host_config * megaCfg)
{
return readl (megaCfg->base + 0x2C);
}
-void WROUTDOOR (mega_host_config * megaCfg, u_long value)
+void WROUTDOOR (mega_host_config * megaCfg, u32 value)
{
writel (value, megaCfg->base + 0x2C);
}
mega_scb * scb,
int intr);
static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
- u_long * buffer, u_long * length);
+ u32 * buffer, u32 * length);
static int mega_busyWaitMbox(mega_host_config *);
static void mega_runpendq (mega_host_config *);
static void mega_cmd_done (mega_host_config *, mega_scb *, int);
static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
static inline void freeSgList(mega_host_config *megaCfg);
+static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry,
+ mega_Enquiry3 *enquiry3,
+ megaRaidProductInfo *productInfo );
/* set SERDEBUG to 1 to enable serial debugging */
#define SERDEBUG 0
*================================================================
*/
-/* Use "megaraid=skipXX" to prohibit driver from scanning XX scsi id
- on each channel. Used for Madrona motherboard, where SAF_TE
- processor id cannot be scanned */
+/* 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
static int skip_id;
static int numCtlrs = 0;
-static mega_host_config *megaCtlrs[12] = {0};
+static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = {0};
#if DEBUG
-static u_long maxCmdTime = 0;
+static u32 maxCmdTime = 0;
#endif
static mega_scb *pLastScb = NULL;
while(1);
}
- islogical = (SCpnt->channel == megaCfg->host->max_channel &&
- SCpnt->target == 0);
+ islogical = (SCpnt->channel == megaCfg->host->max_channel);
+
if (SCpnt->cmnd[0] == INQUIRY &&
((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
!islogical) {
/* clear result; otherwise, success returns corrupt value */
SCpnt->result = 0;
-if (SCpnt->cmnd[0] & 0x80) /* ioctl from megamgr */{
- /*printk(KERN_WARNING "***megamgr cmnd status= %x h\n ", status); */
+if ((SCpnt->cmnd[0] & 0x80) ) {/* i.e. ioctl cmd such as 0x80, 0x81 of megamgr*/
switch (status) {
case 0xF0:
case 0xF4:
SCpnt->result |= (DID_BUS_BUSY << 16)|status;
break;
default:
- SCpnt->result |= (DID_BAD_TARGET << 16);
+ SCpnt->result |= (DID_BAD_TARGET << 16)|status;
break;
}
}
- freeSCB(megaCfg, pScb);
+ if ( SCpnt->cmnd[0]!=IOCTL_CMD_NEW )
+ /* not IOCTL_CMD_NEW SCB, freeSCB()*/
+ /* For IOCTL_CMD_NEW SCB, delay freeSCB() in megaraid_queue()
+ * after copy data back to user space*/
+ freeSCB(megaCfg, pScb);
/* Add Scsi_Command to end of completed queue */
ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
mega_passthru *pthru;
long seg;
char islogical;
+ char lun = SCpnt->lun;
- if (SCpnt == NULL) {
- printk("NULL SCpnt in mega_build_cmd!\n");
- while(1);
- }
-
- if (SCpnt->cmnd[0] & 0x80) /* ioctl from megamgr */
+ if ((SCpnt->cmnd[0] == 0x80) || (SCpnt->cmnd[0] == IOCTL_CMD_NEW) ) /* ioctl */
return mega_ioctl (megaCfg, SCpnt);
+
+ islogical = (SCpnt->channel == megaCfg->host->max_channel);
- islogical = (SCpnt->channel == megaCfg->host->max_channel && SCpnt->target == 0);
-
- if (!islogical && SCpnt->lun != 0) {
+ if (!islogical && lun != 0) {
SCpnt->result = (DID_BAD_TARGET << 16);
callDone (SCpnt);
return NULL;
return NULL;
}
+ 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
+ }
/*-----------------------------------------------------
*
* Logical drive commands
pthru->ars = 1;
pthru->reqsenselen = 14;
pthru->islogical = 1;
- pthru->logdrv = SCpnt->lun;
+ pthru->logdrv = lun;
pthru->cdblen = SCpnt->cmd_len;
pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer);
pthru->dataxferlen = SCpnt->request_bufflen;
mbox = (mega_mailbox *) & pScb->mboxData;
memset (mbox, 0, sizeof (pScb->mboxData));
- mbox->logdrv = SCpnt->lun;
+ mbox->logdrv = lun;
mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE;
/* 6-byte */
if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
mbox->numsectors =
- (u_long) SCpnt->cmnd[4];
+ (u32) SCpnt->cmnd[4];
mbox->lba =
- ((u_long) SCpnt->cmnd[1] << 16) |
- ((u_long) SCpnt->cmnd[2] << 8) |
- (u_long) SCpnt->cmnd[3];
+ ((u32) SCpnt->cmnd[1] << 16) |
+ ((u32) SCpnt->cmnd[2] << 8) |
+ (u32) SCpnt->cmnd[3];
mbox->lba &= 0x1FFFFF;
}
/* 10-byte */
if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
mbox->numsectors =
- (u_long) SCpnt->cmnd[8] |
- ((u_long) SCpnt->cmnd[7] << 8);
+ (u32) SCpnt->cmnd[8] |
+ ((u32) SCpnt->cmnd[7] << 8);
mbox->lba =
- ((u_long) SCpnt->cmnd[2] << 24) |
- ((u_long) SCpnt->cmnd[3] << 16) |
- ((u_long) SCpnt->cmnd[4] << 8) |
- (u_long) SCpnt->cmnd[5];
+ ((u32) SCpnt->cmnd[2] << 24) |
+ ((u32) SCpnt->cmnd[3] << 16) |
+ ((u32) SCpnt->cmnd[4] << 8) |
+ (u32) SCpnt->cmnd[5];
}
/* Calculate Scatter-Gather info */
mbox->numsgelements = build_sglist (megaCfg, pScb,
- (u_long *) & mbox->xferaddr,
- (u_long *) & seg);
+ (u32 *) & mbox->xferaddr,
+ (u32 *) & seg);
return pScb;
memset (mbox, 0, sizeof (pScb->mboxData));
memset (pthru, 0, sizeof (mega_passthru));
- pthru->timeout = 0;
+ pthru->timeout = 2; /*set adapter timeout value to 10 min. for tape drive*/
+ /* 0=6sec/1=60sec/2=10min/3=3hrs */
pthru->ars = 1;
pthru->reqsenselen = 14;
pthru->islogical = 0;
- pthru->channel = SCpnt->channel;
- pthru->target = SCpnt->target;
+ pthru->channel = (megaCfg->flag & BOARD_40LD) ? 0 : SCpnt->channel;
+ pthru->target = (megaCfg->flag & BOARD_40LD) ? /*BOARD_40LD*/
+ (SCpnt->channel<<4)|SCpnt->target : SCpnt->target;
pthru->cdblen = SCpnt->cmd_len;
memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
pthru->numsgelements = build_sglist (megaCfg, pScb,
- (u_long *) & pthru->dataxferaddr,
- (u_long *) & pthru->dataxferlen);
+ (u32 *) & pthru->dataxferaddr,
+ (u32 *) & pthru->dataxferlen);
/* Initialize mailbox */
mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
mega_ioctl_mbox *mbox;
mega_mailbox *mailbox;
mega_passthru *pthru;
+ u8 *mboxdata;
long seg;
unsigned char *data = (unsigned char *)SCpnt->request_buffer;
int i;
printk("......\n");
#endif
+ mboxdata = (u8 *) & pScb->mboxData;
mbox = (mega_ioctl_mbox *) & pScb->mboxData;
mailbox = (mega_mailbox *) & pScb->mboxData;
memset (mailbox, 0, sizeof (pScb->mboxData));
mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
mailbox->xferaddr = virt_to_bus (pthru);
-
pthru->numsgelements = build_sglist (megaCfg, pScb,
- (u_long *) & pthru->dataxferaddr,
- (u_long *) & pthru->dataxferlen);
+ (u32 *) & pthru->dataxferaddr,
+ (u32 *) & pthru->dataxferlen);
for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) {
data[i] = data[i+cdblen+7];
}
/* else normal (nonpassthru) command */
+ if (SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
+ /* use external data area for large xfers */
+ /* If cmnd[0] is set to IOCTL_CMD_NEW then *
+ * cmnd[4..7] = external user buffer *
+ * cmnd[8..11] = length of buffer *
+ * */
+ char *kern_area;
+ char *user_area = *((char **)&SCpnt->cmnd[4]);
+ u32 xfer_size = *((u32 *)&SCpnt->cmnd[8]);
+ if (verify_area(VERIFY_READ, user_area, xfer_size)) {
+ printk("megaraid: Got bad user address.\n");
+ SCpnt->result = (DID_ERROR << 16);
+ callDone (SCpnt);
+ return NULL;
+ }
+ kern_area = kmalloc(xfer_size, GFP_ATOMIC | GFP_DMA);
+ if (kern_area == NULL) {
+ printk("megaraid: Couldn't allocate kernel mem.\n");
+ SCpnt->result = (DID_ERROR << 16);
+ callDone (SCpnt);
+ return NULL;
+ }
+ copy_from_user(kern_area,user_area,xfer_size);
+ pScb->kern_area = kern_area;
+ }
+
mbox->cmd = data[0];
mbox->channel = data[1];
mbox->param = data[2];
mbox->pad[0] = data[3];
mbox->logdrv = data[4];
- mbox->numsgelements = build_sglist (megaCfg, pScb,
- (u_long *) & mbox->xferaddr,
- (u_long *) & seg);
+ if(SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
+ if(data[0]==DCMD_FC_CMD){ /*i.e. 0xA1, then override some mbox data */
+ *(mboxdata+0) = data[0]; /*mailbox byte 0: DCMD_FC_CMD*/
+ *(mboxdata+2) = data[2]; /*sub command*/
+ *(mboxdata+3) = 0; /*number of elements in SG list*/
+ mbox->xferaddr /*i.e. mboxdata byte 0x8 to 0xb*/
+ = virt_to_bus(pScb->kern_area);
+ }
+ else{
+ mbox->xferaddr = virt_to_bus(pScb->kern_area);
+ mbox->numsgelements = 0;
+ }
+ }
+ else {
- for (i=0;i<(SCpnt->request_bufflen-6);i++) {
- data[i] = data[i+6];
+ mbox->numsgelements = build_sglist (megaCfg, pScb,
+ (u32 *) & mbox->xferaddr,
+ (u32 *) & seg);
+
+ for (i=0;i<(SCpnt->request_bufflen-6);i++) {
+ data[i] = data[i+6];
+ }
}
return (pScb);
{
mega_host_config *megaCfg;
u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
- u_long dword;
+ u32 dword;
mega_mailbox *mbox;
mega_scb *pScb;
long flags;
printk("Received aborted SCB! %u\n", (int)((jiffies)-pScb->isrcount));
}
+ if (*(pScb->SCpnt->cmnd)==IOCTL_CMD_NEW)
+ { /* external user buffer */
+ up(&pScb->sem);
+ }
/* Mark command as completed */
mega_cmd_done(megaCfg, pScb, qStatus);
+
}
}
spin_lock_irqsave(&mega_lock, flags);
mega_runpendq(megaCfg);
spin_unlock_irqrestore(&mega_lock,flags);
+
}
#if LINUX_VERSION_CODE >= 0x20100
* u_char *mboxData - Mailbox area, 16 bytes
* mega_scb *pScb - SCB posting (or NULL if N/A)
* int intr - if 1, interrupt, 0 is blocking
+ * Return Value: (added on 7/26 for 40ld/64bit)
+ * -1: the command was not actually issued out
+ * othercases:
+ * intr==0, return ScsiStatus, i.e. mbox->status
+ * intr==1, return 0
*=====================================================
*/
static int megaIssueCmd (mega_host_config * megaCfg,
{
mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
u_char byte;
- u_long cmdDone;
+ u32 cmdDone;
Scsi_Cmnd *SCpnt;
+ u32 phys_mbox;
+ u8 retval=-1;
mboxData[0x1] = (pScb ? pScb->idx + 1: 0x0); /* Set cmdid */
mboxData[0xF] = 1; /* Set busy */
+ phys_mbox = virt_to_bus (megaCfg->mbox);
+
#if 0
if (intr && mbox->busy) {
return 0;
/* Wait until mailbox is free */
while (mega_busyWaitMbox (megaCfg)) {
- printk("Blocked mailbox!!\n");
+ printk("Blocked mailbox......!!\n");
udelay(1000);
#if DEBUG
SCpnt->result = (DID_ABORT << 16);
callDone(SCpnt);
- return 0;
+ return -1;
}
pLastScb = pScb;
/* Copy mailbox data into host structure */
+ megaCfg->mbox64->xferSegment = 0;
memcpy (mbox, mboxData, 16);
/* Kick IO */
if (megaCfg->flag & BOARD_QUARTZ) {
mbox->mraid_poll = 0;
mbox->mraid_ack = 0;
- WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1);
+ WRINDOOR (megaCfg, phys_mbox | 0x1);
}
else {
ENABLE_INTR (megaCfg->host->io_port);
ISSUE_COMMAND (megaCfg->host->io_port);
}
pScb->state = SCB_ISSUED;
+
+ retval=0;
}
else { /* Issue non-ISR (blocking) command */
disable_irq(megaCfg->host->irq);
if (megaCfg->flag & BOARD_QUARTZ) {
mbox->mraid_poll = 0;
mbox->mraid_ack = 0;
- WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1);
+ WRINDOOR (megaCfg, phys_mbox | 0x1);
while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
WROUTDOOR (megaCfg, cmdDone);
mega_rundoneq ();
}
- WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+ WRINDOOR (megaCfg, phys_mbox | 0x2);
while (RDINDOOR (megaCfg) & 0x2);
}
}
enable_irq(megaCfg->host->irq);
+ retval=mbox->status;
}
while (mega_busyWaitMbox (megaCfg)) {
- printk("Blocked mailbox on exit!\n");
+ printk("Blocked mailbox on exit......!\n");
udelay(1000);
}
- return 0;
+ return retval;
}
/*-------------------------------------------------------------------
* Copies data to SGLIST
*-------------------------------------------------------------------*/
static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
- u_long * buffer, u_long * length)
+ u32 * buffer, u32 * length)
{
struct scatterlist *sgList;
int idx;
/* Scatter-gather not used */
if (scb->SCpnt->use_sg == 0) {
*buffer = virt_to_bus (scb->SCpnt->request_buffer);
- *length = (u_long) scb->SCpnt->request_bufflen;
+ *length = (u32) scb->SCpnt->request_bufflen;
return 0;
}
sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
if (scb->SCpnt->use_sg == 1) {
*buffer = virt_to_bus (sgList[0].address);
- *length = (u_long) sgList[0].length;
+ *length = (u32) sgList[0].length;
return 0;
}
/* Copy Scatter-Gather list info into controller structure */
for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
- scb->sgList[idx].length = (u_long) sgList[idx].length;
+ scb->sgList[idx].length = (u32) sgList[idx].length;
}
/* Reset pointer and length fields */
* 10 01 numstatus byte
* 11 01 status byte
*--------------------------------------------------------------------*/
-static int mega_register_mailbox (mega_host_config * megaCfg, u_long paddr)
+static int mega_register_mailbox (mega_host_config * megaCfg, u32 paddr)
{
/* align on 16-byte boundry */
- megaCfg->mbox = &megaCfg->mailbox;
- megaCfg->mbox = (mega_mailbox *) ((((ulong) megaCfg->mbox) + 16) & 0xfffffff0);
- paddr = (paddr + 16) & 0xfffffff0;
+ megaCfg->mbox = &megaCfg->mailbox64.mailbox;
+ megaCfg->mbox = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xfffffff0);
+ megaCfg->mbox64 = (mega_mailbox64 *) (megaCfg->mbox - 4);
+ paddr = (paddr + 4 + 16) & 0xfffffff0;
/* Register mailbox area with the firmware */
if (megaCfg->flag & BOARD_QUARTZ) {
return 0;
}
+
+/*---------------------------------------------------------------------------
+ * mega_Convert8ldTo40ld() -- takes all info in AdapterInquiry structure and
+ * puts it into ProductInfo and Enquiry3 structures for later use
+ *---------------------------------------------------------------------------*/
+static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry,
+ mega_Enquiry3 *enquiry3,
+ megaRaidProductInfo *productInfo )
+{
+ int i;
+
+ productInfo->MaxConcCmds = inquiry->AdpInfo.MaxConcCmds;
+ enquiry3->rbldRate = inquiry->AdpInfo.RbldRate;
+ productInfo->SCSIChanPresent = inquiry->AdpInfo.ChanPresent;
+ for (i=0;i<4;i++) {
+ productInfo->FwVer[i] = inquiry->AdpInfo.FwVer[i];
+ productInfo->BiosVer[i] = inquiry->AdpInfo.BiosVer[i];
+ }
+ enquiry3->cacheFlushInterval = inquiry->AdpInfo.CacheFlushInterval;
+ productInfo->DramSize = inquiry->AdpInfo.DramSize;
+
+ enquiry3->numLDrv = inquiry->LogdrvInfo.NumLDrv;
+ for (i=0;i<MAX_LOGICAL_DRIVES;i++) {
+ enquiry3->lDrvSize[i] = inquiry->LogdrvInfo.LDrvSize[i];
+ enquiry3->lDrvProp[i] = inquiry->LogdrvInfo.LDrvProp[i];
+ enquiry3->lDrvState[i] = inquiry->LogdrvInfo.LDrvState[i];
+ }
+
+ for (i=0;i<(MAX_PHYSICAL_DRIVES);i++) {
+ enquiry3->pDrvState[i] = inquiry->PhysdrvInfo.PDrvState[i];
+ }
+}
+
+
/*-------------------------------------------------------------------
* Issue an adapter info query to the controller
*-------------------------------------------------------------------*/
static int mega_i_query_adapter (mega_host_config * megaCfg)
{
- mega_RAIDINQ *adapterInfo;
+ mega_Enquiry3 *enquiry3Pnt;
mega_mailbox *mbox;
u_char mboxData[16];
- u_long paddr;
+ u32 paddr;
+ u8 retval;
spin_lock_init (&mega_lock);
- /* Initialize adapter inquiry */
+ /* Initialize adapter inquiry mailbox*/
paddr = virt_to_bus (megaCfg->mega_buffer);
mbox = (mega_mailbox *) mboxData;
memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer));
memset (mbox, 0, 16);
- /* Initialize mailbox registers */
- mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ;
- mbox->xferaddr = paddr;
+/*
+ * Try to issue Enquiry3 command
+ * if not suceeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
+ * update enquiry3 structure
+ */
+ mbox->xferaddr = virt_to_bus ( (void*) megaCfg->mega_buffer);
+ /* Initialize mailbox databuffer addr */
+ enquiry3Pnt = (mega_Enquiry3 *) megaCfg->mega_buffer;
+ /* point mega_Enguiry3 to the data buf */
+
+ mboxData[0]=FC_NEW_CONFIG ; /* i.e. mbox->cmd=0xA1 */
+ mboxData[2]=NC_SUBOP_ENQUIRY3; /* i.e. 0x0F */
+ mboxData[3]=ENQ3_GET_SOLICITED_FULL; /* i.e. 0x02 */
/* Issue a blocking command to the card */
- megaIssueCmd (megaCfg, mboxData, NULL, 0);
+ if ( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 )
+ { /* the adapter does not support 40ld*/
- /* Initialize host/local structures with Adapter info */
- adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer;
- megaCfg->host->max_channel = adapterInfo->AdpInfo.ChanPresent;
-/* megaCfg->host->max_id = adapterInfo->AdpInfo.MaxTargPerChan; */
- megaCfg->host->max_id = 16; /* max targets/chan */
- megaCfg->numldrv = adapterInfo->LogdrvInfo.NumLDrv;
+ mega_RAIDINQ adapterInquiryData;
+ mega_RAIDINQ *adapterInquiryPnt = &adapterInquiryData;
-#if 0
- printk ("KERN_DEBUG ---- Logical drive info ----\n");
+ mbox->xferaddr = virt_to_bus ( (void*) adapterInquiryPnt);
+
+ mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ; /*issue old 0x05 command to adapter*/
+ /* Issue a blocking command to the card */;
+ retval=megaIssueCmd (megaCfg, mboxData, NULL, 0);
+
+ /*update Enquiry3 and ProductInfo structures with mega_RAIDINQ structure*/
+ mega_Convert8ldTo40ld( adapterInquiryPnt,
+ enquiry3Pnt,
+ (megaRaidProductInfo * ) &megaCfg->productInfo );
+
+ }
+ else{ /* adapter supports 40ld */
+ megaCfg->flag |= BOARD_40LD;
+
+ /*get productInfo, which is static information and will be unchanged*/
+ mbox->xferaddr = virt_to_bus ( (void*) &megaCfg->productInfo );
+
+ mboxData[0]=FC_NEW_CONFIG ; /* i.e. mbox->cmd=0xA1 */
+ mboxData[2]=NC_SUBOP_PRODUCT_INFO; /* i.e. 0x0E */
+
+ if( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 )
+ printk("ami:Product_info (0x0E) cmd failed with error: %d\n", retval);
+
+ }
+
+ megaCfg->host->max_channel = megaCfg->productInfo.SCSIChanPresent;
+ megaCfg->host->max_id = 16; /* max targets per channel */
+ /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1;*/
+ megaCfg->host->max_lun = /* max lun */
+ (megaCfg->flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
+
+ megaCfg->numldrv = enquiry3Pnt->numLDrv;
+ megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds;
+
+#if 0
+ int i;
+ printk (KERN_DEBUG "---- Logical drive info from enquiry3 struct----\n");
for (i = 0; i < megaCfg->numldrv; i++) {
- printk ("%d: size: %ld prop: %x state: %x\n", i,
- adapterInfo->LogdrvInfo.LDrvSize[i],
- adapterInfo->LogdrvInfo.LDrvProp[i],
- adapterInfo->LogdrvInfo.LDrvState[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 < MAX_PHYSICAL_DRIVES; i++) {
+ for (i = 0; i < FC_MAX_PHYSICAL_DEVICES; i++) {
if (i && !(i % 8))
printk ("\n");
- printk ("%d: %x ", i, adapterInfo->PhysdrvInfo.PDrvState[i]);
+ printk ("%d: %x ", i, enquiry3Pnt->pDrvState[i]);
}
printk ("\n");
#endif
- megaCfg->max_cmds = adapterInfo->AdpInfo.MaxConcCmds;
-
#ifdef HP /* use HP firmware and bios version encoding */
sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
- adapterInfo->AdpInfo.FwVer[2],
- adapterInfo->AdpInfo.FwVer[1] >> 8,
- adapterInfo->AdpInfo.FwVer[1] & 0x0f,
- adapterInfo->AdpInfo.FwVer[2] >> 8,
- adapterInfo->AdpInfo.FwVer[2] & 0x0f);
+ megaCfg->productInfo.FwVer[2],
+ megaCfg->productInfo.FwVer[1] >> 8,
+ megaCfg->productInfo.FwVer[1] & 0x0f,
+ megaCfg->productInfo.FwVer[2] >> 8,
+ megaCfg->productInfo.FwVer[2] & 0x0f);
sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
- adapterInfo->AdpInfo.BiosVer[2],
- adapterInfo->AdpInfo.BiosVer[1] >> 8,
- adapterInfo->AdpInfo.BiosVer[1] & 0x0f,
- adapterInfo->AdpInfo.BiosVer[2] >> 8,
- adapterInfo->AdpInfo.BiosVer[2] & 0x0f);
+ megaCfg->productInfo.BiosVer[2],
+ megaCfg->productInfo.BiosVer[1] >> 8,
+ megaCfg->productInfo.BiosVer[1] & 0x0f,
+ megaCfg->productInfo.BiosVer[2] >> 8,
+ megaCfg->productInfo.BiosVer[2] & 0x0f);
#else
- memcpy (megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4);
+ memcpy (megaCfg->fwVer, megaCfg->productInfo.FwVer, 4);
megaCfg->fwVer[4] = 0;
- memcpy (megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4);
+ memcpy (megaCfg->biosVer, megaCfg->productInfo.BiosVer, 4);
megaCfg->biosVer[4] = 0;
#endif
- printk (KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
- megaCfg->fwVer,
+ printk ("megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
+ megaCfg->fwVer,
megaCfg->biosVer,
megaCfg->numldrv);
+
return 0;
}
}
int findCard (Scsi_Host_Template * pHostTmpl,
- u_short pciVendor, u_short pciDev,
+ u16 pciVendor, u16 pciDev,
long flag)
{
mega_host_config *megaCfg;
struct Scsi_Host *host;
u_char pciBus, pciDevFun, megaIrq;
- u_long megaBase;
- u_short jdx,pciIdx = 0;
- u_short numFound = 0;
+ u32 megaBase;
+ u16 pciIdx = 0;
+ u16 numFound = 0;
#if LINUX_VERSION_CODE < 0x20100
while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
pciBus = pdev->bus->number;
pciDevFun = pdev->devfn;
#endif
- if (flag & BOARD_QUARTZ) {
- u_short magic;
+ if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
+ u16 magic;
pcibios_read_config_word (pciBus, pciDevFun,
PCI_CONF_AMISIG,
&magic);
continue; /* not an AMI board */
}
}
- printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n",
+ printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n",
pciVendor,
pciDev,
pciIdx, pciBus,
pciIdx++;
if (flag & BOARD_QUARTZ) {
+
megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
megaBase = (long) ioremap (megaBase, 128);
}
megaCfg = (mega_host_config *) host->hostdata;
memset (megaCfg, 0, sizeof (mega_host_config));
- printk (" scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR,
+ printk ("scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR,
host->host_no, (u_int) megaBase, megaIrq);
/* Copy resource info into structure */
megaCfg->host->io_port = megaBase;
megaCfg->host->n_io_port = 16;
megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
- megaCtlrs[numCtlrs++] = megaCfg;
-
+ megaCtlrs[numCtlrs++] = megaCfg;
if (flag != BOARD_QUARTZ) {
/* Request our IO Range */
if (check_region (megaBase, 16)) {
continue;
}
- mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox));
+ mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox64));
mega_i_query_adapter (megaCfg);
- for(jdx=0; jdx<MAX_LOGICAL_DRIVES; jdx++) {
- megaCfg->nReads[jdx] = 0;
- megaCfg->nWrites[jdx] = 0;
- }
-
/* Initialize SCBs */
if (initSCB (megaCfg)) {
scsi_unregister (host);
skip_id = (skip_id > 15) ? -1 : skip_id;
}
+ printk ("megaraid: " MEGARAID_VERSION CRLFSTR);
+
count += findCard (pHostTmpl, 0x101E, 0x9010, 0);
count += findCard (pHostTmpl, 0x101E, 0x9060, 0);
count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
{
static char buffer[512];
mega_host_config *megaCfg;
- mega_RAIDINQ *adapterInfo;
megaCfg = (mega_host_config *) pSHost->hostdata;
- adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer;
- sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans",
+ sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans %d luns",
megaCfg->fwVer,
- adapterInfo->AdpInfo.MaxConcCmds,
+ megaCfg->productInfo.MaxConcCmds,
megaCfg->host->max_id,
- megaCfg->host->max_channel);
+ megaCfg->host->max_channel,
+ megaCfg->host->max_lun);
return buffer;
}
megaCfg = (mega_host_config *) SCpnt->host->hostdata;
if (!(megaCfg->flag & (1L << SCpnt->channel))) {
- printk (KERN_INFO "scsi%d: scanning channel %c for devices.\n",
+ if (SCpnt->channel < SCpnt->host->max_channel)
+ printk (/*KERN_INFO*/ "scsi%d: scanning channel %c for devices.\n",
megaCfg->host->host_no,
- SCpnt->channel + 'A');
+ SCpnt->channel + '1');
+ else
+ printk(/*KERN_INFO*/ "scsi%d: scanning virtual channel for logical drives.\n", megaCfg->host->host_no);
+
megaCfg->flag |= (1L << SCpnt->channel);
}
/* Allocate and build a SCB request */
if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
+ /*build SCpnt for IOCTL_CMD_NEW cmd in mega_ioctl()*/
/* Add SCB to the head of the pending queue */
ENQUEUE_NL (pScb, mega_scb, megaCfg->qPending, next);
else {
printk("IRQ pend...\n");
}
+
+ if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW )
+ { /* user data from external user buffer */
+ char *user_area;
+ u32 xfer_size;
+
+ pScb->sem=MUTEX_LOCKED;
+ down(&pScb->sem);
+
+ user_area = *((char **)&pScb->SCpnt->cmnd[4]);
+ xfer_size = *((u32 *)&pScb->SCpnt->cmnd[8]);
+
+ copy_to_user(user_area,pScb->kern_area,xfer_size);
+
+ kfree(pScb->kern_area);
+
+ freeSCB(megaCfg, pScb);
+ }
+
}
spin_unlock_irqrestore(&mega_lock,flags);
#include "scsi_module.c"
#endif
+
#define IN_ABORT 0x40000000L
#define IN_RESET 0x20000000L
#define BOARD_QUARTZ 0x08000000L
+#define BOARD_40LD 0x04000000L
#define SCB_FREE 0x0
#define SCB_ACTIVE 0x1
}
#endif
+
+/***********************************************************************
+ * Structure Declarations for the Firmware supporting 40 Logical Drives
+ * and 256 Physical Drives.
+ ***********************************************************************/
+
+#define FC_MAX_LOGICAL_DRIVES 40
+#define FC_MAX_LOG_DEVICES FC_MAX_LOGICAL_DRIVES
+#define FC_MAX_SPAN_DEPTH 8
+#define FC_MAX_ROW_SIZE 32
+
+#define FC_MAX_CHANNELS 16
+#define FC_MAX_TARGETS_PER_CHANNEL 16
+#define FC_MAX_PHYSICAL_DEVICES 256
+
+#define FC_NEW_CONFIG 0xA1
+#define DCMD_FC_CMD 0xA1
+ #define NC_SUBOP_PRODUCT_INFO 0x0E
+ #define NC_SUBOP_ENQUIRY3 0x0F
+ #define ENQ3_GET_SOLICITED_NOTIFY_ONLY 0x01
+ #define ENQ3_GET_SOLICITED_FULL 0x02
+ #define ENQ3_GET_UNSOLICITED 0x03
+
+
+/********************************************
+ * PRODUCT_INFO Strucure
+ ********************************************/
+
+#define SIG_40LOG_32STR_8SPN 0x00282008
+
+/*
+ * Utilities declare this strcture size as 1024 bytes. So more fields can
+ * be added in future.
+ */
+
+struct MRaidProductInfo
+{
+ u32 DataSize; /* current size in bytes (not including resvd) */
+ u32 ConfigSignature;
+ /* Current value is 0x00282008
+ * 0x28=MAX_LOGICAL_DRIVES,
+ * 0x20=Number of stripes and
+ * 0x08=Number of spans */
+ u8 FwVer[16]; /* printable ASCI string */
+ u8 BiosVer[16]; /* printable ASCI string */
+ u8 ProductName[80]; /* printable ASCI string */
+
+ u8 MaxConcCmds; /* Max. concurrent commands supported */
+ u8 SCSIChanPresent; /* Number of SCSI Channels detected */
+ u8 FCLoopPresent; /* Number of Fibre Loops detected */
+ u8 memType; /* EDO, FPM, SDRAM etc */
+
+ u32 signature;
+ u16 DramSize; /* In terms of MB */
+ u16 subSystemID;
+
+ u16 subSystemVendorID;
+ u8 numNotifyCounters;
+ u8 pad1k[889]; /* 135 + 889 resvd = 1024 total size */
+}__attribute__((packed));
+typedef struct MRaidProductInfo megaRaidProductInfo;
+
+/********************************************
+ * Standard ENQUIRY Strucure
+ ********************************************/
+struct FC_ADP_INFO
+{
+ u8 MaxConcCmds; /* Max. concurrent commands supported. */
+ u8 RbldRate; /* Rebuild Rate. Varies from 0%-100% */
+ u8 MaxTargPerChan; /* Max. Targets supported per chan. */
+ u8 ChanPresent; /* No. of Chans present on this adapter. */
+ u8 FwVer[4]; /* Firmware version. */
+ u16 AgeOfFlash; /* No. of times FW has been downloaded. */
+ u8 ChipSetValue; /* Contents of 0xC0000832 */
+ u8 DramSize; /* In terms of MB */
+ u8 CacheFlushInterval; /* In terms of Seconds */
+ u8 BiosVersion[4];
+ u8 BoardType;
+ u8 sense_alert;
+ u8 write_config_count; /* Increase with evry configuration change */
+ u8 drive_inserted_count; /* Increase with every drive inserted */
+ u8 inserted_drive; /* Channel: Id of inserted drive */
+ u8 battery_status;
+ /*
+ BIT 0 : battery module missing
+ BIT 1 : VBAD
+ BIT 2 : temp high
+ BIT 3 : battery pack missing
+ BIT 4,5 : 00 - charge complete
+ 01 - fast charge in prog
+ 10 - fast charge fail
+ 11 - undefined
+ BIt 6 : counter > 1000
+ Bit 7 : undefined
+ */
+ u8 dec_fault_bus_info; /* was resvd */
+}__attribute__((packed));
+
+struct FC_LDRV_INFO
+{
+ u8 NumLDrv; /* No. of Log. Drvs configured. */
+ u8 recon_state[FC_MAX_LOGICAL_DRIVES/8];
+ /* bit field for State of reconstruct */
+ u16 LDrvOpStatus[FC_MAX_LOGICAL_DRIVES/8];
+ /* bit field Status of Long Operations. */
+
+ u32 LDrvSize[FC_MAX_LOGICAL_DRIVES]; /* Size of each log. Drv. */
+ u8 LDrvProp[FC_MAX_LOGICAL_DRIVES];
+ u8 LDrvState[FC_MAX_LOGICAL_DRIVES]; /* State of Logical Drives. */
+}__attribute__((packed));
+
+#define PREVSTAT_MASK 0xf0
+#define CURRSTAT_MASK 0x0f
+
+struct FC_PDRV_INFO
+{
+ u8 PDrvState[FC_MAX_PHYSICAL_DEVICES]; /* State of Phys Drvs. */
+}__attribute__((packed));
+
+
+struct FC_AdapterInq
+{
+ struct FC_ADP_INFO AdpInfo;
+ struct FC_LDRV_INFO LogdrvInfo;
+ struct FC_PDRV_INFO PhysdrvInfo;
+}__attribute__((packed));
+
+
+typedef struct FC_AdapterInq mega_RAIDINQ_FC;
+
+/********************************************
+ * NOTIFICATION Strucure
+ ********************************************/
+
+#define MAX_NOTIFY_SIZE 0x80
+#define CUR_NOTIFY_SIZE sizeof(struct MegaRAID_Notify)
+
+/*
+ * Utilities declare this strcture size as ?? bytes. So more fields can
+ * be added in future.
+ */
+struct MegaRAID_Notify
+{
+ u32 globalCounter; /* Any change increments this counter */
+
+ u8 paramCounter; /* Indicates any params changed */
+ u8 paramId; /* Param modified - defined below */
+ u16 paramVal; /* New val of last param modified */
+
+ u8 writeConfigCounter; /* write config occurred */
+ u8 writeConfigRsvd[3];
+
+ u8 ldrvOpCounter; /* Indicates ldrv op started/completed */
+ u8 ldrvOpId; /* ldrv num */
+ u8 ldrvOpCmd; /* ldrv operation - defined below */
+ u8 ldrvOpStatus; /* status of the operation */
+
+ u8 ldrvStateCounter; /* Indicates change of ldrv state */
+ u8 ldrvStateId; /* ldrv num */
+ u8 ldrvStateNew; /* New state */
+ u8 ldrvStateOld; /* old state */
+
+ u8 pdrvStateCounter; /* Indicates change of ldrv state */
+ u8 pdrvStateId; /* pdrv id */
+ u8 pdrvStateNew; /* New state */
+ u8 pdrvStateOld; /* old state */
+
+ u8 pdrvFmtCounter; /* Indicates pdrv format started/over */
+ u8 pdrvFmtId; /* pdrv id */
+ u8 pdrvFmtVal; /* format started/over */
+ u8 pdrvFmtRsvd;
+
+ u8 targXferCounter; /* Indicates SCSI-2 Xfer rate change */
+ u8 targXferId; /* pdrv Id */
+ u8 targXferVal; /* new Xfer params of last pdrv */
+ u8 targXferRsvd;
+
+ u8 fcLoopIdChgCounter; /* Indicates loopid changed */
+ u8 fcLoopIdPdrvId; /* pdrv id */
+ u8 fcLoopId0; /* loopid on fc loop 0 */
+ u8 fcLoopId1; /* loopid on fc loop 1 */
+
+ u8 fcLoopStateCounter; /* Indicates loop state changed */
+ u8 fcLoopState0; /* state of fc loop 0 */
+ u8 fcLoopState1; /* state of fc loop 1 */
+ u8 fcLoopStateRsvd;
+}__attribute__((packed));
+
+
+/********************************************
+ * PARAM IDs in Notify struct
+ ********************************************/
+#define PARAM_RBLD_RATE 0x01
+ /*--------------------------------------
+ * Param val =
+ * byte 0: new rbld rate
+ *--------------------------------------*/
+#define PARAM_CACHE_FLUSH_INTERVAL 0x02
+ /*--------------------------------------
+ * Param val =
+ * byte 0: new cache flush interval
+ *--------------------------------------*/
+#define PARAM_SENSE_ALERT 0x03
+ /*--------------------------------------
+ * Param val =
+ * byte 0: last pdrv id causing chkcond
+ *--------------------------------------*/
+#define PARAM_DRIVE_INSERTED 0x04
+ /*--------------------------------------
+ * Param val =
+ * byte 0: last pdrv id inserted
+ *--------------------------------------*/
+#define PARAM_BATTERY_STATUS 0x05
+ /*--------------------------------------
+ * Param val =
+ * byte 0: battery status
+ *--------------------------------------*/
+
+/********************************************
+ * Ldrv operation cmd in Notify struct
+ ********************************************/
+#define LDRV_CMD_CHKCONSISTANCY 0x01
+#define LDRV_CMD_INITIALIZE 0x02
+#define LDRV_CMD_RECONSTRUCTION 0x03
+
+/********************************************
+ * Ldrv operation status in Notify struct
+ ********************************************/
+#define LDRV_OP_SUCCESS 0x00
+#define LDRV_OP_FAILED 0x01
+#define LDRV_OP_ABORTED 0x02
+#define LDRV_OP_CORRECTED 0x03
+#define LDRV_OP_STARTED 0x04
+
+
+/********************************************
+ * Raid Logical drive states.
+ ********************************************/
+#define RDRV_OFFLINE 0
+#define RDRV_DEGRADED 1
+#define RDRV_OPTIMAL 2
+#define RDRV_DELETED 3
+
+/*******************************************
+ * Physical drive states.
+ *******************************************/
+#define PDRV_UNCNF 0
+#define PDRV_ONLINE 3
+#define PDRV_FAILED 4
+#define PDRV_RBLD 5
+/* #define PDRV_HOTSPARE 6 */
+
+/*******************************************
+ * Formal val in Notify struct
+ *******************************************/
+#define PDRV_FMT_START 0x01
+#define PDRV_FMT_OVER 0x02
+
+/********************************************
+ * FC Loop State in Notify Struct
+ ********************************************/
+#define ENQ_FCLOOP_FAILED 0
+#define ENQ_FCLOOP_ACTIVE 1
+#define ENQ_FCLOOP_TRANSIENT 2
+
+/********************************************
+ * ENQUIRY3 Strucure
+ ********************************************/
+/*
+ * Utilities declare this strcture size as 1024 bytes. So more fields can
+ * be added in future.
+ */
+struct MegaRAID_Enquiry3
+{
+ u32 dataSize; /* current size in bytes (not including resvd) */
+
+ struct MegaRAID_Notify notify;
+
+ u8 notifyRsvd[MAX_NOTIFY_SIZE - CUR_NOTIFY_SIZE];
+
+ u8 rbldRate; /* Rebuild rate (0% - 100%) */
+ u8 cacheFlushInterval; /* In terms of Seconds */
+ u8 senseAlert;
+ u8 driveInsertedCount; /* drive insertion count */
+
+ u8 batteryStatus;
+ u8 numLDrv; /* No. of Log Drives configured */
+ u8 reconState[FC_MAX_LOGICAL_DRIVES/8]; /* State of reconstruct */
+ u16 lDrvOpStatus[FC_MAX_LOGICAL_DRIVES/8]; /* log. Drv Status */
+
+ u32 lDrvSize[FC_MAX_LOGICAL_DRIVES]; /* Size of each log. Drv */
+ u8 lDrvProp[FC_MAX_LOGICAL_DRIVES];
+ u8 lDrvState[FC_MAX_LOGICAL_DRIVES]; /* State of Logical Drives */
+ u8 pDrvState[FC_MAX_PHYSICAL_DEVICES]; /* State of Phys. Drvs. */
+ u16 physDrvFormat[FC_MAX_PHYSICAL_DEVICES/16];
+
+ u8 targXfer[80]; /* phys device transfer rate */
+ u8 pad1k[263]; /* 761 + 263reserved = 1024 bytes total size */
+}__attribute__((packed));
+typedef struct MegaRAID_Enquiry3 mega_Enquiry3;
+
/* Structures */
typedef struct _mega_ADP_INFO {
- u_char MaxConcCmds;
- u_char RbldRate;
- u_char MaxTargPerChan;
- u_char ChanPresent;
- u_char FwVer[4];
- u_short AgeOfFlash;
- u_char ChipSet;
- u_char DRAMSize;
- u_char CacheFlushInterval;
- u_char BiosVer[4];
- u_char resvd[7];
+ u8 MaxConcCmds;
+ u8 RbldRate;
+ u8 MaxTargPerChan;
+ u8 ChanPresent;
+ u8 FwVer[4];
+ u16 AgeOfFlash;
+ u8 ChipSetValue;
+ u8 DramSize;
+ u8 CacheFlushInterval;
+ u8 BiosVer[4];
+ u8 resvd[7];
} mega_ADP_INFO;
typedef struct _mega_LDRV_INFO {
- u_char NumLDrv;
- u_char resvd[3];
- u_long LDrvSize[MAX_LOGICAL_DRIVES];
- u_char LDrvProp[MAX_LOGICAL_DRIVES];
- u_char LDrvState[MAX_LOGICAL_DRIVES];
+ u8 NumLDrv;
+ u8 resvd[3];
+ u32 LDrvSize[MAX_LOGICAL_DRIVES];
+ u8 LDrvProp[MAX_LOGICAL_DRIVES];
+ u8 LDrvState[MAX_LOGICAL_DRIVES];
} mega_LDRV_INFO;
typedef struct _mega_PDRV_INFO {
- u_char PDrvState[MAX_PHYSICAL_DRIVES];
- u_char resvd;
+ u8 PDrvState[MAX_PHYSICAL_DRIVES];
+ u8 resvd;
} mega_PDRV_INFO;
// RAID inquiry: Mailbox command 0x5
// Passthrough command: Mailbox command 0x3
typedef struct mega_passthru {
- u_char timeout:3; /* 0=6sec/1=60sec/2=10min/3=3hrs */
- u_char ars:1;
- u_char reserved:3;
- u_char islogical:1;
- u_char logdrv; /* if islogical == 1 */
- u_char channel; /* if islogical == 0 */
- u_char target; /* if islogical == 0 */
- u_char queuetag; /* unused */
- u_char queueaction; /* unused */
- u_char cdb[MAX_CDB_LEN];
- u_char cdblen;
- u_char reqsenselen;
- u_char reqsensearea[MAX_REQ_SENSE_LEN];
- u_char numsgelements;
- u_char scsistatus;
- u_long dataxferaddr;
- u_long dataxferlen;
+ u8 timeout:3; /* 0=6sec/1=60sec/2=10min/3=3hrs */
+ u8 ars:1;
+ u8 reserved:3;
+ u8 islogical:1;
+ u8 logdrv; /* if islogical == 1 */
+ u8 channel; /* if islogical == 0 */
+ u8 target; /* if islogical == 0 */
+ u8 queuetag; /* unused */
+ u8 queueaction; /* unused */
+ u8 cdb[MAX_CDB_LEN];
+ u8 cdblen;
+ u8 reqsenselen;
+ u8 reqsensearea[MAX_REQ_SENSE_LEN];
+ u8 numsgelements;
+ u8 scsistatus;
+ u32 dataxferaddr;
+ u32 dataxferlen;
} mega_passthru;
typedef struct _mega_mailbox {
- /* 0x0 */ u_char cmd;
- /* 0x1 */ u_char cmdid;
- /* 0x2 */ u_short numsectors;
- /* 0x4 */ u_long lba;
- /* 0x8 */ u_long xferaddr;
- /* 0xC */ u_char logdrv;
- /* 0xD */ u_char numsgelements;
- /* 0xE */ u_char resvd;
- /* 0xF */ u_char busy;
- /* 0x10 */ u_char numstatus;
- /* 0x11 */ u_char status;
- /* 0x12 */ u_char completed[46];
- u_char mraid_poll;
- u_char mraid_ack;
- u_char pad[16];
+ /* 0x0 */ u8 cmd;
+ /* 0x1 */ u8 cmdid;
+ /* 0x2 */ u16 numsectors;
+ /* 0x4 */ u32 lba;
+ /* 0x8 */ u32 xferaddr;
+ /* 0xC */ u8 logdrv;
+ /* 0xD */ u8 numsgelements;
+ /* 0xE */ u8 resvd;
+ /* 0xF */ u8 busy;
+ /* 0x10 */ u8 numstatus;
+ /* 0x11 */ u8 status;
+ /* 0x12 */ u8 completed[46];
+ u8 mraid_poll;
+ u8 mraid_ack;
+ u8 pad[16];
} mega_mailbox;
+typedef struct {
+ u32 xferSegment; /* for 64-bit controllers */
+ mega_mailbox mailbox;
+} mega_mailbox64;
+
typedef struct _mega_ioctl_mbox {
- /* 0x0 */ u_char cmd;
- /* 0x1 */ u_char cmdid;
- /* 0x2 */ u_char channel;
- /* 0x3 */ u_char param;
- /* 0x4 */ u_char pad[4];
- /* 0x8 */ u_long xferaddr;
- /* 0xC */ u_char logdrv;
- /* 0xD */ u_char numsgelements;
- /* 0xE */ u_char resvd;
- /* 0xF */ u_char busy;
- /* 0x10 */ u_char numstatus;
- /* 0x11 */ u_char status;
- /* 0x12 */ u_char completed[46];
- u_char mraid_poll;
- u_char mraid_ack;
- u_char malign[16];
+ /* 0x0 */ u8 cmd;
+ /* 0x1 */ u8 cmdid;
+ /* 0x2 */ u8 channel;
+ /* 0x3 */ u8 param;
+ /* 0x4 */ u8 pad[4];
+ /* 0x8 */ u32 xferaddr;
+ /* 0xC */ u8 logdrv;
+ /* 0xD */ u8 numsgelements;
+ /* 0xE */ u8 resvd;
+ /* 0xF */ u8 busy;
+ /* 0x10 */ u8 numstatus;
+ /* 0x11 */ u8 status;
+ /* 0x12 */ u8 completed[46];
+ u8 mraid_poll;
+ u8 mraid_ack;
+ u8 malign[16];
} mega_ioctl_mbox;
typedef struct _mega_sglist {
- u_long address;
- u_long length;
+ u32 address;
+ u32 length;
} mega_sglist;
/* Queued command data */
struct _mega_scb {
int idx;
- u_long state;
- u_long isrcount;
- u_char mboxData[16];
+ u32 state;
+ u32 isrcount;
+ u8 mboxData[16];
mega_passthru pthru;
Scsi_Cmnd *SCpnt;
mega_sglist *sgList;
+ char *kern_area; /* Only used for large ioctl xfers */
+ struct wait_queue *ioctl_wait;
+ struct semaphore sem;
mega_scb *next;
};
/* Per-controller data */
typedef struct _mega_host_config {
- u_char numldrv;
- u_long flag;
- u_long base;
+ u8 numldrv;
+ u32 flag;
+ u32 base;
mega_scb *qFree;
mega_scb *qPending;
- u_long nReads[MAX_LOGICAL_DRIVES];
- u_long nWrites[MAX_LOGICAL_DRIVES];
+ u32 nReads[FC_MAX_LOGICAL_DRIVES];
+ u32 nWrites[FC_MAX_LOGICAL_DRIVES];
/* Host adapter parameters */
- u_char fwVer[7];
- u_char biosVer[7];
+ u8 fwVer[7];
+ u8 biosVer[7];
struct Scsi_Host *host;
- /* The following must be DMA-able!! */
- volatile mega_mailbox *mbox;
- volatile mega_mailbox mailbox;
- volatile u_char mega_buffer[2 * 1024L];
+ volatile mega_mailbox64 *mbox64; /* ptr to beginning of 64-bit mailbox */
+ volatile mega_mailbox *mbox; /* ptr to beginning of standard mailbox */
+ volatile mega_mailbox64 mailbox64;
+#if 0
+ volatile union {
+ u8 generic_buffer[2 * 1024L];
+ mega_RAIDINQ adapterInfoData;
+ mega_Enquiry3 enquiry3Data;
+ }mega_buffer;
+#else
+ volatile u8 mega_buffer[2*1024L];
+#endif
+ volatile megaRaidProductInfo productInfo;
- u_char max_cmds;
+ u8 max_cmds;
mega_scb scbList[MAX_COMMANDS];
} mega_host_config;