[PATCH 2.4.31 1/1] scsi/megaraid2: add 64-bit application support

From: Ju, Seokmann
Date: Fri Jul 15 2005 - 10:35:22 EST


This patch contains accumulated changes over the time.

Description of the changes.
### Version 2.10.10.1
Thu Jan 27 15:59:59 EDT 2005 - Seokmann Ju <sju@xxxxxxxx>
1. There was a bug in the 'megadev_ioctl()' function that cause random
deletion error and has been fixed.

### Version 2.10.10.0
Fri Jan 21 15:59:59 EDT 2005 - Seokmann Ju <sju@xxxxxxxx>
1. Fixed Tape drive issue : For any Direct CDB command to physical
device
including tape, timeout value set by driver was 10 minutes. With
this
value, most of command will return within timeout. However, for
those
command like ERASE or FORMAT, it takes more than an hour depends on
capacity of the device and the command could be terminated before it
completes.
To address this issue, the 'timeout' field in the DCDB command will
have NO TIMEOUT (i.e., 4) value as its timeout on DCDB command.
2. Added NEC ROMB support : NEC MegaRAID PCI Express ROMB controller

### Version 2.10.9.0
Fri Aug 13 15:59:59 EDT 2004 - Rajesh Prabhakaran <rajeshpr@xxxxxxxx>
1. Added Support for 64-applications : mega_ioctl function and
nitioctl_t struct where changed to accomadate 64-bit addressing.

Signed-off-by: Seokmann Ju <seokmann.ju@xxxxxxxx>

---
diff -Naur old/drivers/scsi/megaraid2.c new/drivers/scsi/megaraid2.c
--- old/drivers/scsi/megaraid2.c 2005-07-15 07:52:27.555937432 -0400
+++ new/drivers/scsi/megaraid2.c 2005-07-15 07:52:18.564304368 -0400
@@ -14,7 +14,7 @@
* - speed-ups (list handling fixes, issued_list, optimizations.)
* - lots of cleanups.
*
- * Version : v2.10.8.2 (July 26, 2004)
+ * Version : v2.10.10.1 (January 27, 2005)
*
* Authors: Atul Mukker <Atul.Mukker@xxxxxxxx>
* Sreenivas Bagalkote <Sreenivas.Bagalkote@xxxxxxxx>
@@ -46,7 +46,7 @@

#include "megaraid2.h"

-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
#include <asm/ioctl32.h>
#endif

@@ -233,7 +233,7 @@
"MegaRAID Shutdown routine not
registered!!\n");
}

-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
/*
* Register the 32-bit ioctl conversion
*/
@@ -341,6 +341,7 @@
(subsysvid != INTEL_SUBSYS_VID) &&
(subsysvid != FSC_SUBSYS_VID) &&
(subsysvid != ACER_SUBSYS_VID) &&
+ (subsysvid != NEC_SUBSYS_VID) &&
(subsysvid != LSI_SUBSYS_VID) ) continue;


@@ -989,268 +990,6 @@
}


