From: "Bagalkote, Sreenivas" <sreenib@lsil.com>

We are releasing megaraid 2.20.4.1 driver. This version fixes two issues -

- Handle IOCTL command timeouts properly

- Replace incorrectly introduced pci_dma_sync_{sg,single}_for_cpu with
  correct pci_dma_sync_{sg,single}_for_device.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/Documentation/scsi/ChangeLog.megaraid  |   11 ++++
 25-akpm/drivers/scsi/megaraid/megaraid_ioctl.h |    6 +-
 25-akpm/drivers/scsi/megaraid/megaraid_mbox.c  |    8 +--
 25-akpm/drivers/scsi/megaraid/megaraid_mbox.h  |    4 -
 25-akpm/drivers/scsi/megaraid/megaraid_mm.c    |   64 +++++++++++++++++++++++--
 25-akpm/drivers/scsi/megaraid/megaraid_mm.h    |    4 -
 6 files changed, 84 insertions(+), 13 deletions(-)

diff -puN Documentation/scsi/ChangeLog.megaraid~megaraid-22041-driver Documentation/scsi/ChangeLog.megaraid
--- 25/Documentation/scsi/ChangeLog.megaraid~megaraid-22041-driver	Fri Nov  5 16:23:05 2004
+++ 25-akpm/Documentation/scsi/ChangeLog.megaraid	Fri Nov  5 16:23:05 2004
@@ -1,3 +1,14 @@
+Release Date	: Thu Nov  4 18:24:56 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
+
+Current Version	: 2.20.4.1 (scsi module), 2.20.2.2 (cmm module)
+Older Version	: 2.20.4.0 (scsi module), 2.20.2.1 (cmm module)
+
+i.	Handle IOCTL cmd timeouts more properly.
+
+ii.	pci_dma_sync_{sg,single}_for_cpu was introduced into megaraid_mbox
+	incorrectly (instead of _for_device). Changed to appropriate
+	pci_dma_sync_{sg,single}_for_device.
+
 Release Date	: Wed Oct 06 11:15:29 EDT 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
 Current Version	: 2.20.4.0 (scsi module), 2.20.2.1 (cmm module)
 Older Version	: 2.20.4.0 (scsi module), 2.20.2.0 (cmm module)
diff -puN drivers/scsi/megaraid/megaraid_ioctl.h~megaraid-22041-driver drivers/scsi/megaraid/megaraid_ioctl.h
--- 25/drivers/scsi/megaraid/megaraid_ioctl.h~megaraid-22041-driver	Fri Nov  5 16:23:05 2004
+++ 25-akpm/drivers/scsi/megaraid/megaraid_ioctl.h	Fri Nov  5 16:23:05 2004
@@ -145,6 +145,8 @@ typedef struct uioc {
 	uint8_t			pool_index;
 	uint8_t			free_buf;
 
+	uint8_t			timedout;
+
 } __attribute__ ((aligned(1024),packed)) uioc_t;
 
 
