RE: Major qla2xxx regression on sparc64

From: Seokmann Ju
Date: Tue Apr 17 2007 - 14:41:53 EST


Hello David,
On Mon 4/16/2007 10:02 PM, David Miller wrote:
> > I'm in transit for a redeye to NY so I won't be able to modify the
> > patch, If you would be amenable to the above, Seokmann, could you
> > rework the patch?
>
> Thanks guys.
Here, I've attached updated patch. Please take this.
Sorry for late.

Thank you,

Seokmann
---
diff -Naur linux-2.6.git/drivers/scsi/qla2xxx/qla_gbl.h
linux-2.6.git-nvram/drivers/scsi/qla2xxx/qla_gbl.h
--- linux-2.6.git/drivers/scsi/qla2xxx/qla_gbl.h 2007-04-17
11:06:39.000000000 -0700
+++ linux-2.6.git-nvram/drivers/scsi/qla2xxx/qla_gbl.h 2007-04-17
11:07:24.000000000 -0700
@@ -62,6 +62,7 @@
extern int ql2xallocfwdump;
extern int ql2xextended_error_logging;
extern int ql2xqfullrampup;
+extern int ql2xoverrideinvalidnvram;

extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);

diff -Naur linux-2.6.git/drivers/scsi/qla2xxx/qla_init.c
linux-2.6.git-nvram/drivers/scsi/qla2xxx/qla_init.c
--- linux-2.6.git/drivers/scsi/qla2xxx/qla_init.c 2007-04-17
11:06:39.000000000 -0700
+++ linux-2.6.git-nvram/drivers/scsi/qla2xxx/qla_init.c 2007-04-17
11:07:24.000000000 -0700
@@ -11,6 +11,11 @@

#include "qla_devtbl.h"

+#ifdef CONFIG_SPARC
+#include <asm/prom.h>
+#include <asm/pbm.h>
+#endif
+
/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */
#ifndef EXT_IS_LUN_BIT_SET
#define EXT_IS_LUN_BIT_SET(P,L) \
@@ -1393,6 +1398,42 @@
}
}

