public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Prevent NMI oopser
@ 2005-01-25  7:47 Vasily Averin
  2005-01-25  9:35 ` Marcelo Tosatti
  0 siblings, 1 reply; 12+ messages in thread
From: Vasily Averin @ 2005-01-25  7:47 UTC (permalink / raw)
  To: Marcelo Tosatti, Andrey Melnikov; +Cc: linux-kernel

Marcello, Andrey

I believe this patch is wrong.
First, it prevent nothing: NMI watchdog is a signal that you wait too 
long with disabled interrupts. Your controller was not answered too 
long, obviously it is a hardware issue.
Second, you could not call schedule() with io_request_lock spinlock taken.

You should unlock io_request_lock before msleep, like in latest versions 
of megaraid2 drivers.

Please fix it.

Thank you,
      Vasily Averin, SWSoft Linux Kernel Team

# ChangeSet
#   2005/01/19 14:16:32-02:00 temnota@kmv.ru
#   [PATCH] Prevent NMI oopser from triggering when megaraid2 waits
#   for abort/reset cmd completion
#
#   > We should backport msleep() in 2.4.29-pre1.
#
#   Ok, msleep() backported, but driver isn't fixed. This patch
#   acceptable?
#
#   Prevent NMI oopser kill kernel thread when megaraid2 driver waiting
#   abort or reset command completion.
#
#   Signed-off-by: Andrey Melnikov <temnota+kernel@kmv.ru>



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-01-25  7:47 Vasily Averin
@ 2005-01-25  9:35 ` Marcelo Tosatti
  0 siblings, 0 replies; 12+ messages in thread
From: Marcelo Tosatti @ 2005-01-25  9:35 UTC (permalink / raw)
  To: Vasily Averin; +Cc: Marcelo Tosatti, Andrey Melnikov, linux-kernel

On Tue, Jan 25, 2005 at 10:47:24AM +0300, Vasily Averin wrote:
> Marcello, Andrey
> 
> I believe this patch is wrong.
> First, it prevent nothing: NMI watchdog is a signal that you wait too 
> long with disabled interrupts. Your controller was not answered too 
> long, obviously it is a hardware issue.
> Second, you could not call schedule() with io_request_lock spinlock taken.
> 
> You should unlock io_request_lock before msleep, like in latest versions 
> of megaraid2 drivers.
> 
> Please fix it.

OK, I've reverted it for now - waiting for megaraid2 update from LSI crew.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
       [not found] <41F5FC96.2010103@sw.ru>
@ 2005-01-31 23:17 ` Marcelo Tosatti
  2005-02-02 18:42   ` Vasily Averin
  0 siblings, 1 reply; 12+ messages in thread
From: Marcelo Tosatti @ 2005-01-31 23:17 UTC (permalink / raw)
  To: Vasily Averin, Andrey Melnikov
  Cc: linux-kernel, Atul Mukker, Sreenivas Bagalkote

On Tue, Jan 25, 2005 at 11:00:22AM +0300, Vasily Averin wrote:
> cc: Andrey Melnikov <temnota+kernel@kmv.ru>
> cc: linux-kernel@vger.kernel.org
> 
> Marcello, Andrey
> 
> I believe this patch is wrong.
> First, it prevent nothing: NMI watchdog is a signal that you wait too
> long with disabled interrupts. Your controller was not answered too
> long, obviously it is a hardware issue.
> Second, you could not call schedule() with io_request_lock spinlock taken.
> 
> You should unlock io_request_lock before msleep, like in latest versions
> of megaraid2 drivers.
> 
> Please fix it.

Andrey, 

Can you please update your patch to unlock io_request_lock before sleeping
and locking after coming back? 

What the driver is doing is indeed wrong.

Thank you.

Is there anybody out there at LSI? 

> Thank you,
>       Vasily Averin, SWSoft Linux Kernel Team
> 
> # ChangeSet
> #   2005/01/19 14:16:32-02:00 temnota@kmv.ru
> #   [PATCH] Prevent NMI oopser from triggering when megaraid2 waits
> #   for abort/reset cmd completion
> #
> #   > We should backport msleep() in 2.4.29-pre1.
> #
> #   Ok, msleep() backported, but driver isn't fixed. This patch
> #   acceptable?
> #
> #   Prevent NMI oopser kill kernel thread when megaraid2 driver waiting
> #   abort or reset command completion.
> #
> #   Signed-off-by: Andrey Melnikov <temnota+kernel@kmv.ru>
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-01-31 23:17 ` [PATCH] Prevent NMI oopser Marcelo Tosatti
@ 2005-02-02 18:42   ` Vasily Averin
  2005-02-02 18:53     ` Andrey J. Melnikoff (TEMHOTA)
  2005-02-02 19:06     ` Matt Domsch
  0 siblings, 2 replies; 12+ messages in thread
From: Vasily Averin @ 2005-02-02 18:42 UTC (permalink / raw)
  To: Marcelo Tosatti
  Cc: Andrey Melnikov, linux-kernel, Atul Mukker, Sreenivas Bagalkote

