Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 4641

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Chad Dupuis <cdupuis@redhat.com>
Date: Fri, 3 Sep 2010 21:40:47 -0400
Subject: [scsi] qla2xxx: rom lock recover if fw hangs holding lock
Message-id: <20100903214047.2767.79238.sendpatchset@localhost.localdomain>
Patchwork-id: 28152
O-Subject: [RHEL 5.6 PATCH 9/9] qla2xxx:rom lock recovery if fw hangs while
	holding the lock.
Bugzilla: 619814
RH-Acked-by: Rob Evers <revers@redhat.com>

Bugzilla
--------

Bug 619814 (https://bugzilla.redhat.com/show_bug.cgi?id=619814)

Upstream Status
---------------

Will be submitted upstream with our next patch submission.

Description
-----------

>From a4c213d2107345662b21b036bece950a05b3f5cd Mon Sep 17 00:00:00 2001
From: Saurav Kashyap <saurav.kashyap@qlogic.com>
Date: Wed, 11 Aug 2010 11:49:13 +0530
Subject: [PATCH] qla2xxx:rom lock recovery if fw hangs while holding the lock.


diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 4beb14b..1ab3b22 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -869,8 +869,12 @@ qla82xx_rom_lock(scsi_qla_host_t *ha)
 		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
 		if (done == 1)
 			break;
-		if (timeout >= qla82xx_rom_lock_timeout)
+		if (timeout >= qla82xx_rom_lock_timeout) {
+			qla_printk(KERN_WARNING, ha,
+				"%s(%ld) Failed to acquire rom lock\n",
+				__func__, ha->host_no);
 			return -1;
+		}
 		timeout++;
 
 		/*
@@ -974,6 +978,14 @@ qla82xx_rom_fast_read(scsi_qla_host_t *ha, int addr, int *valp)
 	return ret;
 }
 
+static void qla82xx_rom_lock_recovery(scsi_qla_host_t *ha)
+{
+	if (qla82xx_rom_lock(ha))
+		qla_printk(KERN_INFO, ha,
+			"%s() Resetting the rom lock\n", __func__);
+	qla82xx_rom_unlock(ha);
+}
+
 int
 qla82xx_read_status_reg(scsi_qla_host_t *ha, uint32_t *val)
 {
@@ -2360,11 +2372,13 @@ qla82xx_start_firmware(scsi_qla_host_t *ha)
 static int
 qla82xx_device_bootstrap(scsi_qla_host_t *ha)
 {
-	int rval, i, timeout;
+	int rval = QLA_SUCCESS;
+	int i, timeout;
 	uint32_t old_count, count;
+	int need_reset = 0, peg_stuck = 1;
+
+	need_reset = qla82xx_need_reset(ha);
 
-	if (qla82xx_need_reset(ha))
-		goto dev_initialize;
 
 	old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
 
@@ -2373,11 +2387,27 @@ qla82xx_device_bootstrap(scsi_qla_host_t *ha)
 		if (timeout) {
 			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
 			    QLA82XX_DEV_FAILED);
-			return QLA_FUNCTION_FAILED;
+			rval = QLA_FUNCTION_FAILED;
+			return rval;
 		}
 
 		count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
 		if (count != old_count)
+			peg_stuck = 0;
+	}
+
+	if (need_reset) {
+		/* Do rom lock recovery here */
+		if (peg_stuck)
+			qla82xx_rom_lock_recovery(ha);
+		goto dev_initialize;
+	} else {
+		if (peg_stuck) {
+			/* Either we are first or recovery is in progress */
+			qla82xx_rom_lock_recovery(ha);
+			goto dev_initialize;
+		} else
+			/* Firmware already running */
 			goto dev_ready;
 	}