diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 274 |
1 files changed, 258 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index b6202fe118ac..42eb7ffd5942 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/gfp.h> | ||
10 | 11 | ||
11 | 12 | ||
12 | /* | 13 | /* |
@@ -56,6 +57,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
56 | 57 | ||
57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); | 58 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); |
58 | 59 | ||
60 | if (ha->flags.pci_channel_io_perm_failure) { | ||
61 | DEBUG(printk("%s(%ld): Perm failure on EEH, timeout MBX " | ||
62 | "Exiting.\n", __func__, vha->host_no)); | ||
63 | return QLA_FUNCTION_TIMEOUT; | ||
64 | } | ||
65 | |||
59 | /* | 66 | /* |
60 | * Wait for active mailbox commands to finish by waiting at most tov | 67 | * Wait for active mailbox commands to finish by waiting at most tov |
61 | * seconds. This is to serialize actual issuing of mailbox cmds during | 68 | * seconds. This is to serialize actual issuing of mailbox cmds during |
@@ -154,10 +161,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
154 | /* Check for pending interrupts. */ | 161 | /* Check for pending interrupts. */ |
155 | qla2x00_poll(ha->rsp_q_map[0]); | 162 | qla2x00_poll(ha->rsp_q_map[0]); |
156 | 163 | ||
157 | if (command != MBC_LOAD_RISC_RAM_EXTENDED && | 164 | if (!ha->flags.mbox_int && |
158 | !ha->flags.mbox_int) | 165 | !(IS_QLA2200(ha) && |
166 | command == MBC_LOAD_RISC_RAM_EXTENDED)) | ||
159 | msleep(10); | 167 | msleep(10); |
160 | } /* while */ | 168 | } /* while */ |
169 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
170 | "Waited %d sec\n", | ||
171 | (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ))); | ||
161 | } | 172 | } |
162 | 173 | ||
163 | /* Check whether we timed out */ | 174 | /* Check whether we timed out */ |
@@ -227,7 +238,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
227 | 238 | ||
228 | if (rval == QLA_FUNCTION_TIMEOUT && | 239 | if (rval == QLA_FUNCTION_TIMEOUT && |
229 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { | 240 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { |
230 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 241 | if (!io_lock_on || (mcp->flags & IOCTL_CMD) || |
242 | ha->flags.eeh_busy) { | ||
231 | /* not in dpc. schedule it for dpc to take over. */ | 243 | /* not in dpc. schedule it for dpc to take over. */ |
232 | DEBUG(printk("%s(%ld): timeout schedule " | 244 | DEBUG(printk("%s(%ld): timeout schedule " |
233 | "isp_abort_needed.\n", __func__, | 245 | "isp_abort_needed.\n", __func__, |
@@ -237,7 +249,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
237 | base_vha->host_no)); | 249 | base_vha->host_no)); |
238 | qla_printk(KERN_WARNING, ha, | 250 | qla_printk(KERN_WARNING, ha, |
239 | "Mailbox command timeout occurred. Scheduling ISP " | 251 | "Mailbox command timeout occurred. Scheduling ISP " |
240 | "abort.\n"); | 252 | "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); |
241 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 253 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); |
242 | qla2xxx_wake_dpc(vha); | 254 | qla2xxx_wake_dpc(vha); |
243 | } else if (!abort_active) { | 255 | } else if (!abort_active) { |
@@ -328,6 +340,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, | |||
328 | return rval; | 340 | return rval; |
329 | } | 341 | } |
330 | 342 | ||
343 | #define EXTENDED_BB_CREDITS BIT_0 | ||
331 | /* | 344 | /* |
332 | * qla2x00_execute_fw | 345 | * qla2x00_execute_fw |
333 | * Start adapter firmware. | 346 | * Start adapter firmware. |
@@ -360,7 +373,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) | |||
360 | mcp->mb[1] = MSW(risc_addr); | 373 | mcp->mb[1] = MSW(risc_addr); |
361 | mcp->mb[2] = LSW(risc_addr); | 374 | mcp->mb[2] = LSW(risc_addr); |
362 | mcp->mb[3] = 0; | 375 | mcp->mb[3] = 0; |
363 | mcp->mb[4] = 0; | 376 | if (IS_QLA81XX(ha)) { |
377 | struct nvram_81xx *nv = ha->nvram; | ||
378 | mcp->mb[4] = (nv->enhanced_features & | ||
379 | EXTENDED_BB_CREDITS); | ||
380 | } else | ||
381 | mcp->mb[4] = 0; | ||
364 | mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; | 382 | mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; |
365 | mcp->in_mb |= MBX_1; | 383 | mcp->in_mb |= MBX_1; |
366 | } else { | 384 | } else { |
@@ -2006,7 +2024,7 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma, | |||
2006 | int | 2024 | int |
2007 | qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, | 2025 | qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, |
2008 | uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, | 2026 | uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, |
2009 | uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports) | 2027 | uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs) |
2010 | { | 2028 | { |
2011 | int rval; | 2029 | int rval; |
2012 | mbx_cmd_t mc; | 2030 | mbx_cmd_t mc; |
@@ -2017,6 +2035,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, | |||
2017 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 2035 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
2018 | mcp->out_mb = MBX_0; | 2036 | mcp->out_mb = MBX_0; |
2019 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 2037 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
2038 | if (IS_QLA81XX(vha->hw)) | ||
2039 | mcp->in_mb |= MBX_12; | ||
2020 | mcp->tov = MBX_TOV_SECONDS; | 2040 | mcp->tov = MBX_TOV_SECONDS; |
2021 | mcp->flags = 0; | 2041 | mcp->flags = 0; |
2022 | rval = qla2x00_mailbox_command(vha, mcp); | 2042 | rval = qla2x00_mailbox_command(vha, mcp); |
@@ -2027,9 +2047,10 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, | |||
2027 | vha->host_no, mcp->mb[0])); | 2047 | vha->host_no, mcp->mb[0])); |
2028 | } else { | 2048 | } else { |
2029 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " | 2049 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " |
2030 | "mb7=%x mb10=%x mb11=%x.\n", __func__, vha->host_no, | 2050 | "mb7=%x mb10=%x mb11=%x mb12=%x.\n", __func__, |
2031 | mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], | 2051 | vha->host_no, mcp->mb[1], mcp->mb[2], mcp->mb[3], |
2032 | mcp->mb[10], mcp->mb[11])); | 2052 | mcp->mb[6], mcp->mb[7], mcp->mb[10], mcp->mb[11], |
2053 | mcp->mb[12])); | ||
2033 | 2054 | ||
2034 | if (cur_xchg_cnt) | 2055 | if (cur_xchg_cnt) |
2035 | *cur_xchg_cnt = mcp->mb[3]; | 2056 | *cur_xchg_cnt = mcp->mb[3]; |
@@ -2041,6 +2062,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, | |||
2041 | *orig_iocb_cnt = mcp->mb[10]; | 2062 | *orig_iocb_cnt = mcp->mb[10]; |
2042 | if (vha->hw->flags.npiv_supported && max_npiv_vports) | 2063 | if (vha->hw->flags.npiv_supported && max_npiv_vports) |
2043 | *max_npiv_vports = mcp->mb[11]; | 2064 | *max_npiv_vports = mcp->mb[11]; |
2065 | if (IS_QLA81XX(vha->hw) && max_fcfs) | ||
2066 | *max_fcfs = mcp->mb[12]; | ||
2044 | } | 2067 | } |
2045 | 2068 | ||
2046 | return (rval); | 2069 | return (rval); |
@@ -2313,6 +2336,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, | |||
2313 | { | 2336 | { |
2314 | int rval, rval2; | 2337 | int rval, rval2; |
2315 | struct tsk_mgmt_cmd *tsk; | 2338 | struct tsk_mgmt_cmd *tsk; |
2339 | struct sts_entry_24xx *sts; | ||
2316 | dma_addr_t tsk_dma; | 2340 | dma_addr_t tsk_dma; |
2317 | scsi_qla_host_t *vha; | 2341 | scsi_qla_host_t *vha; |
2318 | struct qla_hw_data *ha; | 2342 | struct qla_hw_data *ha; |
@@ -2352,20 +2376,37 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, | |||
2352 | sizeof(tsk->p.tsk.lun)); | 2376 | sizeof(tsk->p.tsk.lun)); |
2353 | } | 2377 | } |
2354 | 2378 | ||
2379 | sts = &tsk->p.sts; | ||
2355 | rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0); | 2380 | rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0); |
2356 | if (rval != QLA_SUCCESS) { | 2381 | if (rval != QLA_SUCCESS) { |
2357 | DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " | 2382 | DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " |
2358 | "(%x).\n", __func__, vha->host_no, name, rval)); | 2383 | "(%x).\n", __func__, vha->host_no, name, rval)); |
2359 | } else if (tsk->p.sts.entry_status != 0) { | 2384 | } else if (sts->entry_status != 0) { |
2360 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2385 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2361 | "-- error status (%x).\n", __func__, vha->host_no, | 2386 | "-- error status (%x).\n", __func__, vha->host_no, |
2362 | tsk->p.sts.entry_status)); | 2387 | sts->entry_status)); |
2363 | rval = QLA_FUNCTION_FAILED; | 2388 | rval = QLA_FUNCTION_FAILED; |
2364 | } else if (tsk->p.sts.comp_status != | 2389 | } else if (sts->comp_status != |
2365 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2390 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2366 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2391 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2367 | "-- completion status (%x).\n", __func__, | 2392 | "-- completion status (%x).\n", __func__, |
2368 | vha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); | 2393 | vha->host_no, le16_to_cpu(sts->comp_status))); |
2394 | rval = QLA_FUNCTION_FAILED; | ||
2395 | } else if (!(le16_to_cpu(sts->scsi_status) & | ||
2396 | SS_RESPONSE_INFO_LEN_VALID)) { | ||
2397 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | ||
2398 | "-- no response info (%x).\n", __func__, vha->host_no, | ||
2399 | le16_to_cpu(sts->scsi_status))); | ||
2400 | rval = QLA_FUNCTION_FAILED; | ||
2401 | } else if (le32_to_cpu(sts->rsp_data_len) < 4) { | ||
2402 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | ||
2403 | "-- not enough response info (%d).\n", __func__, | ||
2404 | vha->host_no, le32_to_cpu(sts->rsp_data_len))); | ||
2405 | rval = QLA_FUNCTION_FAILED; | ||
2406 | } else if (sts->data[3]) { | ||
2407 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | ||
2408 | "-- response (%x).\n", __func__, | ||
2409 | vha->host_no, sts->data[3])); | ||
2369 | rval = QLA_FUNCTION_FAILED; | 2410 | rval = QLA_FUNCTION_FAILED; |
2370 | } | 2411 | } |
2371 | 2412 | ||
@@ -2507,6 +2548,9 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, | |||
2507 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2548 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2508 | return QLA_FUNCTION_FAILED; | 2549 | return QLA_FUNCTION_FAILED; |
2509 | 2550 | ||
2551 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2552 | return QLA_FUNCTION_FAILED; | ||
2553 | |||
2510 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2554 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2511 | 2555 | ||
2512 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2556 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2542,6 +2586,9 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) | |||
2542 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2586 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2543 | return QLA_FUNCTION_FAILED; | 2587 | return QLA_FUNCTION_FAILED; |
2544 | 2588 | ||
2589 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2590 | return QLA_FUNCTION_FAILED; | ||
2591 | |||
2545 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2592 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2546 | 2593 | ||
2547 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2594 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2572,6 +2619,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, | |||
2572 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) | 2619 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) |
2573 | return QLA_FUNCTION_FAILED; | 2620 | return QLA_FUNCTION_FAILED; |
2574 | 2621 | ||
2622 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2623 | return QLA_FUNCTION_FAILED; | ||
2624 | |||
2575 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2625 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2576 | 2626 | ||
2577 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2627 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2616,6 +2666,9 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) | |||
2616 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2666 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2617 | return QLA_FUNCTION_FAILED; | 2667 | return QLA_FUNCTION_FAILED; |
2618 | 2668 | ||
2669 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2670 | return QLA_FUNCTION_FAILED; | ||
2671 | |||
2619 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2672 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2620 | 2673 | ||
2621 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2674 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2759,8 +2812,10 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
2759 | vp_idx, MSB(stat), | 2812 | vp_idx, MSB(stat), |
2760 | rptid_entry->port_id[2], rptid_entry->port_id[1], | 2813 | rptid_entry->port_id[2], rptid_entry->port_id[1], |
2761 | rptid_entry->port_id[0])); | 2814 | rptid_entry->port_id[0])); |
2762 | if (vp_idx == 0) | 2815 | |
2763 | return; | 2816 | vp = vha; |
2817 | if (vp_idx == 0 && (MSB(stat) != 1)) | ||
2818 | goto reg_needed; | ||
2764 | 2819 | ||
2765 | if (MSB(stat) == 1) { | 2820 | if (MSB(stat) == 1) { |
2766 | DEBUG2(printk("scsi(%ld): Could not acquire ID for " | 2821 | DEBUG2(printk("scsi(%ld): Could not acquire ID for " |
@@ -2783,8 +2838,11 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
2783 | * response queue. Handle it in dpc context. | 2838 | * response queue. Handle it in dpc context. |
2784 | */ | 2839 | */ |
2785 | set_bit(VP_IDX_ACQUIRED, &vp->vp_flags); | 2840 | set_bit(VP_IDX_ACQUIRED, &vp->vp_flags); |
2786 | set_bit(VP_DPC_NEEDED, &vha->dpc_flags); | ||
2787 | 2841 | ||
2842 | reg_needed: | ||
2843 | set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags); | ||
2844 | set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags); | ||
2845 | set_bit(VP_DPC_NEEDED, &vha->dpc_flags); | ||
2788 | qla2xxx_wake_dpc(vha); | 2846 | qla2xxx_wake_dpc(vha); |
2789 | } | 2847 | } |
2790 | } | 2848 | } |
@@ -3585,6 +3643,157 @@ qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data) | |||
3585 | } | 3643 | } |
3586 | 3644 | ||
3587 | int | 3645 | int |
3646 | qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mresp) | ||
3647 | { | ||
3648 | int rval; | ||
3649 | mbx_cmd_t mc; | ||
3650 | mbx_cmd_t *mcp = &mc; | ||
3651 | uint32_t iter_cnt = 0x1; | ||
3652 | |||
3653 | DEBUG11(printk("scsi(%ld): entered.\n", vha->host_no)); | ||
3654 | |||
3655 | memset(mcp->mb, 0 , sizeof(mcp->mb)); | ||
3656 | mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; | ||
3657 | mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing | ||
3658 | |||
3659 | /* transfer count */ | ||
3660 | mcp->mb[10] = LSW(mreq->transfer_size); | ||
3661 | mcp->mb[11] = MSW(mreq->transfer_size); | ||
3662 | |||
3663 | /* send data address */ | ||
3664 | mcp->mb[14] = LSW(mreq->send_dma); | ||
3665 | mcp->mb[15] = MSW(mreq->send_dma); | ||
3666 | mcp->mb[20] = LSW(MSD(mreq->send_dma)); | ||
3667 | mcp->mb[21] = MSW(MSD(mreq->send_dma)); | ||
3668 | |||
3669 | /* recieve data address */ | ||
3670 | mcp->mb[16] = LSW(mreq->rcv_dma); | ||
3671 | mcp->mb[17] = MSW(mreq->rcv_dma); | ||
3672 | mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); | ||
3673 | mcp->mb[7] = MSW(MSD(mreq->rcv_dma)); | ||
3674 | |||
3675 | /* Iteration count */ | ||
3676 | mcp->mb[18] = LSW(iter_cnt); | ||
3677 | mcp->mb[19] = MSW(iter_cnt); | ||
3678 | |||
3679 | mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| | ||
3680 | MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; | ||
3681 | if (IS_QLA81XX(vha->hw)) | ||
3682 | mcp->out_mb |= MBX_2; | ||
3683 | mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; | ||
3684 | |||
3685 | mcp->buf_size = mreq->transfer_size; | ||
3686 | mcp->tov = MBX_TOV_SECONDS; | ||
3687 | mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; | ||
3688 | |||
3689 | rval = qla2x00_mailbox_command(vha, mcp); | ||
3690 | |||
3691 | if (rval != QLA_SUCCESS) { | ||
3692 | DEBUG2(printk(KERN_WARNING | ||
3693 | "(%ld): failed=%x mb[0]=0x%x " | ||
3694 | "mb[1]=0x%x mb[2]=0x%x mb[3]=0x%x mb[18]=0x%x mb[19]=0x%x. \n", vha->host_no, rval, | ||
3695 | mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[18], mcp->mb[19])); | ||
3696 | } else { | ||
3697 | DEBUG2(printk(KERN_WARNING | ||
3698 | "scsi(%ld): done.\n", vha->host_no)); | ||
3699 | } | ||
3700 | |||
3701 | /* Copy mailbox information */ | ||
3702 | memcpy( mresp, mcp->mb, 64); | ||
3703 | mresp[3] = mcp->mb[18]; | ||
3704 | mresp[4] = mcp->mb[19]; | ||
3705 | return rval; | ||
3706 | } | ||
3707 | |||
3708 | int | ||
3709 | qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mresp) | ||
3710 | { | ||
3711 | int rval; | ||
3712 | mbx_cmd_t mc; | ||
3713 | mbx_cmd_t *mcp = &mc; | ||
3714 | struct qla_hw_data *ha = vha->hw; | ||
3715 | |||
3716 | DEBUG11(printk("scsi(%ld): entered.\n", vha->host_no)); | ||
3717 | |||
3718 | memset(mcp->mb, 0 , sizeof(mcp->mb)); | ||
3719 | mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; | ||
3720 | mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */ | ||
3721 | if (IS_QLA81XX(ha)) | ||
3722 | mcp->mb[1] |= BIT_15; | ||
3723 | mcp->mb[2] = IS_QLA81XX(ha) ? vha->fcoe_fcf_idx : 0; | ||
3724 | mcp->mb[16] = LSW(mreq->rcv_dma); | ||
3725 | mcp->mb[17] = MSW(mreq->rcv_dma); | ||
3726 | mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); | ||
3727 | mcp->mb[7] = MSW(MSD(mreq->rcv_dma)); | ||
3728 | |||
3729 | mcp->mb[10] = LSW(mreq->transfer_size); | ||
3730 | |||
3731 | mcp->mb[14] = LSW(mreq->send_dma); | ||
3732 | mcp->mb[15] = MSW(mreq->send_dma); | ||
3733 | mcp->mb[20] = LSW(MSD(mreq->send_dma)); | ||
3734 | mcp->mb[21] = MSW(MSD(mreq->send_dma)); | ||
3735 | |||
3736 | mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| | ||
3737 | MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; | ||
3738 | if (IS_QLA81XX(ha)) | ||
3739 | mcp->out_mb |= MBX_2; | ||
3740 | |||
3741 | mcp->in_mb = MBX_0; | ||
3742 | if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) | ||
3743 | mcp->in_mb |= MBX_1; | ||
3744 | if (IS_QLA81XX(ha)) | ||
3745 | mcp->in_mb |= MBX_3; | ||
3746 | |||
3747 | mcp->tov = MBX_TOV_SECONDS; | ||
3748 | mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; | ||
3749 | mcp->buf_size = mreq->transfer_size; | ||
3750 | |||
3751 | rval = qla2x00_mailbox_command(vha, mcp); | ||
3752 | |||
3753 | if (rval != QLA_SUCCESS) { | ||
3754 | DEBUG2(printk(KERN_WARNING | ||
3755 | "(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n", | ||
3756 | vha->host_no, rval, mcp->mb[0], mcp->mb[1])); | ||
3757 | } else { | ||
3758 | DEBUG2(printk(KERN_WARNING | ||
3759 | "scsi(%ld): done.\n", vha->host_no)); | ||
3760 | } | ||
3761 | |||
3762 | /* Copy mailbox information */ | ||
3763 | memcpy( mresp, mcp->mb, 32); | ||
3764 | return rval; | ||
3765 | } | ||
3766 | int | ||
3767 | qla84xx_reset_chip(scsi_qla_host_t *ha, uint16_t enable_diagnostic, | ||
3768 | uint16_t *cmd_status) | ||
3769 | { | ||
3770 | int rval; | ||
3771 | mbx_cmd_t mc; | ||
3772 | mbx_cmd_t *mcp = &mc; | ||
3773 | |||
3774 | DEBUG16(printk("%s(%ld): enable_diag=%d entered.\n", __func__, | ||
3775 | ha->host_no, enable_diagnostic)); | ||
3776 | |||
3777 | mcp->mb[0] = MBC_ISP84XX_RESET; | ||
3778 | mcp->mb[1] = enable_diagnostic; | ||
3779 | mcp->out_mb = MBX_1|MBX_0; | ||
3780 | mcp->in_mb = MBX_1|MBX_0; | ||
3781 | mcp->tov = MBX_TOV_SECONDS; | ||
3782 | mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; | ||
3783 | rval = qla2x00_mailbox_command(ha, mcp); | ||
3784 | |||
3785 | /* Return mailbox statuses. */ | ||
3786 | *cmd_status = mcp->mb[0]; | ||
3787 | if (rval != QLA_SUCCESS) | ||
3788 | DEBUG16(printk("%s(%ld): failed=%x.\n", __func__, ha->host_no, | ||
3789 | rval)); | ||
3790 | else | ||
3791 | DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
3792 | |||
3793 | return rval; | ||
3794 | } | ||
3795 | |||
3796 | int | ||
3588 | qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | 3797 | qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) |
3589 | { | 3798 | { |
3590 | int rval; | 3799 | int rval; |
@@ -3615,3 +3824,36 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | |||
3615 | 3824 | ||
3616 | return rval; | 3825 | return rval; |
3617 | } | 3826 | } |
3827 | |||
3828 | int | ||
3829 | qla2x00_get_data_rate(scsi_qla_host_t *vha) | ||
3830 | { | ||
3831 | int rval; | ||
3832 | mbx_cmd_t mc; | ||
3833 | mbx_cmd_t *mcp = &mc; | ||
3834 | struct qla_hw_data *ha = vha->hw; | ||
3835 | |||
3836 | if (!IS_FWI2_CAPABLE(ha)) | ||
3837 | return QLA_FUNCTION_FAILED; | ||
3838 | |||
3839 | DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
3840 | |||
3841 | mcp->mb[0] = MBC_DATA_RATE; | ||
3842 | mcp->mb[1] = 0; | ||
3843 | mcp->out_mb = MBX_1|MBX_0; | ||
3844 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
3845 | mcp->tov = MBX_TOV_SECONDS; | ||
3846 | mcp->flags = 0; | ||
3847 | rval = qla2x00_mailbox_command(vha, mcp); | ||
3848 | if (rval != QLA_SUCCESS) { | ||
3849 | DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n", | ||
3850 | __func__, vha->host_no, rval, mcp->mb[0])); | ||
3851 | } else { | ||
3852 | DEBUG11(printk(KERN_INFO | ||
3853 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
3854 | if (mcp->mb[1] != 0x7) | ||
3855 | ha->link_data_rate = mcp->mb[1]; | ||
3856 | } | ||
3857 | |||
3858 | return rval; | ||
3859 | } | ||