-/**
- * issue_scb()
- * @adapter - pointer to our soft state
- * @scb - scsi control block
- *
- * Post a command to the card if the mailbox is available, otherwise return
- * busy. We also take the scb from the pending list if the mailbox is
- * available.
- */
-static inline int
-issue_scb(adapter_t *adapter, scb_t *scb)
-{
- volatile mbox64_t *mbox64 = adapter->mbox64;
- volatile mbox_t *mbox = adapter->mbox;
- unsigned int i = 0;
-
- if(unlikely(mbox->busy)) {
- do {
- udelay(1);
- i++;
- } while( mbox->busy && (i < max_mbox_busy_wait) );
-
- if(mbox->busy) return -1;
- }
-
- /* Copy mailbox data into host structure */
- memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
-
- mbox->cmdid = scb->idx; /* Set cmdid */
- mbox->busy = 1; /* Set busy */
-
-
- /*
- * Increment the pending queue counter
- */
- atomic_inc(&adapter->pend_cmds);
-
- switch (mbox->cmd) {
- case MEGA_MBOXCMD_EXTPTHRU:
- if( !adapter->has_64bit_addr ) break;
- // else fall through
- case MEGA_MBOXCMD_LREAD64:
- case MEGA_MBOXCMD_LWRITE64:
- case MEGA_MBOXCMD_PASSTHRU64:
- mbox64->xfer_segment_lo = mbox->xferaddr;
- mbox64->xfer_segment_hi = 0;
- mbox->xferaddr = 0xFFFFFFFF;
- break;
- default:
- mbox64->xfer_segment_lo = 0;
- mbox64->xfer_segment_hi = 0;
- }
-
- /*
- * post the command
- */
- scb->state |= SCB_ISSUED;
-
- if( likely(adapter->flag & BOARD_MEMMAP) ) {
- mbox->poll = 0;
- mbox->ack = 0;
- WRINDOOR(adapter, adapter->mbox_dma | 0x1);
- }
- else {
- irq_enable(adapter);
- issue_command(adapter);
- }
-
- return 0;
-}
-
-
-/**
- * mega_runpendq()
- * @adapter - pointer to our soft state
- *
- * Runs through the list of pending requests.
- */
-static inline void
-mega_runpendq(adapter_t *adapter)
-{
- if(!list_empty(&adapter->pending_list))
- __mega_runpendq(adapter);
-}
-
-
-static void
-__mega_runpendq(adapter_t *adapter)
-{
- scb_t *scb;
- struct list_head *pos, *next;
-
- /* Issue any pending commands to the card */
- list_for_each_safe(pos, next, &adapter->pending_list) {
-
- scb = list_entry(pos, scb_t, list);
-
- if( !(scb->state & SCB_ISSUED) ) {
-
- if( issue_scb(adapter, scb) != 0 )
- return;
- }
- }
-
- return;
-}
-
-
-/**
- * mega_allocate_scb()
- * @adapter - pointer to our soft state
- * @cmd - scsi command from the mid-layer
- *
- * Allocate a SCB structure. This is the central structure for controller
- * commands.
- */
-static inline scb_t *
-mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd)
-{
- struct list_head *head = &adapter->free_list;
- scb_t *scb;
-
- /* Unlink command from Free List */
- if( !list_empty(head) ) {
-
- scb = list_entry(head->next, scb_t, list);
-
- list_del_init(head->next);
-
- scb->state = SCB_ACTIVE;
- scb->cmd = cmd;
- scb->dma_type = MEGA_DMA_TYPE_NONE;
-
- return scb;
- }
-
- return NULL;
-}
-
-
-/**
- * mega_get_ldrv_num()
- * @adapter - pointer to our soft state
- * @cmd - scsi mid layer command
- * @channel - channel on the controller
- *
- * Calculate the logical drive number based on the information in scsi
command
- * and the channel number.
- */
-static inline int
-mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel)
-{
- int tgt;
- int ldrv_num;
-
- tgt = cmd->target;
-
- if ( tgt > adapter->this_id )
- tgt--; /* we do not get inquires for initiator id */
-
- ldrv_num = (channel * 15) + tgt;
-
-
- /*
- * If we have a logical drive with boot enabled, project it first
- */
- if( adapter->boot_ldrv_enabled ) {
- if( ldrv_num == 0 ) {
- ldrv_num = adapter->boot_ldrv;
- }
- else {
- if( ldrv_num <= adapter->boot_ldrv ) {
- ldrv_num--;
- }
- }
- }
-
- /*
- * If "delete logical drive" feature is enabled on this controller,
- * the value returned should be 0x80+logical drive id.
- */
- if (adapter->support_random_del)
- ldrv_num += 0x80;
-
- return ldrv_num;
-}
-
-/*
- * Wait until the controller's mailbox is available
- */
-static inline int
-mega_busywait_mbox (adapter_t *adapter)
-{
- if (adapter->mbox->busy)
- return __mega_busywait_mbox(adapter);
- return 0;
-}
-
-
-/**
- * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs
- * @adapter - controller's soft state
- *
- * Interrupt ackrowledgement sequence for IO mapped HBAs
- */
-static inline void
-megaraid_iombox_ack_sequence(adapter_t *adapter)
-{
- u8 status;
- u8 nstatus;
- u8 completed[MAX_FIRMWARE_STATUS];
- u8 byte;
- int i;
-
-
- /*
- * loop till F/W has more commands for us to complete.
- */
- do {
- /* Check if a valid interrupt is pending */
- byte = irq_state(adapter);
- if( (byte & VALID_INTR_BYTE) == 0 ) {
- return;
- }
- set_irq_state(adapter, byte);
-
- while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
- cpu_relax();
- }
- adapter->mbox->numstatus = 0xFF;
-
- for (i = 0; i < nstatus; i++) {
- while ((completed[i] = adapter->mbox->completed[i])
- == 0xFF) {
- cpu_relax();
- }
-
- adapter->mbox->completed[i] = 0xFF;
- }
-
- // we must read the valid status now
- if ((status = adapter->mbox->status) == 0xFF) {
- printk(KERN_WARNING
- "megaraid critical: status 0xFF from firmware.\n");
- }
- adapter->mbox->status = 0xFF;
-
- /*
- * decrement the pending queue counter
- */
- atomic_sub(nstatus, &adapter->pend_cmds);
-
- /* Acknowledge interrupt */
- irq_ack(adapter);
-
- mega_cmd_done(adapter, completed, nstatus, status);
-
- } while(1);
-}
-
-
-
/*
* megaraid_queue()
* @scmd - Issue this scsi command
@@ -1755,8 +1494,8 @@
pthru = scb->pthru;
memset(pthru, 0, sizeof (mega_passthru));

- /* 0=6sec/1=60sec/2=10min/3=3hrs */
- pthru->timeout = 2;
+ /* 0=6sec/1=60sec/2=10min/3=3hrs/4=NO timeout */
+ pthru->timeout = 4;

