lkml.org 
[lkml]   [2001]   [Feb]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] megaraid port from 2.2.19pre14 to 2.4.2
Hi

Attached is a patch to port of the megaraid driver from 2.2.19pre14 kernel
to 2.4.2. It seems to be stable, but I have only one (production) machine
for testing. The machine runs now about 4 hours with no glitches.

Alan: could you please integrate this one into your tree?
Anyone: could you confirm this works on something other than Elite 1600 ?


Kind regards,
Robert 'Nite' Varga

P.S. The patch doesn't contain full path... sorry about that

------------------------------------------------------------------------------
n@hq.sk http://hq.sk/~nite/gpgkey.txt

--- megaraid.c Tue Jan 9 19:40:43 2001
+++ megaraid.c Fri Feb 23 15:46:40 2001
@@ -2,19 +2,19 @@
*
* Linux MegaRAID device driver
*
- * Copyright 1999 American Megatrends Inc.
+ * Copyright 2000 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.07b
+ * Version : 1b08b
*
* Description: Linux device driver for AMI MegaRAID controller
*
- * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 490
- *
+ * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 471, 490
+ * 493.
* History:
*
* Version 0.90:
@@ -119,15 +119,66 @@
* Fixed the problem of unnecessary aborts in the abort entry point, which
* also enables the driver to handle large amount of I/O requests for
* long duration of time.
- *
+ * Version 1.06
+ * Intel Release
* 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.
+ * Version 108
+ * Modified mega_ioctl so that 40LD megamanager would run
+ * Made some changes for 2.3.XX compilation , esp wait structures
+ * Code merge between 1.05 and 1.06 .
+ * Bug fixed problem with ioctl interface for concurrency between
+ * 8ld and 40ld firwmare
+ * Removed the flawed semaphore logic for handling new config command
+ * Added support for building own scatter / gather list for big user
+ * mode buffers
+ * Added /proc file system support ,so that information is available in
+ * human readable format
+ *
+ * Version 1a08
+ * Changes for IA64 kernels. Checked for CONFIG_PROC_FS flag
+ *
+ * Version 1b08
+ * Include file changes.
+ * Version 1b08b
+ * Change PCI ID value for the 471 card, use #defines when searching
+ * for megaraid cards.
+ *
+ * Version 1.10
+ *
+ * I) Changes made to make following ioctl commands work in 0x81 interface
+ * a)DCMD_DELETE_LOGDRV
+ * b)DCMD_GET_DISK_CONFIG
+ * c)DCMD_DELETE_DRIVEGROUP
+ * d)NC_SUBOP_ENQUIRY3
+ * e)DCMD_CHANGE_LDNO
+ * f)DCMD_CHANGE_LOOPID
+ * g)DCMD_FC_READ_NVRAM_CONFIG
+ * h)DCMD_WRITE_CONFIG
+ * II) Added mega_build_kernel_sg function
+ * III)Firmware flashing option added
+ *
+ * Version 1.10a
+ *
+ * I)Dell updates included in the source code.
+ * Note: This change is not tested due to the unavailability of IA64 kernel
+ * and it is in the #ifdef DELL_MODIFICATION macro which is not defined
+ *
+ * Version 1.10b
+ *
+ * I)In IOCTL_CMD_NEW command the wrong way of copying the data
+ * to the user address corrected
+ *
+ * Version 1.10c
+ *
+ * I) DCMD_GET_DISK_CONFIG opcode updated for the firmware changes.
+ *
+ * Version 1.11
+ * I) Version number changed from 1.10c to 1.11
+ * II) DCMD_WRITE_CONFIG(0x0D) command in the driver changed from
+ * scatter/gather list mode to direct pointer mode..
*
* BUGS:
* Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
@@ -143,23 +194,26 @@
#define CRLFSTR "\n"
#define IOCTL_CMD_NEW 0x81

-#define MEGARAID_VERSION "v107 (December 22, 1999)"
-
+#define MEGARAID_VERSION "v1.11 (Aug 23, 2000)"
+#define MEGARAID_IOCTL_VERSION 108

#include <linux/version.h>

#ifdef MODULE
#include <linux/module.h>

+#if LINUX_VERSION_CODE >= 0x20100
char kernel_version[] = UTS_RELEASE;

MODULE_AUTHOR ("American Megatrends Inc.");
MODULE_DESCRIPTION ("AMI MegaRAID driver");
#endif
+#endif

#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
+#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
@@ -170,9 +224,19 @@
#include <linux/wait.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <asm/pgtable.h>

#include <linux/stat.h>
-#include <linux/spinlock.h>
+#if LINUX_VERSION_CODE < 0x20100
+#include <linux/bios32.h>
+#else
+#if LINUX_VERSION_CODE < 0x20300
+# include <asm/spinlock.h>
+#else
+# include <linux/spinlock.h>
+#endif
+#endif

#include <asm/io.h>
#include <asm/irq.h>
@@ -193,26 +257,48 @@
*================================================================
*/

+#if LINUX_VERSION_CODE < 0x020100
+#define ioremap vremap
+#define iounmap vfree
+
+/* simulate spin locks */
+typedef struct {
+ volatile char lock;
+} spinlock_t;
+
+#define spin_lock_init(x) { (x)->lock = 0;}
+#define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\
+ (x)->lock=1; save_flags(flags);\
+ cli();}
+#define spin_unlock_irqrestore(x,flags) { (x)->lock=0; restore_flags(flags);}
+
+#endif
+
+#if LINUX_VERSION_CODE >= 0x020100
+#define queue_task_irq(a,b) queue_task(a,b)
+#define queue_task_irq_off(a,b) queue_task(a,b)
+#endif
+
#define MAX_SERBUF 160
#define COM_BASE 0x2f8


-u32 RDINDOOR (mega_host_config * megaCfg)
+ulong RDINDOOR (mega_host_config * megaCfg)
{
return readl (megaCfg->base + 0x20);
}

