diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 177 |
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 | */ | ||
1399 | static 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 | |||
1409 | int | 1431 | int |
1410 | qla2x00_nvram_config(scsi_qla_host_t *ha) | 1432 | qla2x00_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 | ||
1659 | static void | 1738 | static 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 */ |
3106 | isp_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 | */ | ||
3372 | static 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 | |||
3293 | int | 3391 | int |
3294 | qla24xx_nvram_config(scsi_qla_host_t *ha) | 3392 | qla24xx_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 | ||
3485 | static int | 3634 | static int |