.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * QLogic Fibre Channel HBA Driver |
---|
3 | 4 | * Copyright (c) 2003-2014 QLogic Corporation |
---|
4 | | - * |
---|
5 | | - * See LICENSE.qla2xxx for copyright and licensing details. |
---|
6 | 5 | */ |
---|
7 | 6 | #include "qla_def.h" |
---|
8 | 7 | #include "qla_gbl.h" |
---|
.. | .. |
---|
66 | 65 | uint16_t vp_id; |
---|
67 | 66 | struct qla_hw_data *ha = vha->hw; |
---|
68 | 67 | unsigned long flags = 0; |
---|
| 68 | + u8 i; |
---|
69 | 69 | |
---|
70 | 70 | mutex_lock(&ha->vport_lock); |
---|
71 | 71 | /* |
---|
.. | .. |
---|
75 | 75 | * ensures no active vp_list traversal while the vport is removed |
---|
76 | 76 | * from the queue) |
---|
77 | 77 | */ |
---|
78 | | - wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count), |
---|
79 | | - 10*HZ); |
---|
| 78 | + for (i = 0; i < 10; i++) { |
---|
| 79 | + if (wait_event_timeout(vha->vref_waitq, |
---|
| 80 | + !atomic_read(&vha->vref_count), HZ) > 0) |
---|
| 81 | + break; |
---|
| 82 | + } |
---|
80 | 83 | |
---|
81 | 84 | spin_lock_irqsave(&ha->vport_slock, flags); |
---|
82 | 85 | if (atomic_read(&vha->vref_count)) { |
---|
.. | .. |
---|
143 | 146 | "Marking port dead, loop_id=0x%04x : %x.\n", |
---|
144 | 147 | fcport->loop_id, fcport->vha->vp_idx); |
---|
145 | 148 | |
---|
146 | | - qla2x00_mark_device_lost(vha, fcport, 0, 0); |
---|
| 149 | + qla2x00_mark_device_lost(vha, fcport, 0); |
---|
147 | 150 | qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); |
---|
148 | 151 | } |
---|
149 | 152 | } |
---|
.. | .. |
---|
163 | 166 | list_for_each_entry(fcport, &vha->vp_fcports, list) |
---|
164 | 167 | fcport->logout_on_delete = 0; |
---|
165 | 168 | |
---|
166 | | - qla2x00_mark_all_devices_lost(vha, 0); |
---|
| 169 | + qla2x00_mark_all_devices_lost(vha); |
---|
167 | 170 | |
---|
168 | 171 | /* Remove port id from vp target map */ |
---|
169 | 172 | spin_lock_irqsave(&vha->hw->hardware_lock, flags); |
---|
.. | .. |
---|
262 | 265 | spin_lock_irqsave(&ha->vport_slock, flags); |
---|
263 | 266 | list_for_each_entry(vha, &ha->vp_list, list) { |
---|
264 | 267 | if (vha->vp_idx) { |
---|
| 268 | + if (test_bit(VPORT_DELETE, &vha->dpc_flags)) |
---|
| 269 | + continue; |
---|
| 270 | + |
---|
265 | 271 | atomic_inc(&vha->vref_count); |
---|
266 | 272 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
---|
267 | 273 | |
---|
.. | .. |
---|
300 | 306 | int |
---|
301 | 307 | qla2x00_vp_abort_isp(scsi_qla_host_t *vha) |
---|
302 | 308 | { |
---|
| 309 | + fc_port_t *fcport; |
---|
| 310 | + |
---|
| 311 | + /* |
---|
| 312 | + * To exclusively reset vport, we need to log it out first. |
---|
| 313 | + * Note: This control_vp can fail if ISP reset is already |
---|
| 314 | + * issued, this is expected, as the vp would be already |
---|
| 315 | + * logged out due to ISP reset. |
---|
| 316 | + */ |
---|
| 317 | + if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) { |
---|
| 318 | + qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); |
---|
| 319 | + list_for_each_entry(fcport, &vha->vp_fcports, list) |
---|
| 320 | + fcport->logout_on_delete = 0; |
---|
| 321 | + } |
---|
| 322 | + |
---|
303 | 323 | /* |
---|
304 | 324 | * Physical port will do most of the abort and recovery work. We can |
---|
305 | 325 | * just treat it as a loop down |
---|
306 | 326 | */ |
---|
307 | 327 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
---|
308 | 328 | atomic_set(&vha->loop_state, LOOP_DOWN); |
---|
309 | | - qla2x00_mark_all_devices_lost(vha, 0); |
---|
| 329 | + qla2x00_mark_all_devices_lost(vha); |
---|
310 | 330 | } else { |
---|
311 | 331 | if (!atomic_read(&vha->loop_down_timer)) |
---|
312 | 332 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
---|
313 | 333 | } |
---|
314 | 334 | |
---|
315 | | - /* |
---|
316 | | - * To exclusively reset vport, we need to log it out first. Note: this |
---|
317 | | - * control_vp can fail if ISP reset is already issued, this is |
---|
318 | | - * expected, as the vp would be already logged out due to ISP reset. |
---|
319 | | - */ |
---|
320 | | - if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) |
---|
321 | | - qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); |
---|
322 | | - |
---|
323 | 335 | ql_dbg(ql_dbg_taskm, vha, 0x801d, |
---|
324 | 336 | "Scheduling enable of Vport %d.\n", vha->vp_idx); |
---|
| 337 | + |
---|
325 | 338 | return qla24xx_enable_vp(vha); |
---|
326 | 339 | } |
---|
327 | 340 | |
---|
.. | .. |
---|
344 | 357 | ql_dbg(ql_dbg_dpc, vha, 0x4015, |
---|
345 | 358 | "Configure VP end.\n"); |
---|
346 | 359 | return 0; |
---|
| 360 | + } |
---|
| 361 | + } |
---|
| 362 | + |
---|
| 363 | + if (test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags)) { |
---|
| 364 | + if (atomic_read(&vha->loop_state) == LOOP_READY) { |
---|
| 365 | + qla24xx_process_purex_list(&vha->purex_list); |
---|
| 366 | + clear_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags); |
---|
347 | 367 | } |
---|
348 | 368 | } |
---|
349 | 369 | |
---|
.. | .. |
---|
495 | 515 | vha->mgmt_svr_loop_id = qla2x00_reserve_mgmt_server_loop_id(vha); |
---|
496 | 516 | |
---|
497 | 517 | vha->dpc_flags = 0L; |
---|
| 518 | + ha->dpc_active = 0; |
---|
| 519 | + set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
---|
| 520 | + set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); |
---|
498 | 521 | |
---|
499 | 522 | /* |
---|
500 | 523 | * To fix the issue of processing a parent's RSCN for the vport before |
---|
.. | .. |
---|
507 | 530 | qla2x00_start_timer(vha, WATCH_INTERVAL); |
---|
508 | 531 | |
---|
509 | 532 | vha->req = base_vha->req; |
---|
| 533 | + vha->flags.nvme_enabled = base_vha->flags.nvme_enabled; |
---|
510 | 534 | host->can_queue = base_vha->req->length + 128; |
---|
511 | 535 | host->cmd_per_lun = 3; |
---|
512 | 536 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) |
---|
.. | .. |
---|
745 | 769 | req->req_q_in = ®->isp25mq.req_q_in; |
---|
746 | 770 | req->req_q_out = ®->isp25mq.req_q_out; |
---|
747 | 771 | req->max_q_depth = ha->req_q_map[0]->max_q_depth; |
---|
748 | | - req->out_ptr = (void *)(req->ring + req->length); |
---|
| 772 | + req->out_ptr = (uint16_t *)(req->ring + req->length); |
---|
749 | 773 | mutex_unlock(&ha->mq_lock); |
---|
750 | 774 | ql_dbg(ql_dbg_multiq, base_vha, 0xc004, |
---|
751 | 775 | "ring_ptr=%p ring_index=%d, " |
---|
.. | .. |
---|
783 | 807 | { |
---|
784 | 808 | unsigned long flags; |
---|
785 | 809 | struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work); |
---|
786 | | - struct scsi_qla_host *vha; |
---|
787 | | - struct qla_hw_data *ha = qpair->hw; |
---|
| 810 | + struct scsi_qla_host *vha = qpair->vha; |
---|
788 | 811 | |
---|
789 | 812 | spin_lock_irqsave(&qpair->qp_lock, flags); |
---|
790 | | - vha = pci_get_drvdata(ha->pdev); |
---|
791 | 813 | qla24xx_process_response_queue(vha, qpair->rsp); |
---|
792 | 814 | spin_unlock_irqrestore(&qpair->qp_lock, flags); |
---|
793 | 815 | |
---|
.. | .. |
---|
859 | 881 | reg = ISP_QUE_REG(ha, que_id); |
---|
860 | 882 | rsp->rsp_q_in = ®->isp25mq.rsp_q_in; |
---|
861 | 883 | rsp->rsp_q_out = ®->isp25mq.rsp_q_out; |
---|
862 | | - rsp->in_ptr = (void *)(rsp->ring + rsp->length); |
---|
| 884 | + rsp->in_ptr = (uint16_t *)(rsp->ring + rsp->length); |
---|
863 | 885 | mutex_unlock(&ha->mq_lock); |
---|
864 | 886 | ql_dbg(ql_dbg_multiq, base_vha, 0xc00b, |
---|
865 | 887 | "options=%x id=%d rsp_q_in=%p rsp_q_out=%p\n", |
---|
.. | .. |
---|
871 | 893 | rsp->rsp_q_out); |
---|
872 | 894 | |
---|
873 | 895 | ret = qla25xx_request_irq(ha, qpair, qpair->msix, |
---|
874 | | - QLA_MSIX_QPAIR_MULTIQ_RSP_Q); |
---|
| 896 | + ha->flags.disable_msix_handshake ? |
---|
| 897 | + QLA_MSIX_QPAIR_MULTIQ_RSP_Q : QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS); |
---|
875 | 898 | if (ret) |
---|
876 | 899 | goto que_failed; |
---|
877 | 900 | |
---|
.. | .. |
---|
900 | 923 | return 0; |
---|
901 | 924 | } |
---|
902 | 925 | |
---|
903 | | -static void qla_ctrlvp_sp_done(void *s, int res) |
---|
| 926 | +static void qla_ctrlvp_sp_done(srb_t *sp, int res) |
---|
904 | 927 | { |
---|
905 | | - struct srb *sp = s; |
---|
906 | | - |
---|
907 | | - complete(&sp->comp); |
---|
| 928 | + if (sp->comp) |
---|
| 929 | + complete(sp->comp); |
---|
908 | 930 | /* don't free sp here. Let the caller do the free */ |
---|
909 | 931 | } |
---|
910 | 932 | |
---|
.. | .. |
---|
921 | 943 | struct qla_hw_data *ha = vha->hw; |
---|
922 | 944 | int vp_index = vha->vp_idx; |
---|
923 | 945 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
---|
| 946 | + DECLARE_COMPLETION_ONSTACK(comp); |
---|
924 | 947 | srb_t *sp; |
---|
925 | 948 | |
---|
926 | 949 | ql_dbg(ql_dbg_vport, vha, 0x10c1, |
---|
.. | .. |
---|
935 | 958 | |
---|
936 | 959 | sp->type = SRB_CTRL_VP; |
---|
937 | 960 | sp->name = "ctrl_vp"; |
---|
| 961 | + sp->comp = ∁ |
---|
938 | 962 | sp->done = qla_ctrlvp_sp_done; |
---|
939 | 963 | sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; |
---|
940 | 964 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); |
---|
.. | .. |
---|
952 | 976 | ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", |
---|
953 | 977 | sp->name, sp->handle); |
---|
954 | 978 | |
---|
955 | | - wait_for_completion(&sp->comp); |
---|
| 979 | + wait_for_completion(&comp); |
---|
| 980 | + sp->comp = NULL; |
---|
| 981 | + |
---|
956 | 982 | rval = sp->rc; |
---|
957 | 983 | switch (rval) { |
---|
958 | 984 | case QLA_FUNCTION_TIMEOUT: |
---|