-void WRINDOOR (mega_host_config * megaCfg, u32 value)
+void WRINDOOR (mega_host_config * megaCfg, ulong value)
{
writel (value, megaCfg->base + 0x20);
}

-u32 RDOUTDOOR (mega_host_config * megaCfg)
+ulong RDOUTDOOR (mega_host_config * megaCfg)
{
return readl (megaCfg->base + 0x2C);
}

-void WROUTDOOR (mega_host_config * megaCfg, u32 value)
+void WROUTDOOR (mega_host_config * megaCfg, ulong value)
{
writel (value, megaCfg->base + 0x2C);
}
@@ -264,6 +350,19 @@
static int ser_printk (const char *fmt,...);
#endif

+#ifdef CONFIG_PROC_FS
+#define COPY_BACK if (offset > megaCfg->procidx) { \
+ *eof = TRUE; \
+ megaCfg->procidx = 0; \
+ megaCfg->procbuf[0] = 0; \
+ return 0;} \
+ if ((count + offset) > megaCfg->procidx) { \
+ count = megaCfg->procidx - offset; \
+ *eof = TRUE; } \
+ memcpy(page, &megaCfg->procbuf[offset], count); \
+ megaCfg->procidx = 0; \
+ megaCfg->procbuf[0] = 0;
+#endif
/*================================================================
*
* Global variables
@@ -274,14 +373,20 @@
/* 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 */
-#ifdef MODULE
+
+
+
static char *megaraid = NULL;
+#if LINUX_VERSION_CODE > 0x20100
+#ifdef MODULE
MODULE_PARM(megaraid, "s");
#endif
+#endif
static int skip_id;

static int numCtlrs = 0;
static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = {0};
+struct proc_dir_entry *mega_proc_dir_entry;

#if DEBUG
static u32 maxCmdTime = 0;
@@ -294,6 +399,21 @@
static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
#endif

+
+#if LINUX_VERSION_CODE < 0x20300
+struct proc_dir_entry proc_scsi_megaraid =
+{
+ PROC_SCSI_MEGARAID, 8, "megaraid",
+ S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
+#else
+struct proc_dir_entry *proc_scsi_megaraid;
+#endif
+
+#ifdef CONFIG_PROC_FS
+extern struct proc_dir_entry proc_root;
+#endif
+
#if SERDEBUG
static char strbuf[MAX_SERBUF + 1];

@@ -480,7 +600,7 @@
return 0;
}

-/* Run through the list of completed requests */
+/* Run through the list of completed requests and finish it*/
static void mega_rundoneq (mega_host_config *megaCfg)
{
Scsi_Cmnd *SCpnt;
@@ -523,6 +643,8 @@
mega_passthru *pthru;
mega_mailbox *mbox;

+
+
if (pScb == NULL) {
TRACE(("NULL pScb in mega_cmd_done!"));
printk("NULL pScb in mega_cmd_done!");
@@ -554,6 +676,7 @@

if ((SCpnt->cmnd[0] & 0x80) ) {/* i.e. ioctl cmd such as 0x80, 0x81 of megamgr*/
switch (status) {
+ case 2:
case 0xF0:
case 0xF4:
SCpnt->result=(DID_BAD_TARGET<<16)|status;
@@ -588,12 +711,7 @@
break;
}
}
- 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*/
mega_freeSCB(megaCfg, pScb);
-
/* Add Scsi_Command to end of completed queue */
if( megaCfg->qCompletedH == NULL ) {
megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
@@ -624,8 +742,8 @@
char islogical;
char lun = SCpnt->lun;

- if ((SCpnt->cmnd[0] == 0x80) || (SCpnt->cmnd[0] == IOCTL_CMD_NEW) ) /* ioctl */
- return mega_ioctl (megaCfg, SCpnt);
+ if ((SCpnt->cmnd[0] == 0x80) || (SCpnt->cmnd[0] == IOCTL_CMD_NEW) )
+ return mega_ioctl (megaCfg, SCpnt); /* Handle IOCTL command */

islogical = (SCpnt->channel == megaCfg->host->max_channel);

@@ -641,7 +759,7 @@
return NULL;
}

- if ( islogical ) {
+ if (islogical) {
lun = (SCpnt->target * 8) + lun;
if ( lun > FC_MAX_LOGICAL_DRIVES ){
SCpnt->result = (DID_BAD_TARGET << 16);
@@ -723,6 +841,15 @@
((u32) SCpnt->cmnd[2] << 8) |
(u32) SCpnt->cmnd[3];
mbox->lba &= 0x1FFFFF;
+
+ if (*SCpnt->cmnd == READ_6) {
+ megaCfg->nReads[(int)lun]++;
+ megaCfg->nReadBlocks[(int)lun] += mbox->numsectors;
+ }
+ else {
+ megaCfg->nWrites[(int)lun]++;
+ megaCfg->nWriteBlocks[(int)lun] += mbox->numsectors;
+ }
}

/* 10-byte */
@@ -735,6 +862,15 @@
((u32) SCpnt->cmnd[3] << 16) |
((u32) SCpnt->cmnd[4] << 8) |
(u32) SCpnt->cmnd[5];
+
+ if (*SCpnt->cmnd == READ_10) {
+ megaCfg->nReads[(int)lun]++;
+ megaCfg->nReadBlocks[(int)lun] += mbox->numsectors;
+ }
+ else {
+ megaCfg->nWrites[(int)lun]++;
+ megaCfg->nWriteBlocks[(int)lun] += mbox->numsectors;
+ }
}

/* Calculate Scatter-Gather info */
@@ -791,6 +927,42 @@
return NULL;
}

+/* Handle Driver Level IOCTLs
+ * Return value of 0 indicates this function could not handle , so continue
+ * processing
+*/
+
+static int mega_driver_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
+{
+ unsigned char *data = (unsigned char *)SCpnt->request_buffer;
+ mega_driver_info driver_info;
+
+ /* If this is not our command dont do anything */
+ if (SCpnt->cmnd[0] != DRIVER_IOCTL_INTERFACE)
+ return 0;
+
+ switch(SCpnt->cmnd[1]) {
+ case GET_DRIVER_INFO:
+ if (SCpnt->request_bufflen < sizeof(driver_info)) {
+ SCpnt->result = DID_BAD_TARGET << 16 ;
+ callDone(SCpnt);
+ return 1;
+ }
+
+ driver_info.size = sizeof(driver_info) - sizeof(int);
+ driver_info.version = MEGARAID_IOCTL_VERSION;
+ memcpy( data, &driver_info, sizeof(driver_info));
+ break;
+ default:
+ SCpnt->result = DID_BAD_TARGET << 16;
+ }
+
+ callDone(SCpnt);
+ return 1;
+}
+
+
+
/*--------------------------------------------------------------------
* build RAID commands for controller, passed down through ioctl()
*--------------------------------------------------------------------*/
@@ -801,9 +973,9 @@
mega_mailbox *mailbox;
mega_passthru *pthru;
u8 *mboxdata;
- long seg;
+ long seg, i;
unsigned char *data = (unsigned char *)SCpnt->request_buffer;
- int i;
+

if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
SCpnt->result = (DID_ERROR << 16);
@@ -837,8 +1009,8 @@
(u32 *) & pthru->dataxferaddr,
(u32 *) & pthru->dataxferlen);

- for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) {
- data[i] = data[i+cdblen+7];
+ for (i = 0 ; i < (SCpnt->request_bufflen - cdblen - 7) ; i++) {
+ data[i] = data[i + cdblen + 7];
}

return pScb;
@@ -859,24 +1031,56 @@
* 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");
+ switch (data[0])
+ {
+ case FW_FIRE_WRITE:
+ case FW_FIRE_FLASH:
+ if ((ulong)user_area & (PAGE_SIZE - 1)) {
+ printk("megaraid:user address not aligned on 4K boundary.Error.\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");
+ break;
+ default:
+ break;
+ }
+ if(!(pScb->buff_ptr = kmalloc(xfer_size, GFP_KERNEL))) {
+ printk("megaraid: Insufficient mem for IOCTL_CMD_NEW.\n");
SCpnt->result = (DID_ERROR << 16);
callDone (SCpnt);
return NULL;
}
- copy_from_user(kern_area,user_area,xfer_size);
- pScb->kern_area = kern_area;
+
+ copy_from_user(pScb->buff_ptr,user_area,xfer_size);
+ pScb->sgList[0].address = virt_to_bus(pScb->buff_ptr);
+ pScb->sgList[0].length = xfer_size;
+ pScb->iDataSize = xfer_size;
+ mbox->xferaddr = virt_to_bus(pScb->sgList);
+ mbox->numsgelements = 1;
+
+ switch (data[0]) {
+ case DCMD_FC_CMD:
+ switch (data[1]) {
+ case DCMD_FC_READ_NVRAM_CONFIG:
+ case DCMD_GET_DISK_CONFIG:
+ if ((ulong) pScb->buff_ptr & (PAGE_SIZE - 1)) {
+ printk("megaraid:user address not sufficient Error.\n");
+ SCpnt->result = (DID_ERROR << 16);
+ callDone (SCpnt);
+ return NULL;
+ }
+ //building SG list
+ mega_build_kernel_sg(pScb->buff_ptr, xfer_size, pScb, mbox);
+ break;
+ default:
+ break;
+ }//switch (data[1])
+ break;
+ }
+
}
#endif

@@ -887,16 +1091,58 @@
mbox->logdrv = data[4];

if(SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
- if(data[0]==DCMD_FC_CMD){ /*i.e. 0xA1, then override some mbox data */
+ switch (data[0]) {
+ case FW_FIRE_WRITE:
+ mbox->cmd = FW_FIRE_WRITE;
+ mbox->channel = data[1]; /* Current Block Number */
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
+ mbox->numsgelements = 0;
+ break;
+ case FW_FIRE_FLASH:
+ mbox->cmd = FW_FIRE_FLASH;
+ mbox->channel = data[1] | 0x80 ; /* Origin */
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
+ mbox->numsgelements = 0;
+ break;
+ case DCMD_FC_CMD:
*(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);
+ *(mboxdata+2) = data[1]; /*sub command*/
+ switch (data[1]) {
+ case DCMD_FC_READ_NVRAM_CONFIG:
+ *(mboxdata+3) = mbox->numsgelements; /*number of elements in SG list*/
+ break;
+ case DCMD_WRITE_CONFIG:
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
+ mbox->numsgelements = 0;
+ break;
+ case DCMD_GET_DISK_CONFIG:
+ *(mboxdata+3) = data[2]; /*number of elements in SG list*/
+ *(mboxdata+4) = mbox->numsgelements; /*number of elements in SG list*/
+ break;
+ case DCMD_DELETE_LOGDRV:
+ case DCMD_DELETE_DRIVEGROUP:
+ case NC_SUBOP_ENQUIRY3:
+ *(mboxdata+3) = data[2];
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
+ mbox->numsgelements = 0;
+ break;
+ case DCMD_CHANGE_LDNO:
+ case DCMD_CHANGE_LOOPID:
+ *(mboxdata+3) = data[2];
+ *(mboxdata+4) = data[3];
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
mbox->numsgelements = 0;
+ break;
+ default:
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
+ mbox->numsgelements = 0;
+ break;
+ }//switch
+ break;
+ default:
+ mbox->xferaddr = virt_to_bus(pScb->buff_ptr);
+ mbox->numsgelements = 0;
+ break;
}
}
else {
@@ -913,6 +1159,37 @@
return (pScb);
}

+void mega_build_kernel_sg(char *barea, ulong xfersize, mega_scb *pScb,
+ mega_ioctl_mbox *mbox)
+{
+ ulong i, buffer_area, len, end, end_page, x, idx = 0;
+
+ buffer_area = (ulong)barea;
+ i = buffer_area;
+ end = buffer_area + xfersize;
+ end_page = (end) & ~(PAGE_SIZE - 1);
+
+ do {
+ len = PAGE_SIZE - (i % PAGE_SIZE);
+ x = pScb->sgList[idx].address = virt_to_bus((volatile void *)i);
+ pScb->sgList[idx].length = len;
+ i += len;
+ idx++;
+ } while (i < end_page);
+
+ if ((end - i)< 0) {
+ printk("megaraid:Error in user address\n");
+ }
+
+ if (end - i) {
+ pScb->sgList[idx].address = virt_to_bus((volatile void *)i);
+ pScb->sgList[idx].length = end - i;
+ idx++;
+ }
+ mbox->xferaddr = virt_to_bus(pScb->sgList);
+ mbox->numsgelements = idx;
+}
+
#if DEBUG
static void showMbox(mega_scb *pScb)
{
@@ -955,6 +1232,7 @@
mbox = (mega_mailbox *)tmpBox;

if (megaCfg->host->irq == irq) {
+
if (megaCfg->flag & IN_ISR) {
printk(KERN_ERR "ISR called reentrantly!!\n");
}
@@ -986,8 +1264,10 @@

for(idx=0;idx<MAX_FIRMWARE_STATUS;idx++ ) completed[idx] = 0;

+#if LINUX_VERSION_CODE >= 0x20100
IO_LOCK;
-
+#endif
+ megaCfg->nInterrupts++;
qCnt = 0xff;
while ((qCnt = megaCfg->mbox->numstatus) == 0xFF)
;
@@ -1057,13 +1337,18 @@
continue;
}

- if (*(pScb->SCpnt->cmnd)==IOCTL_CMD_NEW)
- { /* external user buffer */
- up(&pScb->sem);
- }
+ /* We don't want the ISR routine to touch IOCTL_CMD_NEW commands, so
+ * don't mark them as complete, instead we pop their semaphore so
+ * that the queue routine can finish them off
+ */
+ if(pScb->SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
+ /* save the status byte for the queue routine to use */
+ pScb->SCpnt->result = qStatus;
+ up(&pScb->ioctl_sem);
+ } else {
/* Mark command as completed */
mega_cmd_done(megaCfg, pScb, qStatus);
-
+ }
}
else {
printk(KERN_ERR "megaraid: wrong cmd id completed from firmware:id=%x\n",sIdx);
@@ -1073,7 +1358,6 @@
mega_rundoneq(megaCfg);

megaCfg->flag &= ~IN_ISR;
-
/* Loop through any pending requests */
mega_runpendq(megaCfg);
#if LINUX_VERSION_CODE >= 0x20100
@@ -1081,6 +1365,7 @@
#endif

}
+
}

/*==================================================*/
@@ -1121,19 +1406,23 @@
mega_scb * pScb,
int intr)
{
- mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
+ volatile mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
u_char byte;
- u32 cmdDone;
+
+#ifdef __LP64__
+ u64 phys_mbox;
+#else
u32 phys_mbox;
+#endif
u8 retval=-1;

- mboxData[0x1] = (pScb ? pScb->idx + 1: 0x0); /* Set cmdid */
+ mboxData[0x1] = (pScb ? pScb->idx + 1: 0xFE); /* Set cmdid */
mboxData[0xF] = 1; /* Set busy */

phys_mbox = virt_to_bus (megaCfg->mbox);

#if DEBUG
- showMbox(pScb);
+ ShowMbox(pScb);
#endif

/* Wait until mailbox is free */
@@ -1158,7 +1447,7 @@

/* Copy mailbox data into host structure */
megaCfg->mbox64->xferSegment = 0;
- memcpy (mbox, mboxData, 16);
+ memcpy ((char *)mbox, mboxData, 16);

/* Kick IO */
if (intr) {
@@ -1182,10 +1471,18 @@
if (megaCfg->flag & BOARD_QUARTZ) {
mbox->mraid_poll = 0;
mbox->mraid_ack = 0;
+ mbox->numstatus = 0xFF;
+ mbox->status = 0xFF;
WRINDOOR (megaCfg, phys_mbox | 0x1);

- while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
- WROUTDOOR (megaCfg, cmdDone);
+ while (mbox->numstatus == 0xFF);
+ while (mbox->status == 0xFF);
+ while (mbox->mraid_poll != 0x77);
+ mbox->mraid_poll = 0;
+ mbox->mraid_ack = 0x77;
+
+ /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
+ WROUTDOOR (megaCfg, cmdDone);*/

if (pScb) {
mega_cmd_done (megaCfg, pScb, mbox->status);
@@ -1282,9 +1579,15 @@
{
/* align on 16-byte boundry */
megaCfg->mbox = &megaCfg->mailbox64.mailbox;
- megaCfg->mbox = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xfffffff0);
+#ifdef __LP64__
+ megaCfg->mbox = (mega_mailbox *) ((((u64) megaCfg->mbox) + 16) & ( (ulong)(-1) ^ 0x0F) );
+ megaCfg->mbox64 = (mega_mailbox64 *) (megaCfg->mbox - 4);
+ paddr = (paddr + 4 + 16) & ( (u64)(-1) ^ 0x0F );
+#else
+ megaCfg->mbox = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xFFFFFFF0);
megaCfg->mbox64 = (mega_mailbox64 *) (megaCfg->mbox - 4);
- paddr = (paddr + 4 + 16) & 0xfffffff0;
+ paddr = (paddr + 4 + 16) & 0xFFFFFFF0;
+#endif

/* Register mailbox area with the firmware */
if (!(megaCfg->flag & BOARD_QUARTZ)) {
@@ -1430,10 +1733,10 @@
megaCfg->productInfo.BiosVer[2] >> 8,
megaCfg->productInfo.BiosVer[2] & 0x0f);
#else
- memcpy (megaCfg->fwVer, (void *)megaCfg->productInfo.FwVer, 4);
+ memcpy (megaCfg->fwVer, (char *)megaCfg->productInfo.FwVer, 4);
megaCfg->fwVer[4] = 0;

- memcpy (megaCfg->biosVer, (void *)megaCfg->productInfo.BiosVer, 4);
+ memcpy (megaCfg->biosVer, (char *)megaCfg->productInfo.BiosVer, 4);
megaCfg->biosVer[4] = 0;
#endif

@@ -1458,6 +1761,7 @@
int length, int host_no, int inout)
{
*start = buffer;
+
return 0;
}

@@ -1465,32 +1769,106 @@
u16 pciVendor, u16 pciDev,
long flag)
{
- mega_host_config *megaCfg;
- struct Scsi_Host *host;
- u_char megaIrq;
+ mega_host_config *megaCfg = NULL;
+ struct Scsi_Host *host = NULL;
+ u_char pciBus, pciDevFun, megaIrq;
+
+#ifdef __LP64__
+ u64 megaBase;
+#else
u32 megaBase;
+#endif
+
+ u16 pciIdx = 0;
u16 numFound = 0;

+#if LINUX_VERSION_CODE < 0x20100
+ while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
+#else
+#if LINUX_VERSION_CODE > 0x20300
struct pci_dev *pdev = NULL;
+#else
+ struct pci_dev *pdev = pci_devices;
+#endif
+ skip_id = -1;
+ if (megaraid && !strncmp(megaraid,"skip",strlen("skip"))) {
+ if (megaraid[4] != '\0') {
+ skip_id = megaraid[4] - '0';
+ if (megaraid[5] != '\0') {
+ skip_id = (skip_id * 10) + (megaraid[5] - '0');
+ }
+ }
+ skip_id = (skip_id > 15) ? -1 : skip_id;
+ }

while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
+
+#ifdef DELL_MODIFICATION
if (pci_enable_device(pdev))
continue;
+#endif
+ pciBus = pdev->bus->number;
+ pciDevFun = pdev->devfn;
+#endif
if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
u16 magic;
- pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
- if ((magic != AMI_SIGNATURE) && (magic != AMI_SIGNATURE_471))
+ pcibios_read_config_word (pciBus, pciDevFun,
+ PCI_CONF_AMISIG,
+ &magic);
+ if ((magic != AMI_SIGNATURE) && (magic != AMI_SIGNATURE_471) ){
+ pciIdx++;
continue; /* not an AMI board */
}
- printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x: in %s\n",
+ }
+
+/* Hmmm...Should we not make this more modularized so that in future we dont add
+ for each firmware */
+
+ 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=2940\n");
+ continue;
+ }
+ }
+
+ printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n",
pciVendor,
pciDev,
- pdev->slot_name);
+ pciIdx, pciBus,
+ PCI_SLOT (pciDevFun),
+ PCI_FUNC (pciDevFun));

/* Read the base port and IRQ from PCI */
megaBase = pci_resource_start (pdev, 0);
megaIrq = pdev->irq;

+ pciIdx++;
+
if (flag & BOARD_QUARTZ)
megaBase = (long) ioremap (megaBase, 128);
else
@@ -1524,6 +1902,7 @@
megaCfg->host->n_io_port = 16;
megaCfg->host->unique_id = (pdev->bus->number << 8) | pdev->devfn;
megaCtlrs[numCtlrs++] = megaCfg;
+
if (flag != BOARD_QUARTZ) {
/* Request our IO Range */
if (request_region (megaBase, 16, "megaraid")) {
@@ -1545,42 +1924,9 @@
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=2940\n");
- megaraid_release (host);
-#ifdef MODULE
- continue;
-#else
- while(1) schedule_timeout(1 * HZ);
-#endif
- }
- }
-
/* Initialize SCBs */
if (mega_initSCB (megaCfg)) {
- megaraid_release (host);
+ scsi_unregister (host);
continue;
}

@@ -1594,20 +1940,53 @@
*---------------------------------------------------------*/
int megaraid_detect (Scsi_Host_Template * pHostTmpl)
{
- int count = 0;
+ int ctlridx = 0, count = 0;

#ifdef MODULE
if (megaraid)
megaraid_setup(megaraid);
#endif

+#if LINUX_VERSION_CODE < 0x20300
+ pHostTmpl->proc_dir = &proc_scsi_megaraid;
+#else
pHostTmpl->proc_name = "megaraid";
+#endif
+
+#if LINUX_VERSION_CODE < 0x20100
+ if (!pcibios_present ()) {
+ printk (KERN_WARNING "megaraid: PCI bios not present." CRLFSTR);
+ return 0;
+ }
+#endif

printk ("megaraid: " MEGARAID_VERSION CRLFSTR);

- count += mega_findCard (pHostTmpl, 0x101E, 0x9010, 0);
- count += mega_findCard (pHostTmpl, 0x101E, 0x9060, 0);
- count += mega_findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
+ count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
+ PCI_DEVICE_ID_AMI_MEGARAID, 0);
+ count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
+ PCI_DEVICE_ID_AMI_MEGARAID2, 0);
+ count += mega_findCard (pHostTmpl, 0x8086,
+ PCI_DEVICE_ID_AMI_MEGARAID3, BOARD_QUARTZ);
+ count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
+ PCI_DEVICE_ID_AMI_MEGARAID3, BOARD_QUARTZ);
+
+#ifdef CONFIG_PROC_FS
+ if (count) {
+#if LINUX_VERSION_CODE > 0x20300
+ mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root);
+#else
+ mega_proc_dir_entry = create_proc_entry("megaraid",
+ S_IFDIR | S_IRUGO | S_IXUGO,
+ &proc_root);
+#endif
+ if (!mega_proc_dir_entry)
+ printk("megaraid: failed to create megaraid root\n");
+ else
+ for (ctlridx = 0; ctlridx < count ; ctlridx++)
+ mega_create_proc_entry(ctlridx, mega_proc_dir_entry);
+ }
+#endif