pthru->ars = 1;
pthru->reqsenselen = 14;
@@ -1819,8 +1558,8 @@
epthru = scb->epthru;
memset(epthru, 0, sizeof(mega_ext_passthru));

- /* 0=6sec/1=60sec/2=10min/3=3hrs */
- epthru->timeout = 2;
+ /* 0=6sec/1=60sec/2=10min/3=3hrs/4=NO timeout */
+ epthru->timeout = 4;

epthru->ars = 1;
epthru->reqsenselen = 14;
@@ -1863,6 +1602,145 @@


/**
+ * mega_allocate_scb()
+ * @adapter - pointer to our soft state
+ * @cmd - scsi command from the mid-layer
+ *
+ * Allocate a SCB structure. This is the central structure for controller
+ * commands.
+ */
+static inline scb_t *
+mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd)
+{
+ struct list_head *head = &adapter->free_list;
+ scb_t *scb;
+
+ /* Unlink command from Free List */
+ if( !list_empty(head) ) {
+
+ scb = list_entry(head->next, scb_t, list);
+
+ list_del_init(head->next);
+
+ scb->state = SCB_ACTIVE;
+ scb->cmd = cmd;
+ scb->dma_type = MEGA_DMA_TYPE_NONE;
+
+ return scb;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * mega_runpendq()
+ * @adapter - pointer to our soft state
+ *
+ * Runs through the list of pending requests.
+ */
+static inline void
+mega_runpendq(adapter_t *adapter)
+{
+ if(!list_empty(&adapter->pending_list))
+ __mega_runpendq(adapter);
+}
+
+static void
+__mega_runpendq(adapter_t *adapter)
+{
+ scb_t *scb;
+ struct list_head *pos, *next;
+
+ /* Issue any pending commands to the card */
+ list_for_each_safe(pos, next, &adapter->pending_list) {
+
+ scb = list_entry(pos, scb_t, list);
+
+ if( !(scb->state & SCB_ISSUED) ) {
+
+ if( issue_scb(adapter, scb) != 0 )
+ return;
+ }
+ }
+
+ return;
+}
+
+
+/**
+ * issue_scb()
+ * @adapter - pointer to our soft state
+ * @scb - scsi control block
+ *
+ * Post a command to the card if the mailbox is available, otherwise return
+ * busy. We also take the scb from the pending list if the mailbox is
+ * available.
+ */
+static inline int
+issue_scb(adapter_t *adapter, scb_t *scb)
+{
+ volatile mbox64_t *mbox64 = adapter->mbox64;
+ volatile mbox_t *mbox = adapter->mbox;
+ unsigned int i = 0;
+
+ if(unlikely(mbox->busy)) {
+ do {
+ udelay(1);
+ i++;
+ } while( mbox->busy && (i < max_mbox_busy_wait) );
+
+ if(mbox->busy) return -1;
+ }
+
+ /* Copy mailbox data into host structure */
+ memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
+
+ mbox->cmdid = scb->idx; /* Set cmdid */
+ mbox->busy = 1; /* Set busy */
+
+
+ /*
+ * Increment the pending queue counter
+ */
+ atomic_inc(&adapter->pend_cmds);
+
+ switch (mbox->cmd) {
+ case MEGA_MBOXCMD_EXTPTHRU:
+ if( !adapter->has_64bit_addr ) break;
+ // else fall through
+ case MEGA_MBOXCMD_LREAD64:
+ case MEGA_MBOXCMD_LWRITE64:
+ case MEGA_MBOXCMD_PASSTHRU64:
+ mbox64->xfer_segment_lo = mbox->xferaddr;
+ mbox64->xfer_segment_hi = 0;
+ mbox->xferaddr = 0xFFFFFFFF;
+ break;
+ default:
+ mbox64->xfer_segment_lo = 0;
+ mbox64->xfer_segment_hi = 0;
+ }
+
+ /*
+ * post the command
+ */
+ scb->state |= SCB_ISSUED;
+
+ if( likely(adapter->flag & BOARD_MEMMAP) ) {
+ mbox->poll = 0;
+ mbox->ack = 0;
+ WRINDOOR(adapter, adapter->mbox_dma | 0x1);
+ }
+ else {
+ irq_enable(adapter);
+ issue_command(adapter);
+ }
+
+ return 0;
+}
+
+
+/**
* issue_scb_block()
* @adapter - pointer to our soft state
* @raw_mbox - the mailbox
@@ -1979,7 +1857,6 @@
adapter_t *adapter = devp;
unsigned long flags;

-
spin_lock_irqsave(adapter->host_lock, flags);

megaraid_iombox_ack_sequence(adapter);
@@ -1996,6 +1873,99 @@


/**
+ * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs
+ * @adapter - controller's soft state
+ *
+ * Interrupt ackrowledgement sequence for IO mapped HBAs
+ */
+static inline void
+megaraid_iombox_ack_sequence(adapter_t *adapter)
+{
+ u8 status;
+ int nstatus;
+ u8 completed[MAX_FIRMWARE_STATUS];
+ u8 byte;
+ int i;
+
+
+ /*
+ * loop till F/W has more commands for us to complete.
+ */
+ do {
+ /* Check if a valid interrupt is pending */
+ byte = irq_state(adapter);
+ if( (byte & VALID_INTR_BYTE) == 0 ) {
+ return;
+ }
+ set_irq_state(adapter, byte);
+
+ while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
+ cpu_relax();
+ }
+ adapter->mbox->numstatus = 0xFF;
+
+ for (i = 0; i < nstatus; i++) {
+ while ((completed[i] = adapter->mbox->completed[i])
+ == 0xFF) {
+ cpu_relax();
+ }
+
+ adapter->mbox->completed[i] = 0xFF;
+ }
+
+ // we must read the valid status now
+ if ((status = adapter->mbox->status) == 0xFF) {
+ printk(KERN_WARNING
+ "megaraid critical: status 0xFF from firmware.\n");
+ }
+ adapter->mbox->status = 0xFF;
+
+ /*
+ * decrement the pending queue counter
+ */
+ atomic_sub(nstatus, &adapter->pend_cmds);
+
+ /* Acknowledge interrupt */
+ irq_ack(adapter);
+
+ mega_cmd_done(adapter, completed, nstatus, status);
+
+ } while(1);
+}
+
+
+/**
+ * megaraid_isr_memmapped()
+ * @irq - irq
+ * @devp - pointer to our soft state
+ * @regs - unused
+ *
+ * Interrupt service routine for memory-mapped controllers.
+ * Find out if our device is interrupting. If yes, acknowledge the
interrupt
+ * and service the completed commands.
+ */
+static void
+megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
+{
+ adapter_t *adapter = devp;
+ unsigned long flags;
+
+ spin_lock_irqsave(adapter->host_lock, flags);
+
+ megaraid_memmbox_ack_sequence(adapter);
+
+ /* Loop through any pending requests */
+ if(atomic_read(&adapter->quiescent) == 0) {
+ mega_runpendq(adapter);
+ }
+
+ spin_unlock_irqrestore(adapter->host_lock, flags);
+
+ return;
+}
+
+
+/**
* megaraid_memmbox_ack_sequence - interrupt ack sequence for memory mapped
HBAs
* @adapter - controller's soft state
*
@@ -2006,7 +1976,7 @@
{
u8 status;
u32 dword = 0;
- u8 nstatus;
+ int nstatus;
u8 completed[MAX_FIRMWARE_STATUS];
int i;

@@ -2063,37 +2033,6 @@


/**
- * megaraid_isr_memmapped()
- * @irq - irq
- * @devp - pointer to our soft state
- * @regs - unused
- *
- * Interrupt service routine for memory-mapped controllers.
- * Find out if our device is interrupting. If yes, acknowledge the
interrupt
- * and service the completed commands.
- */
-static void
-megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
-{
- adapter_t *adapter = devp;
- unsigned long flags;
-
-
- spin_lock_irqsave(adapter->host_lock, flags);
-
- megaraid_memmbox_ack_sequence(adapter);
-
- /* Loop through any pending requests */
- if(atomic_read(&adapter->quiescent) == 0) {
- mega_runpendq(adapter);
- }
-
- spin_unlock_irqrestore(adapter->host_lock, flags);
-
- return;
-}
-
-/**
* mega_cmd_done()
* @adapter - pointer to our soft state
* @completed - array of ids of completed commands
@@ -2102,7 +2041,7 @@
*
* Complete the comamnds and call the scsi mid-layer callback hooks.
*/
-static void
+static inline void
mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
{
mega_ext_passthru *epthru = NULL;
@@ -2404,6 +2343,18 @@
list_add(&scb->list, &adapter->free_list);
}

+
+/*
+ * Wait until the controller's mailbox is available
+ */
+static inline int
+mega_busywait_mbox (adapter_t *adapter)
+{
+ if (adapter->mbox->busy)
+ return __mega_busywait_mbox(adapter);
+ return 0;
+}
+
static int
__mega_busywait_mbox (adapter_t *adapter)
{
@@ -2434,7 +2385,7 @@

cmd = scb->cmd;

- /* return 0 elements if no data transfer */
+ // return 0 elements if no data transfer
if (!cmd->request_buffer || !cmd->request_bufflen)
return 0;

@@ -2561,43 +2512,6 @@
enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
}

-static inline void
-mega_free_sgl(adapter_t *adapter)
-{
- scb_t *scb;
- int i;
-
- for(i = 0; i < adapter->max_cmds; i++) {
-
- scb = &adapter->scb_list[i];
-
- if( scb->sgl64 ) {
- pci_free_consistent(adapter->dev,
- sizeof(mega_sgl64) * adapter->sglen,
- scb->sgl64,
- scb->sgl_dma_addr);
-
- scb->sgl64 = NULL;
- }
-
- if( scb->pthru ) {
- pci_free_consistent(adapter->dev,
sizeof(mega_passthru),
- scb->pthru, scb->pthru_dma_addr);
-
- scb->pthru = NULL;
- }
-
- if( scb->epthru ) {
- pci_free_consistent(adapter->dev,
- sizeof(mega_ext_passthru),
- scb->epthru, scb->epthru_dma_addr);
-
- scb->epthru = NULL;
- }
-
- }
-}
-

/*
* Release the controller's resources
@@ -2726,7 +2640,7 @@
*/
scsi_unregister(host);

-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
unregister_ioctl32_conversion(MEGAIOCCMD);
#endif

@@ -2735,6 +2649,44 @@
return 0;
}