@@ -247,6 +249,7 @@ typedef struct mm_dmapool {
  * @pdev		: pci dev; used for allocating dma'ble memory
  * @issue_uioc		: Driver supplied routine to issue uioc_t commands
  *			: issue_uioc(drvr_data, kioc, ISSUE/ABORT, uioc_done)
+ * @quiescent		: flag to indicate if ioctl can be issued to this adp
  * @list		: attach with the global list of adapters
  * @kioc_list		: block of mem for @max_kioc number of kiocs
  * @kioc_pool		: pool of free kiocs
@@ -264,7 +267,7 @@ typedef struct mraid_mmadp {
 	uint32_t		unique_id;
 	uint32_t		drvr_type;
 	unsigned long		drvr_data;
-	uint8_t			timeout;
+	uint16_t		timeout;
 	uint8_t			max_kioc;
 
 	struct pci_dev		*pdev;
@@ -272,6 +275,7 @@ typedef struct mraid_mmadp {
 	int(*issue_uioc)(unsigned long, uioc_t *, uint32_t);
 
 /* Maintained by common module */
+	uint32_t		quiescent;
 
 	struct list_head	list;
 	uioc_t			*kioc_list;
diff -puN drivers/scsi/megaraid/megaraid_mbox.c~megaraid-22041-driver drivers/scsi/megaraid/megaraid_mbox.c
--- 25/drivers/scsi/megaraid/megaraid_mbox.c~megaraid-22041-driver	Fri Nov  5 16:23:05 2004
+++ 25-akpm/drivers/scsi/megaraid/megaraid_mbox.c	Fri Nov  5 16:23:05 2004
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mbox.c
- * Version	: v2.20.4 (September 27 2004)
+ * Version	: v2.20.4.1 (Nov 04 2004)
  *
  * Authors:
  * 	Atul Mukker		<Atul.Mukker@lsil.com>
@@ -1559,12 +1559,12 @@ mbox_post_cmd(adapter_t *adapter, scb_t 
 
 	if (scb->dma_direction == PCI_DMA_TODEVICE) {
 		if (!scb->scp->use_sg) {	// sg list not used
-			pci_dma_sync_single_for_cpu(adapter->pdev, ccb->buf_dma_h,
+			pci_dma_sync_single_for_device(adapter->pdev, ccb->buf_dma_h,
 					scb->scp->request_bufflen,
 					PCI_DMA_TODEVICE);
 		}
 		else {
-			pci_dma_sync_sg_for_cpu(adapter->pdev, scb->scp->request_buffer,
+			pci_dma_sync_sg_for_device(adapter->pdev, scb->scp->request_buffer,
 				scb->scp->use_sg, PCI_DMA_TODEVICE);
 		}
 	}
@@ -3596,7 +3596,7 @@ megaraid_cmm_register(adapter_t *adapter
 	adp.drvr_data		= (unsigned long)adapter;
 	adp.pdev		= adapter->pdev;
 	adp.issue_uioc		= megaraid_mbox_mm_handler;
-	adp.timeout		= 30;
+	adp.timeout		= 300;
 	adp.max_kioc		= MBOX_MAX_USER_CMDS;
 
 	if ((rval = mraid_mm_register_adp(&adp)) != 0) {
diff -puN drivers/scsi/megaraid/megaraid_mbox.h~megaraid-22041-driver drivers/scsi/megaraid/megaraid_mbox.h
--- 25/drivers/scsi/megaraid/megaraid_mbox.h~megaraid-22041-driver	Fri Nov  5 16:23:05 2004
+++ 25-akpm/drivers/scsi/megaraid/megaraid_mbox.h	Fri Nov  5 16:23:05 2004
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION	"2.20.4.0"
-#define MEGARAID_EXT_VERSION	"(Release Date: Mon Sep 27 22:15:07 EDT 2004)"
+#define MEGARAID_VERSION	"2.20.4.1"
+#define MEGARAID_EXT_VERSION	"(Release Date: Thu Nov  4 17:44:59 EST 2004)"
 
 
 /*
diff -puN drivers/scsi/megaraid/megaraid_mm.c~megaraid-22041-driver drivers/scsi/megaraid/megaraid_mm.c
--- 25/drivers/scsi/megaraid/megaraid_mm.c~megaraid-22041-driver	Fri Nov  5 16:23:05 2004
+++ 25-akpm/drivers/scsi/megaraid/megaraid_mm.c	Fri Nov  5 16:23:05 2004
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mm.c
- * Version	: v2.20.2.1 (Oct 06 2004)
+ * Version	: v2.20.2.2 (Nov 04 2004)
  *
  * Common management module
  */
@@ -156,6 +156,17 @@ mraid_mm_ioctl(struct inode *inode, stru
 	}
 
 	/*
+	 * Check if adapter can accept ioctl. We may have marked it offline
+	 * if any previous kioc had timedout on this controller.
+	 */
+	if (!adp->quiescent) {
+		con_log(CL_ANN, (KERN_WARNING
+			"megaraid cmm: controller cannot accept cmds due to "
+			"earlier errors\n" ));
+		return -EFAULT;
+	}
+
+	/*
 	 * The following call will block till a kioc is available
 	 */
 	kioc = mraid_mm_alloc_kioc(adp);
@@ -171,10 +182,15 @@ mraid_mm_ioctl(struct inode *inode, stru
 	kioc->done = ioctl_done;
 
 	/*
-	 * Issue the IOCTL to the low level driver
+	 * Issue the IOCTL to the low level driver. After the IOCTL completes
+	 * release the kioc if and only if it was _not_ timedout. If it was
+	 * timedout, that means that resources are still with low level driver.
 	 */
 	if ((rval = lld_ioctl(adp, kioc))) {
-		mraid_mm_dealloc_kioc(adp, kioc);
+
+		if (!kioc->timedout)
+			mraid_mm_dealloc_kioc(adp, kioc);
+
 		return rval;
 	}
 
@@ -581,6 +597,7 @@ mraid_mm_alloc_kioc(mraid_mmadp_t *adp)
 	kioc->user_data		= NULL;
 	kioc->user_data_len	= 0;
 	kioc->user_pthru	= NULL;
+	kioc->timedout		= 0;
 
 	return kioc;
 }
@@ -667,6 +684,14 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *ki
 		del_timer_sync(tp);
 	}
 
+	/*
+	 * If the command had timedout, we mark the controller offline
+	 * before returning
+	 */
+	if (kioc->timedout) {
+		adp->quiescent = 0;
+	}
+
 	return kioc->status;
 }
 
@@ -679,6 +704,10 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *ki
 static void
 ioctl_done(uioc_t *kioc)
 {
+	uint32_t	adapno;
+	int		iterator;
+	mraid_mmadp_t*	adapter;
+
 	/*
 	 * When the kioc returns from driver, make sure it still doesn't
 	 * have ENODATA in status. Otherwise, driver will hang on wait_event
@@ -691,7 +720,32 @@ ioctl_done(uioc_t *kioc)
 		kioc->status = -EINVAL;
 	}
 
-	wake_up(&wait_q);
+	/*
+	 * Check if this kioc was timedout before. If so, nobody is waiting
+	 * on this kioc. We don't have to wake up anybody. Instead, we just
+	 * have to free the kioc
+	 */
+	if (kioc->timedout) {
+		iterator	= 0;
+		adapter		= NULL;
+		adapno		= kioc->adapno;
+
+		con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed "
+					"ioctl that was timedout before\n"));
+
+		list_for_each_entry(adapter, &adapters_list_g, list) {
+			if (iterator++ == adapno) break;
+		}
+
+		kioc->timedout = 0;
+
+		if (adapter) {
+			mraid_mm_dealloc_kioc( adapter, kioc );
+		}
+	}
+	else {
+		wake_up(&wait_q);
+	}
 }
 
 
@@ -706,6 +760,7 @@ lld_timedout(unsigned long ptr)
 	uioc_t *kioc	= (uioc_t *)ptr;
 
 	kioc->status 	= -ETIME;
+	kioc->timedout	= 1;
 
 	con_log(CL_ANN, (KERN_WARNING "megaraid cmm: ioctl timed out\n"));
 
@@ -850,6 +905,7 @@ mraid_mm_register_adp(mraid_mmadp_t *lld
 	adapter->issue_uioc	= lld_adp->issue_uioc;
 	adapter->timeout	= lld_adp->timeout;
 	adapter->max_kioc	= lld_adp->max_kioc;
+	adapter->quiescent	= 1;
 
 	/*
 	 * Allocate single blocks of memory for all required kiocs,
diff -puN drivers/scsi/megaraid/megaraid_mm.h~megaraid-22041-driver drivers/scsi/megaraid/megaraid_mm.h
--- 25/drivers/scsi/megaraid/megaraid_mm.h~megaraid-22041-driver	Fri Nov  5 16:23:05 2004
+++ 25-akpm/drivers/scsi/megaraid/megaraid_mm.h	Fri Nov  5 16:23:05 2004
@@ -29,9 +29,9 @@
 #include "megaraid_ioctl.h"
 
 
-#define LSI_COMMON_MOD_VERSION	"2.20.2.1"
+#define LSI_COMMON_MOD_VERSION	"2.20.2.2"
 #define LSI_COMMON_MOD_EXT_VERSION	\
-		"(Release Date: Wed Oct 06 11:15:29 EDT 2004)"
+		"(Release Date: Thu Nov  4 17:46:29 EST 2004)"
 
 
 #define LSI_DBGLVL			dbglevel
_