aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
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