return count;
}
@@ -1620,6 +1999,7 @@
mega_host_config *megaCfg;
mega_mailbox *mbox;
u_char mboxData[16];
+ int i;

megaCfg = (mega_host_config *) pSHost->hostdata;
mbox = (mega_mailbox *) mboxData;
@@ -1645,6 +2025,22 @@
mega_freeSgList(megaCfg);
scsi_unregister (pSHost);

+#ifdef CONFIG_PROC_FS
+ if (megaCfg->controller_proc_dir_entry) {
+ remove_proc_entry("stat",megaCfg->controller_proc_dir_entry);
+ remove_proc_entry("status", megaCfg->controller_proc_dir_entry);
+ remove_proc_entry("config", megaCfg->controller_proc_dir_entry);
+ remove_proc_entry("mailbox", megaCfg->controller_proc_dir_entry);
+ for (i = 0; i < numCtlrs; i++) {
+ char buf[12];
+ memset(buf,0,12);
+ sprintf(buf,"%d",i);
+ remove_proc_entry(buf,mega_proc_dir_entry);
+ }
+ remove_proc_entry("megaraid", &proc_root);
+ }
+#endif
+
return 0;
}

@@ -1697,6 +2093,7 @@
DRIVER_LOCK_T
mega_host_config *megaCfg;
mega_scb *pScb;
+ char *user_area = NULL;

