RE: Major qla2xxx regression on sparc64

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 "
+                   "([email protected]).\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 "
+                   "([email protected]).\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


[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux