Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3554

kernel-2.6.18-194.11.1.el5.src.rpm

From: Marcus Barrow <mbarrow@redhat.com>
Date: Tue, 1 Dec 2009 16:09:43 -0500
Subject: [scsi] qla2xxx: CT passthrough and link data rate fixes
Message-id: <20091201160943.9308.77644.sendpatchset@file.bos.redhat.com>
Patchwork-id: 21568
O-Subject: [rhel 5.5 patch] qla2xxx - 3rd batch, testing updates
Bugzilla: 543057
RH-Acked-by: Tomas Henzl <thenzl@redhat.com>

BZ 543057

qla2xxx - rhel 5.5 updates, 3rd batch.

These patches fix the problems described below. They apply and build cleanly on 2.6.18-175 on top of the earlier patches.

Tested at QLogic.

 - Correct CT pass through timeout value.

    In qla2x00_wait_for_passthru_completion the timeout of 10
    seconds is shorter than the 25 seconds or 2*ra_tov in the iocb,
    causing premature [non-graceful] recovery.

 - Recover gracefully on CT pass through timeout.

    In the event the timeout occurs, the firmware dump /
    restart clears the firmware resources for the CT request, however
    the "ha->pass_thru_cmd_in_process"  flag remains set, preventing
    subsequent CT pass through requests via sysfs.

 - Get the link data rate explicitly during device resync.

    When the hba port gets logged out of the fabric, or other
    such transitional state when the physical link is still present,
    the driver doesn't receive a loop up asyn event (where the link
    data rate currently gets set). Hence send a explicit mailbox command
    to get the link rate in such conditions


diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 0234348..a176cf0 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -586,10 +586,15 @@ qla2x00_wait_for_passthru_completion(struct scsi_qla_host *ha)
 	if (unlikely(pci_channel_offline(ha->pdev)))
 		return;
 
-	if (!wait_for_completion_timeout(&ha->pass_thru_intr_comp, 10 * HZ)) {
+	if (!wait_for_completion_timeout(&ha->pass_thru_intr_comp,
+	    (ha->r_a_tov / 10 * 2) + 5) * HZ) {
 		DEBUG2(qla_printk(KERN_WARNING, ha,
 		    "Passthru request timed out.\n"));
 		ha->isp_ops->fw_dump(ha, 0);
+		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+		qla2xxx_wake_dpc(ha);
+		ha->pass_thru_cmd_result = 0;
+		ha->pass_thru_cmd_in_process = 0;
 	}
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index b3df11e..e484f26 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -301,6 +301,9 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *);
 extern int
 qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t);
 
+extern int
+qla2x00_get_data_rate(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 7b61a89..87a1b11 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1991,6 +1991,8 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
 	clear_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
 	clear_bit(RSCN_UPDATE, &ha->dpc_flags);
 
+	qla2x00_get_data_rate(ha);
+
 	/* Determine what we need to do */
 	if (ha->current_topology == ISP_CFG_FL &&
 	    (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 929e6e4..819a1db 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3519,3 +3519,35 @@ qla2x00_write_ram_word(scsi_qla_host_t *ha, uint32_t risc_addr, uint32_t data)
 
 	return rval;
 }
+
+int
+qla2x00_get_data_rate(scsi_qla_host_t *ha)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (!IS_FWI2_CAPABLE(ha))
+		return QLA_FUNCTION_FAILED;
+
+	DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, ha->host_no));
+
+	mcp->mb[0] = MBC_DATA_RATE;
+	mcp->mb[1] = 0;
+	mcp->out_mb = MBX_1|MBX_0;
+	mcp->in_mb = MBX_2|MBX_1|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(ha, mcp);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n",
+		    __func__, ha->host_no, rval, mcp->mb[0]));
+	} else {
+		DEBUG11(printk(KERN_INFO
+		    "%s(%ld): done.\n", __func__, ha->host_no));
+		if (mcp->mb[1] != 0x7)
+			ha->link_data_rate = mcp->mb[1];
+	}
+
+	return rval;
+}