All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jack Hammer <jack_hammer@adaptec.com>
To: James.Bottomley@steeleye.com, linux-scsi@vger.kernel.org
Subject: ips init / kdump
Date: Mon, 29 Aug 2005 10:44:34 -0400	[thread overview]
Message-ID: <43131F52.2040307@adaptec.com> (raw)

This patch, applied to ips version 7.12.02 in the 2.6.13 kernel, fixes an
initialization bug found with kdump.

If I/O is active on the adapter, and an unexpected interrupt is pending 
during initialization, the driver blows it's brains out. Since the driver
didn't initiate the I/O, the data in it's internal tables will contain NULL
pointers.

When this condition is detected, a "flush cache and reset" is performed. 
The flush cache allows any pending "lazy writes" that the adapter is 
processing to complete ( a "must have" for a RAID adapter ) and the reset
puts the adapter back into a known, good state.


Signed-off-by: Jack Hammer <jack_hammer@adaptec.com>



--- a/drivers/scsi/ips.c	Mon Aug  8 12:22:19 2005
+++ b/drivers/scsi/ips.c	Mon Aug  8 12:22:08 2005
@@ -358,6 +358,9 @@
 static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
 static int ips_register_scsi(int index);
 
+static int  ips_poll_for_flush_complete(ips_ha_t * ha);
+static void ips_flush_and_reset(ips_ha_t *ha);
+
 /*
  * global variables
  */
@@ -4807,6 +4810,9 @@
 	uint32_t bits;
 
 	METHOD_TRACE("ips_is_init_morpheus", 1);
+   
+	if (ips_isintr_morpheus(ha)) 
+	    ips_flush_and_reset(ha);
 
 	post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
 	bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
@@ -4818,6 +4824,93 @@
 	else
 		return (1);
 }
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_flush_and_reset                                        */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Perform cleanup ( FLUSH and RESET ) when the adapter is in an unknown  */
+/*   state ( was trying to INIT and an interrupt was already pending ) ...  */
+/*                                                                          */
+/****************************************************************************/
+static void 
+ips_flush_and_reset(ips_ha_t *ha)
+{
+	ips_scb_t *scb;
+	int  ret;
+ 	int  time;
+	int  done;
+	dma_addr_t command_dma;
+
+	/* Create a usuable SCB */
+	scb = pci_alloc_consistent(ha->pcidev, sizeof(ips_scb_t), &command_dma);
+	if (scb) {
+	    memset(scb, 0, sizeof(ips_scb_t));
+	    ips_init_scb(ha, scb);
+	    scb->scb_busaddr = command_dma;
+
+	    scb->timeout = ips_cmd_timeout;
+	    scb->cdb[0] = IPS_CMD_FLUSH;
+
+	    scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+	    scb->cmd.flush_cache.command_id = IPS_MAX_CMDS;   /* Use an ID that would otherwise not exist */
+	    scb->cmd.flush_cache.state = IPS_NORM_STATE;
+	    scb->cmd.flush_cache.reserved = 0;
+	    scb->cmd.flush_cache.reserved2 = 0;
+	    scb->cmd.flush_cache.reserved3 = 0;
+	    scb->cmd.flush_cache.reserved4 = 0;
+
+	    ret = ips_send_cmd(ha, scb);                      /* Send the Flush Command */
+
+	    if (ret == IPS_SUCCESS) {
+	        time = 60 * IPS_ONE_SEC;	              /* Max Wait time is 60 seconds */
+	        done = 0;
+	            
+	        while ((time > 0) && (!done)) {
+	           done = ips_poll_for_flush_complete(ha); 	   
+	           /* This may look evil, but it's only done during extremely rare start-up conditions ! */
+	           udelay(1000);
+	           time--;
+	        }
+        }
+	}
+
+	/* Now RESET and INIT the adapter */
+	(*ha->func.reset) (ha);
+
+	pci_free_consistent(ha->pcidev, sizeof(ips_scb_t), scb, command_dma);
+	return;
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_poll_for_flush_complete                                */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Poll for the Flush Command issued by ips_flush_and_reset() to complete */
+/*   All other responses are just taken off the queue and ignored           */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_poll_for_flush_complete(ips_ha_t * ha)
+{
+	IPS_STATUS cstatus;
+    
+	while (TRUE) {
+	    cstatus.value = (*ha->func.statupd) (ha);
+
+	    if (cstatus.value == 0xffffffff)      /* If No Interrupt to process */
+			break;
+            
+	    /* Success is when we see the Flush Command ID */
+	    if (cstatus.fields.command_id == IPS_MAX_CMDS ) 
+	        return 1;
+	 }	
+
+	return 0;
 
 /****************************************************************************/
 /*                                                                          */

             reply	other threads:[~2005-08-29 14:44 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-29 14:44 Jack Hammer [this message]
2005-10-31 18:17 ` ips init / kdump Jack Hammer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43131F52.2040307@adaptec.com \
    --to=jack_hammer@adaptec.com \
    --cc=James.Bottomley@steeleye.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.