[-- Attachment #1: Type: text/plain, Size: 619 bytes --]

Marcelo Tosatti wrote:
> On Tue, Jan 25, 2005 at 11:00:22AM +0300, Vasily Averin wrote:
>>You should unlock io_request_lock before msleep, like in latest versions
>>of megaraid2 drivers.
> 
> Andrey, 
> 
> Can you please update your patch to unlock io_request_lock before sleeping
> and locking after coming back? 
> 
> What the driver is doing is indeed wrong.

Marcelo,

This is megaraid2 driver update (2.10.8.2 version, latest 2.4-compatible
version that I've seen), taken from latest RHEL3 kernel update. I
believe it should prevent NMI in abort/reset handler.

Thank you,
	Vasily Averin, SWSoft Linux Kernel Team

[-- Attachment #2: linux-2.4.29-megaraid2-2.10.8.2.patch --]
[-- Type: text/plain, Size: 37057 bytes --]

--- ./drivers/scsi/megaraid2.c.mr2	Wed Feb  2 08:27:13 2005
+++ ./drivers/scsi/megaraid2.c	Wed Feb  2 10:28:52 2005
@@ -14,7 +14,7 @@
  *	  - speed-ups (list handling fixes, issued_list, optimizations.)
  *	  - lots of cleanups.
  *
- * Version : v2.10.3 (Apr 08, 2004)
+ * Version : v2.10.8.2 (July 26, 2004)
  *
  * Authors:	Atul Mukker <Atul.Mukker@lsil.com>
  *		Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
@@ -46,7 +46,7 @@
 
 #include "megaraid2.h"
 
-#ifdef LSI_CONFIG_COMPAT
+#if defined(__x86_64__)
 #include <asm/ioctl32.h>
 #endif
 
@@ -90,10 +90,15 @@ static struct notifier_block mega_notifi
 static struct mega_hbas mega_hbas[MAX_CONTROLLERS];
 
 /*
+ * Lock to protect access to IOCTL
+ */
+static struct semaphore megaraid_ioc_mtx;
+
+/*
  * The File Operations structure for the serial/ioctl interface of the driver
  */
 static struct file_operations megadev_fops = {
-	.ioctl		= megadev_ioctl,
+	.ioctl		= megadev_ioctl_entry,
 	.open		= megadev_open,
 	.release	= megadev_close,
 	.owner		= THIS_MODULE,
@@ -107,7 +112,7 @@ static struct file_operations megadev_fo
 static struct mcontroller mcontroller[MAX_CONTROLLERS];
 
 /* The current driver version */
-static u32 driver_ver = 0x02100000;
+static u32 driver_ver = 0x02104000;
 
 /* major number used by the device for character interface */
 static int major;
@@ -189,6 +194,11 @@ megaraid_detect(Scsi_Host_Template *host
 		 */
 		mega_reorder_hosts();
 
+		/*
+		 * Initialize the IOCTL lock
+		 */
+		init_MUTEX( &megaraid_ioc_mtx );
+
 #ifdef CONFIG_PROC_FS
 		mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root);
 
@@ -223,7 +233,7 @@ megaraid_detect(Scsi_Host_Template *host
 				"MegaRAID Shutdown routine not registered!!\n");
 		}
 
-#ifdef LSI_CONFIG_COMPAT
+#if defined(__x86_64__)
 		/*
 		 * Register the 32-bit ioctl conversion
 		 */
@@ -273,6 +283,8 @@ mega_find_card(Scsi_Host_Template *host_
 	unsigned long	tbase;
 	unsigned long	flag = 0;
 	int	i, j;
+	u8	did_int_pthru_f	= 0;
+	u8	did_int_data_f	= 0;
 
 	while((pdev = pci_find_device(pci_vendor, pci_device, pdev))) {
 
@@ -328,6 +340,7 @@ mega_find_card(Scsi_Host_Template *host_
 				(subsysvid != HP_SUBSYS_VID) &&
 				(subsysvid != INTEL_SUBSYS_VID) &&
 				(subsysvid != FSC_SUBSYS_VID) &&
+				(subsysvid != ACER_SUBSYS_VID) &&
 				(subsysvid != LSI_SUBSYS_VID) ) continue;
 
 
@@ -465,6 +478,33 @@ mega_find_card(Scsi_Host_Template *host_
 
 		alloc_scb_f = 1;
 
+		/*
+		 * Allocate memory for ioctls
+		 */
+		adapter->int_pthru = pci_alloc_consistent ( 
+					adapter->dev,
+					sizeof(mega_passthru),
+					&adapter->int_pthru_dma_hndl );
+
+		if( adapter->int_pthru == NULL ) {
+			printk(KERN_WARNING "megaraid: out of RAM.\n");
+			goto fail_attach;
+		}
+		else
+			did_int_pthru_f = 1;
+
+		adapter->int_data = pci_alloc_consistent (
+					adapter->dev,
+					INT_MEMBLK_SZ,
+					&adapter->int_data_dma_hndl );
+
+		if( adapter->int_data == NULL ) {
+			printk(KERN_WARNING "megaraid: out of RAM.\n");
+			goto fail_attach;
+		}
+		else
+			did_int_data_f = 1;
+
 		/* Request our IRQ */
 		if( adapter->flag & BOARD_MEMMAP ) {
 			if(request_irq(irq, megaraid_isr_memmapped, SA_SHIRQ,
@@ -676,6 +716,19 @@ mega_find_card(Scsi_Host_Template *host_
 		continue;
 
 fail_attach:
+		if( did_int_data_f ) {
+			pci_free_consistent(
+				adapter->dev, INT_MEMBLK_SZ, adapter->int_data, 
+				adapter->int_data_dma_hndl );
+		}
+
+		if( did_int_pthru_f ) {
+			pci_free_consistent(
+				adapter->dev, sizeof(mega_passthru),
+				(void*) adapter->int_pthru,
+				adapter->int_pthru_dma_hndl );
+		}
+
 		if( did_setup_mbox_f ) {
 			pci_free_consistent(adapter->dev, sizeof(mbox64_t),
 					(void *)adapter->una_mbox64,
@@ -936,19 +989,6 @@ mega_query_adapter(adapter_t *adapter)
 }
 
 
-/**
- * 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);
-}
-
 /*
  * megaraid_queue()
  * @scmd - Issue this scsi command
@@ -999,98 +1039,6 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*d
 
 
 /**
- * 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.
-	 * Do only if at least one delete logical drive operation was done.
-	 *
-	 * Also, after logical drive deletion, instead of logical drive number,
-	 * the value returned should be 0x80+logical drive id.
-	 *
-	 * These is valid only for IO commands.
-	 */
-
-	if (adapter->support_random_del && adapter->read_ldidmap )
-		switch (cmd->cmnd[0]) {
-		case READ_6:	/* fall through */
-		case WRITE_6:	/* fall through */
-		case READ_10:	/* fall through */
-		case WRITE_10:
-			ldrv_num += 0x80;
-		}
-
-	return ldrv_num;
-}
-
-
-/**
  * mega_build_cmd()
  * @adapter - pointer to our soft state
  * @cmd - Prepare using this scsi command
@@ -1112,7 +1060,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_
 	mbox_t	*mbox;
 	long	seg;
 	char	islogical;
-	int	max_ldrv_num;
 	int	channel = 0;
 	int	target = 0;
 	int	ldrv_num = 0;   /* logical drive number */
@@ -1184,24 +1131,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_
 		}
 
 		ldrv_num = mega_get_ldrv_num(adapter, cmd, channel);
-
-
-		max_ldrv_num = (adapter->flag & BOARD_40LD) ?
-			MAX_LOGICAL_DRIVES_40LD : MAX_LOGICAL_DRIVES_8LD;
-
-		/*
-		 * max_ldrv_num increases by 0x80 if some logical drive was
-		 * deleted.
-		 */
-		if(adapter->read_ldidmap)
-			max_ldrv_num += 0x80;
-
-		if(ldrv_num > max_ldrv_num ) {
-			cmd->result = (DID_BAD_TARGET << 16);
-			cmd->scsi_done(cmd);
-			return NULL;
-		}
-
 	}
 	else {
 		if( cmd->lun > 7) {
@@ -1671,6 +1600,51 @@ mega_prepare_extpassthru(adapter_t *adap
 }
 
 
+/**
+ * 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)
 {
@@ -1702,7 +1676,7 @@ __mega_runpendq(adapter_t *adapter)
  * busy. We also take the scb from the pending list if the mailbox is
  * available.
  */
-static int
+static inline int
 issue_scb(adapter_t *adapter, scb_t *scb)
 {
 	volatile mbox64_t	*mbox64 = adapter->mbox64;
@@ -1765,17 +1739,6 @@ issue_scb(adapter_t *adapter, scb_t *scb
 }
 
 
-/*
- * 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;
-}
-
 /**
  * issue_scb_block()
  * @adapter - pointer to our soft state
@@ -1878,6 +1841,38 @@ bug_blocked_mailbox:
 
 
 /**
+ * megaraid_isr_iomapped()
+ * @irq - irq
+ * @devp - pointer to our soft state
+ * @regs - unused
+ *
+ * Interrupt service routine for io-mapped controllers.
+ * Find out if our device is interrupting. If yes, acknowledge the interrupt
+ * and service the completed commands.
+ */
+static void
+megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
+{
+	adapter_t	*adapter = devp;
+	unsigned long	flags;
+
+
+	spin_lock_irqsave(adapter->host_lock, flags);
+
+	megaraid_iombox_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_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs
  * @adapter	- controller's soft state
  *
@@ -1940,6 +1935,38 @@ megaraid_iombox_ack_sequence(adapter_t *
 
 
 /**
+ * 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
  *
@@ -2007,70 +2034,6 @@ megaraid_memmbox_ack_sequence(adapter_t 
 
 
 /**
- * megaraid_isr_iomapped()
- * @irq - irq
- * @devp - pointer to our soft state
- * @regs - unused
- *
- * Interrupt service routine for io-mapped controllers.
- * Find out if our device is interrupting. If yes, acknowledge the interrupt
- * and service the completed commands.
- */
-static void
-megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
-{
-	adapter_t	*adapter = devp;
-	unsigned long	flags;
-
-
-	spin_lock_irqsave(adapter->host_lock, flags);
-
-	megaraid_iombox_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_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
@@ -2079,7 +2042,7 @@ megaraid_isr_memmapped(int irq, void *de
  *
  * 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;
@@ -2382,6 +2345,17 @@ mega_free_scb(adapter_t *adapter, scb_t 
 }
 
 
+/*
+ * 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)
 {
@@ -2412,6 +2386,10 @@ mega_build_sglist(adapter_t *adapter, sc
 
 	cmd = scb->cmd;
 
+	/* return 0 elements if no data transfer */
+	if (!cmd->request_buffer || !cmd->request_bufflen)
+		return 0;
+
 	/* Scatter-gather not used */
 	if( !cmd->use_sg ) {
 
@@ -2519,58 +2497,20 @@ mega_8_to_40ld(mraid_inquiry *inquiry, m
 			inquiry->adapter_info.bios_version[i];
 	}
 	enquiry3->cache_flush_interval =
-		inquiry->adapter_info.cache_flush_interval;
-
-	product_info->dram_size = inquiry->adapter_info.dram_size;
-
-	enquiry3->num_ldrv = inquiry->logdrv_info.num_ldrv;
-
-	for (i = 0; i < MAX_LOGICAL_DRIVES_8LD; i++) {
-		enquiry3->ldrv_size[i] = inquiry->logdrv_info.ldrv_size[i];
-		enquiry3->ldrv_prop[i] = inquiry->logdrv_info.ldrv_prop[i];
-		enquiry3->ldrv_state[i] = inquiry->logdrv_info.ldrv_state[i];
-	}
-
-	for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++)
-		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);
+		inquiry->adapter_info.cache_flush_interval;
 
-			scb->epthru = NULL;
-		}
+	product_info->dram_size = inquiry->adapter_info.dram_size;
 
+	enquiry3->num_ldrv = inquiry->logdrv_info.num_ldrv;
+
+	for (i = 0; i < MAX_LOGICAL_DRIVES_8LD; i++) {
+		enquiry3->ldrv_size[i] = inquiry->logdrv_info.ldrv_size[i];
+		enquiry3->ldrv_prop[i] = inquiry->logdrv_info.ldrv_prop[i];
+		enquiry3->ldrv_state[i] = inquiry->logdrv_info.ldrv_state[i];
 	}
+
+	for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++)
+		enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
 }
 
 
@@ -2666,6 +2606,13 @@ megaraid_release(struct Scsi_Host *host)
 	pci_free_consistent(adapter->dev, sizeof(mbox64_t),
 			(void *)adapter->una_mbox64, adapter->una_mbox64_dma);
 
+	pci_free_consistent( adapter->dev, sizeof(mega_passthru),
+				(void*) adapter->int_pthru, 
+				adapter->int_pthru_dma_hndl );
+
+	pci_free_consistent( adapter->dev, INT_MEMBLK_SZ, adapter->int_data,
+				adapter->int_data_dma_hndl );
+
 	hba_count--;
 
 	if( hba_count == 0 ) {
@@ -2694,7 +2641,7 @@ megaraid_release(struct Scsi_Host *host)
 	 */
 	scsi_unregister(host);
 
-#ifdef LSI_CONFIG_COMPAT
+#if defined(__x86_64__)
 	unregister_ioctl32_conversion(MEGAIOCCMD);
 #endif
 
@@ -2703,6 +2650,44 @@ megaraid_release(struct Scsi_Host *host)
 	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
  */
@@ -2736,30 +2721,36 @@ megaraid_command (Scsi_Cmnd *cmd)
 }
 
 
-/**
- * megaraid_abort - abort the scsi command
- * @scp	- command to be aborted
- *
- * Abort a previous SCSI request. Only commands on the pending list can be
- * aborted. All the commands issued to the F/W must complete.
- */
 static int
 megaraid_abort(Scsi_Cmnd *scp)
 {
 	adapter_t		*adapter;
 	struct list_head	*pos, *next;
 	scb_t			*scb;
-	long			iter;
-	int			rval = SUCCESS;
+
+	printk("megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n",
+		scp->serial_number, scp->cmnd[0], scp->channel,
+		scp->target, scp->lun);
 
 	adapter = (adapter_t *)scp->host->hostdata;
 
-	ASSERT( spin_is_locked(adapter->host_lock) );
+	/*
+	 * Check if hw_error flag was set in previous RESET call. If it was,
+	 * then FW is hanging and unlikely to function. We can return FAILURE
+	 * from here and expect the RESET handler to be called.
+	 */
 
-	printk("megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n",
-		scp->serial_number, scp->cmnd[0], scp->channel, scp->target,
-		scp->lun);
+	if (adapter->hw_error) {
+		printk("megaraid: hw error, cannot abort\n");
+		return FAILED;
+	}
+
+	ASSERT( spin_is_locked(adapter->host_lock) );
 
+	/*
+	 * If cmd is waiting to be issued to FW, ABORT it with SUCEESS. If it
+	 * has already been issued, return FAILURE and expect RESET later.
+	 */
 
 	list_for_each_safe( pos, next, &adapter->pending_list ) {
 
@@ -2769,15 +2760,11 @@ megaraid_abort(Scsi_Cmnd *scp)
 
 			scb->state |= SCB_ABORT;
 
-			/*
-			 * Check if this command was never issued. If this is
-			 * the case, take it off from the pending list and
-			 * complete.
-			 */
 			if( !(scb->state & SCB_ISSUED) ) {
 
-				printk(KERN_WARNING
-				"megaraid: %ld:%d, driver owner.\n",
+				/* Not issued to the FW yet; ABORT it */
+
+				printk( "megaraid: %ld:%d, driver owner.\n",
 					scp->serial_number, scb->idx);
 
 				scp->result = (DID_ABORT << 16);
@@ -2786,67 +2773,31 @@ megaraid_abort(Scsi_Cmnd *scp)
 
 				scp->scsi_done(scp);
 
-				break;
+				return SUCCESS;
+			}
+			else {
+				/* Issued to the FW; can do nothing */
+				return FAILED;
 			}
 		}
 	}
 
 	/*
-	 * By this time, either all commands are completed or aborted by
-	 * mid-layer. Do not return until all the commands are actually
-	 * completed by the firmware
+	 * cmd is _not_ in our pending_list. Most likely we completed the cmd
 	 */
-	iter = 0;
-	while( atomic_read(&adapter->pend_cmds) > 0 ) {
-		/*
-		 * Perform the ack sequence, since interrupts are not
-		 * available right now!
-		 */
-		if( adapter->flag & BOARD_MEMMAP ) {
-			megaraid_memmbox_ack_sequence(adapter);
-		}
-		else {
-			megaraid_iombox_ack_sequence(adapter);
-		}
-
-		/*
-		 * print a message once every second only
-		 */
-		if( !(iter % 1000) ) {
-			printk(
-			"megaraid: Waiting for %d commands to flush: iter:%ld\n",
-				atomic_read(&adapter->pend_cmds), iter);
-		}
-
-		if( iter++ < MBOX_ABORT_SLEEP*1000 ) {
-			mdelay(1);
-		}
-		else {
-			printk(KERN_WARNING
-				"megaraid: critical hardware error!\n");
-
-			rval = FAILED;
-
-			break;
-		}
-	}
-
-	if( rval == SUCCESS ) {
-		printk(KERN_INFO
-			"megaraid: abort sequence successfully completed.\n");
-	}
-
-	return rval;
+	return SUCCESS;
 }
 
 
 static int
 megaraid_reset(Scsi_Cmnd *cmd)
 {
-	adapter_t	*adapter;
-	megacmd_t	mc;
-	long		iter;
-	int		rval = SUCCESS;
+	DECLARE_WAIT_QUEUE_HEAD(wq);
+	int			i;
+	scb_t			*scb;
+	adapter_t		*adapter;
+	struct list_head	*pos, *next;
+	int			rval;
 
 	adapter = (adapter_t *)cmd->host->hostdata;
 
@@ -2856,31 +2807,54 @@ megaraid_reset(Scsi_Cmnd *cmd)
 		cmd->serial_number, cmd->cmnd[0], cmd->channel, cmd->target,
 		cmd->lun);
 
+	/*
+	 * Check if hw_error flag was set in previous RESET call. If it was,
+	 * then we needn't do any handling here. The controller will be marked
+	 * offline soon
+	 */
 
-#if MEGA_HAVE_CLUSTERING
-	mc.cmd = MEGA_CLUSTER_CMD;
-	mc.opcode = MEGA_RESET_RESERVATIONS;
-
-	spin_unlock_irq(adapter->host_lock);
-	if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
-		printk(KERN_WARNING
-				"megaraid: reservation reset failed.\n");
+	if (adapter->hw_error) {
+		printk("megaraid: hw error, cannot reset\n");
+		return FAILED;
 	}
-	else {
-		printk(KERN_INFO "megaraid: reservation reset.\n");
+
+	/*
+	 * Return all the pending cmds to the mid-layer with the cmd result
+	 * DID_RESET. Make sure you don't return the cmds ISSUED to FW.
+	 */
+	list_for_each_safe( pos, next, &adapter->pending_list ) {
+
+		scb		= list_entry(pos, scb_t, list);
+		scb->state	|= SCB_RESET;
+
+		if( !(scb->state & SCB_ISSUED) ) {
+
+			/* Not issued to the FW; return with RESET */
+			cmd->result = (DID_RESET << 16);
+
+			mega_free_scb(adapter, scb);
+			cmd->scsi_done(cmd);
+		}
 	}
-	spin_lock_irq(adapter->host_lock);
-#endif
 
 	/*
-	 * Do not return until all the commands are actually completed by the
-	 * firmware
+	 * Under exceptional conditions, FW may take up to 3 mins to complete
+	 * processing all pending commands. We'll wait for maximum 3 mins to
+	 * see if all outstanding commands are completed.
 	 */
-	iter = 0;
-	while( atomic_read(&adapter->pend_cmds) > 0 ) {
+
+	if (atomic_read(&adapter->pend_cmds) == 0)
+		return SUCCESS;
+
+	printk("megaraid: %d pending cmds; max wait %d seconds\n",
+		atomic_read(&adapter->pend_cmds), MBOX_RESET_WAIT );
+
+	for(i=0; (i<MBOX_RESET_WAIT)&&(atomic_read(&adapter->pend_cmds)); i++){
+
+		ASSERT( spin_is_locked(adapter->host_lock) );
+
 		/*
-		 * Perform the ack sequence, since interrupts are not
-		 * available right now!
+		 * Perform the ack sequence, since interrupts are unavailable
 		 */
 		if( adapter->flag & BOARD_MEMMAP ) {
 			megaraid_memmbox_ack_sequence(adapter);
@@ -2889,55 +2863,35 @@ megaraid_reset(Scsi_Cmnd *cmd)
 			megaraid_iombox_ack_sequence(adapter);
 		}
 
-		/*
-		 * print a message once every second only
-		 */
-		if( !(iter % 1000) ) {
-			printk(
-			"megaraid: Waiting for %d commands to flush: iter:%ld\n",
-				atomic_read(&adapter->pend_cmds), iter);
-		}
+		spin_unlock(adapter->host_lock);
 
-		if( iter++ < MBOX_RESET_SLEEP*1000 ) {
-			mdelay(1);
+		/* Print a message once every 5 seconds */
+		if (!(i % 5)) {
+			printk("megaraid: pending %d; remaining %d seconds\n",
+				atomic_read(&adapter->pend_cmds),
+				MBOX_RESET_WAIT - i);
 		}
-		else {
-			printk(KERN_WARNING
-				"megaraid: critical hardware error!\n");
 
-			rval = FAILED;
+		sleep_on_timeout(&wq, HZ);
 
-			break;
-		}
-	}
-
-	if( rval == SUCCESS ) {
-		printk(KERN_INFO
-			"megaraid: reset sequence successfully completed.\n");
+		spin_lock(adapter->host_lock);
 	}
 
-	return rval;
-}
-
+	/*
+	 * If after 3 mins there are still outstanding cmds, set the hw_error
+	 * flag so that we can return from subsequent ABORT/RESET handlers
+	 * without any processing
+	 */
 
-/**
- * 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);
-}
+	rval = SUCCESS;
+	if (atomic_read(&adapter->pend_cmds)) {
 
+		adapter->hw_error = 1;
+		printk("megaraid: critical hardware error!\n" );
+		rval = FAILED;
+	}
 
-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);
+	return rval;
 }
 
 
@@ -3988,6 +3942,7 @@ static int
 megaraid_reboot_notify (struct notifier_block *this, unsigned long code,
 		void *unused)
 {
+	DECLARE_WAIT_QUEUE_HEAD(wq);
 	adapter_t *adapter;
 	struct Scsi_Host *host;
 	u8 raw_mbox[sizeof(mbox_t)];
@@ -4040,10 +3995,10 @@ megaraid_reboot_notify (struct notifier_
 	printk(KERN_INFO "megaraid: cache flush delay:   ");
 	for( i = 9; i >= 0; i-- ) {
 		printk("\b\b\b[%d]", i);
-		mdelay(1000);
+		sleep_on_timeout(&wq, HZ);
 	}
 	printk("\b\b\b[done]\n");
-	mdelay(1000);
+	sleep_on_timeout(&wq, HZ);
 
 	return NOTIFY_DONE;
 }
@@ -4150,17 +4105,27 @@ megadev_open (struct inode *inode, struc
 }
 
 
-#ifdef LSI_CONFIG_COMPAT
+#if defined(__x86_64__)
 static int
 megadev_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
 		struct file *filep)
 {
 	struct inode *inode = filep->f_dentry->d_inode;
 
-	return megadev_ioctl(inode, filep, cmd, arg);
+	return megadev_ioctl_entry(inode, filep, cmd, arg);
 }
 #endif
 
+static int
+megadev_ioctl_entry(struct inode *inode, struct file *filep, unsigned int cmd,
+		unsigned long arg)
+{
+	int rval;
+	down( &megaraid_ioc_mtx );
+	rval = megadev_ioctl( inode, filep, cmd, arg );
+	up( &megaraid_ioc_mtx );
+	return rval;
+}
 
 /**
  * megadev_ioctl()
@@ -4184,9 +4149,8 @@ megadev_ioctl(struct inode *inode, struc
 	int		rval;
 	mega_passthru	*upthru;	/* user address for passthru */
 	mega_passthru	*pthru;		/* copy user passthru here */
-	dma_addr_t	pthru_dma_hndl;
 	void		*data = NULL;	/* data to be transferred */
-	dma_addr_t	data_dma_hndl;	/* dma handle for data xfer area */
+	dma_addr_t	data_dma_hndl = 0;
 	megacmd_t	mc;
 	megastat_t	*ustats;
 	int		num_ldrv;
@@ -4302,7 +4266,7 @@ megadev_ioctl(struct inode *inode, struc
 		/*
 		 * Which adapter
 		 */
-		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
+		if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) 
 			return (-ENODEV);
 
 		adapter = hba_soft_state[adapno];
@@ -4358,13 +4322,7 @@ megadev_ioctl(struct inode *inode, struc
 		if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
 			/* Passthru commands */
 
-			pthru = pci_alloc_consistent(pdev,
-					sizeof(mega_passthru),
-					&pthru_dma_hndl);
-
-			if( pthru == NULL ) {
-				return (-ENOMEM);
-			}
+			pthru = adapter->int_pthru;
 
 			/*
 			 * The user passthru structure
@@ -4376,29 +4334,27 @@ megadev_ioctl(struct inode *inode, struc
 			 */
 			if( copy_from_user(pthru, (char *)upthru,
 						sizeof(mega_passthru)) ) {
-
-				pci_free_consistent(pdev,
-						sizeof(mega_passthru), pthru,
-						pthru_dma_hndl);
-
 				return (-EFAULT);
 			}
 
 			/*
-			 * Is there a data transfer
+			 * 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 
+			 * here.
 			 */
-			if( pthru->dataxferlen ) {
-				data = pci_alloc_consistent(pdev,
-						pthru->dataxferlen,
-						&data_dma_hndl);
-
-				if( data == NULL ) {
-					pci_free_consistent(pdev,
-							sizeof(mega_passthru),
-							pthru,
-							pthru_dma_hndl);
+			if (pthru->dataxferlen) {
+				if (pthru->dataxferlen > INT_MEMBLK_SZ) {
+					data = pci_alloc_consistent (
+							pdev,
+							pthru->dataxferlen,
+							&data_dma_hndl );
 
-					return (-ENOMEM);
+					if (data == NULL)
+						return (-ENOMEM);
+				}
+				else {
+					data = adapter->int_data;
 				}
 
 				/*
@@ -4406,7 +4362,11 @@ megadev_ioctl(struct inode *inode, struc
 				 * address at just allocated memory
 				 */
 				uxferaddr = pthru->dataxferaddr;
-				pthru->dataxferaddr = data_dma_hndl;
+				if (data_dma_hndl)
+					pthru->dataxferaddr = data_dma_hndl;
+				else
+					pthru->dataxferaddr = 
+						adapter->int_data_dma_hndl;
 			}
 
 
@@ -4421,14 +4381,14 @@ megadev_ioctl(struct inode *inode, struc
 						(char *)((ulong)uxferaddr),
 						pthru->dataxferlen) ) {
 					rval = (-EFAULT);
-					goto freemem_and_return;
+					goto freedata_and_return;
 				}
 			}
 
 			memset(&mc, 0, sizeof(megacmd_t));
 
 			mc.cmd = MEGA_MBOXCMD_PASSTHRU;
-			mc.xferaddr = (u32)pthru_dma_hndl;
+			mc.xferaddr = (u32)adapter->int_pthru_dma_hndl;
 
 			/*
 			 * Issue the command
@@ -4437,7 +4397,7 @@ megadev_ioctl(struct inode *inode, struc
 
 			rval = mega_n_to_m((void *)arg, &mc);
 
-			if( rval ) goto freemem_and_return;
+			if( rval ) goto freedata_and_return;
 
 
 			/*
@@ -4456,18 +4416,14 @@ megadev_ioctl(struct inode *inode, struc
 			 */
 			copy_to_user(upthru->reqsensearea,
 					pthru->reqsensearea, 14);
-
-freemem_and_return:
-			if( pthru->dataxferlen ) {
-				pci_free_consistent(pdev,
-						pthru->dataxferlen, data,
-						data_dma_hndl);
+freedata_and_return:
+			if (data_dma_hndl) {
+				pci_free_consistent( pdev, pthru->dataxferlen,
+							data, data_dma_hndl );
 			}
 
-			pci_free_consistent(pdev, sizeof(mega_passthru),
-					pthru, pthru_dma_hndl);
-
 			return rval;
+
 		}
 		else {
 			/* DCMD commands */
@@ -4476,13 +4432,18 @@ freemem_and_return:
 			 * Is there a data transfer
 			 */
 			if( uioc.xferlen ) {
-				data = pci_alloc_consistent(pdev,
-						uioc.xferlen, &data_dma_hndl);
+				if (uioc.xferlen > INT_MEMBLK_SZ) {
+					data = pci_alloc_consistent(
+							pdev,
+							uioc.xferlen,
+							&data_dma_hndl );
 
-				if( data == NULL ) {
-					return (-ENOMEM);
+					if (data == NULL)
+						return (-ENOMEM);
+				}
+				else {
+					data = adapter->int_data;
 				}
-
 				uxferaddr = MBOX(uioc)->xferaddr;
 			}
 
@@ -4497,9 +4458,9 @@ freemem_and_return:
 						(char *)((ulong)uxferaddr),
 						uioc.xferlen) ) {
 
-					pci_free_consistent(pdev,
-						uioc.xferlen, data,
-						data_dma_hndl);
+					pci_free_consistent(
+						pdev, uioc.xferlen,
+						data, data_dma_hndl );
 
 					return (-EFAULT);
 				}
@@ -4507,7 +4468,10 @@ freemem_and_return:
 
 			memcpy(&mc, MBOX(uioc), sizeof(megacmd_t));
 
-			mc.xferaddr = (u32)data_dma_hndl;
+			if (data_dma_hndl )
+				mc.xferaddr = (u32)data_dma_hndl;
+			else
+				mc.xferaddr = (u32)(adapter->int_data_dma_hndl);
 
 			/*
 			 * Issue the command
@@ -4517,12 +4481,10 @@ freemem_and_return:
 			rval = mega_n_to_m((void *)arg, &mc);
 
 			if( rval ) {
-				if( uioc.xferlen ) {
-					pci_free_consistent(pdev,
-							uioc.xferlen, data,
-							data_dma_hndl);
+				if (data_dma_hndl) {
+					pci_free_consistent( pdev, uioc.xferlen,
+							data, data_dma_hndl );
 				}
-
 				return rval;
 			}
 
@@ -4537,10 +4499,9 @@ freemem_and_return:
 				}
 			}
 
-			if( uioc.xferlen ) {
-				pci_free_consistent(pdev,
-						uioc.xferlen, data,
-						data_dma_hndl);
+			if (data_dma_hndl) {
+				pci_free_consistent( pdev, uioc.xferlen,
+							data, data_dma_hndl );
 			}
 
 			return rval;
@@ -4725,19 +4686,22 @@ mega_n_to_m(void *arg, megacmd_t *mc)
 	else {
 		uioc_mimd = (struct uioctl_t *)arg;
 
-		if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) )
+		if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) ) {
 			return (-EFAULT);
+		}
 
 		if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
 
 			umc = (megacmd_t *)uioc_mimd->mbox;
-			if (copy_from_user(&kmc, umc, sizeof(megacmd_t)))
+			if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) {
 				return -EFAULT;
+			}
 
 			upthru = (mega_passthru *)((ulong)kmc.xferaddr);
 
-			if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
+			if( put_user(mc->status, (u8 *)&upthru->scsistatus) ){
 				return (-EFAULT);
+			}
 		}
 	}
 
@@ -5150,6 +5114,54 @@ mega_support_cluster(adapter_t *adapter)
 
 
 /**
+ * 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()
  *
  * Hack: reorder the scsi hosts in mid-layer so that the controller with the
@@ -5363,6 +5375,27 @@ mega_adapinq(adapter_t *adapter, dma_add
 }
 
 
+/**
+ * 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
  * @ch - channel for this device
--- ./drivers/scsi/megaraid2.h.mr2	Wed Feb  2 08:27:20 2005
+++ ./drivers/scsi/megaraid2.h	Wed Feb  2 10:31:16 2005
@@ -6,7 +6,7 @@
 
 
 #define MEGARAID_VERSION	\
-	"v2.10.3 (Release Date: Thu Apr  8 16:16:05 EDT 2004)\n"
+	"v2.10.8.2 (Release Date: Mon Jul 26 12:15:51 EDT 2004)\n"
 
 /*
  * Driver features - change the values to enable or disable features in the
@@ -82,6 +82,7 @@
 #define LSI_SUBSYS_VID			0x1000
 #define INTEL_SUBSYS_VID		0x8086
 #define FSC_SUBSYS_VID			0x1734
+#define ACER_SUBSYS_VID			0x1025
 
 #define HBA_SIGNATURE	      		0x3344
 #define HBA_SIGNATURE_471	  	0xCCCC
@@ -978,6 +979,15 @@ typedef struct {
 						 cmds */
 
 	int	has_cluster;	/* cluster support on this HBA */
+
+#define INT_MEMBLK_SZ		(28*1024)
+	mega_passthru		*int_pthru;		/*internal pthru*/
+	dma_addr_t		int_pthru_dma_hndl;
+	caddr_t			int_data;		/*internal data*/
+	dma_addr_t		int_data_dma_hndl;
+
+	int			hw_error;
+
 }adapter_t;
 
 
@@ -1085,18 +1095,21 @@ typedef enum { LOCK_INT, LOCK_EXT } lock
 
 #define MBOX_ABORT_SLEEP	60
 #define MBOX_RESET_SLEEP	30
+#define MBOX_RESET_WAIT		180
 
 const char *megaraid_info (struct Scsi_Host *);
 
 static int megaraid_detect(Scsi_Host_Template *);
 static void mega_find_card(Scsi_Host_Template *, u16, u16);
 static int mega_query_adapter(adapter_t *);
-static int issue_scb(adapter_t *, scb_t *);
+static inline int issue_scb(adapter_t *, scb_t *);
 static int mega_setup_mailbox(adapter_t *);
 
 static int megaraid_queue (Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
 static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *);
+static inline scb_t *mega_allocate_scb(adapter_t *, Scsi_Cmnd *);
 static void __mega_runpendq(adapter_t *);
+static inline void mega_runpendq(adapter_t *);
 static int issue_scb_block(adapter_t *, u_char *);
 
 static void megaraid_isr_memmapped(int, void *, struct pt_regs *);
@@ -1113,8 +1126,9 @@ static int megaraid_reset(Scsi_Cmnd *);
 
 static int mega_build_sglist (adapter_t *adapter, scb_t *scb,
 			      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 *);
@@ -1123,15 +1137,13 @@ static int megaraid_reboot_notify (struc
 				   unsigned long, void *);
 static int megadev_open (struct inode *, struct file *);
 
-#if defined(CONFIG_COMPAT) || defined( __x86_64__) || defined(IA32_EMULATION)
-#define LSI_CONFIG_COMPAT
-#endif
-
-#ifdef LSI_CONFIG_COMPAT
+#if defined(__x86_64__)
 static int megadev_compat_ioctl(unsigned int, unsigned int, unsigned long,
 	struct file *);
 #endif
 
+static int megadev_ioctl_entry (struct inode *, struct file *, unsigned int,
+		unsigned long);
 static int megadev_ioctl (struct inode *, struct file *, unsigned int,
 		unsigned long);
 static int mega_m_to_n(void *, nitioctl_t *);
@@ -1164,6 +1176,8 @@ static int proc_rdrv(adapter_t *, char *
 
 static int mega_adapinq(adapter_t *, dma_addr_t);
 static int mega_internal_dev_inquiry(adapter_t *, u8, u8, dma_addr_t);
+static inline caddr_t mega_allocate_inquiry(dma_addr_t *, struct pci_dev *);
+static inline void mega_free_inquiry(caddr_t, dma_addr_t, struct pci_dev *);
 static int mega_print_inquiry(char *, char *);
 #endif
 
@@ -1174,6 +1188,7 @@ static mega_ext_passthru* mega_prepare_e
 		scb_t *, Scsi_Cmnd *, int, int);
 static void mega_enum_raid_scsi(adapter_t *);
 static void mega_get_boot_drv(adapter_t *);
+static inline int mega_get_ldrv_num(adapter_t *, Scsi_Cmnd *, int);
 static int mega_support_random_del(adapter_t *);
 static int mega_del_logdrv(adapter_t *, int);
 static int mega_do_del_logdrv(adapter_t *, int);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 18:42   ` Vasily Averin
@ 2005-02-02 18:53     ` Andrey J. Melnikoff (TEMHOTA)
  2005-02-02 19:06     ` Matt Domsch
  1 sibling, 0 replies; 12+ messages in thread
From: Andrey J. Melnikoff (TEMHOTA) @ 2005-02-02 18:53 UTC (permalink / raw)
  To: Vasily Averin
  Cc: Marcelo Tosatti, linux-kernel, Atul Mukker, Sreenivas Bagalkote

Hi Vasily Averin!

 On Wed, Feb 02, 2005 at 09:42:02PM +0300, Vasily Averin wrote next:

> Marcelo Tosatti wrote:
> >On Tue, Jan 25, 2005 at 11:00:22AM +0300, Vasily Averin wrote:
> >>You should unlock io_request_lock before msleep, like in latest versions
> >>of megaraid2 drivers.
> >
> >Andrey, 
> >
> >Can you please update your patch to unlock io_request_lock before sleeping
> >and locking after coming back? 
> >
> >What the driver is doing is indeed wrong.
> 
> Marcelo,
> 
> This is megaraid2 driver update (2.10.8.2 version, latest 2.4-compatible
> version that I've seen), 
Where ? Last version (i see announce + patch from 2.10.3) is 2.10.6. 

> taken from latest RHEL3 kernel update. I believe it should prevent NMI 
> in abort/reset handler.
Thnx for patch, I try it on my server at next week.

-- 
 Best regards, TEMHOTA-RIPN aka MJA13-RIPE
 System Administrator. mailto:temnota@kmv.ru


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 18:42   ` Vasily Averin
  2005-02-02 18:53     ` Andrey J. Melnikoff (TEMHOTA)
@ 2005-02-02 19:06     ` Matt Domsch
  2005-02-02 19:32       ` Vasily Averin
                         ` (2 more replies)
  1 sibling, 3 replies; 12+ messages in thread
From: Matt Domsch @ 2005-02-02 19:06 UTC (permalink / raw)
  To: Vasily Averin
  Cc: Marcelo Tosatti, Andrey Melnikov, linux-kernel, Atul Mukker,
	Sreenivas Bagalkote

On Wed, Feb 02, 2005 at 09:42:02PM +0300, Vasily Averin wrote:
> Marcelo Tosatti wrote:
> >On Tue, Jan 25, 2005 at 11:00:22AM +0300, Vasily Averin wrote:
> >>You should unlock io_request_lock before msleep, like in latest versions
> >>of megaraid2 drivers.
> >
> >Andrey, 
> >
> >Can you please update your patch to unlock io_request_lock before sleeping
> >and locking after coming back? 
> >
> >What the driver is doing is indeed wrong.
> 
> Marcelo,
> 
> This is megaraid2 driver update (2.10.8.2 version, latest 2.4-compatible
> version that I've seen), taken from latest RHEL3 kernel update. I
> believe it should prevent NMI in abort/reset handler.
> 
> Thank you,
> 	Vasily Averin, SWSoft Linux Kernel Team

Thanks Vasily, I was just looking at this again yesterday.

You'll also find that because the driver doesn't define its inline
functions prior to their use, newest compilers refuse to compile this
version of the driver.  Earlier compilers just ignore it and don't
inline anything.

As a hack, one could #define inline /*nothing*/ in megaraid2.h to
avoid this, but it would be nice if the functions could all get
reordered such that inlining works properly, and the need for function
declarations in megaraid2.h would disappear completely.

Thanks,
Matt


-- 
Matt Domsch
Software Architect
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 19:06     ` Matt Domsch
@ 2005-02-02 19:32       ` Vasily Averin
  2005-02-02 20:19         ` Matt Domsch
  2005-02-02 19:39       ` Vasily Averin
  2005-02-02 19:50       ` Vasily Averin
  2 siblings, 1 reply; 12+ messages in thread
From: Vasily Averin @ 2005-02-02 19:32 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Marcelo Tosatti, Andrey Melnikov, linux-kernel, Atul Mukker,
	Sreenivas Bagalkote

Hello Matt

Matt Domsch wrote:
> On Wed, Feb 02, 2005 at 09:42:02PM +0300, Vasily Averin wrote:
>>Marcelo,
>>
>>This is megaraid2 driver update (2.10.8.2 version, latest 2.4-compatible
>>version that I've seen), taken from latest RHEL3 kernel update. I
>>believe it should prevent NMI in abort/reset handler.
> 
> Thanks Vasily, I was just looking at this again yesterday.
> 
> You'll also find that because the driver doesn't define its inline
> functions prior to their use, newest compilers refuse to compile this
> version of the driver.  Earlier compilers just ignore it and don't
> inline anything.
> 
> As a hack, one could #define inline /*nothing*/ in megaraid2.h to
> avoid this, but it would be nice if the functions could all get
> reordered such that inlining works properly, and the need for function
> declarations in megaraid2.h would disappear completely.


Could you fix it by additional patch? Or you going to prepare a new one?

Thank you,
	Vasily Averin, SWSoft Linux Kernel Team


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 19:06     ` Matt Domsch
  2005-02-02 19:32       ` Vasily Averin
@ 2005-02-02 19:39       ` Vasily Averin
  2005-02-02 19:50       ` Vasily Averin
  2 siblings, 0 replies; 12+ messages in thread
From: Vasily Averin @ 2005-02-02 19:39 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Marcelo Tosatti, Andrey Melnikov, linux-kernel, Atul Mukker,
	Sreenivas Bagalkote

Hello Matt

Matt Domsch wrote:
> On Wed, Feb 02, 2005 at 09:42:02PM +0300, Vasily Averin wrote:
>>This is megaraid2 driver update (2.10.8.2 version, latest 2.4-compatible
>>version that I've seen), taken from latest RHEL3 kernel update. I
>>believe it should prevent NMI in abort/reset handler.
> 
> Thanks Vasily, I was just looking at this again yesterday.
> 
> You'll also find that because the driver doesn't define its inline
> functions prior to their use, newest compilers refuse to compile this
> version of the driver.  Earlier compilers just ignore it and don't
> inline anything.
> 
> As a hack, one could #define inline /*nothing*/ in megaraid2.h to
> avoid this, but it would be nice if the functions could all get
> reordered such that inlining works properly, and the need for function
> declarations in megaraid2.h would disappear completely.

Could you fix it by additional patch? Or do you going to prepare a new one?

Thank you,
	Vasily Averin, SWSoft Linux Kernel Team


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 19:06     ` Matt Domsch
  2005-02-02 19:32       ` Vasily Averin
  2005-02-02 19:39       ` Vasily Averin
@ 2005-02-02 19:50       ` Vasily Averin
  2 siblings, 0 replies; 12+ messages in thread
From: Vasily Averin @ 2005-02-02 19:50 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Marcelo Tosatti, Andrey Melnikov, linux-kernel, Atul Mukker,
	Sreenivas Bagalkote

Matt Domsch wrote:
> On Wed, Feb 02, 2005 at 09:42:02PM +0300, Vasily Averin wrote:
>>This is megaraid2 driver update (2.10.8.2 version, latest 2.4-compatible
>>version that I've seen), taken from latest RHEL3 kernel update. I
>>believe it should prevent NMI in abort/reset handler.
> 
> Thanks Vasily, I was just looking at this again yesterday.
> 
> You'll also find that because the driver doesn't define its inline
> functions prior to their use, newest compilers refuse to compile this
> version of the driver.  Earlier compilers just ignore it and don't
> inline anything.
> 
> As a hack, one could #define inline /*nothing*/ in megaraid2.h to
> avoid this, but it would be nice if the functions could all get
> reordered such that inlining works properly, and the need for function
> declarations in megaraid2.h would disappear completely.

Could you fix it by additional fix? Or you going to release new driver 
version for 2.4 kernels?

Thank you,
	Vasily Averin


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 19:32       ` Vasily Averin
@ 2005-02-02 20:19         ` Matt Domsch
  2005-02-02 21:08           ` Andrey J. Melnikoff (TEMHOTA)
       [not found]           ` <20050207202745.GA19104@kmv.ru>
  0 siblings, 2 replies; 12+ messages in thread
From: Matt Domsch @ 2005-02-02 20:19 UTC (permalink / raw)
  To: Vasily Averin
  Cc: Marcelo Tosatti, Andrey Melnikov, linux-kernel, Atul Mukker,
	Sreenivas Bagalkote

On Wed, Feb 02, 2005 at 10:32:28PM +0300, Vasily Averin wrote:
> >As a hack, one could #define inline /*nothing*/ in megaraid2.h to
> >avoid this, but it would be nice if the functions could all get
> >reordered such that inlining works properly, and the need for function
> >declarations in megaraid2.h would disappear completely.
> 
> 
> Could you fix it by additional patch? Or you going to prepare a new one?

Here's the hack patch (will apply after yours).

Signed-off-by: Matt Domsch <Matt_Domsch@dell.com>

-- 
Matt Domsch
Software Architect
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

===== drivers/scsi/megaraid2.h 1.6 vs edited =====
--- 1.6/drivers/scsi/megaraid2.h	2005-02-02 13:48:22 -06:00
+++ edited/drivers/scsi/megaraid2.h	2005-02-02 13:55:42 -06:00
@@ -5,6 +5,18 @@
 #include <linux/spinlock.h>
 
 
+/* This is an ugly hack, but gets around the fact that earlier
+ * versions of gcc ignores the inline specification when
+ * the function definition comes after function use (thereby
+ * not inlining the code), and newer gcc fails to compile the
+ * code.  This should be removed once the functions are properly
+ * ordered in megaraid2.c, and the function declarations removed
+ * in megaraid2.h.
+ */
+#undef inline
+#define inline /*nothing*/
+
+
 #define MEGARAID_VERSION	\
 	"v2.10.8.2 (Release Date: Mon Jul 26 12:15:51 EDT 2004)\n"
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] Prevent NMI oopser
  2005-02-02 20:19         ` Matt Domsch
@ 2005-02-02 21:08           ` Andrey J. Melnikoff (TEMHOTA)
       [not found]           ` <20050207202745.GA19104@kmv.ru>
  1 sibling, 0 replies; 12+ messages in thread
From: Andrey J. Melnikoff (TEMHOTA) @ 2005-02-02 21:08 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Vasily Averin, Marcelo Tosatti, linux-kernel, Atul Mukker,
	Sreenivas Bagalkote

Hi Matt Domsch!
 On Wed, Feb 02, 2005 at 02:19:14PM -0600, Matt Domsch wrote next:

> On Wed, Feb 02, 2005 at 10:32:28PM +0300, Vasily Averin wrote:
> > >As a hack, one could #define inline /*nothing*/ in megaraid2.h to
> > >avoid this, but it would be nice if the functions could all get
> > >reordered such that inlining works properly, and the need for function
> > >declarations in megaraid2.h would disappear completely.
> > 
> > 
> > Could you fix it by additional patch? Or you going to prepare a new one?
> 
> Here's the hack patch (will apply after yours).

Reorder inline functions
Uninline big mega_cmd_done() function

Signed-off-by: <temnota+kernel@kmv.ru>

--- drivers/scsi/megaraid2.c.orig	Wed Feb  2 23:30:04 2005
+++ drivers/scsi/megaraid2.c	Wed Feb  2 23:57:15 2005
@@ -989,6 +989,268 @@
 }
 
 
+/**
+ * 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
@@ -1601,145 +1863,6 @@
 
 
 /**
- * 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
@@ -1807,145 +1930,51 @@
 		WRINDOOR(adapter, adapter->mbox_dma | 0x2);
 
 		while(RDINDOOR(adapter) & 0x2)
-			cpu_relax();
-	}
-	else {
-		irq_disable(adapter);
-		issue_command(adapter);
-
-		while (!((byte = irq_state(adapter)) & INTR_VALID))
-			cpu_relax();
-
-		status = mbox->status;
-		mbox->numstatus = 0xFF;
-		mbox->status = 0xFF;
-
-		set_irq_state(adapter, byte);
-		irq_enable(adapter);
-		irq_ack(adapter);
-	}
-
-	// invalidate the completed command id array. After command
-	// completion, firmware would write the valid id.
-	for (i = 0; i < MAX_FIRMWARE_STATUS; i++) {
-		mbox->completed[i] = 0xFF;
-	}
-
-	return status;
-
-bug_blocked_mailbox:
-	printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n");
-	udelay (1000);
-	return -1;
-}
-
-
-/**
- * megaraid_isr_iomapped()
- * @irq - irq
- * @devp - pointer to our soft state
- * @regs - unused
- *
- * Interrupt service routine for io-mapped controllers.
- * Find out if our device is interrupting. If yes, acknowledge the interrupt
- * and service the completed commands.
- */
-static void
-megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
-{
-	adapter_t	*adapter = devp;
-	unsigned long	flags;
-
-
-	spin_lock_irqsave(adapter->host_lock, flags);
-
-	megaraid_iombox_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_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;
-		}
+			cpu_relax();
+	}
+	else {
+		irq_disable(adapter);
+		issue_command(adapter);
 
-		// 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;
+		while (!((byte = irq_state(adapter)) & INTR_VALID))
+			cpu_relax();
 
-		/*
-		 * decrement the pending queue counter
-		 */
-		atomic_sub(nstatus, &adapter->pend_cmds);
+		status = mbox->status;
+		mbox->numstatus = 0xFF;
+		mbox->status = 0xFF;
 
-		/* Acknowledge interrupt */
+		set_irq_state(adapter, byte);
+		irq_enable(adapter);
 		irq_ack(adapter);
+	}
 
-		mega_cmd_done(adapter, completed, nstatus, status);
+	// invalidate the completed command id array. After command
+	// completion, firmware would write the valid id.
+	for (i = 0; i < MAX_FIRMWARE_STATUS; i++) {
+		mbox->completed[i] = 0xFF;
+	}
 
-	} while(1);
+	return status;
+
+bug_blocked_mailbox:
+	printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n");
+	udelay (1000);
+	return -1;
 }
 
 
 /**
- * megaraid_isr_memmapped()
+ * megaraid_isr_iomapped()
  * @irq - irq
  * @devp - pointer to our soft state
  * @regs - unused
  *
- * Interrupt service routine for memory-mapped controllers.
+ * Interrupt service routine for io-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)
+megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
 {
 	adapter_t	*adapter = devp;
 	unsigned long	flags;
@@ -1953,10 +1982,10 @@
 
 	spin_lock_irqsave(adapter->host_lock, flags);
 
-	megaraid_memmbox_ack_sequence(adapter);
+	megaraid_iombox_ack_sequence(adapter);
 
 	/* Loop through any pending requests */
-	if(atomic_read(&adapter->quiescent) == 0) {
+	if( atomic_read(&adapter->quiescent ) == 0) {
 		mega_runpendq(adapter);
 	}
 
@@ -2034,6 +2063,37 @@
 
 
 /**
+ * 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
@@ -2042,7 +2102,7 @@
  *
  * Complete the comamnds and call the scsi mid-layer callback hooks.
  */
-static inline void
+static void
 mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 {
 	mega_ext_passthru	*epthru = NULL;
@@ -2344,18 +2404,6 @@
 	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)
 {
@@ -2513,6 +2561,43 @@
 		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
@@ -2650,44 +2735,6 @@
 	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
  */
@@ -3153,6 +3200,26 @@
 	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()
@@ -5112,55 +5179,6 @@
 }
 
 
-
-/**
- * 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()
  *
@@ -5374,26 +5392,6 @@
 	return 0;
 }
 
-
-/**
- * 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()
--- drivers/scsi/megaraid2.h.orig	Wed Feb  2 23:30:04 2005
+++ drivers/scsi/megaraid2.h	Wed Feb  2 23:49:09 2005
@@ -1128,7 +1128,7 @@
 			      u32 *buffer, u32 *length);
 static inline int mega_busywait_mbox (adapter_t *);
 static int __mega_busywait_mbox (adapter_t *);
-static inline void mega_cmd_done(adapter_t *, u8 [], int, int);
+static 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 *);

-- 
 Best regards, TEMHOTA-RIPN aka MJA13-RIPE
 System Administrator. mailto:temnota@kmv.ru


^ permalink raw reply	[flat|nested] 12+ messages in thread

* v2.4 megaraid2 update Re: [PATCH] Prevent NMI oopser
       [not found]           ` <20050207202745.GA19104@kmv.ru>
@ 2005-02-23  7:06             ` Marcelo Tosatti
  0 siblings, 0 replies; 12+ messages in thread
From: Marcelo Tosatti @ 2005-02-23  7:06 UTC (permalink / raw)
  To: Andrey J. Melnikoff (TEMHOTA), Vasily Averin
  Cc: Matt Domsch, linux-kernel, Mukker, Atul, Bagalkote, Sreenivas


Hi, 

As the megaraid2 maintainers dont seem to care about v2.4 mainline at all, completly 
ignoring my requests to fix the NMI oopser bug for several months, I'm applying the RHEL3 
update + inline reordering, which should do it.

At this point I'm quite sure they wont answer this message either.  :( 

Thanks Vasily and Andrey.

On Mon, Feb 07, 2005 at 11:27:45PM +0300, Andrey J. Melnikoff (TEMHOTA) wrote:
> Hi Matt, Marcelo!
>  On Wed, Feb 02, 2005 at 02:19:14PM -0600, Matt Domsch wrote next:
> 
> > On Wed, Feb 02, 2005 at 10:32:28PM +0300, Vasily Averin wrote:
> > > >As a hack, one could #define inline /*nothing*/ in megaraid2.h to
> > > >avoid this, but it would be nice if the functions could all get
> > > >reordered such that inlining works properly, and the need for function
> > > >declarations in megaraid2.h would disappear completely.
> > > 
> > > 
> > > Could you fix it by additional patch? Or you going to prepare a new one?
> 
> Any chance to include this two patches before 2.4.30 release?
> 
> Vasily Averin patch:
> http://marc.theaimsgroup.com/?l=linux-kernel&m=110737085714273&w=2
> And my (incremental) patch:
> http://marc.theaimsgroup.com/?l=linux-kernel&m=110738438005846&w=2

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-02-23 18:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <41F5FC96.2010103@sw.ru>
2005-01-31 23:17 ` [PATCH] Prevent NMI oopser Marcelo Tosatti
2005-02-02 18:42   ` Vasily Averin
2005-02-02 18:53     ` Andrey J. Melnikoff (TEMHOTA)
2005-02-02 19:06     ` Matt Domsch
2005-02-02 19:32       ` Vasily Averin
2005-02-02 20:19         ` Matt Domsch
2005-02-02 21:08           ` Andrey J. Melnikoff (TEMHOTA)
     [not found]           ` <20050207202745.GA19104@kmv.ru>
2005-02-23  7:06             ` v2.4 megaraid2 update " Marcelo Tosatti
2005-02-02 19:39       ` Vasily Averin
2005-02-02 19:50       ` Vasily Averin
2005-01-25  7:47 Vasily Averin
2005-01-25  9:35 ` Marcelo Tosatti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox