aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2007-04-16 15:37:43 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-04-30 10:58:52 -0400
commit4e08df3f91837656c36712f559d5ce8d80852760 (patch)
tree1293da261c3a2bd224992d62bcb0ff9a68074b2f /drivers/scsi/qla2xxx/qla_init.c
parentd7b8bcb0a0819315a51cae620ff7ae0c1704c069 (diff)
[SCSI] qla2xxx: fix regression on sparc64
Some sparc64 boxes don't have a valid NVRAM (from which the driver takes its WWPN) try to extract this from open firmware instead and if that fails, fall back to a default, which would be invalid if more than one machine on the same SAN does this, since two machines with the same WWPN would be illegal, so warn when taking this potentially invalid default. Tested on SunBlade-1000: Acked-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c177
1 files changed, 163 insertions, 14 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 98c01cd5e1a8..3e296ab845b6 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -11,6 +11,11 @@
11 11
12#include "qla_devtbl.h" 12#include "qla_devtbl.h"
13 13
14#ifdef CONFIG_SPARC
15#include <asm/prom.h>
16#include <asm/pbm.h>
17#endif
18
14/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ 19/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */
15#ifndef EXT_IS_LUN_BIT_SET 20#ifndef EXT_IS_LUN_BIT_SET
16#define EXT_IS_LUN_BIT_SET(P,L) \ 21#define EXT_IS_LUN_BIT_SET(P,L) \
@@ -88,12 +93,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
88 93
89 qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); 94 qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
90 95
91 rval = ha->isp_ops.nvram_config(ha); 96 ha->isp_ops.nvram_config(ha);
92 if (rval) {
93 DEBUG2(printk("scsi(%ld): Unable to verify NVRAM data.\n",
94 ha->host_no));
95 return rval;
96 }
97 97
98 if (ha->flags.disable_serdes) { 98 if (ha->flags.disable_serdes) {
99 /* Mask HBA via NVRAM settings? */ 99 /* Mask HBA via NVRAM settings? */
@@ -1393,6 +1393,28 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de
1393 } 1393 }
1394} 1394}
1395 1395
1396/* On sparc systems, obtain port and node WWN from firmware
1397 * properties.
1398 */
1399static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, nvram_t *nv)
1400{
1401#ifdef CONFIG_SPARC
1402 struct pci_dev *pdev = ha->pdev;
1403 struct pcidev_cookie *pcp = pdev->sysdata;
1404 struct device_node *dp = pcp->prom_node;
1405 u8 *val;
1406 int len;
1407
1408 val = of_get_property(dp, "port-wwn", &len);
1409 if (val && len >= WWN_SIZE)
1410 memcpy(nv->port_name, val, WWN_SIZE);
1411
1412 val = of_get_property(dp, "node-wwn", &len);
1413 if (val && len >= WWN_SIZE)
1414 memcpy(nv->node_name, val, WWN_SIZE);
1415#endif
1416}
1417
1396/* 1418/*
1397* NVRAM configuration for ISP 2xxx 1419* NVRAM configuration for ISP 2xxx
1398* 1420*
@@ -1409,6 +1431,7 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de
1409int 1431int
1410qla2x00_nvram_config(scsi_qla_host_t *ha) 1432qla2x00_nvram_config(scsi_qla_host_t *ha)
1411{ 1433{
1434 int rval;
1412 uint8_t chksum = 0; 1435 uint8_t chksum = 0;
1413 uint16_t cnt; 1436 uint16_t cnt;
1414 uint8_t *dptr1, *dptr2; 1437 uint8_t *dptr1, *dptr2;
@@ -1417,6 +1440,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1417 uint8_t *ptr = (uint8_t *)ha->request_ring; 1440 uint8_t *ptr = (uint8_t *)ha->request_ring;
1418 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 1441 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1419 1442
1443 rval = QLA_SUCCESS;
1444
1420 /* Determine NVRAM starting address. */ 1445 /* Determine NVRAM starting address. */
1421 ha->nvram_size = sizeof(nvram_t); 1446 ha->nvram_size = sizeof(nvram_t);
1422 ha->nvram_base = 0; 1447 ha->nvram_base = 0;
@@ -1440,7 +1465,57 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1440 qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " 1465 qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
1441 "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], 1466 "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
1442 nv->nvram_version); 1467 nv->nvram_version);
1443 return QLA_FUNCTION_FAILED; 1468 qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
1469 "invalid -- WWPN) defaults.\n");
1470
1471 /*
1472 * Set default initialization control block.
1473 */
1474 memset(nv, 0, ha->nvram_size);
1475 nv->parameter_block_version = ICB_VERSION;
1476
1477 if (IS_QLA23XX(ha)) {
1478 nv->firmware_options[0] = BIT_2 | BIT_1;
1479 nv->firmware_options[1] = BIT_7 | BIT_5;
1480 nv->add_firmware_options[0] = BIT_5;
1481 nv->add_firmware_options[1] = BIT_5 | BIT_4;
1482 nv->frame_payload_size = __constant_cpu_to_le16(2048);
1483 nv->special_options[1] = BIT_7;
1484 } else if (IS_QLA2200(ha)) {
1485 nv->firmware_options[0] = BIT_2 | BIT_1;
1486 nv->firmware_options[1] = BIT_7 | BIT_5;
1487 nv->add_firmware_options[0] = BIT_5;
1488 nv->add_firmware_options[1] = BIT_5 | BIT_4;
1489 nv->frame_payload_size = __constant_cpu_to_le16(1024);
1490 } else if (IS_QLA2100(ha)) {
1491 nv->firmware_options[0] = BIT_3 | BIT_1;
1492 nv->firmware_options[1] = BIT_5;
1493 nv->frame_payload_size = __constant_cpu_to_le16(1024);
1494 }
1495
1496 nv->max_iocb_allocation = __constant_cpu_to_le16(256);
1497 nv->execution_throttle = __constant_cpu_to_le16(16);
1498 nv->retry_count = 8;
1499 nv->retry_delay = 1;
1500
1501 nv->port_name[0] = 33;
1502 nv->port_name[3] = 224;
1503 nv->port_name[4] = 139;
1504
1505 qla2xxx_nvram_wwn_from_ofw(ha, nv);
1506
1507 nv->login_timeout = 4;
1508
1509 /*
1510 * Set default host adapter parameters
1511 */
1512 nv->host_p[1] = BIT_2;
1513 nv->reset_delay = 5;
1514 nv->port_down_retry_count = 8;
1515 nv->max_luns_per_target = __constant_cpu_to_le16(8);
1516 nv->link_down_timeout = 60;
1517
1518 rval = 1;
1444 } 1519 }
1445 1520
1446#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) 1521#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
@@ -1653,7 +1728,11 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1653 } 1728 }
1654 } 1729 }
1655 1730
1656 return QLA_SUCCESS; 1731 if (rval) {
1732 DEBUG2_3(printk(KERN_WARNING
1733 "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
1734 }
1735 return (rval);
1657} 1736}
1658 1737
1659static void 1738static void
@@ -3071,9 +3150,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
3071 3150
3072 ha->isp_ops.get_flash_version(ha, ha->request_ring); 3151 ha->isp_ops.get_flash_version(ha, ha->request_ring);
3073 3152
3074 rval = ha->isp_ops.nvram_config(ha); 3153 ha->isp_ops.nvram_config(ha);
3075 if (rval)
3076 goto isp_abort_retry;
3077 3154
3078 if (!qla2x00_restart_isp(ha)) { 3155 if (!qla2x00_restart_isp(ha)) {
3079 clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); 3156 clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
@@ -3103,7 +3180,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
3103 } 3180 }
3104 } 3181 }
3105 } else { /* failed the ISP abort */ 3182 } else { /* failed the ISP abort */
3106isp_abort_retry:
3107 ha->flags.online = 1; 3183 ha->flags.online = 1;
3108 if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { 3184 if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) {
3109 if (ha->isp_abort_cnt == 0) { 3185 if (ha->isp_abort_cnt == 0) {
@@ -3290,9 +3366,32 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha)
3290 spin_unlock_irqrestore(&ha->hardware_lock, flags); 3366 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3291} 3367}
3292 3368
3369/* On sparc systems, obtain port and node WWN from firmware
3370 * properties.
3371 */
3372static void qla24xx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, struct nvram_24xx *nv)
3373{
3374#ifdef CONFIG_SPARC
3375 struct pci_dev *pdev = ha->pdev;
3376 struct pcidev_cookie *pcp = pdev->sysdata;
3377 struct device_node *dp = pcp->prom_node;
3378 u8 *val;
3379 int len;
3380
3381 val = of_get_property(dp, "port-wwn", &len);
3382 if (val && len >= WWN_SIZE)
3383 memcpy(nv->port_name, val, WWN_SIZE);
3384
3385 val = of_get_property(dp, "node-wwn", &len);
3386 if (val && len >= WWN_SIZE)
3387 memcpy(nv->node_name, val, WWN_SIZE);
3388#endif
3389}
3390
3293int 3391int
3294qla24xx_nvram_config(scsi_qla_host_t *ha) 3392qla24xx_nvram_config(scsi_qla_host_t *ha)
3295{ 3393{
3394 int rval;
3296 struct init_cb_24xx *icb; 3395 struct init_cb_24xx *icb;
3297 struct nvram_24xx *nv; 3396 struct nvram_24xx *nv;
3298 uint32_t *dptr; 3397 uint32_t *dptr;
@@ -3300,6 +3399,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
3300 uint32_t chksum; 3399 uint32_t chksum;
3301 uint16_t cnt; 3400 uint16_t cnt;
3302 3401
3402 rval = QLA_SUCCESS;
3303 icb = (struct init_cb_24xx *)ha->init_cb; 3403 icb = (struct init_cb_24xx *)ha->init_cb;
3304 nv = (struct nvram_24xx *)ha->request_ring; 3404 nv = (struct nvram_24xx *)ha->request_ring;
3305 3405
@@ -3332,7 +3432,52 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
3332 qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " 3432 qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
3333 "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], 3433 "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
3334 le16_to_cpu(nv->nvram_version)); 3434 le16_to_cpu(nv->nvram_version));
3335 return QLA_FUNCTION_FAILED; 3435 qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
3436 "invalid -- WWPN) defaults.\n");
3437
3438 /*
3439 * Set default initialization control block.
3440 */
3441 memset(nv, 0, ha->nvram_size);
3442 nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION);
3443 nv->version = __constant_cpu_to_le16(ICB_VERSION);
3444 nv->frame_payload_size = __constant_cpu_to_le16(2048);
3445 nv->execution_throttle = __constant_cpu_to_le16(0xFFFF);
3446 nv->exchange_count = __constant_cpu_to_le16(0);
3447 nv->hard_address = __constant_cpu_to_le16(124);
3448 nv->port_name[0] = 0x21;
3449 nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
3450 nv->port_name[2] = 0x00;
3451 nv->port_name[3] = 0xe0;
3452 nv->port_name[4] = 0x8b;
3453 nv->port_name[5] = 0x1c;
3454 nv->port_name[6] = 0x55;
3455 nv->port_name[7] = 0x86;
3456 nv->node_name[0] = 0x20;
3457 nv->node_name[1] = 0x00;
3458 nv->node_name[2] = 0x00;
3459 nv->node_name[3] = 0xe0;
3460 nv->node_name[4] = 0x8b;
3461 nv->node_name[5] = 0x1c;
3462 nv->node_name[6] = 0x55;
3463 nv->node_name[7] = 0x86;
3464 qla24xx_nvram_wwn_from_ofw(ha, nv);
3465 nv->login_retry_count = __constant_cpu_to_le16(8);
3466 nv->interrupt_delay_timer = __constant_cpu_to_le16(0);
3467 nv->login_timeout = __constant_cpu_to_le16(0);
3468 nv->firmware_options_1 =
3469 __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
3470 nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4);
3471 nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12);
3472 nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13);
3473 nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10);
3474 nv->efi_parameters = __constant_cpu_to_le32(0);
3475 nv->reset_delay = 5;
3476 nv->max_luns_per_target = __constant_cpu_to_le16(128);
3477 nv->port_down_retry_count = __constant_cpu_to_le16(30);
3478 nv->link_down_timeout = __constant_cpu_to_le16(30);
3479
3480 rval = 1;
3336 } 3481 }
3337 3482
3338 /* Reset Initialization control block */ 3483 /* Reset Initialization control block */
@@ -3479,7 +3624,11 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
3479 ha->flags.process_response_queue = 1; 3624 ha->flags.process_response_queue = 1;
3480 } 3625 }
3481 3626
3482 return QLA_SUCCESS; 3627 if (rval) {
3628 DEBUG2_3(printk(KERN_WARNING
3629 "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
3630 }
3631 return (rval);
3483} 3632}
3484 3633
3485static int 3634static int