megaCfg = (mega_host_config *) SCpnt->host->hostdata;
DRIVER_LOCK(megaCfg);
@@ -1714,6 +2111,9 @@

SCpnt->scsi_done = pktComp;

+ if (mega_driver_ioctl(megaCfg, SCpnt))
+ return 0;
+
/* If driver in abort or reset.. cancel this command */
if (megaCfg->flag & IN_ABORT) {
SCpnt->result = (DID_ABORT << 16);
@@ -1765,31 +2165,31 @@
megaCfg->qPcnt++;

mega_runpendq(megaCfg);
-
-#if LINUX_VERSION_CODE > 0x020024
- if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW )
- { /* user data from external user buffer */
- char *user_area;
- u32 xfer_size;
-
- init_MUTEX_LOCKED(&pScb->sem);
- down(&pScb->sem);
-
+ if(pScb->SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
+ init_MUTEX_LOCKED(&pScb->ioctl_sem);
+ spin_unlock_irq(&io_request_lock);
+ down(&pScb->ioctl_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);
-
- mega_freeSCB(megaCfg, pScb);
+ if(copy_to_user(user_area,pScb->buff_ptr,pScb->iDataSize)) {
+ printk("megaraid: Error copying ioctl return value to user buffer.\n");
+ pScb->SCpnt->result = (DID_ERROR << 16);
}
-#endif
+ spin_lock_irq(&io_request_lock);
+ DRIVER_LOCK(megaCfg);
+ kfree(pScb->buff_ptr);
+ pScb->buff_ptr = NULL;
+ mega_cmd_done(megaCfg, pScb, pScb->SCpnt->result);
+ mega_rundoneq(megaCfg);
+ mega_runpendq(megaCfg);
+ DRIVER_UNLOCK(megaCfg);
}

megaCfg->flag &= ~IN_QUEUE;
- DRIVER_UNLOCK(megaCfg);

+ }
+
+
+ DRIVER_UNLOCK(megaCfg);
return 0;
}

@@ -1798,7 +2198,13 @@
*----------------------------------------------------------------------*/
volatile static int internal_done_flag = 0;
volatile static int internal_done_errcode = 0;
-static DECLARE_WAIT_QUEUE_HEAD(internal_wait);
+
+#if LINUX_VERSION_CODE < 0x20300
+ static struct wait_queue *internal_wait = NULL;
+#else
+ static DECLARE_WAIT_QUEUE_HEAD(internal_wait);
+#endif
+