+/* On sparc systems, obtain port and node WWN from firmware
+ * properties.
+ */
+static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, nvram_t
*nv)
+{
+#ifdef CONFIG_SPARC
+ struct pci_dev *pdev = ha->pdev;
+ struct pcidev_cookie *pcp = pdev->sysdata;
+ struct device_node *dp = pcp->prom_node;
+ u8 *val;
+ int len;
+
+ val = of_get_property(dp, "port-wwn", &len);
+ if (val && len >= WWN_SIZE)
+ memcpy(nv->port_name, val, WWN_SIZE);
+
+ val = of_get_property(dp, "node-wwn", &len);
+ if (val && len >= WWN_SIZE)
+ memcpy(nv->node_name, val, WWN_SIZE);
+#endif
+}
+
+static inline int
+qla2x00_override_invalid_nvram(scsi_qla_host_t *ha)
+{
+ if (!ql2xoverrideinvalidnvram) {
+ qla_printk(KERN_WARNING, ha,
+ "Reload the driver with the ql2xoverrideinvalidnvram
\n");
+ qla_printk(KERN_WARNING, ha,
+ " module parameter set to a non-zero value to ignore
\n");
+ qla_printk(KERN_WARNING, ha,
+ " this warning.\n");
+ }
+ return ql2xoverrideinvalidnvram;
+}
+
/*
* NVRAM configuration for ISP 2xxx
*
@@ -1440,7 +1481,58 @@
qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM
detected: "
"checksum=0x%x id=%c version=0x%x.\n", chksum,
nv->id[0],
nv->nvram_version);
- return QLA_FUNCTION_FAILED;
+ if (!qla2x00_override_invalid_nvram(ha))
+ return QLA_FUNCTION_FAILED;
+ qla_printk(KERN_WARNING, ha, "FC IDs may conflict and
cause "
+ "miscommunication - please report this to QLogic "
+ "(linux-driver@xxxxxxxxxx).\n");
+
+ /*
+ * Set default initialization control block.
+ */
+ memset(nv, 0, ha->nvram_size);
+ nv->parameter_block_version = ICB_VERSION;
+
+ if (IS_QLA23XX(ha)) {
+ nv->firmware_options[0] = BIT_2 | BIT_1;
+ nv->firmware_options[1] = BIT_7 | BIT_5;
+ nv->add_firmware_options[0] = BIT_5;
+ nv->add_firmware_options[1] = BIT_5 | BIT_4;
+ nv->frame_payload_size =
__constant_cpu_to_le16(2048);
+ nv->special_options[1] = BIT_7;
+ } else if (IS_QLA2200(ha)) {
+ nv->firmware_options[0] = BIT_2 | BIT_1;
+ nv->firmware_options[1] = BIT_7 | BIT_5;
+ nv->add_firmware_options[0] = BIT_5;
+ nv->add_firmware_options[1] = BIT_5 | BIT_4;
+ nv->frame_payload_size =
__constant_cpu_to_le16(1024);
+ } else if (IS_QLA2100(ha)) {
+ nv->firmware_options[0] = BIT_3 | BIT_1;
+ nv->firmware_options[1] = BIT_5;
+ nv->frame_payload_size =
__constant_cpu_to_le16(1024);
+ }
+
+ nv->max_iocb_allocation = __constant_cpu_to_le16(256);
+ nv->execution_throttle = __constant_cpu_to_le16(16);
+ nv->retry_count = 8;
+ nv->retry_delay = 1;
+
+ nv->port_name[0] = 33;
+ nv->port_name[3] = 224;
+ nv->port_name[4] = 139;
+
+ qla2xxx_nvram_wwn_from_ofw(ha, nv);
+
+ nv->login_timeout = 4;
+
+ /*
+ * Set default host adapter parameters
+ */
+ nv->host_p[1] = BIT_2;
+ nv->reset_delay = 5;
+ nv->port_down_retry_count = 8;
+ nv->max_luns_per_target = __constant_cpu_to_le16(8);
+ nv->link_down_timeout = 60;
}

#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
@@ -3290,6 +3382,28 @@
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

+/* On sparc systems, obtain port and node WWN from firmware
+ * properties.
+ */
+static void qla24xx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, struct
nvram_24xx *nv)
+{
+#ifdef CONFIG_SPARC
+ struct pci_dev *pdev = ha->pdev;
+ struct pcidev_cookie *pcp = pdev->sysdata;
+ struct device_node *dp = pcp->prom_node;
+ u8 *val;
+ int len;
+
+ val = of_get_property(dp, "port-wwn", &len);
+ if (val && len >= WWN_SIZE)
+ memcpy(nv->port_name, val, WWN_SIZE);
+
+ val = of_get_property(dp, "node-wwn", &len);
+ if (val && len >= WWN_SIZE)
+ memcpy(nv->node_name, val, WWN_SIZE);
+#endif
+}
+
int
qla24xx_nvram_config(scsi_qla_host_t *ha)
{
@@ -3332,7 +3446,53 @@
qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM
detected: "
"checksum=0x%x id=%c version=0x%x.\n", chksum,
nv->id[0],
le16_to_cpu(nv->nvram_version));
- return QLA_FUNCTION_FAILED;
+ if (!qla2x00_override_invalid_nvram(ha))
+ return QLA_FUNCTION_FAILED;
+ qla_printk(KERN_WARNING, ha, "FC IDs may conflict and
cause "
+ "miscommunication - please report this to QLogic "
+ "(linux-driver@xxxxxxxxxx).\n");
+
+ /*
+ * Set default initialization control block.
+ */
+ memset(nv, 0, ha->nvram_size);
+ nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION);
+ nv->version = __constant_cpu_to_le16(ICB_VERSION);
+ nv->frame_payload_size = __constant_cpu_to_le16(2048);
+ nv->execution_throttle = __constant_cpu_to_le16(0xFFFF);
+ nv->exchange_count = __constant_cpu_to_le16(0);
+ nv->hard_address = __constant_cpu_to_le16(124);
+ nv->port_name[0] = 0x21;
+ nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
+ nv->port_name[2] = 0x00;
+ nv->port_name[3] = 0xe0;
+ nv->port_name[4] = 0x8b;
+ nv->port_name[5] = 0x1c;
+ nv->port_name[6] = 0x55;
+ nv->port_name[7] = 0x86;
+ nv->node_name[0] = 0x20;
+ nv->node_name[1] = 0x00;
+ nv->node_name[2] = 0x00;
+ nv->node_name[3] = 0xe0;
+ nv->node_name[4] = 0x8b;
+ nv->node_name[5] = 0x1c;
+ nv->node_name[6] = 0x55;
+ nv->node_name[7] = 0x86;
+ qla24xx_nvram_wwn_from_ofw(ha, nv);
+ nv->login_retry_count = __constant_cpu_to_le16(8);
+ nv->interrupt_delay_timer = __constant_cpu_to_le16(0);
+ nv->login_timeout = __constant_cpu_to_le16(0);
+ nv->firmware_options_1 =
+ __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
+ nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4);
+ nv->firmware_options_2 |=
__constant_cpu_to_le32(BIT_12);
+ nv->firmware_options_3 = __constant_cpu_to_le32(2 <<
13);
+ nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10);
+ nv->efi_parameters = __constant_cpu_to_le32(0);
+ nv->reset_delay = 5;
+ nv->max_luns_per_target = __constant_cpu_to_le16(128);
+ nv->port_down_retry_count = __constant_cpu_to_le16(30);
+ nv->link_down_timeout = __constant_cpu_to_le16(30);
}

/* Reset Initialization control block */
diff -Naur linux-2.6.git/drivers/scsi/qla2xxx/qla_os.c
linux-2.6.git-nvram/drivers/scsi/qla2xxx/qla_os.c
--- linux-2.6.git/drivers/scsi/qla2xxx/qla_os.c 2007-04-17
11:06:39.000000000 -0700
+++ linux-2.6.git-nvram/drivers/scsi/qla2xxx/qla_os.c 2007-04-17
11:07:24.000000000 -0700
@@ -90,6 +90,13 @@
"depth for a device after a queue-full condition has
been "
"detected. Default is 120 seconds.");

+int ql2xoverrideinvalidnvram;
+module_param(ql2xoverrideinvalidnvram, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xoverrideinvalidnvram,
+ "When set and upon detecting an invalid or non-present "
+ "NVRAM state, use doctored settings (potentially
invalid) "
+ "to initialize the HBA.");
+
/*
* SCSI host template entry points
*/
@@ -1575,9 +1582,7 @@
goto probe_failed;
}

- if (qla2x00_initialize_adapter(ha) &&
- !(ha->device_flags & DFLG_NO_CABLE)) {
-
+ if (qla2x00_initialize_adapter(ha)) {
qla_printk(KERN_WARNING, ha,
"Failed to initialize adapter\n");

@@ -1733,7 +1738,8 @@
ha->flags.online = 0;

/* Stop currently executing firmware. */
- qla2x00_try_to_stop_firmware(ha);
+ if (ha->fw_major_version)
+ qla2x00_try_to_stop_firmware(ha);

/* turn-off interrupts on the card */
if (ha->interrupts_on)
---

Attachment: nvram_override.patch
Description: nvram_override.patch