diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 206 |
1 files changed, 152 insertions, 54 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index bd7dd84c0648..262026129325 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -634,7 +634,7 @@ qla2x00_chip_diag(scsi_qla_host_t *vha) | |||
634 | goto chip_diag_failed; | 634 | goto chip_diag_failed; |
635 | 635 | ||
636 | DEBUG3(printk("scsi(%ld): Reset register cleared by chip reset\n", | 636 | DEBUG3(printk("scsi(%ld): Reset register cleared by chip reset\n", |
637 | ha->host_no)); | 637 | vha->host_no)); |
638 | 638 | ||
639 | /* Reset RISC processor. */ | 639 | /* Reset RISC processor. */ |
640 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); | 640 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
@@ -655,7 +655,7 @@ qla2x00_chip_diag(scsi_qla_host_t *vha) | |||
655 | goto chip_diag_failed; | 655 | goto chip_diag_failed; |
656 | 656 | ||
657 | /* Check product ID of chip */ | 657 | /* Check product ID of chip */ |
658 | DEBUG3(printk("scsi(%ld): Checking product ID of chip\n", ha->host_no)); | 658 | DEBUG3(printk("scsi(%ld): Checking product ID of chip\n", vha->host_no)); |
659 | 659 | ||
660 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); | 660 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); |
661 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); | 661 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); |
@@ -730,9 +730,6 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) | |||
730 | struct qla_hw_data *ha = vha->hw; | 730 | struct qla_hw_data *ha = vha->hw; |
731 | struct req_que *req = ha->req_q_map[0]; | 731 | struct req_que *req = ha->req_q_map[0]; |
732 | 732 | ||
733 | /* Perform RISC reset. */ | ||
734 | qla24xx_reset_risc(vha); | ||
735 | |||
736 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length; | 733 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length; |
737 | 734 | ||
738 | rval = qla2x00_mbx_reg_test(vha); | 735 | rval = qla2x00_mbx_reg_test(vha); |
@@ -786,7 +783,6 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
786 | sizeof(uint32_t); | 783 | sizeof(uint32_t); |
787 | if (ha->mqenable) | 784 | if (ha->mqenable) |
788 | mq_size = sizeof(struct qla2xxx_mq_chain); | 785 | mq_size = sizeof(struct qla2xxx_mq_chain); |
789 | |||
790 | /* Allocate memory for Fibre Channel Event Buffer. */ | 786 | /* Allocate memory for Fibre Channel Event Buffer. */ |
791 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)) | 787 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)) |
792 | goto try_eft; | 788 | goto try_eft; |
@@ -850,8 +846,7 @@ cont_alloc: | |||
850 | rsp_q_size = rsp->length * sizeof(response_t); | 846 | rsp_q_size = rsp->length * sizeof(response_t); |
851 | 847 | ||
852 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | 848 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
853 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | 849 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size; |
854 | eft_size; | ||
855 | ha->chain_offset = dump_size; | 850 | ha->chain_offset = dump_size; |
856 | dump_size += mq_size + fce_size; | 851 | dump_size += mq_size + fce_size; |
857 | 852 | ||
@@ -891,6 +886,56 @@ cont_alloc: | |||
891 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); | 886 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); |
892 | } | 887 | } |
893 | 888 | ||
889 | static int | ||
890 | qla81xx_mpi_sync(scsi_qla_host_t *vha) | ||
891 | { | ||
892 | #define MPS_MASK 0xe0 | ||
893 | int rval; | ||
894 | uint16_t dc; | ||
895 | uint32_t dw; | ||
896 | struct qla_hw_data *ha = vha->hw; | ||
897 | |||
898 | if (!IS_QLA81XX(vha->hw)) | ||
899 | return QLA_SUCCESS; | ||
900 | |||
901 | rval = qla2x00_write_ram_word(vha, 0x7c00, 1); | ||
902 | if (rval != QLA_SUCCESS) { | ||
903 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
904 | "Sync-MPI: Unable to acquire semaphore.\n")); | ||
905 | goto done; | ||
906 | } | ||
907 | |||
908 | pci_read_config_word(vha->hw->pdev, 0x54, &dc); | ||
909 | rval = qla2x00_read_ram_word(vha, 0x7a15, &dw); | ||
910 | if (rval != QLA_SUCCESS) { | ||
911 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
912 | "Sync-MPI: Unable to read sync.\n")); | ||
913 | goto done_release; | ||
914 | } | ||
915 | |||
916 | dc &= MPS_MASK; | ||
917 | if (dc == (dw & MPS_MASK)) | ||
918 | goto done_release; | ||
919 | |||
920 | dw &= ~MPS_MASK; | ||
921 | dw |= dc; | ||
922 | rval = qla2x00_write_ram_word(vha, 0x7a15, dw); | ||
923 | if (rval != QLA_SUCCESS) { | ||
924 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
925 | "Sync-MPI: Unable to gain sync.\n")); | ||
926 | } | ||
927 | |||
928 | done_release: | ||
929 | rval = qla2x00_write_ram_word(vha, 0x7c00, 0); | ||
930 | if (rval != QLA_SUCCESS) { | ||
931 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
932 | "Sync-MPI: Unable to release semaphore.\n")); | ||
933 | } | ||
934 | |||
935 | done: | ||
936 | return rval; | ||
937 | } | ||
938 | |||
894 | /** | 939 | /** |
895 | * qla2x00_setup_chip() - Load and start RISC firmware. | 940 | * qla2x00_setup_chip() - Load and start RISC firmware. |
896 | * @ha: HA context | 941 | * @ha: HA context |
@@ -915,6 +960,8 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) | |||
915 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 960 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
916 | } | 961 | } |
917 | 962 | ||
963 | qla81xx_mpi_sync(vha); | ||
964 | |||
918 | /* Load firmware sequences */ | 965 | /* Load firmware sequences */ |
919 | rval = ha->isp_ops->load_risc(vha, &srisc_address); | 966 | rval = ha->isp_ops->load_risc(vha, &srisc_address); |
920 | if (rval == QLA_SUCCESS) { | 967 | if (rval == QLA_SUCCESS) { |
@@ -931,13 +978,16 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) | |||
931 | /* Retrieve firmware information. */ | 978 | /* Retrieve firmware information. */ |
932 | if (rval == QLA_SUCCESS) { | 979 | if (rval == QLA_SUCCESS) { |
933 | fw_major_version = ha->fw_major_version; | 980 | fw_major_version = ha->fw_major_version; |
934 | qla2x00_get_fw_version(vha, | 981 | rval = qla2x00_get_fw_version(vha, |
935 | &ha->fw_major_version, | 982 | &ha->fw_major_version, |
936 | &ha->fw_minor_version, | 983 | &ha->fw_minor_version, |
937 | &ha->fw_subminor_version, | 984 | &ha->fw_subminor_version, |
938 | &ha->fw_attributes, &ha->fw_memory_size, | 985 | &ha->fw_attributes, &ha->fw_memory_size, |
939 | ha->mpi_version, &ha->mpi_capabilities, | 986 | ha->mpi_version, &ha->mpi_capabilities, |
940 | ha->phy_version); | 987 | ha->phy_version); |
988 | if (rval != QLA_SUCCESS) | ||
989 | goto failed; | ||
990 | |||
941 | ha->flags.npiv_supported = 0; | 991 | ha->flags.npiv_supported = 0; |
942 | if (IS_QLA2XXX_MIDTYPE(ha) && | 992 | if (IS_QLA2XXX_MIDTYPE(ha) && |
943 | (ha->fw_attributes & BIT_2)) { | 993 | (ha->fw_attributes & BIT_2)) { |
@@ -989,7 +1039,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) | |||
989 | ha->fw_subminor_version); | 1039 | ha->fw_subminor_version); |
990 | } | 1040 | } |
991 | } | 1041 | } |
992 | 1042 | failed: | |
993 | if (rval) { | 1043 | if (rval) { |
994 | DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n", | 1044 | DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n", |
995 | vha->host_no)); | 1045 | vha->host_no)); |
@@ -1013,12 +1063,14 @@ qla2x00_init_response_q_entries(struct rsp_que *rsp) | |||
1013 | uint16_t cnt; | 1063 | uint16_t cnt; |
1014 | response_t *pkt; | 1064 | response_t *pkt; |
1015 | 1065 | ||
1066 | rsp->ring_ptr = rsp->ring; | ||
1067 | rsp->ring_index = 0; | ||
1068 | rsp->status_srb = NULL; | ||
1016 | pkt = rsp->ring_ptr; | 1069 | pkt = rsp->ring_ptr; |
1017 | for (cnt = 0; cnt < rsp->length; cnt++) { | 1070 | for (cnt = 0; cnt < rsp->length; cnt++) { |
1018 | pkt->signature = RESPONSE_PROCESSED; | 1071 | pkt->signature = RESPONSE_PROCESSED; |
1019 | pkt++; | 1072 | pkt++; |
1020 | } | 1073 | } |
1021 | |||
1022 | } | 1074 | } |
1023 | 1075 | ||
1024 | /** | 1076 | /** |
@@ -1176,7 +1228,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
1176 | if (ha->flags.msix_enabled) { | 1228 | if (ha->flags.msix_enabled) { |
1177 | msix = &ha->msix_entries[1]; | 1229 | msix = &ha->msix_entries[1]; |
1178 | DEBUG2_17(printk(KERN_INFO | 1230 | DEBUG2_17(printk(KERN_INFO |
1179 | "Reistering vector 0x%x for base que\n", msix->entry)); | 1231 | "Registering vector 0x%x for base que\n", msix->entry)); |
1180 | icb->msix = cpu_to_le16(msix->entry); | 1232 | icb->msix = cpu_to_le16(msix->entry); |
1181 | } | 1233 | } |
1182 | /* Use alternate PCI bus number */ | 1234 | /* Use alternate PCI bus number */ |
@@ -1230,14 +1282,14 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1230 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1282 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1231 | 1283 | ||
1232 | /* Clear outstanding commands array. */ | 1284 | /* Clear outstanding commands array. */ |
1233 | for (que = 0; que < ha->max_queues; que++) { | 1285 | for (que = 0; que < ha->max_req_queues; que++) { |
1234 | req = ha->req_q_map[que]; | 1286 | req = ha->req_q_map[que]; |
1235 | if (!req) | 1287 | if (!req) |
1236 | continue; | 1288 | continue; |
1237 | for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) | 1289 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) |
1238 | req->outstanding_cmds[cnt] = NULL; | 1290 | req->outstanding_cmds[cnt] = NULL; |
1239 | 1291 | ||
1240 | req->current_outstanding_cmd = 0; | 1292 | req->current_outstanding_cmd = 1; |
1241 | 1293 | ||
1242 | /* Initialize firmware. */ | 1294 | /* Initialize firmware. */ |
1243 | req->ring_ptr = req->ring; | 1295 | req->ring_ptr = req->ring; |
@@ -1245,13 +1297,10 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1245 | req->cnt = req->length; | 1297 | req->cnt = req->length; |
1246 | } | 1298 | } |
1247 | 1299 | ||
1248 | for (que = 0; que < ha->max_queues; que++) { | 1300 | for (que = 0; que < ha->max_rsp_queues; que++) { |
1249 | rsp = ha->rsp_q_map[que]; | 1301 | rsp = ha->rsp_q_map[que]; |
1250 | if (!rsp) | 1302 | if (!rsp) |
1251 | continue; | 1303 | continue; |
1252 | rsp->ring_ptr = rsp->ring; | ||
1253 | rsp->ring_index = 0; | ||
1254 | |||
1255 | /* Initialize response queue entries */ | 1304 | /* Initialize response queue entries */ |
1256 | qla2x00_init_response_q_entries(rsp); | 1305 | qla2x00_init_response_q_entries(rsp); |
1257 | } | 1306 | } |
@@ -1307,7 +1356,7 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) | |||
1307 | unsigned long wtime, mtime, cs84xx_time; | 1356 | unsigned long wtime, mtime, cs84xx_time; |
1308 | uint16_t min_wait; /* Minimum wait time if loop is down */ | 1357 | uint16_t min_wait; /* Minimum wait time if loop is down */ |
1309 | uint16_t wait_time; /* Wait time if loop is coming ready */ | 1358 | uint16_t wait_time; /* Wait time if loop is coming ready */ |
1310 | uint16_t state[3]; | 1359 | uint16_t state[5]; |
1311 | struct qla_hw_data *ha = vha->hw; | 1360 | struct qla_hw_data *ha = vha->hw; |
1312 | 1361 | ||
1313 | rval = QLA_SUCCESS; | 1362 | rval = QLA_SUCCESS; |
@@ -1406,8 +1455,9 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) | |||
1406 | vha->host_no, state[0], jiffies)); | 1455 | vha->host_no, state[0], jiffies)); |
1407 | } while (1); | 1456 | } while (1); |
1408 | 1457 | ||
1409 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1458 | DEBUG(printk("scsi(%ld): fw_state=%x (%x, %x, %x, %x) curr time=%lx.\n", |
1410 | vha->host_no, state[0], jiffies)); | 1459 | vha->host_no, state[0], state[1], state[2], state[3], state[4], |
1460 | jiffies)); | ||
1411 | 1461 | ||
1412 | if (rval) { | 1462 | if (rval) { |
1413 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", | 1463 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", |
@@ -1541,6 +1591,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, | |||
1541 | char *st, *en; | 1591 | char *st, *en; |
1542 | uint16_t index; | 1592 | uint16_t index; |
1543 | struct qla_hw_data *ha = vha->hw; | 1593 | struct qla_hw_data *ha = vha->hw; |
1594 | int use_tbl = !IS_QLA25XX(ha) && !IS_QLA81XX(ha); | ||
1544 | 1595 | ||
1545 | if (memcmp(model, BINZERO, len) != 0) { | 1596 | if (memcmp(model, BINZERO, len) != 0) { |
1546 | strncpy(ha->model_number, model, len); | 1597 | strncpy(ha->model_number, model, len); |
@@ -1553,14 +1604,16 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, | |||
1553 | } | 1604 | } |
1554 | 1605 | ||
1555 | index = (ha->pdev->subsystem_device & 0xff); | 1606 | index = (ha->pdev->subsystem_device & 0xff); |
1556 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | 1607 | if (use_tbl && |
1608 | ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | ||
1557 | index < QLA_MODEL_NAMES) | 1609 | index < QLA_MODEL_NAMES) |
1558 | strncpy(ha->model_desc, | 1610 | strncpy(ha->model_desc, |
1559 | qla2x00_model_name[index * 2 + 1], | 1611 | qla2x00_model_name[index * 2 + 1], |
1560 | sizeof(ha->model_desc) - 1); | 1612 | sizeof(ha->model_desc) - 1); |
1561 | } else { | 1613 | } else { |
1562 | index = (ha->pdev->subsystem_device & 0xff); | 1614 | index = (ha->pdev->subsystem_device & 0xff); |
1563 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | 1615 | if (use_tbl && |
1616 | ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | ||
1564 | index < QLA_MODEL_NAMES) { | 1617 | index < QLA_MODEL_NAMES) { |
1565 | strcpy(ha->model_number, | 1618 | strcpy(ha->model_number, |
1566 | qla2x00_model_name[index * 2]); | 1619 | qla2x00_model_name[index * 2]); |
@@ -2061,8 +2114,10 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2061 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { | 2114 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { |
2062 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) | 2115 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) |
2063 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 2116 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
2064 | if (test_bit(RSCN_UPDATE, &save_flags)) | 2117 | if (test_bit(RSCN_UPDATE, &save_flags)) { |
2065 | set_bit(RSCN_UPDATE, &vha->dpc_flags); | 2118 | set_bit(RSCN_UPDATE, &vha->dpc_flags); |
2119 | vha->flags.rscn_queue_overflow = 1; | ||
2120 | } | ||
2066 | } | 2121 | } |
2067 | 2122 | ||
2068 | return (rval); | 2123 | return (rval); |
@@ -2110,7 +2165,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) | |||
2110 | goto cleanup_allocation; | 2165 | goto cleanup_allocation; |
2111 | 2166 | ||
2112 | DEBUG3(printk("scsi(%ld): Entries in ID list (%d)\n", | 2167 | DEBUG3(printk("scsi(%ld): Entries in ID list (%d)\n", |
2113 | ha->host_no, entries)); | 2168 | vha->host_no, entries)); |
2114 | DEBUG3(qla2x00_dump_buffer((uint8_t *)ha->gid_list, | 2169 | DEBUG3(qla2x00_dump_buffer((uint8_t *)ha->gid_list, |
2115 | entries * sizeof(struct gid_list_info))); | 2170 | entries * sizeof(struct gid_list_info))); |
2116 | 2171 | ||
@@ -2243,7 +2298,8 @@ static void | |||
2243 | qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | 2298 | qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) |
2244 | { | 2299 | { |
2245 | #define LS_UNKNOWN 2 | 2300 | #define LS_UNKNOWN 2 |
2246 | static char *link_speeds[5] = { "1", "2", "?", "4", "8" }; | 2301 | static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" }; |
2302 | char *link_speed; | ||
2247 | int rval; | 2303 | int rval; |
2248 | uint16_t mb[6]; | 2304 | uint16_t mb[6]; |
2249 | struct qla_hw_data *ha = vha->hw; | 2305 | struct qla_hw_data *ha = vha->hw; |
@@ -2266,10 +2322,15 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
2266 | fcport->port_name[6], fcport->port_name[7], rval, | 2322 | fcport->port_name[6], fcport->port_name[7], rval, |
2267 | fcport->fp_speed, mb[0], mb[1])); | 2323 | fcport->fp_speed, mb[0], mb[1])); |
2268 | } else { | 2324 | } else { |
2325 | link_speed = link_speeds[LS_UNKNOWN]; | ||
2326 | if (fcport->fp_speed < 5) | ||
2327 | link_speed = link_speeds[fcport->fp_speed]; | ||
2328 | else if (fcport->fp_speed == 0x13) | ||
2329 | link_speed = link_speeds[5]; | ||
2269 | DEBUG2(qla_printk(KERN_INFO, ha, | 2330 | DEBUG2(qla_printk(KERN_INFO, ha, |
2270 | "iIDMA adjusted to %s GB/s on " | 2331 | "iIDMA adjusted to %s GB/s on " |
2271 | "%02x%02x%02x%02x%02x%02x%02x%02x.\n", | 2332 | "%02x%02x%02x%02x%02x%02x%02x%02x.\n", |
2272 | link_speeds[fcport->fp_speed], fcport->port_name[0], | 2333 | link_speed, fcport->port_name[0], |
2273 | fcport->port_name[1], fcport->port_name[2], | 2334 | fcport->port_name[1], fcport->port_name[2], |
2274 | fcport->port_name[3], fcport->port_name[4], | 2335 | fcport->port_name[3], fcport->port_name[4], |
2275 | fcport->port_name[5], fcport->port_name[6], | 2336 | fcport->port_name[5], fcport->port_name[6], |
@@ -3180,9 +3241,14 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) | |||
3180 | { | 3241 | { |
3181 | int rval = QLA_SUCCESS; | 3242 | int rval = QLA_SUCCESS; |
3182 | uint32_t wait_time; | 3243 | uint32_t wait_time; |
3183 | struct qla_hw_data *ha = vha->hw; | 3244 | struct req_que *req; |
3184 | struct req_que *req = ha->req_q_map[vha->req_ques[0]]; | 3245 | struct rsp_que *rsp; |
3185 | struct rsp_que *rsp = req->rsp; | 3246 | |
3247 | if (ql2xmultique_tag) | ||
3248 | req = vha->hw->req_q_map[0]; | ||
3249 | else | ||
3250 | req = vha->req; | ||
3251 | rsp = req->rsp; | ||
3186 | 3252 | ||
3187 | atomic_set(&vha->loop_state, LOOP_UPDATE); | 3253 | atomic_set(&vha->loop_state, LOOP_UPDATE); |
3188 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | 3254 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); |
@@ -3448,7 +3514,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) | |||
3448 | int ret = -1; | 3514 | int ret = -1; |
3449 | int i; | 3515 | int i; |
3450 | 3516 | ||
3451 | for (i = 1; i < ha->max_queues; i++) { | 3517 | for (i = 1; i < ha->max_rsp_queues; i++) { |
3452 | rsp = ha->rsp_q_map[i]; | 3518 | rsp = ha->rsp_q_map[i]; |
3453 | if (rsp) { | 3519 | if (rsp) { |
3454 | rsp->options &= ~BIT_0; | 3520 | rsp->options &= ~BIT_0; |
@@ -3462,6 +3528,8 @@ qla25xx_init_queues(struct qla_hw_data *ha) | |||
3462 | "%s Rsp que:%d inited\n", __func__, | 3528 | "%s Rsp que:%d inited\n", __func__, |
3463 | rsp->id)); | 3529 | rsp->id)); |
3464 | } | 3530 | } |
3531 | } | ||
3532 | for (i = 1; i < ha->max_req_queues; i++) { | ||
3465 | req = ha->req_q_map[i]; | 3533 | req = ha->req_q_map[i]; |
3466 | if (req) { | 3534 | if (req) { |
3467 | /* Clear outstanding commands array. */ | 3535 | /* Clear outstanding commands array. */ |
@@ -3566,14 +3634,15 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
3566 | nv = ha->nvram; | 3634 | nv = ha->nvram; |
3567 | 3635 | ||
3568 | /* Determine NVRAM starting address. */ | 3636 | /* Determine NVRAM starting address. */ |
3569 | ha->nvram_size = sizeof(struct nvram_24xx); | 3637 | if (ha->flags.port0) { |
3570 | ha->nvram_base = FA_NVRAM_FUNC0_ADDR; | 3638 | ha->nvram_base = FA_NVRAM_FUNC0_ADDR; |
3571 | ha->vpd_size = FA_NVRAM_VPD_SIZE; | 3639 | ha->vpd_base = FA_NVRAM_VPD0_ADDR; |
3572 | ha->vpd_base = FA_NVRAM_VPD0_ADDR; | 3640 | } else { |
3573 | if (PCI_FUNC(ha->pdev->devfn)) { | ||
3574 | ha->nvram_base = FA_NVRAM_FUNC1_ADDR; | 3641 | ha->nvram_base = FA_NVRAM_FUNC1_ADDR; |
3575 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; | 3642 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; |
3576 | } | 3643 | } |
3644 | ha->nvram_size = sizeof(struct nvram_24xx); | ||
3645 | ha->vpd_size = FA_NVRAM_VPD_SIZE; | ||
3577 | 3646 | ||
3578 | /* Get VPD data into cache */ | 3647 | /* Get VPD data into cache */ |
3579 | ha->vpd = ha->nvram + VPD_OFFSET; | 3648 | ha->vpd = ha->nvram + VPD_OFFSET; |
@@ -3587,7 +3656,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
3587 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) | 3656 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) |
3588 | chksum += le32_to_cpu(*dptr++); | 3657 | chksum += le32_to_cpu(*dptr++); |
3589 | 3658 | ||
3590 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); | 3659 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", vha->host_no)); |
3591 | DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); | 3660 | DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); |
3592 | 3661 | ||
3593 | /* Bad NVRAM data, set defaults parameters. */ | 3662 | /* Bad NVRAM data, set defaults parameters. */ |
@@ -3612,7 +3681,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
3612 | nv->exchange_count = __constant_cpu_to_le16(0); | 3681 | nv->exchange_count = __constant_cpu_to_le16(0); |
3613 | nv->hard_address = __constant_cpu_to_le16(124); | 3682 | nv->hard_address = __constant_cpu_to_le16(124); |
3614 | nv->port_name[0] = 0x21; | 3683 | nv->port_name[0] = 0x21; |
3615 | nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn); | 3684 | nv->port_name[1] = 0x00 + ha->port_no; |
3616 | nv->port_name[2] = 0x00; | 3685 | nv->port_name[2] = 0x00; |
3617 | nv->port_name[3] = 0xe0; | 3686 | nv->port_name[3] = 0xe0; |
3618 | nv->port_name[4] = 0x8b; | 3687 | nv->port_name[4] = 0x8b; |
@@ -3798,11 +3867,11 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
3798 | } | 3867 | } |
3799 | 3868 | ||
3800 | static int | 3869 | static int |
3801 | qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) | 3870 | qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, |
3871 | uint32_t faddr) | ||
3802 | { | 3872 | { |
3803 | int rval = QLA_SUCCESS; | 3873 | int rval = QLA_SUCCESS; |
3804 | int segments, fragment; | 3874 | int segments, fragment; |
3805 | uint32_t faddr; | ||
3806 | uint32_t *dcode, dlen; | 3875 | uint32_t *dcode, dlen; |
3807 | uint32_t risc_addr; | 3876 | uint32_t risc_addr; |
3808 | uint32_t risc_size; | 3877 | uint32_t risc_size; |
@@ -3811,12 +3880,11 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
3811 | struct req_que *req = ha->req_q_map[0]; | 3880 | struct req_que *req = ha->req_q_map[0]; |
3812 | 3881 | ||
3813 | qla_printk(KERN_INFO, ha, | 3882 | qla_printk(KERN_INFO, ha, |
3814 | "FW: Loading from flash (%x)...\n", ha->flt_region_fw); | 3883 | "FW: Loading from flash (%x)...\n", faddr); |
3815 | 3884 | ||
3816 | rval = QLA_SUCCESS; | 3885 | rval = QLA_SUCCESS; |
3817 | 3886 | ||
3818 | segments = FA_RISC_CODE_SEGMENTS; | 3887 | segments = FA_RISC_CODE_SEGMENTS; |
3819 | faddr = ha->flt_region_fw; | ||
3820 | dcode = (uint32_t *)req->ring; | 3888 | dcode = (uint32_t *)req->ring; |
3821 | *srisc_addr = 0; | 3889 | *srisc_addr = 0; |
3822 | 3890 | ||
@@ -4104,6 +4172,9 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
4104 | { | 4172 | { |
4105 | int rval; | 4173 | int rval; |
4106 | 4174 | ||
4175 | if (ql2xfwloadbin == 1) | ||
4176 | return qla81xx_load_risc(vha, srisc_addr); | ||
4177 | |||
4107 | /* | 4178 | /* |
4108 | * FW Load priority: | 4179 | * FW Load priority: |
4109 | * 1) Firmware via request-firmware interface (.bin file). | 4180 | * 1) Firmware via request-firmware interface (.bin file). |
@@ -4113,24 +4184,45 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
4113 | if (rval == QLA_SUCCESS) | 4184 | if (rval == QLA_SUCCESS) |
4114 | return rval; | 4185 | return rval; |
4115 | 4186 | ||
4116 | return qla24xx_load_risc_flash(vha, srisc_addr); | 4187 | return qla24xx_load_risc_flash(vha, srisc_addr, |
4188 | vha->hw->flt_region_fw); | ||
4117 | } | 4189 | } |
4118 | 4190 | ||
4119 | int | 4191 | int |
4120 | qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | 4192 | qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) |
4121 | { | 4193 | { |
4122 | int rval; | 4194 | int rval; |
4195 | struct qla_hw_data *ha = vha->hw; | ||
4196 | |||
4197 | if (ql2xfwloadbin == 2) | ||
4198 | goto try_blob_fw; | ||
4123 | 4199 | ||
4124 | /* | 4200 | /* |
4125 | * FW Load priority: | 4201 | * FW Load priority: |
4126 | * 1) Firmware residing in flash. | 4202 | * 1) Firmware residing in flash. |
4127 | * 2) Firmware via request-firmware interface (.bin file). | 4203 | * 2) Firmware via request-firmware interface (.bin file). |
4204 | * 3) Golden-Firmware residing in flash -- limited operation. | ||
4128 | */ | 4205 | */ |
4129 | rval = qla24xx_load_risc_flash(vha, srisc_addr); | 4206 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw); |
4130 | if (rval == QLA_SUCCESS) | 4207 | if (rval == QLA_SUCCESS) |
4131 | return rval; | 4208 | return rval; |
4132 | 4209 | ||
4133 | return qla24xx_load_risc_blob(vha, srisc_addr); | 4210 | try_blob_fw: |
4211 | rval = qla24xx_load_risc_blob(vha, srisc_addr); | ||
4212 | if (rval == QLA_SUCCESS || !ha->flt_region_gold_fw) | ||
4213 | return rval; | ||
4214 | |||
4215 | qla_printk(KERN_ERR, ha, | ||
4216 | "FW: Attempting to fallback to golden firmware...\n"); | ||
4217 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw); | ||
4218 | if (rval != QLA_SUCCESS) | ||
4219 | return rval; | ||
4220 | |||
4221 | qla_printk(KERN_ERR, ha, | ||
4222 | "FW: Please update operational firmware...\n"); | ||
4223 | ha->flags.running_gold_fw = 1; | ||
4224 | |||
4225 | return rval; | ||
4134 | } | 4226 | } |
4135 | 4227 | ||
4136 | void | 4228 | void |
@@ -4146,7 +4238,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) | |||
4146 | 4238 | ||
4147 | ret = qla2x00_stop_firmware(vha); | 4239 | ret = qla2x00_stop_firmware(vha); |
4148 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && | 4240 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && |
4149 | retries ; retries--) { | 4241 | ret != QLA_INVALID_COMMAND && retries ; retries--) { |
4150 | ha->isp_ops->reset_chip(vha); | 4242 | ha->isp_ops->reset_chip(vha); |
4151 | if (ha->isp_ops->chip_diag(vha) != QLA_SUCCESS) | 4243 | if (ha->isp_ops->chip_diag(vha) != QLA_SUCCESS) |
4152 | continue; | 4244 | continue; |
@@ -4165,13 +4257,19 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha) | |||
4165 | uint16_t mb[MAILBOX_REGISTER_COUNT]; | 4257 | uint16_t mb[MAILBOX_REGISTER_COUNT]; |
4166 | struct qla_hw_data *ha = vha->hw; | 4258 | struct qla_hw_data *ha = vha->hw; |
4167 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | 4259 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
4168 | struct req_que *req = ha->req_q_map[vha->req_ques[0]]; | 4260 | struct req_que *req; |
4169 | struct rsp_que *rsp = req->rsp; | 4261 | struct rsp_que *rsp; |
4170 | 4262 | ||
4171 | if (!vha->vp_idx) | 4263 | if (!vha->vp_idx) |
4172 | return -EINVAL; | 4264 | return -EINVAL; |
4173 | 4265 | ||
4174 | rval = qla2x00_fw_ready(base_vha); | 4266 | rval = qla2x00_fw_ready(base_vha); |
4267 | if (ql2xmultique_tag) | ||
4268 | req = ha->req_q_map[0]; | ||
4269 | else | ||
4270 | req = vha->req; | ||
4271 | rsp = req->rsp; | ||
4272 | |||
4175 | if (rval == QLA_SUCCESS) { | 4273 | if (rval == QLA_SUCCESS) { |
4176 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); | 4274 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
4177 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); | 4275 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); |
@@ -4305,7 +4403,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
4305 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) | 4403 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) |
4306 | chksum += le32_to_cpu(*dptr++); | 4404 | chksum += le32_to_cpu(*dptr++); |
4307 | 4405 | ||
4308 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); | 4406 | DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", vha->host_no)); |
4309 | DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); | 4407 | DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); |
4310 | 4408 | ||
4311 | /* Bad NVRAM data, set defaults parameters. */ | 4409 | /* Bad NVRAM data, set defaults parameters. */ |
@@ -4329,7 +4427,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
4329 | nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); | 4427 | nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); |
4330 | nv->exchange_count = __constant_cpu_to_le16(0); | 4428 | nv->exchange_count = __constant_cpu_to_le16(0); |
4331 | nv->port_name[0] = 0x21; | 4429 | nv->port_name[0] = 0x21; |
4332 | nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn); | 4430 | nv->port_name[1] = 0x00 + ha->port_no; |
4333 | nv->port_name[2] = 0x00; | 4431 | nv->port_name[2] = 0x00; |
4334 | nv->port_name[3] = 0xe0; | 4432 | nv->port_name[3] = 0xe0; |
4335 | nv->port_name[4] = 0x8b; | 4433 | nv->port_name[4] = 0x8b; |
@@ -4358,12 +4456,12 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
4358 | nv->max_luns_per_target = __constant_cpu_to_le16(128); | 4456 | nv->max_luns_per_target = __constant_cpu_to_le16(128); |
4359 | nv->port_down_retry_count = __constant_cpu_to_le16(30); | 4457 | nv->port_down_retry_count = __constant_cpu_to_le16(30); |
4360 | nv->link_down_timeout = __constant_cpu_to_le16(30); | 4458 | nv->link_down_timeout = __constant_cpu_to_le16(30); |
4361 | nv->enode_mac[0] = 0x01; | 4459 | nv->enode_mac[0] = 0x00; |
4362 | nv->enode_mac[1] = 0x02; | 4460 | nv->enode_mac[1] = 0x02; |
4363 | nv->enode_mac[2] = 0x03; | 4461 | nv->enode_mac[2] = 0x03; |
4364 | nv->enode_mac[3] = 0x04; | 4462 | nv->enode_mac[3] = 0x04; |
4365 | nv->enode_mac[4] = 0x05; | 4463 | nv->enode_mac[4] = 0x05; |
4366 | nv->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn); | 4464 | nv->enode_mac[5] = 0x06 + ha->port_no; |
4367 | 4465 | ||
4368 | rval = 1; | 4466 | rval = 1; |
4369 | } | 4467 | } |
@@ -4396,7 +4494,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
4396 | icb->enode_mac[2] = 0x03; | 4494 | icb->enode_mac[2] = 0x03; |
4397 | icb->enode_mac[3] = 0x04; | 4495 | icb->enode_mac[3] = 0x04; |
4398 | icb->enode_mac[4] = 0x05; | 4496 | icb->enode_mac[4] = 0x05; |
4399 | icb->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn); | 4497 | icb->enode_mac[5] = 0x06 + ha->port_no; |
4400 | } | 4498 | } |
4401 | 4499 | ||
4402 | /* Use extended-initialization control block. */ | 4500 | /* Use extended-initialization control block. */ |