static void internal_done (Scsi_Cmnd * SCpnt)
{
@@ -1958,6 +2364,221 @@
mega_rundoneq(megaCfg);
return rc;
}
+
+
+#ifdef CONFIG_PROC_FS
+/* Following code handles /proc fs */
+static int proc_printf (mega_host_config *megaCfg, const char *fmt,...)
+{
+ va_list args;
+ int i;
+
+ if (megaCfg->procidx > PROCBUFSIZE)
+ return 0;
+
+ va_start (args, fmt);
+ i = vsprintf ((megaCfg->procbuf + megaCfg->procidx), fmt, args);
+ va_end (args);
+
+ megaCfg->procidx += i;
+ return i;
+}
+
+
+static int proc_read_config(char *page, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+
+ mega_host_config *megaCfg = (mega_host_config *)data;
+
+ *start = page;
+
+ if (megaCfg->productInfo.ProductName[0] != 0)
+ proc_printf(megaCfg,"%s\n",megaCfg->productInfo.ProductName);
+
+ proc_printf(megaCfg,"Controller Type: ");
+
+ if (megaCfg->flag & BOARD_QUARTZ)
+ proc_printf(megaCfg,"438/466/467/471/493\n");
+ else
+ proc_printf(megaCfg,"418/428/434\n");
+
+ if (megaCfg->flag & BOARD_40LD)
+ proc_printf(megaCfg,"Controller Supports 40 Logical Drives\n");
+
+ proc_printf(megaCfg,"Base = %08x, Irq = %d, ",megaCfg->base,
+ megaCfg->host->irq);
+
+ proc_printf(megaCfg, "Logical Drives = %d, Channels = %d\n",
+ megaCfg->numldrv, megaCfg->productInfo.SCSIChanPresent);
+
+ proc_printf(megaCfg, "Version =%s:%s, DRAM = %dMb\n",
+ megaCfg->fwVer,megaCfg->biosVer,
+ megaCfg->productInfo.DramSize);
+
+ proc_printf(megaCfg,"Controller Queue Depth = %d, Driver Queue Depth = %d\n",
+ megaCfg->productInfo.MaxConcCmds, megaCfg->max_cmds);
+ COPY_BACK;
+ return count;
+}
+
+
+
+static int proc_read_stat(char *page, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int i;
+ mega_host_config *megaCfg = (mega_host_config *)data;
+
+ *start = page;
+
+ proc_printf(megaCfg,"Statistical Information for this controller\n");
+ proc_printf(megaCfg,"Interrupts Collected = %d\n", megaCfg->nInterrupts);
+
+ for (i = 0; i < megaCfg->numldrv; i++) {
+ proc_printf(megaCfg,"Logical Drive %d:\n", i);
+ proc_printf(megaCfg,"\tReads Issued = %10d, Writes Issued = %10d\n",
+ megaCfg->nReads[i], megaCfg->nWrites[i]);
+
+ proc_printf(megaCfg,"\tSectors Read = %10d, Sectors Written = %10d\n\n", megaCfg->nReadBlocks[i],
+ megaCfg->nWriteBlocks[i]);
+ }
+
+ COPY_BACK;
+ return count;
+}
+
+
+
+static int proc_read_status(char *page, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ mega_host_config *megaCfg = (mega_host_config *)data;
+ *start = page;
+
+ proc_printf(megaCfg,"TBD\n");
+ COPY_BACK;
+ return count;
+}
+
+
+static int proc_read_mbox(char *page, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+// int i;
+// char *dta = NULL;
+ mega_host_config *megaCfg = (mega_host_config *)data;
+ volatile mega_mailbox *mbox = megaCfg->mbox;
+
+ *start = page;
+
+ proc_printf(megaCfg,"Contents of Mail Box Structure\n");
+ proc_printf(megaCfg," Fw Command = 0x%02x\n", mbox->cmd);
+ proc_printf(megaCfg," Cmd Sequence = 0x%02x\n", mbox->cmdid);
+ proc_printf(megaCfg," No of Sectors= %04d\n", mbox->numsectors);
+ proc_printf(megaCfg," LBA = 0x%02x\n", mbox->lba);
+ proc_printf(megaCfg," DTA = 0x%08x\n", mbox->xferaddr);
+ proc_printf(megaCfg," Logical Drive= 0x%02x\n", mbox->logdrv);
+ proc_printf(megaCfg," No of SG Elmt= 0x%02x\n", mbox->numsgelements);
+ proc_printf(megaCfg," Busy = %01x\n", mbox->busy);
+ proc_printf(megaCfg," Status = 0x%02x\n", mbox->status);
+
+/* proc_printf(megaCfg, "Dump of MailBox\n");
+ for (i = 0; i < 16; i++)
+ proc_printf(megaCfg, "%02x ",*(mbox + i));
+
+proc_printf(megaCfg, "\n\nNumber of Status = %02d\n",mbox->numstatus);
+
+ for (i = 0; i < 46; i++) {
+ proc_printf(megaCfg,"%02d ",*(mbox + 16 + i));
+ if (i%16)
+ proc_printf(megaCfg,"\n");
+}
+
+if (!mbox->numsgelements) {
+ dta = phys_to_virt(mbox->xferaddr);
+ for (i = 0; i < mbox->numsgelements; i++)
+ if (dta) {
+ proc_printf(megaCfg,"Addr = %08x\n", (ulong)*(dta + i)); proc_printf(megaCfg,"Length = %08x\n",
+ (ulong)*(dta + i + 4));
+ }
+}*/
+ COPY_BACK;
+ return count;
+}
+
+
+#if LINUX_VERSION_CODE > 0x20300
+#define CREATE_READ_PROC(string, fxn) create_proc_read_entry(string, \
+ S_IRUSR | S_IFREG,\
+ controller_proc_dir_entry,\
+ fxn, megaCfg)
+#else
+#define CREATE_READ_PROC(string, fxn) create_proc_read_entry(string,S_IRUSR | S_IFREG, controller_proc_dir_entry, fxn, megaCfg)
+
+struct proc_dir_entry *create_proc_read_entry(const char *string,
+ int mode,
+ struct proc_dir_entry *parent,
+ read_proc_t *fxn,
+ mega_host_config *megaCfg)
+{
+ struct proc_dir_entry *temp = NULL;
+
+ temp = kmalloc(sizeof(struct proc_dir_entry),
+ GFP_KERNEL);
+ if (!temp)
+ return NULL;
+ memset(temp, 0, sizeof(struct proc_dir_entry));
+
+ if ( (temp->name = kmalloc(strlen(string) + 1, GFP_KERNEL)) == NULL) {
+ kfree(temp);
+ return NULL;
+ }
+
+ strcpy((char *)temp->name, string);
+ temp->namelen = strlen(string);
+ temp->mode = mode ; /*S_IFREG | S_IRUSR*/;
+ temp->data = (void *)megaCfg;
+ temp->read_proc = fxn;
+ proc_register(parent, temp);
+ return temp;
+}
+#endif
+
+
+
+void mega_create_proc_entry(int index, struct proc_dir_entry *parent)
+{
+ u_char string[64] = {0};
+ mega_host_config *megaCfg = megaCtlrs[index];
+ struct proc_dir_entry *controller_proc_dir_entry = NULL;
+
+ sprintf(string,"%d", index);
+
+#if LINUX_VERSION_CODE > 0x20300
+ controller_proc_dir_entry =
+ megaCfg->controller_proc_dir_entry =
+ proc_mkdir(string, parent);
+#else
+ controller_proc_dir_entry =
+ megaCfg->controller_proc_dir_entry =
+ create_proc_entry(string,S_IFDIR | S_IRUGO | S_IXUGO, parent);
+#endif
+
+ if (!controller_proc_dir_entry)
+ printk("\nmegaraid: proc_mkdir failed\n");
+ else
+ {
+ megaCfg->proc_read = CREATE_READ_PROC("config", proc_read_config);
+ megaCfg->proc_status = CREATE_READ_PROC("status", proc_read_status);
+ megaCfg->proc_stat = CREATE_READ_PROC("stat", proc_read_stat);
+ megaCfg->proc_mbox = CREATE_READ_PROC("mailbox", proc_read_mbox);
+ }
+
+}
+#endif /* CONFIG_PROC_FS */
+
+

/*-------------------------------------------------------------
* Return the disk geometry for a particular disk
--- megaraid.h Mon Dec 11 22:19:40 2000
+++ megaraid.h Fri Feb 23 15:46:36 2001
@@ -22,6 +22,11 @@
#define SCB_RESET 0x6
#endif

+/* IOCTL DRIVER INFO */
+#define DRIVER_IOCTL_INTERFACE 0x82
+/* Methods */
+#define GET_DRIVER_INFO 1
+
#define MEGA_CMD_TIMEOUT 10

/* Feel free to fiddle with these.. max values are:
@@ -96,13 +101,42 @@
#define ENABLE_INTR(base) WRITE_PORT(base,I_TOGGLE_PORT,ENABLE_INTR_BYTE)
#define DISABLE_INTR(base) WRITE_PORT(base,I_TOGGLE_PORT,DISABLE_INTR_BYTE)

+/* Special Adapter Commands */
+#define FW_FIRE_WRITE 0x2C
+#define FW_FIRE_FLASH 0x2D
+
+#define FC_NEW_CONFIG 0xA1
+#define DCMD_FC_CMD 0xA1
+ #define DCMD_FC_PROCEED 0x02
+ #define DCMD_DELETE_LOGDRV 0x03
+ #define DCMD_FC_READ_NVRAM_CONFIG 0x04
+ #define DCMD_FC_READ_FINAL_CONFIG 0x05
+ #define DCMD_GET_DISK_CONFIG 0x06
+ #define DCMD_CHANGE_LDNO 0x07
+ #define DCMD_COMPACT_CONFIG 0x08
+ #define DCMD_DELETE_DRIVEGROUP 0x09
+ #define DCMD_GET_LOOPID_INFO 0x0A
+ #define DCMD_CHANGE_LOOPID 0x0B
+ #define DCMD_GET_NUM_SCSI_CHANS 0x0C
+ #define DCMD_WRITE_CONFIG 0x0D /* writes 40-ld config */
+ #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
+
+
/* Define AMI's PCI codes */
#undef PCI_VENDOR_ID_AMI
#undef PCI_DEVICE_ID_AMI_MEGARAID
+#undef PCI_DEVICE_ID_AMI_MEGARAID2
+#undef PCI_DEVICE_ID_AMI_MEGARAID3

#ifndef PCI_VENDOR_ID_AMI
#define PCI_VENDOR_ID_AMI 0x101E
#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010
+#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060
+#define PCI_DEVICE_ID_AMI_MEGARAID3 0x1960
#endif

#define PCI_CONF_BASE_ADDR_OFFSET 0x10
@@ -528,8 +562,8 @@
/* 0x10 */ u8 numstatus;
/* 0x11 */ u8 status;
/* 0x12 */ u8 completed[46];
- u8 mraid_poll;
- u8 mraid_ack;
+ volatile u8 mraid_poll;
+ volatile u8 mraid_ack;
u8 pad[16]; /* for alignment purposes */
}__attribute__((packed));
typedef struct _mega_mailbox mega_mailbox;
@@ -574,9 +608,9 @@
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;
+ struct semaphore ioctl_sem;
+ void *buff_ptr;
+ u32 iDataSize;
mega_scb *next;
};

@@ -584,7 +618,12 @@
typedef struct _mega_host_config {
u8 numldrv;
u32 flag;
+
+#ifdef __LP64__
+ u64 base;
+#else
u32 base;
+#endif

mega_scb *qFreeH;
mega_scb *qFreeT;
@@ -598,7 +637,10 @@
u32 qCcnt;

u32 nReads[FC_MAX_LOGICAL_DRIVES];
+ u32 nReadBlocks[FC_MAX_LOGICAL_DRIVES];
u32 nWrites[FC_MAX_LOGICAL_DRIVES];
+ u32 nWriteBlocks[FC_MAX_LOGICAL_DRIVES];
+ u32 nInterrupts;

/* Host adapter parameters */
u8 fwVer[7];
@@ -622,8 +664,18 @@

u8 max_cmds;
mega_scb scbList[MAX_COMMANDS];
+#define PROCBUFSIZE 4096
+ char procbuf[PROCBUFSIZE];
+ int procidx;
+ struct proc_dir_entry *controller_proc_dir_entry;
+ struct proc_dir_entry *proc_read, *proc_stat, *proc_status, *proc_mbox;
} mega_host_config;

+typedef struct _driver_info {
+ int size;
+ ulong version;
+} mega_driver_info;
+
const char *megaraid_info(struct Scsi_Host *);
int megaraid_detect(Scsi_Host_Template *);
int megaraid_release(struct Scsi_Host *);
@@ -634,5 +686,8 @@
int megaraid_biosparam(Disk *, kdev_t, int *);
int megaraid_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout);
+
+void mega_build_kernel_sg(char *, ulong , mega_scb *, mega_ioctl_mbox *);
+void mega_create_proc_entry(int index, struct proc_dir_entry *);

#endif[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2005-03-22 13:17    [W:0.072 / U:0.148 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site