diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 218 |
1 files changed, 59 insertions, 159 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b3dac26ddba3..98c01cd5e1a8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -65,7 +65,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
65 | ha->flags.reset_active = 0; | 65 | ha->flags.reset_active = 0; |
66 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 66 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); |
67 | atomic_set(&ha->loop_state, LOOP_DOWN); | 67 | atomic_set(&ha->loop_state, LOOP_DOWN); |
68 | ha->device_flags = 0; | 68 | ha->device_flags = DFLG_NO_CABLE; |
69 | ha->dpc_flags = 0; | 69 | ha->dpc_flags = 0; |
70 | ha->flags.management_server_logged_in = 0; | 70 | ha->flags.management_server_logged_in = 0; |
71 | ha->marker_needed = 0; | 71 | ha->marker_needed = 0; |
@@ -77,16 +77,23 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
77 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); | 77 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); |
78 | rval = ha->isp_ops.pci_config(ha); | 78 | rval = ha->isp_ops.pci_config(ha); |
79 | if (rval) { | 79 | if (rval) { |
80 | DEBUG2(printk("scsi(%ld): Unable to configure PCI space=n", | 80 | DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n", |
81 | ha->host_no)); | 81 | ha->host_no)); |
82 | return (rval); | 82 | return (rval); |
83 | } | 83 | } |
84 | 84 | ||
85 | ha->isp_ops.reset_chip(ha); | 85 | ha->isp_ops.reset_chip(ha); |
86 | 86 | ||
87 | ha->isp_ops.get_flash_version(ha, ha->request_ring); | ||
88 | |||
87 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); | 89 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); |
88 | 90 | ||
89 | ha->isp_ops.nvram_config(ha); | 91 | rval = 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 | } | ||
90 | 97 | ||
91 | if (ha->flags.disable_serdes) { | 98 | if (ha->flags.disable_serdes) { |
92 | /* Mask HBA via NVRAM settings? */ | 99 | /* Mask HBA via NVRAM settings? */ |
@@ -293,6 +300,8 @@ qla24xx_pci_config(scsi_qla_host_t *ha) | |||
293 | d &= ~PCI_ROM_ADDRESS_ENABLE; | 300 | d &= ~PCI_ROM_ADDRESS_ENABLE; |
294 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | 301 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); |
295 | 302 | ||
303 | pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->chip_revision); | ||
304 | |||
296 | /* Get PCI bus information. */ | 305 | /* Get PCI bus information. */ |
297 | spin_lock_irqsave(&ha->hardware_lock, flags); | 306 | spin_lock_irqsave(&ha->hardware_lock, flags); |
298 | ha->pci_attr = RD_REG_DWORD(®->ctrl_status); | 307 | ha->pci_attr = RD_REG_DWORD(®->ctrl_status); |
@@ -1351,6 +1360,39 @@ qla2x00_configure_hba(scsi_qla_host_t *ha) | |||
1351 | return(rval); | 1360 | return(rval); |
1352 | } | 1361 | } |
1353 | 1362 | ||
1363 | static inline void | ||
1364 | qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *def) | ||
1365 | { | ||
1366 | char *st, *en; | ||
1367 | uint16_t index; | ||
1368 | |||
1369 | if (memcmp(model, BINZERO, len) != 0) { | ||
1370 | strncpy(ha->model_number, model, len); | ||
1371 | st = en = ha->model_number; | ||
1372 | en += len - 1; | ||
1373 | while (en > st) { | ||
1374 | if (*en != 0x20 && *en != 0x00) | ||
1375 | break; | ||
1376 | *en-- = '\0'; | ||
1377 | } | ||
1378 | |||
1379 | index = (ha->pdev->subsystem_device & 0xff); | ||
1380 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | ||
1381 | index < QLA_MODEL_NAMES) | ||
1382 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | ||
1383 | } else { | ||
1384 | index = (ha->pdev->subsystem_device & 0xff); | ||
1385 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | ||
1386 | index < QLA_MODEL_NAMES) { | ||
1387 | strcpy(ha->model_number, | ||
1388 | qla2x00_model_name[index * 2]); | ||
1389 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | ||
1390 | } else { | ||
1391 | strcpy(ha->model_number, def); | ||
1392 | } | ||
1393 | } | ||
1394 | } | ||
1395 | |||
1354 | /* | 1396 | /* |
1355 | * NVRAM configuration for ISP 2xxx | 1397 | * NVRAM configuration for ISP 2xxx |
1356 | * | 1398 | * |
@@ -1367,7 +1409,6 @@ qla2x00_configure_hba(scsi_qla_host_t *ha) | |||
1367 | int | 1409 | int |
1368 | qla2x00_nvram_config(scsi_qla_host_t *ha) | 1410 | qla2x00_nvram_config(scsi_qla_host_t *ha) |
1369 | { | 1411 | { |
1370 | int rval; | ||
1371 | uint8_t chksum = 0; | 1412 | uint8_t chksum = 0; |
1372 | uint16_t cnt; | 1413 | uint16_t cnt; |
1373 | uint8_t *dptr1, *dptr2; | 1414 | uint8_t *dptr1, *dptr2; |
@@ -1376,8 +1417,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1376 | uint8_t *ptr = (uint8_t *)ha->request_ring; | 1417 | uint8_t *ptr = (uint8_t *)ha->request_ring; |
1377 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1418 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
1378 | 1419 | ||
1379 | rval = QLA_SUCCESS; | ||
1380 | |||
1381 | /* Determine NVRAM starting address. */ | 1420 | /* Determine NVRAM starting address. */ |
1382 | ha->nvram_size = sizeof(nvram_t); | 1421 | ha->nvram_size = sizeof(nvram_t); |
1383 | ha->nvram_base = 0; | 1422 | ha->nvram_base = 0; |
@@ -1401,55 +1440,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1401 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " | 1440 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " |
1402 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], | 1441 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], |
1403 | nv->nvram_version); | 1442 | nv->nvram_version); |
1404 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 1443 | return QLA_FUNCTION_FAILED; |
1405 | "invalid -- WWPN) defaults.\n"); | ||
1406 | |||
1407 | /* | ||
1408 | * Set default initialization control block. | ||
1409 | */ | ||
1410 | memset(nv, 0, ha->nvram_size); | ||
1411 | nv->parameter_block_version = ICB_VERSION; | ||
1412 | |||
1413 | if (IS_QLA23XX(ha)) { | ||
1414 | nv->firmware_options[0] = BIT_2 | BIT_1; | ||
1415 | nv->firmware_options[1] = BIT_7 | BIT_5; | ||
1416 | nv->add_firmware_options[0] = BIT_5; | ||
1417 | nv->add_firmware_options[1] = BIT_5 | BIT_4; | ||
1418 | nv->frame_payload_size = __constant_cpu_to_le16(2048); | ||
1419 | nv->special_options[1] = BIT_7; | ||
1420 | } else if (IS_QLA2200(ha)) { | ||
1421 | nv->firmware_options[0] = BIT_2 | BIT_1; | ||
1422 | nv->firmware_options[1] = BIT_7 | BIT_5; | ||
1423 | nv->add_firmware_options[0] = BIT_5; | ||
1424 | nv->add_firmware_options[1] = BIT_5 | BIT_4; | ||
1425 | nv->frame_payload_size = __constant_cpu_to_le16(1024); | ||
1426 | } else if (IS_QLA2100(ha)) { | ||
1427 | nv->firmware_options[0] = BIT_3 | BIT_1; | ||
1428 | nv->firmware_options[1] = BIT_5; | ||
1429 | nv->frame_payload_size = __constant_cpu_to_le16(1024); | ||
1430 | } | ||
1431 | |||
1432 | nv->max_iocb_allocation = __constant_cpu_to_le16(256); | ||
1433 | nv->execution_throttle = __constant_cpu_to_le16(16); | ||
1434 | nv->retry_count = 8; | ||
1435 | nv->retry_delay = 1; | ||
1436 | |||
1437 | nv->port_name[0] = 33; | ||
1438 | nv->port_name[3] = 224; | ||
1439 | nv->port_name[4] = 139; | ||
1440 | |||
1441 | nv->login_timeout = 4; | ||
1442 | |||
1443 | /* | ||
1444 | * Set default host adapter parameters | ||
1445 | */ | ||
1446 | nv->host_p[1] = BIT_2; | ||
1447 | nv->reset_delay = 5; | ||
1448 | nv->port_down_retry_count = 8; | ||
1449 | nv->max_luns_per_target = __constant_cpu_to_le16(8); | ||
1450 | nv->link_down_timeout = 60; | ||
1451 | |||
1452 | rval = 1; | ||
1453 | } | 1444 | } |
1454 | 1445 | ||
1455 | #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) | 1446 | #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) |
@@ -1489,33 +1480,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1489 | strcpy(ha->model_number, "QLA2300"); | 1480 | strcpy(ha->model_number, "QLA2300"); |
1490 | } | 1481 | } |
1491 | } else { | 1482 | } else { |
1492 | if (rval == 0 && | 1483 | qla2x00_set_model_info(ha, nv->model_number, |
1493 | memcmp(nv->model_number, BINZERO, | 1484 | sizeof(nv->model_number), "QLA23xx"); |
1494 | sizeof(nv->model_number)) != 0) { | ||
1495 | char *st, *en; | ||
1496 | |||
1497 | strncpy(ha->model_number, nv->model_number, | ||
1498 | sizeof(nv->model_number)); | ||
1499 | st = en = ha->model_number; | ||
1500 | en += sizeof(nv->model_number) - 1; | ||
1501 | while (en > st) { | ||
1502 | if (*en != 0x20 && *en != 0x00) | ||
1503 | break; | ||
1504 | *en-- = '\0'; | ||
1505 | } | ||
1506 | } else { | ||
1507 | uint16_t index; | ||
1508 | |||
1509 | index = (ha->pdev->subsystem_device & 0xff); | ||
1510 | if (index < QLA_MODEL_NAMES) { | ||
1511 | strcpy(ha->model_number, | ||
1512 | qla2x00_model_name[index * 2]); | ||
1513 | ha->model_desc = | ||
1514 | qla2x00_model_name[index * 2 + 1]; | ||
1515 | } else { | ||
1516 | strcpy(ha->model_number, "QLA23xx"); | ||
1517 | } | ||
1518 | } | ||
1519 | } | 1485 | } |
1520 | } else if (IS_QLA2200(ha)) { | 1486 | } else if (IS_QLA2200(ha)) { |
1521 | nv->firmware_options[0] |= BIT_2; | 1487 | nv->firmware_options[0] |= BIT_2; |
@@ -1687,11 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1687 | } | 1653 | } |
1688 | } | 1654 | } |
1689 | 1655 | ||
1690 | if (rval) { | 1656 | return QLA_SUCCESS; |
1691 | DEBUG2_3(printk(KERN_WARNING | ||
1692 | "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); | ||
1693 | } | ||
1694 | return (rval); | ||
1695 | } | 1657 | } |
1696 | 1658 | ||
1697 | static void | 1659 | static void |
@@ -3107,7 +3069,11 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3107 | } | 3069 | } |
3108 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3070 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
3109 | 3071 | ||
3110 | ha->isp_ops.nvram_config(ha); | 3072 | ha->isp_ops.get_flash_version(ha, ha->request_ring); |
3073 | |||
3074 | rval = ha->isp_ops.nvram_config(ha); | ||
3075 | if (rval) | ||
3076 | goto isp_abort_retry; | ||
3111 | 3077 | ||
3112 | if (!qla2x00_restart_isp(ha)) { | 3078 | if (!qla2x00_restart_isp(ha)) { |
3113 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3079 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
@@ -3137,6 +3103,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3137 | } | 3103 | } |
3138 | } | 3104 | } |
3139 | } else { /* failed the ISP abort */ | 3105 | } else { /* failed the ISP abort */ |
3106 | isp_abort_retry: | ||
3140 | ha->flags.online = 1; | 3107 | ha->flags.online = 1; |
3141 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { | 3108 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { |
3142 | if (ha->isp_abort_cnt == 0) { | 3109 | if (ha->isp_abort_cnt == 0) { |
@@ -3326,7 +3293,6 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha) | |||
3326 | int | 3293 | int |
3327 | qla24xx_nvram_config(scsi_qla_host_t *ha) | 3294 | qla24xx_nvram_config(scsi_qla_host_t *ha) |
3328 | { | 3295 | { |
3329 | int rval; | ||
3330 | struct init_cb_24xx *icb; | 3296 | struct init_cb_24xx *icb; |
3331 | struct nvram_24xx *nv; | 3297 | struct nvram_24xx *nv; |
3332 | uint32_t *dptr; | 3298 | uint32_t *dptr; |
@@ -3334,7 +3300,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3334 | uint32_t chksum; | 3300 | uint32_t chksum; |
3335 | uint16_t cnt; | 3301 | uint16_t cnt; |
3336 | 3302 | ||
3337 | rval = QLA_SUCCESS; | ||
3338 | icb = (struct init_cb_24xx *)ha->init_cb; | 3303 | icb = (struct init_cb_24xx *)ha->init_cb; |
3339 | nv = (struct nvram_24xx *)ha->request_ring; | 3304 | nv = (struct nvram_24xx *)ha->request_ring; |
3340 | 3305 | ||
@@ -3367,51 +3332,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3367 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " | 3332 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " |
3368 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], | 3333 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], |
3369 | le16_to_cpu(nv->nvram_version)); | 3334 | le16_to_cpu(nv->nvram_version)); |
3370 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 3335 | return QLA_FUNCTION_FAILED; |
3371 | "invalid -- WWPN) defaults.\n"); | ||
3372 | |||
3373 | /* | ||
3374 | * Set default initialization control block. | ||
3375 | */ | ||
3376 | memset(nv, 0, ha->nvram_size); | ||
3377 | nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION); | ||
3378 | nv->version = __constant_cpu_to_le16(ICB_VERSION); | ||
3379 | nv->frame_payload_size = __constant_cpu_to_le16(2048); | ||
3380 | nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); | ||
3381 | nv->exchange_count = __constant_cpu_to_le16(0); | ||
3382 | nv->hard_address = __constant_cpu_to_le16(124); | ||
3383 | nv->port_name[0] = 0x21; | ||
3384 | nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn); | ||
3385 | nv->port_name[2] = 0x00; | ||
3386 | nv->port_name[3] = 0xe0; | ||
3387 | nv->port_name[4] = 0x8b; | ||
3388 | nv->port_name[5] = 0x1c; | ||
3389 | nv->port_name[6] = 0x55; | ||
3390 | nv->port_name[7] = 0x86; | ||
3391 | nv->node_name[0] = 0x20; | ||
3392 | nv->node_name[1] = 0x00; | ||
3393 | nv->node_name[2] = 0x00; | ||
3394 | nv->node_name[3] = 0xe0; | ||
3395 | nv->node_name[4] = 0x8b; | ||
3396 | nv->node_name[5] = 0x1c; | ||
3397 | nv->node_name[6] = 0x55; | ||
3398 | nv->node_name[7] = 0x86; | ||
3399 | nv->login_retry_count = __constant_cpu_to_le16(8); | ||
3400 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); | ||
3401 | nv->login_timeout = __constant_cpu_to_le16(0); | ||
3402 | nv->firmware_options_1 = | ||
3403 | __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1); | ||
3404 | nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4); | ||
3405 | nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12); | ||
3406 | nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13); | ||
3407 | nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10); | ||
3408 | nv->efi_parameters = __constant_cpu_to_le32(0); | ||
3409 | nv->reset_delay = 5; | ||
3410 | nv->max_luns_per_target = __constant_cpu_to_le16(128); | ||
3411 | nv->port_down_retry_count = __constant_cpu_to_le16(30); | ||
3412 | nv->link_down_timeout = __constant_cpu_to_le16(30); | ||
3413 | |||
3414 | rval = 1; | ||
3415 | } | 3336 | } |
3416 | 3337 | ||
3417 | /* Reset Initialization control block */ | 3338 | /* Reset Initialization control block */ |
@@ -3438,25 +3359,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3438 | /* | 3359 | /* |
3439 | * Setup driver NVRAM options. | 3360 | * Setup driver NVRAM options. |
3440 | */ | 3361 | */ |
3441 | if (memcmp(nv->model_name, BINZERO, sizeof(nv->model_name)) != 0) { | 3362 | qla2x00_set_model_info(ha, nv->model_name, sizeof(nv->model_name), |
3442 | char *st, *en; | 3363 | "QLA2462"); |
3443 | uint16_t index; | ||
3444 | |||
3445 | strncpy(ha->model_number, nv->model_name, | ||
3446 | sizeof(nv->model_name)); | ||
3447 | st = en = ha->model_number; | ||
3448 | en += sizeof(nv->model_name) - 1; | ||
3449 | while (en > st) { | ||
3450 | if (*en != 0x20 && *en != 0x00) | ||
3451 | break; | ||
3452 | *en-- = '\0'; | ||
3453 | } | ||
3454 | |||
3455 | index = (ha->pdev->subsystem_device & 0xff); | ||
3456 | if (index < QLA_MODEL_NAMES) | ||
3457 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | ||
3458 | } else | ||
3459 | strcpy(ha->model_number, "QLA2462"); | ||
3460 | 3364 | ||
3461 | /* Use alternate WWN? */ | 3365 | /* Use alternate WWN? */ |
3462 | if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { | 3366 | if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { |
@@ -3575,11 +3479,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3575 | ha->flags.process_response_queue = 1; | 3479 | ha->flags.process_response_queue = 1; |
3576 | } | 3480 | } |
3577 | 3481 | ||
3578 | if (rval) { | 3482 | return QLA_SUCCESS; |
3579 | DEBUG2_3(printk(KERN_WARNING | ||
3580 | "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); | ||
3581 | } | ||
3582 | return (rval); | ||
3583 | } | 3483 | } |
3584 | 3484 | ||
3585 | static int | 3485 | static int |