+static inline void
+mega_free_sgl(adapter_t *adapter)
+{
+ scb_t *scb;
+ int i;
+
+ for(i = 0; i < adapter->max_cmds; i++) {
+
+ scb = &adapter->scb_list[i];
+
+ if( scb->sgl64 ) {
+ pci_free_consistent(adapter->dev,
+ sizeof(mega_sgl64) * adapter->sglen,
+ scb->sgl64,
+ scb->sgl_dma_addr);
+
+ scb->sgl64 = NULL;
+ }
+
+ if( scb->pthru ) {
+ pci_free_consistent(adapter->dev,
sizeof(mega_passthru),
+ scb->pthru, scb->pthru_dma_addr);
+
+ scb->pthru = NULL;
+ }
+
+ if( scb->epthru ) {
+ pci_free_consistent(adapter->dev,
+ sizeof(mega_ext_passthru),
+ scb->epthru, scb->epthru_dma_addr);
+
+ scb->epthru = NULL;
+ }
+
+ }
+}
+
+
/*
* Get information about the card/driver
*/
@@ -2835,7 +2787,6 @@
return SUCCESS;
}

-
static int
megaraid_reset(Scsi_Cmnd *cmd)
{
@@ -2903,12 +2854,10 @@
/*
* Perform the ack sequence, since interrupts are
unavailable
*/
- if( adapter->flag & BOARD_MEMMAP ) {
+ if (adapter->flag & BOARD_MEMMAP)
megaraid_memmbox_ack_sequence(adapter);
- }
- else {
+ else
megaraid_iombox_ack_sequence(adapter);
- }

spin_unlock(adapter->host_lock);

@@ -2941,7 +2890,6 @@
return rval;
}

-
#ifdef CONFIG_PROC_FS
/* Following code handles /proc fs */

@@ -3200,26 +3148,6 @@
return len;
}

-/**
- * mega_allocate_inquiry()
- * @dma_handle - handle returned for dma address
- * @pdev - handle to pci device
- *
- * allocates memory for inquiry structure
- */
-static inline caddr_t
-mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
-{
- return pci_alloc_consistent(pdev, sizeof(mega_inquiry3),
dma_handle);
-}
-
-
-static inline void
-mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev
*pdev)
-{
- pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry,
dma_handle);
-}
-

/**
* proc_rebuild_rate()
@@ -4172,7 +4100,7 @@
}


-#if defined(__x86_64__)
+#ifdef LSI_CONFIG_COMPAT
static int
megadev_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
struct file *filep)
@@ -4221,7 +4149,7 @@
megacmd_t mc;
megastat_t *ustats;
int num_ldrv;
- u32 uxferaddr = 0;
+ caddr_t uxferaddr=NULL;
struct pci_dev *pdev;

ustats = NULL; /* avoid compilation warnings */
@@ -4251,13 +4179,13 @@
switch( uioc.opcode ) {

case GET_DRIVER_VER:
- if( put_user(driver_ver, (u32 *)uioc.uioc_uaddr) )
+ if( put_user(driver_ver, (u32 *)uioc.u_dataaddr) )
return (-EFAULT);

break;

case GET_N_ADAP:
- if( put_user(hba_count, (u32 *)uioc.uioc_uaddr) )
+ if( put_user(hba_count, (u32 *)uioc.u_dataaddr) )
return (-EFAULT);

/*
@@ -4275,7 +4203,7 @@
if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
return (-ENODEV);

- if( copy_to_user(uioc.uioc_uaddr, mcontroller+adapno,
+ if( copy_to_user(uioc.u_dataaddr, mcontroller+adapno,
sizeof(struct mcontroller)) )
return (-EFAULT);
break;
@@ -4291,7 +4219,7 @@

adapter = hba_soft_state[adapno];

- ustats = (megastat_t *)uioc.uioc_uaddr;
+ ustats = (megastat_t *)uioc.u_dataaddr;

if( copy_from_user(&num_ldrv, &ustats->num_ldrv,
sizeof(int)) )
return (-EFAULT);
@@ -4333,7 +4261,7 @@
/*
* Which adapter
*/
- if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
+ if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
return (-ENODEV);

adapter = hba_soft_state[adapno];
@@ -4342,37 +4270,37 @@
* Deletion of logical drive is a special case. The adapter
* should be quiescent before this command is issued.
*/
- if( uioc.uioc_rmbox[0] == FC_DEL_LOGDRV &&
- uioc.uioc_rmbox[2] == OP_DEL_LOGDRV ) {
+ if( RMBOX(uioc)[0] == FC_DEL_LOGDRV ) {
+ if ( RMBOX(uioc)[2] == OP_DEL_LOGDRV ) {
+ /*
+ * Do we support this feature
+ */
+ if( !adapter->support_random_del ) {
+ printk(KERN_WARNING "megaraid:
logdrv ");
+ printk("delete on non-supporting
F/W.\n");

- /*
- * Do we support this feature
- */
- if( !adapter->support_random_del ) {
- printk(KERN_WARNING "megaraid: logdrv ");
- printk("delete on non-supporting F/W.\n");
+ return (-EINVAL);
+ }

- return (-EINVAL);
- }
+ rval = mega_del_logdrv( adapter,
RMBOX(uioc)[3] );

- rval = mega_del_logdrv( adapter, uioc.uioc_rmbox[3]
);
+ if( rval == 0 ) {
+ memset(&mc, 0, sizeof(megacmd_t));

- if( rval == 0 ) {
- memset(&mc, 0, sizeof(megacmd_t));
+ mc.status = rval;

- mc.status = rval;
+ rval = mega_n_to_m((void *)arg,
&mc);
+ }

- rval = mega_n_to_m((void *)arg, &mc);
+ return rval;
}
-
- return rval;
}
/*
* This interface only support the regular passthru
commands.
* Reject extended passthru and 64-bit passthru
*/
- if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU64 ||
- uioc.uioc_rmbox[0] == MEGA_MBOXCMD_EXTPTHRU ) {
+ if( RMBOX(uioc)[0] == MEGA_MBOXCMD_PASSTHRU64 ||
+ RMBOX(uioc)[0] == MEGA_MBOXCMD_EXTPTHRU ) {

printk(KERN_WARNING "megaraid: rejected
passthru.\n");

@@ -4386,7 +4314,7 @@
pdev = adapter->dev;

/* Is it a passthru command or a DCMD */
- if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
+ if( RMBOX(uioc)[0] == MEGA_MBOXCMD_PASSTHRU ) {
/* Passthru commands */

pthru = adapter->int_pthru;
@@ -4394,20 +4322,12 @@
/*
* The user passthru structure
*/
- upthru = (mega_passthru *)
- ((ulong)(MBOX(uioc)->xferaddr));
- /*
- * Copy in the user passthru here.
- */
- if( copy_from_user(pthru, (char *)upthru,
- sizeof(mega_passthru)) ) {
- return (-EFAULT);
- }
-
+ upthru = &uioc.pthru;
+ memcpy(pthru, (char
*)upthru,sizeof(mega_passthru));
/*
* Is there a data transfer; If the data transfer
- * length is <= INT_MEMBLK_SZ, usr the buffer
- * allocated at the load time. Otherwise, allocate
it
+ * length is <= INT_MEMBLK_SZ, usr the buffer
+ * allocated at the load time. Otherwise, allocate
it
* here.
*/
if (pthru->dataxferlen) {
@@ -4417,8 +4337,9 @@
pthru->dataxferlen,
&data_dma_hndl );

- if (data == NULL)
+ if (data == NULL) {
return (-ENOMEM);
+ }
}
else {
data = adapter->int_data;
@@ -4428,11 +4349,11 @@
* Save the user address and point the
kernel
* address at just allocated memory
*/
- uxferaddr = pthru->dataxferaddr;
+ uxferaddr = (caddr_t) uioc.u_dataaddr;
if (data_dma_hndl)
pthru->dataxferaddr = data_dma_hndl;
else
- pthru->dataxferaddr =
+ pthru->dataxferaddr =
adapter->int_data_dma_hndl;
}

@@ -4440,12 +4361,12 @@
/*
* Is data coming down-stream
*/
- if( pthru->dataxferlen && (uioc.flags & UIOC_WR) ) {
+ if(pthru->dataxferlen && (uioc.flags & UIOC_WR) ) {
/*
* Get the user data
*/
if( copy_from_user(data,
- (char *)((ulong)uxferaddr),
+ (char *)uxferaddr,
pthru->dataxferlen) ) {
rval = (-EFAULT);
goto freedata_and_return;
@@ -4471,7 +4392,7 @@
* Is data going up-stream
*/
if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
- if( copy_to_user((char *)((ulong)uxferaddr),
+ if( copy_to_user((char *)uxferaddr,
data, pthru->dataxferlen) )
{
rval = (-EFAULT);
}
@@ -4511,7 +4432,7 @@
else {
data = adapter->int_data;
}
- uxferaddr = MBOX(uioc)->xferaddr;
+ uxferaddr = uioc.u_dataaddr;
}

/*
@@ -4559,7 +4480,7 @@
* Is data going up-stream
*/
if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
- if( copy_to_user((char *)((ulong)uxferaddr),
+ if( copy_to_user((char *)uxferaddr,
data, uioc.xferlen) ) {

rval = (-EFAULT);
@@ -4648,18 +4569,18 @@

case MEGAIOC_QDRVRVER: /* Query driver version */
uioc->opcode = GET_DRIVER_VER;
- uioc->uioc_uaddr = uioc_mimd.data;
+ uioc->u_dataaddr = uioc_mimd.data;
break;

case MEGAIOC_QNADAP: /* Get # of adapters */
uioc->opcode = GET_N_ADAP;
- uioc->uioc_uaddr = uioc_mimd.data;
+ uioc->u_dataaddr = uioc_mimd.data;
break;

case MEGAIOC_QADAPINFO: /* Get adapter information */
uioc->opcode = GET_ADAP_INFO;
uioc->adapno = uioc_mimd.ui.fcs.adapno;
- uioc->uioc_uaddr = uioc_mimd.data;
+ uioc->u_dataaddr = uioc_mimd.data;
break;

default:
@@ -4674,9 +4595,16 @@
uioc->opcode = MBOX_CMD;
uioc->adapno = uioc_mimd.ui.fcs.adapno;

- memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
+ memcpy(&uioc->u_mbox, uioc_mimd.mbox, 18);

uioc->xferlen = uioc_mimd.ui.fcs.length;
+ uioc->u_dataaddr = uioc_mimd.ui.fcs.buffer;
+
+ if (uioc_mimd.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
+ memcpy(&uioc->pthru,&uioc_mimd.pthru,
+ sizeof(mega_passthru));
+
+ }

if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
@@ -4688,13 +4616,20 @@
uioc->opcode = MBOX_CMD;
uioc->adapno = uioc_mimd.ui.fcs.adapno;

- memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
+ memcpy(&uioc->u_mbox, uioc_mimd.mbox, 18);

/*
* Choose the xferlen bigger of input and output data
*/
uioc->xferlen = uioc_mimd.outlen > uioc_mimd.inlen ?
uioc_mimd.outlen : uioc_mimd.inlen;
+ uioc->u_dataaddr = uioc_mimd.data;
+
+ if (uioc_mimd.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
+ memcpy(&uioc->pthru,&uioc_mimd.pthru,
+ sizeof(mega_passthru));
+
+ }

if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
@@ -4735,20 +4670,14 @@

if( memcmp(signature, "MEGANIT", 7) == 0 ) {

- uiocp = (nitioctl_t *)arg;
-
- if( put_user(mc->status, (u8 *)&MBOX_P(uiocp)->status) )
- return (-EFAULT);
-
- if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
-
- umc = MBOX_P(uiocp);
-
- upthru = (mega_passthru *)((ulong)(umc->xferaddr));

- if( put_user(mc->status, (u8 *)&upthru->scsistatus)
)
- return (-EFAULT);
- }
+ /*
+ * NOTE: The nit ioctl is still under flux because of
+ * change of mailbox definition, in HPE. No applications yet
+ * use this interface and let's not have applications use
this
+ * interface till the new specifitions are in place.
+ */
+ return -EINVAL;
}
else {
uioc_mimd = (struct uioctl_t *)arg;
@@ -4763,8 +4692,7 @@
if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) {
return -EFAULT;
}
-
- upthru = (mega_passthru *)((ulong)kmc.xferaddr);
+ upthru = (mega_passthru
*)((ulong)&uioc_mimd->pthru);

if( put_user(mc->status, (u8 *)&upthru->scsistatus)
){
return (-EFAULT);
@@ -5179,6 +5107,55 @@
}


+
+/**
+ * mega_get_ldrv_num()
+ * @adapter - pointer to our soft state
+ * @cmd - scsi mid layer command
+ * @channel - channel on the controller
+ *
+ * Calculate the logical drive number based on the information in scsi
command
+ * and the channel number.
+ */
+static inline int
+mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel)
+{
+ int tgt;
+ int ldrv_num;
+
+ tgt = cmd->target;
+
+ if ( tgt > adapter->this_id )
+ tgt--; /* we do not get inquires for initiator id */
+
+ ldrv_num = (channel * 15) + tgt;
+
+
+ /*
+ * If we have a logical drive with boot enabled, project it first
+ */
+ if( adapter->boot_ldrv_enabled ) {
+ if( ldrv_num == 0 ) {
+ ldrv_num = adapter->boot_ldrv;
+ }
+ else {
+ if( ldrv_num <= adapter->boot_ldrv ) {
+ ldrv_num--;
+ }
+ }
+ }
+
+ /*
+ * If "delete logical drive" feature is enabled on this controller,
+ * the value returned should be 0x80+logical drive id.
+ */
+ if (adapter->support_random_del)
+ ldrv_num += 0x80;
+
+ return ldrv_num;
+}
+
+
/**
* mega_reorder_hosts()
*
@@ -5393,6 +5370,26 @@
}


+/**
+ * mega_allocate_inquiry()
+ * @dma_handle - handle returned for dma address
+ * @pdev - handle to pci device
+ *
+ * allocates memory for inquiry structure
+ */
+static inline caddr_t
+mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
+{
+ return pci_alloc_consistent(pdev, sizeof(mega_inquiry3),
dma_handle);
+}
+
+
+static inline void
+mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev
*pdev)
+{
+ pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry,
dma_handle);
+}
+

/** mega_internal_dev_inquiry()
* @adapter - pointer to our soft state
diff -Naur old/drivers/scsi/megaraid2.h new/drivers/scsi/megaraid2.h
--- old/drivers/scsi/megaraid2.h 2005-07-15 07:52:27.558936976 -0400
+++ new/drivers/scsi/megaraid2.h 2005-07-15 07:52:18.566304064 -0400
@@ -6,7 +6,7 @@


#define MEGARAID_VERSION \
- "v2.10.8.2 (Release Date: Mon Jul 26 12:15:51 EDT 2004)\n"
+ "v2.10.10.1 (Release Date: Thu Jan 27 16:19:44 EDT 2005)\n"

/*
* Driver features - change the values to enable or disable features in the
@@ -83,6 +83,7 @@
#define INTEL_SUBSYS_VID 0x8086
#define FSC_SUBSYS_VID 0x1734
#define ACER_SUBSYS_VID 0x1025
+#define NEC_SUBSYS_VID 0x1033

#define HBA_SIGNATURE 0x3344
#define HBA_SIGNATURE_471 0xCCCC
@@ -143,7 +144,8 @@
.eh_device_reset_handler = megaraid_reset, \
.eh_bus_reset_handler = megaraid_reset, \
.eh_host_reset_handler = megaraid_reset, \
- .highmem_io = 1 \
+ .highmem_io = 1, \
+ .vary_io = 1 \
}


@@ -707,15 +709,15 @@
char signature[8]; /* Must contain "MEGANIT" */
u32 opcode; /* opcode for the command */
u32 adapno; /* adapter number */
- union {
- u8 __raw_mbox[18];
- caddr_t __uaddr; /* xferaddr for non-mbox cmds */
- }__ua;
-
-#define uioc_rmbox __ua.__raw_mbox
-#define MBOX(uioc) ((megacmd_t *)&((uioc).__ua.__raw_mbox[0]))
-#define MBOX_P(uioc) ((megacmd_t *)&((uioc)->__ua.__raw_mbox[0]))
-#define uioc_uaddr __ua.__uaddr
+ mbox_t u_mbox; /* user mailbox */
+ caddr_t u_dataaddr; /* xferaddr for DCMD and non-mbox
+ commands */
+ mega_passthru pthru;
+
+#define RMBOX(uioc) ((u8 *)&(uioc).u_mbox)
+#define MBOX(uioc) ((megacmd_t *)&(uioc).u_mbox)
+#define MBOX_P(uioc) ((megacmd_t *)&(uioc)->u_mbox)
+

u32 xferlen; /* xferlen for DCMD and non-mbox
commands */
@@ -1128,7 +1130,7 @@
u32 *buffer, u32 *length);
static inline int mega_busywait_mbox (adapter_t *);
static int __mega_busywait_mbox (adapter_t *);
-static void mega_cmd_done(adapter_t *, u8 [], int, int);
+static inline void mega_cmd_done(adapter_t *, u8 [], int, int);
static inline void mega_free_sgl (adapter_t *adapter);
static void mega_8_to_40ld (mraid_inquiry *inquiry,
mega_inquiry3 *enquiry3, mega_product_info *);
@@ -1137,7 +1139,14 @@
unsigned long, void *);
static int megadev_open (struct inode *, struct file *);

-#if defined(__x86_64__)
+#if defined(CONFIG_COMPAT) || defined( __x86_64__) ||
defined(IA32_EMULATION)
+#ifndef __ia64__
+#define LSI_CONFIG_COMPAT
+#endif
+#endif
+
+
+#ifdef LSI_CONFIG_COMPAT
static int megadev_compat_ioctl(unsigned int, unsigned int, unsigned long,
struct file *);
#endif
---

Attachment: megaraid2_for_2.4.31.patch
Description: Binary data