From 6ab30263a4c342ada7f1053c3c0b67751643fb13 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:21:41 +0000 Subject: [PATCH 01/44] qla2x00t-32gbit: Minimize diff with upstream git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8519 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 62c7224de..f3ab38bad 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -6819,7 +6819,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) */ ql_log(ql_log_warn, vha, 0xd03c, "corrupted fcp frame SID[%3phN] OXID[%04x] EXCG[%x] %64phN\n", - &pkt->u.isp24.fcp_hdr.s_id.domain, + &pkt->u.isp24.fcp_hdr.s_id, be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id), le32_to_cpu(pkt->u.isp24.exchange_addr), pkt); From 6f6114a7c011e268736812decc482f8fb22cbfef Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:26:01 +0000 Subject: [PATCH 02/44] qla2x00t-32gbit: Revert r8322 Since r8322 was the result of an incorrect application of an upstream patch, revert it. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8520 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index c7cb69138..998306a27 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -6110,6 +6110,8 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) qla2x00_delete_all_vps(ha, base_vha); + qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); + qla2x00_dfs_remove(base_vha); qla84xx_put_chip(base_vha); From b4b1569ed02653617a98c3fa4aeb22ec85a13a9c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:33:38 +0000 Subject: [PATCH 03/44] qla2x00t-32gbit: Remove unnecessary null check A null check before dma_pool_destroy is redundant, so remove it. This is detected by coccinelle. [ commit 0b3b6fe299c471e44ed8713b7a602882626e693f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8521 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 998306a27..89b6a728d 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4786,8 +4786,7 @@ qla2x00_mem_free(struct qla_hw_data *ha) } } - if (ha->dif_bundl_pool) - dma_pool_destroy(ha->dif_bundl_pool); + dma_pool_destroy(ha->dif_bundl_pool); ha->dif_bundl_pool = NULL; qlt_mem_free(ha); From a2c285efafd53745bb89215bc8c2202a34164c17 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:36:09 +0000 Subject: [PATCH 04/44] qla2x00t-32gbit: Replace vmalloc + memset with vzalloc Use vzalloc instead of using vmalloc to allocate memory and then zeroing it with memset. This simplifies the code. [ commit 56cc8fae5f7e9f38cb367754c52491ba1645d1bf upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8522 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index dec2699a1..e9c449ef5 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -382,7 +382,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, ha->optrom_region_size = size; ha->optrom_state = QLA_SREADING; - ha->optrom_buffer = vmalloc(ha->optrom_region_size); + ha->optrom_buffer = vzalloc(ha->optrom_region_size); if (ha->optrom_buffer == NULL) { ql_log(ql_log_warn, vha, 0x7062, "Unable to allocate memory for optrom retrieval " @@ -404,7 +404,6 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, "Reading flash region -- 0x%x/0x%x.\n", ha->optrom_region_start, ha->optrom_region_size); - memset(ha->optrom_buffer, 0, ha->optrom_region_size); ha->isp_ops->read_optrom(vha, ha->optrom_buffer, ha->optrom_region_start, ha->optrom_region_size); break; @@ -457,7 +456,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, ha->optrom_region_size = size; ha->optrom_state = QLA_SWRITING; - ha->optrom_buffer = vmalloc(ha->optrom_region_size); + ha->optrom_buffer = vzalloc(ha->optrom_region_size); if (ha->optrom_buffer == NULL) { ql_log(ql_log_warn, vha, 0x7066, "Unable to allocate memory for optrom update " @@ -472,7 +471,6 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, "Staging flash region write -- 0x%x/0x%x.\n", ha->optrom_region_start, ha->optrom_region_size); - memset(ha->optrom_buffer, 0, ha->optrom_region_size); break; case 3: if (ha->optrom_state != QLA_SWRITING) { From 566fb0424f69eae48542aa12be6c59137b6caec3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:37:24 +0000 Subject: [PATCH 05/44] qla2x00t-32gbit: Fix DMA unmap leak With debug kernel we see following wanings indicating memory leak. [28809.523959] WARNING: CPU: 3 PID: 6790 at lib/dma-debug.c:978 dma_debug_device_change+0x166/0x1d0 [28809.523964] pci 0000:0c:00.6: DMA-API: device driver has pending DMA allocations while released from device [count=5] [28809.523964] One of leaked entries details: [device address=0x00000002aefe4000] [size=8208 bytes] [mapped with DMA_BIDIRECTIONAL] [mapped as coherent] Fix this by unmapping DMA memory. [ commit 5d328de64d89400dcf9911125844d8adc0db697f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8523 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_bsg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index d7711091e..e262eedd2 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -380,6 +380,8 @@ qla2x00_process_els(struct bsg_job *bsg_job) dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); if (!req_sg_cnt) { + dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); rval = -ENOMEM; goto done_free_fcport; } @@ -387,6 +389,8 @@ qla2x00_process_els(struct bsg_job *bsg_job) rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); if (!rsp_sg_cnt) { + dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); rval = -ENOMEM; goto done_free_fcport; } From 5c1d76e9f334f75f493e31866fc0c22fe3183fb7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:39:35 +0000 Subject: [PATCH 06/44] qla2x00t-32gbit: Fix different size DMA Alloc/Unmap Fix the following complaint: qla2xxx 0000:05:00.0: DMA-API: device driver frees DMA memory with different size [device address=0x00000006198b0000] [map size=32784 bytes] [unmap size=8208 bytes] RIP: 0010:check_unmap+0x7a2/0x1750 Call Trace: debug_dma_free_coherent+0x1b5/0x2d5 dma_free_attrs+0x7f/0x140 qla24xx_sp_unmap+0x1e2/0x610 [qla2xxx] qla24xx_async_gnnft_done+0x9c6/0x17d0 [qla2xxx] qla2x00_do_work+0x514/0x2200 [qla2xxx] [ commit d376dbda187317d06d3a2d495b43a7983e4a3250 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8524 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 7d03d34a6..d6e4125bc 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -4144,7 +4144,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) rspsz, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt); + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz; if (!sp->u.iocb_cmd.u.ctarg.rsp) { ql_log(ql_log_warn, vha, 0xffff, "Failed to allocate ct_sns request.\n"); From 92c488d37f8de3d1fdfb69e45a700324d57cad90 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:40:40 +0000 Subject: [PATCH 07/44] qla2x00t-32gbit: Fix abort timeout race condition If an abort times out, the Abort IOCB completion and Abort timer can race against each other. This patch provides unique error code for timer path to allow proper cleanup. [ commit 0c6df59061b23c7a951836d23977be34e896d3da upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8525 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 + qla2x00t-32gbit/qla_init.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index f67e9dcbf..f3a6dad8d 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -4706,6 +4706,7 @@ struct secure_flash_update_block_pk { #define QLA_SUSPENDED 0x106 #define QLA_BUSY 0x107 #define QLA_ALREADY_REGISTERED 0x109 +#define QLA_OS_TIMER_EXPIRED 0x10a #define NVRAM_DELAY() udelay(10) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index b4ff4cf80..d27271ba9 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -98,9 +98,22 @@ static void qla24xx_abort_iocb_timeout(void *data) { srb_t *sp = data; struct srb_iocb *abt = &sp->u.iocb_cmd; + struct qla_qpair *qpair = sp->qpair; + u32 handle; + unsigned long flags; + + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { + /* removing the abort */ + if (qpair->req->outstanding_cmds[handle] == sp) { + qpair->req->outstanding_cmds[handle] = NULL; + break; + } + } + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); abt->u.abt.comp_status = CS_TIMEOUT; - sp->done(sp, QLA_FUNCTION_TIMEOUT); + sp->done(sp, QLA_OS_TIMER_EXPIRED); } static void qla24xx_abort_sp_done(void *ptr, int res) From e57539b76b17c63959edc140770712e29e5b70cc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:41:37 +0000 Subject: [PATCH 08/44] qla2x00t-32gbit: Use Correct index for Q-Pair array For target mode, the default number of Q-Pairs allowed to use is 2. If the number of Q-Pairs allocated is lower than the default Q-Pairs, then lower value should be the set as default. [ commit 178235f43ea142cf0f07dba67657494fcec21254 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8526 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index f3ab38bad..1fa63079a 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -6674,6 +6674,8 @@ qlt_enable_vha(struct scsi_qla_host *vha) if (vha->qlini_mode == QLA2XXX_INI_MODE_ENABLED) return; + if (ha->tgt.num_act_qpairs > ha->max_qpairs) + ha->tgt.num_act_qpairs = ha->max_qpairs; spin_lock_irqsave(&ha->hardware_lock, flags); tgt->tgt_stopped = 0; qlt_set_mode(vha); From 7c020b4dbdd5865e6e19766a4bff9c213d6fc0c2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:42:11 +0000 Subject: [PATCH 09/44] qla2x00t-32gbit: Skip FW dump on LOOP initialization error Firmware dump captured during LOOP Init error does not yield any significant information. This patch removes call to trigger firmware dump collection during Loop Initialization. [ commit 5e5402c147083786db2238302e25c44b7a7dc5e9 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8527 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 5d82d4433..fd52c5888 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -788,7 +788,6 @@ skip_rio: case MBA_LOOP_INIT_ERR: ql_log(ql_log_warn, vha, 0x5090, "LOOP INIT ERROR (%x).\n", mb[1]); - ha->isp_ops->fw_dump(vha, 1); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); break; From 591d4d7319480ed913aa621a6fe6ce7f6c7081a5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:42:45 +0000 Subject: [PATCH 10/44] qla2x00t-32gbit: Reject EH_{abort|device_reset|target_request} Reject eh_{abort|device_reset|target_reset} when rport is being torn down or chip is down. [ commit 7f4374e67b3046c9628cf0ab93a117704a38e95d upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8528 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 89b6a728d..fe1b59019 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1468,6 +1468,9 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, if (err != 0) return err; + if (fcport->deleted) + return SUCCESS; + ql_log(ql_log_info, vha, 0x8009, "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no, cmd->device->id, (u64)cmd->device->lun, cmd); @@ -1582,6 +1585,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) return ret; ret = FAILED; + if (qla2x00_chip_is_down(vha)) + return ret; + ql_log(ql_log_info, vha, 0x8012, "BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun); From 9bb911c130cc3c41631df79bcbfdc0ae0fef2852 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:47:58 +0000 Subject: [PATCH 11/44] qla2x00t-32gbit: Fix Relogin to prevent modifying scan_state flag Relogin fails to move forward due to scan_state flag indicating device is not there. Before relogin process, Session delete process accidently modified the scan_state flag. [ commit 8b5292bcfcacf15182a77a973a98d310e76fd58b upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8529 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 25 ++++++++++++++++++++----- qla2x00t-32gbit/qla_os.c | 1 + qla2x00t-32gbit/qla_target.c | 1 - 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index d27271ba9..13c9798f8 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -298,8 +298,13 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED; - if (!vha->flags.online) - goto done; + if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) || + fcport->loop_id == FC_NO_LOOP_ID) { + ql_log(ql_log_warn, vha, 0xffff, + "%s: %8phC - not sending command.\n", + __func__, fcport->port_name); + return rval; + } sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) @@ -1273,8 +1278,13 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) struct port_database_24xx *pd; struct qla_hw_data *ha = vha->hw; - if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) + if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) || + fcport->loop_id == FC_NO_LOOP_ID) { + ql_log(ql_log_warn, vha, 0xffff, + "%s: %8phC - not sending command.\n", + __func__, fcport->port_name); return rval; + } fcport->disc_state = DSC_GPDB; @@ -1961,8 +1971,11 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) return; } - if (fcport->disc_state == DSC_DELETE_PEND) + if ((fcport->disc_state == DSC_DELETE_PEND) || + (fcport->disc_state == DSC_DELETED)) { + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); return; + } if (ea->sp->gen2 != fcport->login_gen) { /* target side must have changed it. */ @@ -6706,8 +6719,10 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) } /* Clear all async request states across all VPs. */ - list_for_each_entry(fcport, &vha->vp_fcports, list) + list_for_each_entry(fcport, &vha->vp_fcports, list) { fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); + fcport->scan_state = 0; + } spin_lock_irqsave(&ha->vport_slock, flags); list_for_each_entry(vp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index fe1b59019..1e98e50ce 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5143,6 +5143,7 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) if (fcport) { fcport->id_changed = 1; fcport->scan_state = QLA_FCPORT_FOUND; + fcport->chip_reset = vha->hw->base_qpair->chip_reset; memcpy(fcport->node_name, e->u.new_sess.node_name, WWN_SIZE); if (pla) { diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 1fa63079a..d9fef9e72 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1224,7 +1224,6 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess) sess->logout_on_delete = 0; sess->logo_ack_needed = 0; sess->fw_login_state = DSC_LS_PORT_UNAVAIL; - sess->scan_state = 0; } } From 4107c7164f089a79fb491c26cc9026772e3b7095 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:50:09 +0000 Subject: [PATCH 12/44] qla2x00t-32gbit: Fix premature timer expiration For any qla2xxx async command, the SRB buffer is used to send it. In setting up the SRB buffer, the timer for this command is started before all memory allocation has finished. Under low memory pressure, memory alloc can go to sleep and not wake up before the timer expires. Once timer has expired, the timer thread will access uninitialize fields resulting into NULL pointer crash. This patch fixes this crash by moving the start of timer after everything is setup. backtrace shows following PID: 3720 TASK: ffff996928401040 CPU: 0 COMMAND: "qla2xxx_1_dpc" 0 [ffff99652751b698] __schedule at ffffffff965676c7 1 [ffff99652751b728] schedule at ffffffff96567bc9 2 [ffff99652751b738] schedule_timeout at ffffffff965655e8 3 [ffff99652751b7e0] io_schedule_timeout at ffffffff9656726d 4 [ffff99652751b810] congestion_wait at ffffffff95fd8d12 5 [ffff99652751b870] isolate_migratepages_range at ffffffff95fddaf3 6 [ffff99652751b930] compact_zone at ffffffff95fdde96 7 [ffff99652751b980] compact_zone_order at ffffffff95fde0bc 8 [ffff99652751ba20] try_to_compact_pages at ffffffff95fde481 9 [ffff99652751ba80] __alloc_pages_direct_compact at ffffffff9655cc31 10 [ffff99652751bae0] __alloc_pages_slowpath at ffffffff9655d101 11 [ffff99652751bbd0] __alloc_pages_nodemask at ffffffff95fc0e95 12 [ffff99652751bc80] dma_generic_alloc_coherent at ffffffff95e3217f 13 [ffff99652751bcc8] x86_swiotlb_alloc_coherent at ffffffff95e6b7a1 14 [ffff99652751bcf8] qla2x00_rft_id at ffffffffc055b5e0 [qla2xxx] 15 [ffff99652751bd50] qla2x00_loop_resync at ffffffffc0533e71 [qla2xxx] 16 [ffff99652751be68] qla2x00_do_dpc at ffffffffc05210ca [qla2xxx] PID: 0 TASK: ffffffff96a18480 CPU: 0 COMMAND: "swapper/0" 0 [ffff99652fc03ae0] machine_kexec at ffffffff95e63674 1 [ffff99652fc03b40] __crash_kexec at ffffffff95f1ce12 2 [ffff99652fc03c10] crash_kexec at ffffffff95f1cf00 3 [ffff99652fc03c28] oops_end at ffffffff9656c758 4 [ffff99652fc03c50] no_context at ffffffff9655aa7e 5 [ffff99652fc03ca0] __bad_area_nosemaphore at ffffffff9655ab15 6 [ffff99652fc03cf0] bad_area_nosemaphore at ffffffff9655ac86 7 [ffff99652fc03d00] __do_page_fault at ffffffff9656f6b0 8 [ffff99652fc03d70] do_page_fault at ffffffff9656f915 9 [ffff99652fc03da0] page_fault at ffffffff9656b758 [exception RIP: unknown or invalid address] RIP: 0000000000000000 RSP: ffff99652fc03e50 RFLAGS: 00010202 RAX: 0000000000000000 RBX: ffff99652b79a600 RCX: ffff99652b79a760 RDX: ffff99652b79a600 RSI: ffffffffc0525ad0 RDI: ffff99652b79a600 RBP: ffff99652fc03e60 R8: ffffffff96a18a18 R9: ffffffff96ee3c00 R10: 0000000000000002 R11: ffff99652fc03de8 R12: ffff99652b79a760 R13: 0000000000000100 R14: ffffffffc0525ad0 R15: ffff99652b79a600 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 10 [ffff99652fc03e50] qla2x00_sp_timeout at ffffffffc0525af8 [qla2xxx] 11 [ffff99652fc03e68] call_timer_fn at ffffffff95ea7f58 12 [ffff99652fc03ea0] run_timer_softirq at ffffffff95eaa3bd 13 [ffff99652fc03f18] __do_softirq at ffffffff95ea0f05 14 [ffff99652fc03f88] call_softirq at ffffffff9657832c 15 [ffff99652fc03fa0] do_softirq at ffffffff95e2e675 16 [ffff99652fc03fc0] irq_exit at ffffffff95ea1285 17 [ffff99652fc03fd8] smp_apic_timer_interrupt at ffffffff965796c8 18 [ffff99652fc03ff0] apic_timer_interrupt at ffffffff96575df2 [ commit 3a4b6cc7332130ac5cbf3b505d8cddf0aa2ea745 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8530 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 + qla2x00t-32gbit/qla_iocb.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index f3a6dad8d..8f3d31dff 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -610,6 +610,7 @@ typedef struct srb { wait_queue_head_t nvme_ls_waitq; struct fc_port *fcport; struct scsi_qla_host *vha; + unsigned int start_timer:1; uint32_t handle; uint16_t flags; uint16_t type; diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 468827f07..3e7ada018 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2547,7 +2547,7 @@ void qla2x00_init_timer(srb_t *sp, unsigned long tmo) sp->free = qla2x00_sp_free; if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD) init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp); - add_timer(&sp->u.iocb_cmd.timer); + sp->start_timer = 1; } static void @@ -3683,6 +3683,9 @@ qla2x00_start_sp(srb_t *sp) break; } + if (sp->start_timer) + add_timer(&sp->u.iocb_cmd.timer); + wmb(); qla2x00_start_iocbs(vha, qp->req); done: From 3991bf033b52970406f27cdd07f65082c24c1b97 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:51:03 +0000 Subject: [PATCH 13/44] qla2x00t-32gbit: Retry fabric Scan on IOCB queue full when fabric scan thread encounters IOCB Q Full, schedule a delayed work to retry fabric scan. [ commit f0cecc1eec0c24e790a4daac71858f1f14e6f7b5 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8531 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index d6e4125bc..10c1e769c 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -4045,9 +4045,6 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { - spin_lock_irqsave(&vha->work_lock, flags); - vha->scan.scan_flags &= ~SF_SCANNING; - spin_unlock_irqrestore(&vha->work_lock, flags); goto done_free_sp; } @@ -4071,6 +4068,17 @@ done_free_sp: sp->free(sp); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; + if (vha->scan.scan_flags == 0) { + ql_dbg(ql_dbg_disc, vha, 0xffff, + "%s: schedule\n", __func__); + vha->scan.scan_flags |= SF_QUEUED; + schedule_delayed_work(&vha->scan.scan_work, 5); + } + spin_unlock_irqrestore(&vha->work_lock, flags); + + return rval; } /* GNNFT */ @@ -4200,9 +4208,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { - spin_lock_irqsave(&vha->work_lock, flags); - vha->scan.scan_flags &= ~SF_SCANNING; - spin_unlock_irqrestore(&vha->work_lock, flags); goto done_free_sp; } @@ -4226,6 +4231,17 @@ done_free_sp: sp->free(sp); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; + if (vha->scan.scan_flags == 0) { + ql_dbg(ql_dbg_disc, vha, 0xffff, + "%s: schedule\n", __func__); + vha->scan.scan_flags |= SF_QUEUED; + schedule_delayed_work(&vha->scan.scan_work, 5); + } + spin_unlock_irqrestore(&vha->work_lock, flags); + + return rval; } From b29d9e15c4da7acbc23799496c9ffcdd33742ba0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:52:23 +0000 Subject: [PATCH 14/44] qla2x00t-32gbit: Correct error handling during initialization failures Current code misses or fails to account for proper recovery during early initialization failures: - Properly unwind allocations during probe() failures. - Protect against non-initialization memory allocations during unwinding. - Propagate error status during HW initialization. - Release SCSI host reference when memory allocations fail. [ commit 26a77799195f4ff105f877042012c7fb355b3da1 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8532 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 4 ++++ qla2x00t-32gbit/qla_os.c | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 13c9798f8..1a4db55f0 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -2287,6 +2287,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha)) rval = qla2x00_init_rings(vha); + /* No point in continuing if firmware initialization failed. */ + if (rval != QLA_SUCCESS) + return rval; + ha->flags.chip_reset_done = 1; if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) { diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 1e98e50ce..96d331e5e 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1854,8 +1854,13 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) int que; struct qla_hw_data *ha = vha->hw; + /* Continue only if initialization complete. */ + if (!ha->base_qpair) + return; __qla2x00_abort_all_cmds(ha->base_qpair, res); + if (!ha->queue_pair_map) + return; for (que = 0; que < ha->max_qpairs; que++) { if (!ha->queue_pair_map[que]) continue; @@ -3212,6 +3217,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql_log(ql_log_fatal, base_vha, 0x003d, "Failed to allocate memory for queue pointers..." "aborting.\n"); + ret = -ENODEV; goto probe_failed; } @@ -4769,7 +4775,7 @@ qla2x00_mem_free(struct qla_hw_data *ha) mempool_destroy(ha->ctx_mempool); ha->ctx_mempool = NULL; - if (ql2xenabledif) { + if (ql2xenabledif && ha->dif_bundl_pool) { struct dsd_dma *dsd, *nxt; list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head, @@ -4864,7 +4870,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, if (!vha->gnl.l) { ql_log(ql_log_fatal, vha, 0xd04a, "Alloc failed for name list.\n"); - scsi_remove_host(vha->host); + scsi_host_put(vha->host); return NULL; } @@ -4876,7 +4882,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, "Alloc failed for scan database.\n"); dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, vha->gnl.ldma); - scsi_remove_host(vha->host); + scsi_host_put(vha->host); return NULL; } INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); From 89d0b88f67ab6b1eb5fe858c7c3d01812362dc7a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:54:46 +0000 Subject: [PATCH 15/44] qla2x00t-32gbit: Fix NVMe port discovery after a short device port loss The following sequence of event leads to NVME port disappearing: - device port shut - nvme_fc_unregister_remoteport - device port online - remote port delete completes - relogin is scheduled - "post gidpn" message appears due to rscn generation # mismatch In short, if a device comes back online sooner than an unregister completion, a mismatch in rscn generation number occurs, which is not handled correctly during device relogin. Fix this by starting with a redo of GNL. When ql2xextended_error_logging is enabled, the re-plugged device's discovery stops with the following messages printed: --8<-- qla2xxx [0000:41:00.0]-480d:3: Relogin scheduled. qla2xxx [0000:41:00.0]-4800:3: DPC handler sleeping. qla2xxx [0000:41:00.0]-2902:3: qla24xx_handle_relogin_event 21:00:00:24:ff:17:9e:91 DS 0 LS 7 P 0 del 2 cnfl (null) rscn 1|2 login 1|2 fl 1 qla2xxx [0000:41:00.0]-28e9:3: qla24xx_handle_relogin_event 1666 21:00:00:24:ff:17:9e:91 post gidpn qla2xxx [0000:41:00.0]-480e:3: Relogin end. --8<-- [ commit 9e744591ef1b8df27c25c68dac858dada8688f77 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8533 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 1a4db55f0..dd2c5427c 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1686,6 +1686,7 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %s post gidpn\n", __func__, __LINE__, wwn_to_str(fcport->port_name)); + qla24xx_post_gnl_work(vha, fcport); return; } From 21dc61fb60b4565b5aec9e27bfc3e93b05ad87c3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:55:29 +0000 Subject: [PATCH 16/44] qla2x00t-32gbit: Use common update-firmware-options routine for ISP27xx+ Leverage the generic routine, qla24xx_update_fw_options(), for the configuration of firmware options for ISP27xx/ISP28xx. [ commit a36f1443e6fc738c1bcfc4be80d6f1609163c614 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8534 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 96d331e5e..cceb4ef6d 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -2462,7 +2462,7 @@ static struct isp_operations qla83xx_isp_ops = { .config_rings = qla24xx_config_rings, .reset_adapter = qla24xx_reset_adapter, .nvram_config = qla81xx_nvram_config, - .update_fw_options = qla81xx_update_fw_options, + .update_fw_options = qla24xx_update_fw_options, .load_risc = qla81xx_load_risc, .pci_info_str = qla24xx_pci_info_str, .fw_version_str = qla24xx_fw_version_str, From aa2356632e3efd2da5dffc3bfa7ae430487603fa Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:57:50 +0000 Subject: [PATCH 17/44] qla2x00t-32gbit: Allow NVMe IO to resume with short cable pull Current driver report dev_loss_tmo to 0 for NVMe devices with short cable pull. This causes NVMe controller to be freed along with NVMe namespace. The side affect is IO would stop. By not setting dev_loss_tmo to 0, NVMe namespace would stay until cable is plugged back in. This allows IO to resume afterward. [ commit 03cc44bf682af289d6536eb911e928b415bd0e1f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8535 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index aaca5ca1e..e4ba0381a 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -664,7 +664,8 @@ void qla_nvme_unregister_remote_port(struct fc_port *fcport) __func__, fcport, fcport->port_name); #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) - nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0); + if (test_bit(PFLG_DRIVER_REMOVING, &fcport->vha->pci_flags)) + nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0); #endif init_completion(&fcport->nvme_del_done); ret = nvme_fc_unregister_remoteport(fcport->nvme_remote_port); From 5c7951c8d94938d60a33196c3c9b96af677def64 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:58:24 +0000 Subject: [PATCH 18/44] qla2x00t-32gbit: Update driver version to 10.01.00.18-k [ commit 4d0b32b853f52760bf70288f2751d2ca86581352 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8536 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index cd6bdf71e..0833546a1 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.01.00.16-k" +#define QLA2XXX_VERSION "10.01.00.18-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 1 From 5499f34f2294cc8450aff7297c1688b961d46f48 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 01:59:09 +0000 Subject: [PATCH 19/44] qla2x00t-32gbit: Make qla2x00_abort_srb() again decrease the sp reference count Since qla2x00_abort_srb() starts with increasing the reference count of @sp, decrease that same reference count before returning. [ commit d2d2b5a5741d317bed1fa38211f1f3b142d8cf7a upstram ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8537 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index cceb4ef6d..0736e5dbf 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1800,6 +1800,8 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, spin_lock_irqsave(qp->qp_lock_ptr, *flags); sp->comp = NULL; } + + atomic_dec(&sp->ref_count); } static void From 9bfb9931eefe9839c4b5d9ad43feab44e55dcfd7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:04:12 +0000 Subject: [PATCH 20/44] qla2x00t-32gbit: Really fix qla2xxx_eh_abort() I'm not sure how this happened but the patch that was intended to fix abort handling was incomplete. This patch fixes that patch as follows: - If aborting the SCSI command failed, wait until the SCSI command completes. - Return SUCCESS instead of FAILED if an abort attempt races with SCSI command completion. - Since qla2xxx_eh_abort() increments the sp reference count by calling sp_get(), decrement the sp reference count before returning. Fixes: 1b4ae64d8da6 ("qla2xxx: Fix a race condition between aborting and completing a SCSI command") [ commit 8dd9593cc07ad7d999bef81b06789ef873a94881 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8538 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 0736e5dbf..b8f014f59 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1355,7 +1355,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", vha->host_no, id, lun, sp, cmd, sp->handle); - ret = SUCCESS; rval = ha->isp_ops->abort_command(sp); ql_dbg(ql_dbg_taskm, vha, 0x8003, "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); @@ -1367,9 +1366,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) * won't report a completion. */ sp->done(sp, DID_ABORT << 16); + ret = SUCCESS; break; - case QLA_FUNCTION_PARAMETER_ERROR: - default: { + case QLA_FUNCTION_PARAMETER_ERROR: { /* Wait for the command completion. */ uint32_t ratov = ha->r_a_tov/10; uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000); @@ -1380,10 +1379,18 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", __func__, ha->r_a_tov); ret = FAILED; - break; + } else { + ret = SUCCESS; } break; } + default: + /* + * Either abort failed or abort and completion raced. Let + * the SCSI core retry the abort in the former case. + */ + ret = FAILED; + break; } sp->comp = NULL; From 12ca81c33895a35cd293ee70f5b122543060d3f6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:09:18 +0000 Subject: [PATCH 21/44] qla2x00t-32gbit: Fix up a misapplied patch Not sure why 'patch' misapplied a patch ... git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8539 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index b8f014f59..02847b795 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -2471,7 +2471,7 @@ static struct isp_operations qla83xx_isp_ops = { .config_rings = qla24xx_config_rings, .reset_adapter = qla24xx_reset_adapter, .nvram_config = qla81xx_nvram_config, - .update_fw_options = qla24xx_update_fw_options, + .update_fw_options = qla81xx_update_fw_options, .load_risc = qla81xx_load_risc, .pci_info_str = qla24xx_pci_info_str, .fw_version_str = qla24xx_fw_version_str, @@ -2549,7 +2549,7 @@ static struct isp_operations qla27xx_isp_ops = { .config_rings = qla24xx_config_rings, .reset_adapter = qla24xx_reset_adapter, .nvram_config = qla81xx_nvram_config, - .update_fw_options = qla81xx_update_fw_options, + .update_fw_options = qla24xx_update_fw_options, .load_risc = qla81xx_load_risc, .pci_info_str = qla24xx_pci_info_str, .fw_version_str = qla24xx_fw_version_str, From 0ff3d58d02ffe9cca9eee4147ba3ee6e0763e4ef Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:14:43 +0000 Subject: [PATCH 22/44] qla2x00t-32gbit: Use tabs instead of spaces for indentation This patch only modifies whitespace. [ commit 0184793df2e860534380a66aa76b8807e71188c2 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8540 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 76 ++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 10c1e769c..2ad495f1a 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3459,54 +3459,54 @@ done: void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea) { - fc_port_t *fcport = ea->fcport; + fc_port_t *fcport = ea->fcport; - qla24xx_post_gnl_work(vha, fcport); + qla24xx_post_gnl_work(vha, fcport); } void qla24xx_async_gffid_sp_done(void *s, int res) { - struct srb *sp = s; - struct scsi_qla_host *vha = sp->vha; - fc_port_t *fcport = sp->fcport; - struct ct_sns_rsp *ct_rsp; - struct event_arg ea; + struct srb *sp = s; + struct scsi_qla_host *vha = sp->vha; + fc_port_t *fcport = sp->fcport; + struct ct_sns_rsp *ct_rsp; + struct event_arg ea; - ql_dbg(ql_dbg_disc, vha, 0x2133, - "Async done-%s res %x ID %x. %s\n", - sp->name, res, fcport->d_id.b24, wwn_to_str(fcport->port_name)); + ql_dbg(ql_dbg_disc, vha, 0x2133, + "Async done-%s res %x ID %x. %s\n", + sp->name, res, fcport->d_id.b24, wwn_to_str(fcport->port_name)); - fcport->flags &= ~FCF_ASYNC_SENT; - ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; - /* - * FC-GS-7, 5.2.3.12 FC-4 Features - format - * The format of the FC-4 Features object, as defined by the FC-4, - * Shall be an array of 4-bit values, one for each type code value - */ - if (!res) { - if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { - /* w1 b00:03 */ - fcport->fc4_type = - ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; - fcport->fc4_type &= 0xf; - } + fcport->flags &= ~FCF_ASYNC_SENT; + ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; + /* + * FC-GS-7, 5.2.3.12 FC-4 Features - format + * The format of the FC-4 Features object, as defined by the FC-4, + * Shall be an array of 4-bit values, one for each type code value + */ + if (!res) { + if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { + /* w1 b00:03 */ + fcport->fc4_type = + ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; + fcport->fc4_type &= 0xf; + } - if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { - /* w5 [00:03]/28h */ - fcport->fc4f_nvme = - ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; - fcport->fc4f_nvme &= 0xf; - } - } + if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { + /* w5 [00:03]/28h */ + fcport->fc4f_nvme = + ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; + fcport->fc4f_nvme &= 0xf; + } + } - memset(&ea, 0, sizeof(ea)); - ea.sp = sp; - ea.fcport = sp->fcport; - ea.rc = res; - ea.event = FCME_GFFID_DONE; + memset(&ea, 0, sizeof(ea)); + ea.sp = sp; + ea.fcport = sp->fcport; + ea.rc = res; + ea.event = FCME_GFFID_DONE; - qla2x00_fcport_event_handler(vha, &ea); - sp->free(sp); + qla2x00_fcport_event_handler(vha, &ea); + sp->free(sp); } /* Get FC4 Feature with Nport ID. */ From 6ee78e839e3d0b328bdae994b4789bc49d46291f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:20:58 +0000 Subject: [PATCH 23/44] qla2x00t-32gbit: Suppress a recently introduced kernel warning Fixes: 6ab417a5ef05 ("qla2x00t-32gbit: Always check the qla2x00_wait_for_hba_online() return value"). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8541 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index d9fef9e72..ac65b860c 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -6721,7 +6721,9 @@ static void qlt_disable_vha(struct scsi_qla_host *vha) set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); - WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS); + if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) + ql_dbg(ql_dbg_tgt, vha, 0xe081, + "qla2x00_wait_for_hba_online() failed\n"); } /* From 790661121f4939b243e37850d921e79046d12084 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:25:18 +0000 Subject: [PATCH 24/44] qla2x00t-32gbit: Use strlcpy() instead of strncpy() [ commit cc74049f35e8 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8542 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_mr.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index 3dde54c16..fec197a6f 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -1889,22 +1889,22 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) phost_info = &preg_hsi->hsi; memset(preg_hsi, 0, sizeof(struct register_host_info)); phost_info->os_type = OS_TYPE_LINUX; - strlcpy(phost_info->sysname, - p_sysid->sysname, SYSNAME_LENGTH); - strlcpy(phost_info->nodename, - p_sysid->nodename, NODENAME_LENGTH); + strlcpy(phost_info->sysname, p_sysid->sysname, + sizeof(phost_info->sysname)); + strlcpy(phost_info->nodename, p_sysid->nodename, + sizeof(phost_info->nodename)); if (!strcmp(phost_info->nodename, "(none)")) ha->mr.host_info_resend = true; - strlcpy(phost_info->release, - p_sysid->release, RELEASE_LENGTH); - strlcpy(phost_info->version, - p_sysid->version, VERSION_LENGTH); - strlcpy(phost_info->machine, - p_sysid->machine, MACHINE_LENGTH); - strlcpy(phost_info->domainname, - p_sysid->domainname, DOMNAME_LENGTH); - strlcpy(phost_info->hostdriver, - QLA2XXX_VERSION, VERSION_LENGTH); + strlcpy(phost_info->release, p_sysid->release, + sizeof(phost_info->release)); + strlcpy(phost_info->version, p_sysid->version, + sizeof(phost_info->version)); + strlcpy(phost_info->machine, p_sysid->machine, + sizeof(phost_info->machine)); + strlcpy(phost_info->domainname, p_sysid->domainname, + sizeof(phost_info->domainname)); + strlcpy(phost_info->hostdriver, QLA2XXX_VERSION, + sizeof(phost_info->hostdriver)); preg_hsi->utc = (uint64_t)ktime_get_real_seconds(); ql_dbg(ql_dbg_init, vha, 0x0149, "ISP%04X: Host registration with firmware\n", From dc61adfa3a121e6f81cae1afe3f026812d1b812d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:31:44 +0000 Subject: [PATCH 25/44] qla2x00t-32gbit: Use be_id_t etc. in more code [ commit df95f39ae76474d922d9be9c0260dc263c451b09 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8543 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 12 +++---- qla2x00t-32gbit/qla_gs.c | 74 ++++++++++++--------------------------- 2 files changed, 29 insertions(+), 57 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 8f3d31dff..12b319d9e 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2824,7 +2824,7 @@ struct ct_sns_req { /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */ struct { uint8_t reserved; - uint8_t port_id[3]; + be_id_t port_id; } port_id; struct { @@ -2843,13 +2843,13 @@ struct ct_sns_req { struct { uint8_t reserved; - uint8_t port_id[3]; + be_id_t port_id; uint8_t fc4_types[32]; } rft_id; struct { uint8_t reserved; - uint8_t port_id[3]; + be_id_t port_id; uint16_t reserved2; uint8_t fc4_feature; uint8_t fc4_type; @@ -2857,7 +2857,7 @@ struct ct_sns_req { struct { uint8_t reserved; - uint8_t port_id[3]; + be_id_t port_id; uint8_t node_name[8]; } rnn_id; @@ -2944,7 +2944,7 @@ struct ct_rsp_hdr { struct ct_sns_gid_pt_data { uint8_t control_byte; - uint8_t port_id[3]; + be_id_t port_id; }; /* It's the same for both GPN_FT and GNN_FT */ @@ -2974,7 +2974,7 @@ struct ct_sns_rsp { union { struct { uint8_t port_type; - uint8_t port_id[3]; + be_id_t port_id; uint8_t port_name[8]; uint8_t sym_port_name_len; uint8_t sym_port_name[255]; diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 2ad495f1a..7f1d43ce1 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -226,9 +226,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id */ - ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; - ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; - ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, @@ -242,9 +240,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) rval = QLA_FUNCTION_FAILED; } else { /* Populate fc_port_t entry. */ - fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; - fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; - fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; + fcport->d_id = be_to_port_id(ct_rsp->rsp.ga_nxt.port_id); memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, WWN_SIZE); @@ -337,9 +333,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) /* Set port IDs in switch info list. */ for (i = 0; i < ha->max_fibre_devices; i++) { gid_data = &ct_rsp->rsp.gid_pt.entries[i]; - list[i].d_id.b.domain = gid_data->port_id[0]; - list[i].d_id.b.area = gid_data->port_id[1]; - list[i].d_id.b.al_pa = gid_data->port_id[2]; + list[i].d_id = be_to_port_id(gid_data->port_id); memset(list[i].fabric_port_name, 0, WWN_SIZE); list[i].fp_speed = PORT_SPEED_UNKNOWN; @@ -403,9 +397,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id */ - ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; - ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; - ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, @@ -472,9 +464,7 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id */ - ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; - ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; - ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, @@ -639,9 +629,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id) ct_req = qla2x00_prep_ct_req(ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE); /* Prepare CT arguments -- port_id, FC-4 types */ - ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain; - ct_req->req.rft_id.port_id[1] = vha->d_id.b.area; - ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa; + ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id); ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ if (vha->flags.nvme_enabled) @@ -737,9 +725,7 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id, ct_req = qla2x00_prep_ct_req(ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE); /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ - ct_req->req.rff_id.port_id[0] = d_id->b.domain; - ct_req->req.rff_id.port_id[1] = d_id->b.area; - ct_req->req.rff_id.port_id[2] = d_id->b.al_pa; + ct_req->req.rff_id.port_id = port_id_to_be_id(*d_id); ct_req->req.rff_id.fc4_feature = fc4feature; ct_req->req.rff_id.fc4_type = fc4type; /* SCSI - FCP */ @@ -830,9 +816,7 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id, ct_req = qla2x00_prep_ct_req(ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE); /* Prepare CT arguments -- port_id, node_name */ - ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain; - ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area; - ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa; + ct_req->req.rnn_id.port_id = port_id_to_be_id(vha->d_id); memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE); sp->u.iocb_cmd.u.ctarg.req_size = RNN_ID_REQ_SIZE; @@ -2728,9 +2712,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list) ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id */ - ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; - ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; - ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, @@ -2934,9 +2916,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id */ - ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; - ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; - ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, @@ -3283,25 +3263,23 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res) ql_dbg(ql_dbg_disc, vha, 0x2066, "Async done-%s fail res %x rscn gen %d ID %02x:%02x:%02x. %s\n", sp->name, res, sp->gen1, - ct_req->req.port_id.port_id[0], - ct_req->req.port_id.port_id[1], - ct_req->req.port_id.port_id[2], + ct_req->req.port_id.port_id.domain, + ct_req->req.port_id.port_id.area, + ct_req->req.port_id.port_id.al_pa, wwn_to_str(ct_rsp->rsp.gpn_id.port_name)); else ql_dbg(ql_dbg_disc, vha, 0x2066, "Async done-%s good rscn gen %d ID %02x:%02x:%02x. %s\n", sp->name, sp->gen1, - ct_req->req.port_id.port_id[0], - ct_req->req.port_id.port_id[1], - ct_req->req.port_id.port_id[2], + ct_req->req.port_id.port_id.domain, + ct_req->req.port_id.port_id.area, + ct_req->req.port_id.port_id.al_pa, wwn_to_str(ct_rsp->rsp.gpn_id.port_name)); memset(&ea, 0, sizeof(ea)); memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); ea.sp = sp; - ea.id.b.domain = ct_req->req.port_id.port_id[0]; - ea.id.b.area = ct_req->req.port_id.port_id[1]; - ea.id.b.al_pa = ct_req->req.port_id.port_id[2]; + ea.id = be_to_port_id(ct_req->req.port_id.port_id); ea.rc = res; ea.event = FCME_GPNID_DONE; @@ -3409,9 +3387,7 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE); /* GPN_ID req */ - ct_req->req.port_id.port_id[0] = id->b.domain; - ct_req->req.port_id.port_id[1] = id->b.area; - ct_req->req.port_id.port_id[2] = id->b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(*id); sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE; sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE; @@ -3422,9 +3398,9 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) ql_dbg(ql_dbg_disc, vha, 0x2067, "Async-%s hdl=%x ID %02x:%02x:%02x.\n", sp->name, sp->handle, - ct_req->req.port_id.port_id[0], - ct_req->req.port_id.port_id[1], - ct_req->req.port_id.port_id[2]); + ct_req->req.port_id.port_id.domain, + ct_req->req.port_id.port_id.area, + ct_req->req.port_id.port_id.al_pa); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) @@ -4327,9 +4303,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) GNN_ID_RSP_SIZE); /* GNN_ID req */ - ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; - ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; - ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id); /* req & rsp use the same buffer */ @@ -4460,9 +4434,7 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) GFPN_ID_RSP_SIZE); /* GFPN_ID req */ - ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; - ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; - ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; + ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id); /* req & rsp use the same buffer */ From 41d4d6316b1d2f84c4c0aa7d4c78327aff139782 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:33:13 +0000 Subject: [PATCH 26/44] qla2x00t-32gbit: Enable type checking for the SRB free and done callback functions Since all pointers passed to the srb_t.done() and srb_t.free() functions have type srb_t, change the type of the first argument of these functions from void * into struct srb *. This allows the compiler to verify the argument types for these functions. This patch does not change any functionality. [ commit 6c18a43e3c82b0b67531a1cdec7ba31540fe6424 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8544 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_bsg.c | 8 ++------ qla2x00t-32gbit/qla_def.h | 14 +++++++++++-- qla2x00t-32gbit/qla_gbl.h | 14 ++++++------- qla2x00t-32gbit/qla_gs.c | 21 +++++++------------ qla2x00t-32gbit/qla_init.c | 40 +++++++++--------------------------- qla2x00t-32gbit/qla_iocb.c | 12 +++-------- qla2x00t-32gbit/qla_mbx.c | 4 +--- qla2x00t-32gbit/qla_mid.c | 4 +--- qla2x00t-32gbit/qla_mr.c | 4 +--- qla2x00t-32gbit/qla_nvme.c | 11 ++++------ qla2x00t-32gbit/qla_nvme.h | 3 +-- qla2x00t-32gbit/qla_os.c | 16 ++++----------- qla2x00t-32gbit/qla_target.c | 4 +--- 13 files changed, 54 insertions(+), 101 deletions(-) diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index e262eedd2..9ec31a5fa 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -33,10 +33,8 @@ static inline void bsg_job_done_backport(struct fc_bsg_job *job, int result, #endif /* BSG support for ELS/CT pass through */ -void -qla2x00_bsg_job_done(void *ptr, int res) +void qla2x00_bsg_job_done(srb_t *sp, int res) { - srb_t *sp = ptr; #ifndef NEW_LIBFC_API struct fc_bsg_job *bsg_job = sp->u.bsg_job; #else @@ -50,10 +48,8 @@ qla2x00_bsg_job_done(void *ptr, int res) sp->free(sp); } -void -qla2x00_bsg_sp_free(void *ptr) +void qla2x00_bsg_sp_free(srb_t *sp) { - srb_t *sp = ptr; struct qla_hw_data *ha = sp->vha->hw; #ifndef NEW_LIBFC_API struct fc_bsg_job *bsg_job = sp->u.bsg_job; diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 12b319d9e..379b17e41 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -632,8 +632,18 @@ typedef struct srb { #endif struct srb_cmd scmd; } u; - void (*done)(void *, int); - void (*free)(void *); + /* + * Report completion status @res and call sp_put(@sp). @res is + * an NVMe status code, a SCSI result (e.g. DID_OK << 16) or a + * QLA_* status value. + */ + void (*done)(struct srb *sp, int res); + /* Stop the timer and free @sp. Only used by the FCP code. */ + void (*free)(struct srb *sp); + /* + * Call nvme_private->fd->done() and free @sp. Only used by the NVMe + * code. + */ void (*put_fn)(struct kref *kref); } srb_t; diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 4c7449247..09a4bc22c 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -219,9 +219,9 @@ extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); extern void qla2x00_disable_board_on_pci_error(struct work_struct *); -extern void qla2x00_sp_compl(void *, int); -extern void qla2xxx_qpair_sp_free_dma(void *); -extern void qla2xxx_qpair_sp_compl(void *, int); +extern void qla2x00_sp_compl(srb_t *sp, int); +extern void qla2xxx_qpair_sp_free_dma(srb_t *sp); +extern void qla2xxx_qpair_sp_compl(srb_t *sp, int); extern void qla24xx_sched_upd_fcport(fc_port_t *); void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, uint16_t *); @@ -250,7 +250,7 @@ extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *); extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *); extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *); -extern void qla2x00_sp_free_dma(void *); +extern void qla2x00_sp_free_dma(srb_t *sp); extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); @@ -796,10 +796,10 @@ extern int qla82xx_restart_isp(scsi_qla_host_t *); /* IOCB related functions */ extern int qla82xx_start_scsi(srb_t *); -extern void qla2x00_sp_free(void *); +extern void qla2x00_sp_free(srb_t *sp); extern void qla2x00_sp_timeout(struct timer_list *); -extern void qla2x00_bsg_job_done(void *, int); -extern void qla2x00_bsg_sp_free(void *); +extern void qla2x00_bsg_job_done(srb_t *sp, int); +extern void qla2x00_bsg_sp_free(srb_t *sp); extern void qla2x00_start_iocbs(struct scsi_qla_host *, struct req_que *); /* Interrupt related */ diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 7f1d43ce1..b503c18ec 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -499,9 +499,8 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) return (rval); } -static void qla2x00_async_sns_sp_done(void *s, int rc) +static void qla2x00_async_sns_sp_done(srb_t *sp, int rc) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; struct ct_sns_pkt *ct_sns; struct qla_work_evt *e; @@ -2989,9 +2988,8 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea) qla_post_iidma_work(vha, fcport); } -static void qla24xx_async_gpsc_sp_done(void *s, int res) +static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; struct qla_hw_data *ha = vha->hw; fc_port_t *fcport = sp->fcport; @@ -3247,9 +3245,8 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) } } -static void qla2x00_async_gpnid_sp_done(void *s, int res) +static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; struct ct_sns_req *ct_req = (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; @@ -3440,9 +3437,8 @@ void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea) qla24xx_post_gnl_work(vha, fcport); } -void qla24xx_async_gffid_sp_done(void *s, int res) +void qla24xx_async_gffid_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; fc_port_t *fcport = sp->fcport; struct ct_sns_rsp *ct_rsp; @@ -3866,9 +3862,8 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, } } -static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) +static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; struct ct_sns_req *ct_req = (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; @@ -4245,9 +4240,8 @@ void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea) qla24xx_post_gnl_work(vha, ea->fcport); } -static void qla2x00_async_gnnid_sp_done(void *s, int res) +static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; fc_port_t *fcport = sp->fcport; u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name; @@ -4379,9 +4373,8 @@ void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) qla24xx_post_gpsc_work(vha, fcport); } -static void qla2x00_async_gfpnid_sp_done(void *s, int res) +static void qla2x00_async_gfpnid_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; fc_port_t *fcport = sp->fcport; u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index dd2c5427c..2eb11d888 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -62,10 +62,8 @@ qla2x00_sp_timeout(struct timer_list *t) iocb->timeout(sp); } -void -qla2x00_sp_free(void *ptr) +void qla2x00_sp_free(srb_t *sp) { - srb_t *sp = ptr; struct srb_iocb *iocb = &sp->u.iocb_cmd; del_timer(&iocb->timer); @@ -116,9 +114,8 @@ static void qla24xx_abort_iocb_timeout(void *data) sp->done(sp, QLA_OS_TIMER_EXPIRED); } -static void qla24xx_abort_sp_done(void *ptr, int res) +static void qla24xx_abort_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; struct srb_iocb *abt = &sp->u.iocb_cmd; del_timer(&sp->u.iocb_cmd.timer); @@ -246,10 +243,8 @@ qla2x00_async_iocb_timeout(void *data) } } -static void -qla2x00_async_login_sp_done(void *ptr, int res) +static void qla2x00_async_login_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; struct scsi_qla_host *vha = sp->vha; struct srb_iocb *lio = &sp->u.iocb_cmd; struct event_arg ea; @@ -356,11 +351,8 @@ done: return rval; } -static void -qla2x00_async_logout_sp_done(void *ptr, int res) +static void qla2x00_async_logout_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; - sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); sp->fcport->login_gen++; qlt_logo_completion_handler(sp->fcport, res); @@ -420,10 +412,8 @@ qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, qlt_logo_completion_handler(fcport, data[0]); } -static void -qla2x00_async_prlo_sp_done(void *s, int res) +static void qla2x00_async_prlo_sp_done(srb_t *sp, int res) { - srb_t *sp = (srb_t *)s; struct srb_iocb *lio = &sp->u.iocb_cmd; struct scsi_qla_host *vha = sp->vha; @@ -526,10 +516,8 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) return qla2x00_post_work(vha, e); } -static void -qla2x00_async_adisc_sp_done(void *ptr, int res) +static void qla2x00_async_adisc_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; struct scsi_qla_host *vha = sp->vha; struct event_arg ea; struct srb_iocb *lio = &sp->u.iocb_cmd; @@ -934,10 +922,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, } } /* gnl_event */ -static void -qla24xx_async_gnl_sp_done(void *s, int res) +static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; unsigned long flags; struct fc_port *fcport = NULL, *tf; @@ -1123,10 +1109,8 @@ int qla24xx_post_gnl_work(struct scsi_qla_host *vha, fc_port_t *fcport) return qla2x00_post_work(vha, e); } -static -void qla24xx_async_gpdb_sp_done(void *s, int res) +static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) { - struct srb *sp = s; struct scsi_qla_host *vha = sp->vha; struct qla_hw_data *ha = vha->hw; fc_port_t *fcport = sp->fcport; @@ -1170,10 +1154,8 @@ static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport) return qla2x00_post_work(vha, e); } -static void -qla2x00_async_prli_sp_done(void *ptr, int res) +static void qla2x00_async_prli_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; struct scsi_qla_host *vha = sp->vha; struct srb_iocb *lio = &sp->u.iocb_cmd; struct event_arg ea; @@ -1809,10 +1791,8 @@ qla2x00_tmf_iocb_timeout(void *data) complete(&tmf->u.tmf.comp); } -static void -qla2x00_tmf_sp_done(void *ptr, int res) +static void qla2x00_tmf_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; struct srb_iocb *tmf = &sp->u.iocb_cmd; complete(&tmf->u.tmf.comp); diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 3e7ada018..7a0fd965a 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2550,10 +2550,8 @@ void qla2x00_init_timer(srb_t *sp, unsigned long tmo) sp->start_timer = 1; } -static void -qla2x00_els_dcmd_sp_free(void *data) +static void qla2x00_els_dcmd_sp_free(srb_t *sp) { - srb_t *sp = data; struct srb_iocb *elsio = &sp->u.iocb_cmd; kfree(sp->fcport); @@ -2583,10 +2581,8 @@ qla2x00_els_dcmd_iocb_timeout(void *data) complete(&lio->u.els_logo.comp); } -static void -qla2x00_els_dcmd_sp_done(void *ptr, int res) +static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; fc_port_t *fcport = sp->fcport; struct srb_iocb *lio = &sp->u.iocb_cmd; struct scsi_qla_host *vha = sp->vha; @@ -2779,10 +2775,8 @@ void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi) els_plogi->els_resp_pyld_dma); } -static void -qla2x00_els_dcmd2_sp_done(void *ptr, int res) +static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; fc_port_t *fcport = sp->fcport; struct srb_iocb *lio = &sp->u.iocb_cmd; struct scsi_qla_host *vha = sp->vha; diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index f680b0d6d..675a2565d 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -6214,10 +6214,8 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha, return rval; } -static void qla2x00_async_mb_sp_done(void *s, int res) +static void qla2x00_async_mb_sp_done(srb_t *sp, int res) { - struct srb *sp = s; - sp->u.iocb_cmd.u.mbx.rc = res; complete(&sp->u.iocb_cmd.u.mbx.comp); diff --git a/qla2x00t-32gbit/qla_mid.c b/qla2x00t-32gbit/qla_mid.c index b2977e493..1a9a11ae7 100644 --- a/qla2x00t-32gbit/qla_mid.c +++ b/qla2x00t-32gbit/qla_mid.c @@ -901,10 +901,8 @@ failed: return 0; } -static void qla_ctrlvp_sp_done(void *s, int res) +static void qla_ctrlvp_sp_done(srb_t *sp, int res) { - struct srb *sp = s; - if (sp->comp) complete(sp->comp); /* don't free sp here. Let the caller do the free */ diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index fec197a6f..8db2862d7 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -1797,10 +1797,8 @@ qla2x00_fxdisc_iocb_timeout(void *data) complete(&lio->u.fxiocb.fxiocb_comp); } -static void -qla2x00_fxdisc_sp_done(void *ptr, int res) +static void qla2x00_fxdisc_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; struct srb_iocb *lio = &sp->u.iocb_cmd; complete(&lio->u.fxiocb.fxiocb_comp); diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index e4ba0381a..ed3b41e08 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -191,10 +191,9 @@ static void qla_nvme_ls_complete(struct work_struct *work) kref_put(&priv->sp->cmd_kref, qla_nvme_release_ls_cmd_kref); } -static void qla_nvme_sp_ls_done(void *ptr, int res) +static void qla_nvme_sp_ls_done(srb_t *sp, int res) { - srb_t *sp = ptr; - struct nvme_private *priv; + struct nvme_private *priv = sp->priv; if (WARN_ON_ONCE(kref_read(&sp->cmd_kref) == 0)) return; @@ -202,17 +201,15 @@ static void qla_nvme_sp_ls_done(void *ptr, int res) if (res) res = -EINVAL; - priv = (struct nvme_private *)sp->priv; priv->comp_status = res; INIT_WORK(&priv->ls_work, qla_nvme_ls_complete); schedule_work(&priv->ls_work); } /* it assumed that QPair lock is held. */ -static void qla_nvme_sp_done(void *ptr, int res) +static void qla_nvme_sp_done(srb_t *sp, int res) { - srb_t *sp = ptr; - struct nvme_private *priv = (struct nvme_private *)sp->priv; + struct nvme_private *priv = sp->priv; priv->comp_status = res; kref_put(&sp->cmd_kref, qla_nvme_release_fcp_cmd_kref); diff --git a/qla2x00t-32gbit/qla_nvme.h b/qla2x00t-32gbit/qla_nvme.h index 32c1caf40..c6fd3ac33 100644 --- a/qla2x00t-32gbit/qla_nvme.h +++ b/qla2x00t-32gbit/qla_nvme.h @@ -164,6 +164,5 @@ static inline void qla_nvme_delete(struct scsi_qla_host *vha) void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *, struct req_que *); -void qla24xx_async_gffid_sp_done(void *, int); - +void qla24xx_async_gffid_sp_done(struct srb *sp, int); #endif diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 02847b795..7da18a8be 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -672,10 +672,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str, size_t size) return str; } -void -qla2x00_sp_free_dma(void *ptr) +void qla2x00_sp_free_dma(srb_t *sp) { - srb_t *sp = ptr; struct qla_hw_data *ha = sp->vha->hw; struct scsi_cmnd *cmd = GET_CMD_SP(sp); void *ctx = GET_CMD_CTX_SP(sp); @@ -719,10 +717,8 @@ qla2x00_sp_free_dma(void *ptr) } } -void -qla2x00_sp_compl(void *ptr, int res) +void qla2x00_sp_compl(srb_t *sp, int res) { - srb_t *sp = ptr; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; @@ -740,10 +736,8 @@ qla2x00_sp_compl(void *ptr, int res) qla2x00_rel_sp(sp); } -void -qla2xxx_qpair_sp_free_dma(void *ptr) +void qla2xxx_qpair_sp_free_dma(srb_t *sp) { - srb_t *sp = (srb_t *)ptr; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct qla_hw_data *ha = sp->fcport->vha->hw; void *ctx = GET_CMD_CTX_SP(sp); @@ -824,10 +818,8 @@ qla2xxx_qpair_sp_free_dma(void *ptr) } } -void -qla2xxx_qpair_sp_compl(void *ptr, int res) +void qla2xxx_qpair_sp_compl(srb_t *sp, int res) { - srb_t *sp = ptr; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index ac65b860c..d44f1c12a 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -572,10 +572,8 @@ static int qla24xx_post_nack_work(struct scsi_qla_host *vha, fc_port_t *fcport, return qla2x00_post_work(vha, e); } -static -void qla2x00_async_nack_sp_done(void *s, int res) +static void qla2x00_async_nack_sp_done(srb_t *sp, int res) { - struct srb *sp = (struct srb *)s; struct scsi_qla_host *vha = sp->vha; unsigned long flags; From 7d3e856e615efe7d7ef97d54964a7e52156775b1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:34:07 +0000 Subject: [PATCH 27/44] qla2x00t-32gbit: Introduce the function qla2xxx_init_sp() This patch does not change any functionality but makes the next patch easier to read. [ commit bdb61b9b944d1e5b7cee5a9fe21014363c55b811 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8545 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_inline.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index 44bde2c60..c1bae436c 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -174,6 +174,18 @@ qla2x00_chip_is_down(scsi_qla_host_t *vha) return (qla2x00_reset_active(vha) || !vha->hw->flags.fw_started); } +static void qla2xxx_init_sp(srb_t *sp, scsi_qla_host_t *vha, + struct qla_qpair *qpair, fc_port_t *fcport) +{ + memset(sp, 0, sizeof(*sp)); + sp->fcport = fcport; + sp->iocbs = 1; + sp->vha = vha; + sp->qpair = qpair; + sp->cmd_type = TYPE_SRB; + INIT_LIST_HEAD(&sp->elem); +} + static inline srb_t * qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair, fc_port_t *fcport, gfp_t flag) @@ -186,19 +198,9 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair, return NULL; sp = mempool_alloc(qpair->srb_mempool, flag); - if (!sp) - goto done; - - memset(sp, 0, sizeof(*sp)); - sp->fcport = fcport; - sp->iocbs = 1; - sp->vha = vha; - sp->qpair = qpair; - sp->cmd_type = TYPE_SRB; - INIT_LIST_HEAD(&sp->elem); - -done: - if (!sp) + if (sp) + qla2xxx_init_sp(sp, vha, qpair, fcport); + else QLA_QPAIR_MARK_NOT_BUSY(qpair); return sp; } From bc7f5b55fb27d0de7d13cafdb5efffb349cc551f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:34:53 +0000 Subject: [PATCH 28/44] qla2x00t-32gbit: Fix a race condition between aborting and completing a SCSI command Instead of allocating a struct srb dynamically from inside .queuecommand(), set qla2xxx_driver_template.cmd_size such that struct scsi_cmnd and struct srb are contiguous. Do not call QLA_QPAIR_MARK_BUSY() / QLA_QPAIR_MARK_NOT_BUSY() for SRBs associated with SCSI commands. That is safe because scsi_remove_host() is called before queue pairs are deleted and scsi_remove_host() waits for all outstanding SCSI commands to finish. [ commit 85cffefa09e448906a6f0bc20f422d75a18675bd upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8546 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 - qla2x00t-32gbit/qla_os.c | 46 ++++++++------------------------------- 2 files changed, 9 insertions(+), 38 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 379b17e41..22b164e05 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -648,7 +648,6 @@ typedef struct srb { } srb_t; #define GET_CMD_SP(sp) (sp->u.scmd.cmd) -#define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd) #define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx) #define GET_CMD_SENSE_LEN(sp) \ diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 7da18a8be..48389f8bb 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -733,7 +733,6 @@ void qla2x00_sp_compl(srb_t *sp, int res) cmd->scsi_done(cmd); if (comp) complete(comp); - qla2x00_rel_sp(sp); } void qla2xxx_qpair_sp_free_dma(srb_t *sp) @@ -834,7 +833,6 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res) cmd->scsi_done(cmd); if (comp) complete(comp); - qla2xxx_rel_qpair_sp(sp->qpair, sp); } #if defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 >= 2 @@ -945,9 +943,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) else goto qc24_target_busy; - sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); - if (!sp) - goto qc24_host_busy; + sp = scsi_cmd_priv(cmd); + qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport); sp->u.scmd.cmd = cmd; sp->type = SRB_SCSI_CMD; @@ -968,9 +965,6 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) qc24_host_busy_free_sp: sp->free(sp); -qc24_host_busy: - return SCSI_MLQUEUE_HOST_BUSY; - qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; @@ -1031,9 +1025,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, else goto qc24_target_busy; - sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC); - if (!sp) - goto qc24_host_busy; + sp = scsi_cmd_priv(cmd); + qla2xxx_init_sp(sp, vha, qpair, fcport); sp->u.scmd.cmd = cmd; sp->type = SRB_SCSI_CMD; @@ -1057,9 +1050,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, qc24_host_busy_free_sp: sp->free(sp); -qc24_host_busy: - return SCSI_MLQUEUE_HOST_BUSY; - qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; @@ -1301,10 +1291,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) int ret; unsigned int id; uint64_t lun; - unsigned long flags; int rval; struct qla_hw_data *ha = vha->hw; - struct qla_qpair *qpair; if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, @@ -1316,30 +1304,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) if (ret != 0) return ret; - sp = (srb_t *) CMD_SP(cmd); - if (!sp) - return SUCCESS; + sp = scsi_cmd_priv(cmd); - qpair = sp->qpair; - if (!qpair) + /* Return if the command has already finished. */ + if (sp_get(sp)) return SUCCESS; - spin_lock_irqsave(qpair->qp_lock_ptr, flags); - if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) { - /* there's a chance an interrupt could clear - the ptr as part of done & free */ - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - return SUCCESS; - } - - /* Get a reference to the sp and drop the lock. */ - if (sp_get(sp)){ - /* ref_count is already 0 */ - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - return SUCCESS; - } - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - id = cmd->device->id; lun = cmd->device->lun; @@ -1365,6 +1335,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) uint32_t ratov = ha->r_a_tov/10; uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000); + WARN_ON_ONCE(sp->comp); sp->comp = ∁ if (!wait_for_completion_timeout(&comp, ratov_j)) { ql_dbg(ql_dbg_taskm, vha, 0xffff, @@ -7244,6 +7215,7 @@ struct scsi_host_template qla2xxx_driver_template = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) .track_queue_depth = 1, #endif + .cmd_size = sizeof(srb_t), }; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \ From 1f88b95c155b2ed942679b2a92572ad28e429e08 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:35:42 +0000 Subject: [PATCH 29/44] qla2x00t-32gbit: Introduce qla2xxx_get_next_handle() This patch reduces code duplication. [ commit bcc856574356df2eb5eb2d4491e7205339e55728 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8547 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gbl.h | 1 + qla2x00t-32gbit/qla_iocb.c | 128 +++++++++++-------------------------- qla2x00t-32gbit/qla_mr.c | 13 +--- qla2x00t-32gbit/qla_nvme.c | 14 +--- 4 files changed, 42 insertions(+), 114 deletions(-) diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 09a4bc22c..7ef6ca1ee 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -278,6 +278,7 @@ extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); extern void qla2x00_build_scsi_iocbs_64(srb_t *, cmd_entry_t *, uint16_t); extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t, struct req_que *); +extern uint32_t qla2xxx_get_next_handle(struct req_que *req); extern int qla2x00_start_scsi(srb_t *sp); extern int qla24xx_start_scsi(srb_t *sp); int qla2x00_marker(struct scsi_qla_host *, struct qla_qpair *, diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 7a0fd965a..e75343d91 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -292,6 +292,26 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, } } +/* + * Find the first handle that is not in use, starting from + * req->current_outstanding_cmd + 1. The caller must hold the lock that is + * associated with @req. + */ +uint32_t qla2xxx_get_next_handle(struct req_que *req) +{ + uint32_t index, handle = req->current_outstanding_cmd; + + for (index = 1; index < req->num_outstanding_cmds; index++) { + handle++; + if (handle == req->num_outstanding_cmds) + handle = 1; + if (!req->outstanding_cmds[handle]) + return handle; + } + + return 0; +} + /** * qla2x00_start_scsi() - Send a SCSI command to the ISP * @sp: command to send to the ISP @@ -306,7 +326,6 @@ qla2x00_start_scsi(srb_t *sp) scsi_qla_host_t *vha; struct scsi_cmnd *cmd; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; cmd_entry_t *cmd_pkt; uint16_t cnt; @@ -339,16 +358,8 @@ qla2x00_start_scsi(srb_t *sp) /* Acquire ring specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Map the sg table so we have an accurate count of sg entries needed */ @@ -1590,7 +1601,6 @@ qla24xx_start_scsi(srb_t *sp) int nseg; unsigned long flags; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; struct cmd_type_7 *cmd_pkt; uint16_t cnt; @@ -1618,16 +1628,8 @@ qla24xx_start_scsi(srb_t *sp) /* Acquire ring specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Map the sg table so we have an accurate count of sg entries needed */ @@ -1730,7 +1732,6 @@ qla24xx_dif_start_scsi(srb_t *sp) int nseg; unsigned long flags; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; uint16_t cnt; uint16_t req_cnt = 0; @@ -1771,17 +1772,8 @@ qla24xx_dif_start_scsi(srb_t *sp) /* Acquire ring specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Compute number of required data segments */ @@ -1926,7 +1918,6 @@ qla2xxx_start_scsi_mq(srb_t *sp) int nseg; unsigned long flags; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; struct cmd_type_7 *cmd_pkt; uint16_t cnt; @@ -1957,16 +1948,8 @@ qla2xxx_start_scsi_mq(srb_t *sp) vha->marker_needed = 0; } - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Map the sg table so we have an accurate count of sg entries needed */ @@ -2070,7 +2053,6 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp) int nseg; unsigned long flags; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; uint16_t cnt; uint16_t req_cnt = 0; @@ -2125,17 +2107,8 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp) vha->marker_needed = 0; } - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Compute number of required data segments */ @@ -2282,7 +2255,7 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp) struct qla_hw_data *ha = vha->hw; struct req_que *req = qpair->req; device_reg_t *reg = ISP_QUE_REG(ha, req->id); - uint32_t index, handle; + uint32_t handle; request_t *pkt; uint16_t cnt, req_cnt; @@ -2322,16 +2295,8 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp) goto queuing_error; if (sp) { - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == req->num_outstanding_cmds) { + handle = qla2xxx_get_next_handle(req); + if (handle == 0) { ql_log(ql_log_warn, vha, 0x700b, "No room on outstanding cmd array.\n"); goto queuing_error; @@ -3124,7 +3089,6 @@ qla82xx_start_scsi(srb_t *sp) unsigned long flags; struct scsi_cmnd *cmd; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; uint16_t cnt; uint16_t req_cnt; @@ -3164,16 +3128,8 @@ qla82xx_start_scsi(srb_t *sp) /* Acquire ring specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Map the sg table so we have an accurate count of sg entries needed */ @@ -3785,7 +3741,6 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) struct qla_hw_data *ha = vha->hw; unsigned long flags; uint32_t handle; - uint32_t index; uint16_t req_cnt; uint16_t cnt; uint32_t *clr_ptr; @@ -3810,17 +3765,8 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) /* Acquire ring specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - - if (index == req->num_outstanding_cmds) { + handle = qla2xxx_get_next_handle(req); + if (handle == 0) { rval = EXT_STATUS_BUSY; goto queuing_error; } diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index 8db2862d7..6df086462 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -3086,7 +3086,6 @@ qlafx00_start_scsi(srb_t *sp) { int nseg; unsigned long flags; - uint32_t index; uint32_t handle; uint16_t cnt; uint16_t req_cnt; @@ -3110,16 +3109,8 @@ qlafx00_start_scsi(srb_t *sp) /* Acquire ring specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == req->num_outstanding_cmds) + handle = qla2xxx_get_next_handle(req); + if (handle == 0) goto queuing_error; /* Map the sg table so we have an accurate count of sg entries needed */ diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index ed3b41e08..9b65e26d3 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -364,7 +364,6 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) { unsigned long flags; uint32_t *clr_ptr; - uint32_t index; uint32_t handle; struct cmd_nvme *cmd_pkt; uint16_t cnt, i; @@ -388,17 +387,8 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) /* Acquire qpair specific lock */ spin_lock_irqsave(&qpair->qp_lock, flags); - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < req->num_outstanding_cmds; index++) { - handle++; - if (handle == req->num_outstanding_cmds) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - - if (index == req->num_outstanding_cmds) { + handle = qla2xxx_get_next_handle(req); + if (handle == 0) { rval = -EBUSY; goto queuing_error; } From 72cc459a40552823d6862a260ebbe0c56e0c2ad9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:36:13 +0000 Subject: [PATCH 30/44] qla2x00t-32gbit: Complain if sp->done() is not called from the completion path Not calling sp->done() from the command completion path is a severe bug. Hence complain loudly if that happens. [ commit 88263208dd23327b56fbd7c2858c389c1153b366 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8548 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 4 ++++ qla2x00t-32gbit/qla_isr.c | 2 ++ qla2x00t-32gbit/qla_mr.c | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 2eb11d888..04bd42f7e 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -240,6 +240,10 @@ qla2x00_async_iocb_timeout(void *data) sp->done(sp, QLA_FUNCTION_TIMEOUT); } break; + default: + WARN_ON_ONCE(true); + sp->done(sp, QLA_FUNCTION_TIMEOUT); + break; } } diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index fd52c5888..37eeb5b7d 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -2867,6 +2867,8 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) if (sense_len == 0) { rsp->status_srb = NULL; sp->done(sp, cp->result); + } else { + WARN_ON_ONCE(true); } } diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index 6df086462..4a9d3149f 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -2554,6 +2554,8 @@ check_scsi_status: if (rsp->status_srb == NULL) sp->done(sp, res); + else + WARN_ON_ONCE(true); } /** @@ -2631,6 +2633,8 @@ qlafx00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) if (sense_len == 0) { rsp->status_srb = NULL; sp->done(sp, cp->result); + } else { + WARN_ON_ONCE(true); } } From f5a2e510169b76e836139c937bab6ad4234b7768 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:36:49 +0000 Subject: [PATCH 31/44] qla2x00t-32gbit: Let the compiler check the type of the SCSI command context pointer Split srb_cmd.ctx into two pointers such that the compiler can check the type of that pointer. [ commit 5ec9f9040f61dfd0412a53fa2fc1e321727a5a61 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8549 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 4 ++-- qla2x00t-32gbit/qla_iocb.c | 20 +++++++++----------- qla2x00t-32gbit/qla_nx.c | 2 +- qla2x00t-32gbit/qla_os.c | 24 ++++++++---------------- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 22b164e05..8dc76a5f9 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -331,7 +331,8 @@ struct srb_cmd { uint32_t request_sense_length; uint32_t fw_sense_length; uint8_t *request_sense_ptr; - void *ctx; + struct ct6_dsd *ct6_ctx; + struct crc_context *crc_ctx; }; /* @@ -648,7 +649,6 @@ typedef struct srb { } srb_t; #define GET_CMD_SP(sp) (sp->u.scmd.cmd) -#define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx) #define GET_CMD_SENSE_LEN(sp) \ (sp->u.scmd.request_sense_length) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index e75343d91..4e6b8e2bb 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -621,7 +621,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, } cur_seg = scsi_sglist(cmd); - ctx = GET_CMD_CTX_SP(sp); + ctx = sp->u.scmd.ct6_ctx; while (tot_dsds) { avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ? @@ -954,8 +954,7 @@ alloc_and_fill: if (sp) { list_add_tail(&dsd_ptr->list, - &((struct crc_context *) - sp->u.scmd.ctx)->dsd_list); + &sp->u.scmd.crc_ctx->dsd_list); sp->flags |= SRB_CRC_CTX_DSD_VALID; } else { @@ -1052,8 +1051,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, if (sp) { list_add_tail(&dsd_ptr->list, - &((struct crc_context *) - sp->u.scmd.ctx)->dsd_list); + &sp->u.scmd.crc_ctx->dsd_list); sp->flags |= SRB_CRC_CTX_DSD_VALID; } else { @@ -1100,7 +1098,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, sgl = scsi_prot_sglist(cmd); vha = sp->vha; - difctx = sp->u.scmd.ctx; + difctx = sp->u.scmd.crc_ctx; direction_to_device = cmd->sc_data_direction == DMA_TO_DEVICE; ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe021, "%s: scsi_cmnd: %p, crc_ctx: %p, sp: %p\n", @@ -1441,7 +1439,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, bundling = 0; /* Allocate CRC context from global pool */ - crc_ctx_pkt = sp->u.scmd.ctx = + crc_ctx_pkt = sp->u.scmd.crc_ctx = dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma); if (!crc_ctx_pkt) @@ -3200,7 +3198,7 @@ sufficient_dsds: goto queuing_error; } - ctx = sp->u.scmd.ctx = + ctx = sp->u.scmd.ct6_ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); if (!ctx) { ql_log(ql_log_fatal, vha, 0x3010, @@ -3396,9 +3394,9 @@ queuing_error: if (tot_dsds) scsi_dma_unmap(cmd); - if (sp->u.scmd.ctx) { - mempool_free(sp->u.scmd.ctx, ha->ctx_mempool); - sp->u.scmd.ctx = NULL; + if (sp->u.scmd.crc_ctx) { + mempool_free(sp->u.scmd.crc_ctx, ha->ctx_mempool); + sp->u.scmd.crc_ctx = NULL; } spin_unlock_irqrestore(&ha->hardware_lock, flags); diff --git a/qla2x00t-32gbit/qla_nx.c b/qla2x00t-32gbit/qla_nx.c index b7aae5ca2..f34f988da 100644 --- a/qla2x00t-32gbit/qla_nx.c +++ b/qla2x00t-32gbit/qla_nx.c @@ -3685,7 +3685,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { - if ((!sp->u.scmd.ctx || + if ((!sp->u.scmd.crc_ctx || (sp->flags & SRB_FCP_CMND_DMA_VALID)) && !ha->flags.isp82xx_fw_hung) { diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 48389f8bb..0908f2cb9 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -676,7 +676,6 @@ void qla2x00_sp_free_dma(srb_t *sp) { struct qla_hw_data *ha = sp->vha->hw; struct scsi_cmnd *cmd = GET_CMD_SP(sp); - void *ctx = GET_CMD_CTX_SP(sp); if (sp->flags & SRB_DMA_VALID) { scsi_dma_unmap(cmd); @@ -689,24 +688,21 @@ void qla2x00_sp_free_dma(srb_t *sp) sp->flags &= ~SRB_CRC_PROT_DMA_VALID; } - if (!ctx) - return; - if (sp->flags & SRB_CRC_CTX_DSD_VALID) { /* List assured to be having elements */ - qla2x00_clean_dsd_pool(ha, ctx); + qla2x00_clean_dsd_pool(ha, sp->u.scmd.crc_ctx); sp->flags &= ~SRB_CRC_CTX_DSD_VALID; } if (sp->flags & SRB_CRC_CTX_DMA_VALID) { - struct crc_context *ctx0 = ctx; + struct crc_context *ctx0 = sp->u.scmd.crc_ctx; dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma); sp->flags &= ~SRB_CRC_CTX_DMA_VALID; } if (sp->flags & SRB_FCP_CMND_DMA_VALID) { - struct ct6_dsd *ctx1 = ctx; + struct ct6_dsd *ctx1 = sp->u.scmd.ct6_ctx; dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, ctx1->fcp_cmnd_dma); @@ -739,7 +735,6 @@ void qla2xxx_qpair_sp_free_dma(srb_t *sp) { struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct qla_hw_data *ha = sp->fcport->vha->hw; - void *ctx = GET_CMD_CTX_SP(sp); if (sp->flags & SRB_DMA_VALID) { scsi_dma_unmap(cmd); @@ -752,17 +747,14 @@ void qla2xxx_qpair_sp_free_dma(srb_t *sp) sp->flags &= ~SRB_CRC_PROT_DMA_VALID; } - if (!ctx) - return; - if (sp->flags & SRB_CRC_CTX_DSD_VALID) { /* List assured to be having elements */ - qla2x00_clean_dsd_pool(ha, ctx); + qla2x00_clean_dsd_pool(ha, sp->u.scmd.crc_ctx); sp->flags &= ~SRB_CRC_CTX_DSD_VALID; } if (sp->flags & SRB_DIF_BUNDL_DMA_VALID) { - struct crc_context *difctx = ctx; + struct crc_context *difctx = sp->u.scmd.crc_ctx; struct dsd_dma *dif_dsd, *nxt_dsd; list_for_each_entry_safe(dif_dsd, nxt_dsd, @@ -798,7 +790,7 @@ void qla2xxx_qpair_sp_free_dma(srb_t *sp) } if (sp->flags & SRB_FCP_CMND_DMA_VALID) { - struct ct6_dsd *ctx1 = ctx; + struct ct6_dsd *ctx1 = sp->u.scmd.ct6_ctx; dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, ctx1->fcp_cmnd_dma); @@ -810,9 +802,9 @@ void qla2xxx_qpair_sp_free_dma(srb_t *sp) } if (sp->flags & SRB_CRC_CTX_DMA_VALID) { - struct crc_context *ctx0 = ctx; + struct crc_context *ctx0 = sp->u.scmd.crc_ctx; - dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma); + dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma); sp->flags &= ~SRB_CRC_CTX_DMA_VALID; } } From cddc0c892d794abe8b5383659d3ddc67dbb36033 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:37:29 +0000 Subject: [PATCH 32/44] qla2x00t-32gbit: Remove superfluous sts_entry_* casts The C language supports implicit casting of void pointers to non-void pointers. Remove explicit sts_entry_* casts that are not necessary. [ commit 1a20719e074ada3e6d06ee065afd527779a6793b upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8550 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 37eeb5b7d..9b0947d0e 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1529,7 +1529,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, if (comp_status == CS_DATA_UNDERRUN) { res = DID_OK << 16; bsg_reply->reply_payload_rcv_len = - le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); + le16_to_cpu(pkt->rsp_info_len); ql_log(ql_log_warn, vha, 0x5048, "CT pass-through-%s error comp_status=0x%x total_byte=0x%x.\n", @@ -2280,11 +2280,8 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt, #endif struct fc_bsg_request *bsg_request; struct fc_bsg_reply *bsg_reply; - sts_entry_t *sts; - struct sts_entry_24xx *sts24; - - sts = (sts_entry_t *) pkt; - sts24 = (struct sts_entry_24xx *) pkt; + sts_entry_t *sts = pkt; + struct sts_entry_24xx *sts24 = pkt; /* Validate handle. */ if (index >= req->num_outstanding_cmds) { @@ -2430,8 +2427,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) srb_t *sp; fc_port_t *fcport; struct scsi_cmnd *cp; - sts_entry_t *sts; - struct sts_entry_24xx *sts24; + sts_entry_t *sts = pkt; + struct sts_entry_24xx *sts24 = pkt; uint16_t comp_status; uint16_t scsi_status; uint16_t ox_id; @@ -2449,8 +2446,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) uint16_t state_flags = 0; uint16_t retry_delay = 0; - sts = (sts_entry_t *) pkt; - sts24 = (struct sts_entry_24xx *) pkt; if (IS_FWI2_CAPABLE(ha)) { comp_status = le16_to_cpu(sts24->comp_status); scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK; From 446ae4566154de130129e649cbf0c86a9b5dfa8f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:37:55 +0000 Subject: [PATCH 33/44] qla2x00t-32gbit: Report invalid mailbox status codes It is easy to mix up the QLA_* and the MBS_* status codes. Complain loudly if that happens. [ commit 724361921f65a40ae5b80641dc1e92c0ff314d89 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8551 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 5 +++++ qla2x00t-32gbit/qla_init.c | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 8dc76a5f9..804b4af98 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -1008,6 +1008,11 @@ struct mbx_cmd_32 { #define MBS_LINK_DOWN_ERROR 0x400B #define MBS_DIAG_ECHO_TEST_ERROR 0x400C +static inline bool qla2xxx_is_valid_mbs(unsigned int mbs) +{ + return MBS_COMMAND_COMPLETE <= mbs && mbs <= MBS_DIAG_ECHO_TEST_ERROR; +} + /* * ISP mailbox asynchronous event status codes */ diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 04bd42f7e..0afdd8f56 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -478,6 +478,9 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea) fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2, fcport->rscn_gen, ea->sp->gen1, fcport->loop_id); + WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n", + ea->data[0]); + if (ea->data[0] != MBS_COMMAND_COMPLETE) { ql_dbg(ql_dbg_disc, vha, 0x2066, "%s %s: adisc fail: post delete\n", @@ -1894,6 +1897,9 @@ qla24xx_async_abort_command(srb_t *sp) static void qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) { + WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n", + ea->data[0]); + switch (ea->data[0]) { case MBS_COMMAND_COMPLETE: ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %s post gpdb\n", @@ -1978,6 +1984,9 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) return; } + WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n", + ea->data[0]); + switch (ea->data[0]) { case MBS_COMMAND_COMPLETE: /* From a2cefa63a93222380b4516dd848347ee095f688a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:38:32 +0000 Subject: [PATCH 34/44] qla2x00t-32gbit: Inline the qla2x00_fcport_event_handler() function Instead of calling qla2x00_fcport_event_handler() and letting the switch statement inside that function decide which other function to call, call the latter function directly. Remove the event member from the event_arg structure because it is no longer needed. Remove the qla_handle_els_plogi_done() function because it is never called. [ commit 897def2004213636ffe2e9ee6a75660c5b53b03d upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8552 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 17 -------------- qla2x00t-32gbit/qla_gbl.h | 6 ++++- qla2x00t-32gbit/qla_gs.c | 9 +++---- qla2x00t-32gbit/qla_init.c | 48 +++++++++++++++++++++++++------------- qla2x00t-32gbit/qla_iocb.c | 3 +-- qla2x00t-32gbit/qla_isr.c | 3 +-- qla2x00t-32gbit/qla_os.c | 3 +-- 7 files changed, 43 insertions(+), 46 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 804b4af98..36b6c6aa5 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2381,22 +2381,6 @@ enum login_state { /* FW control Target side */ DSC_LS_LOGO_PEND, }; -enum fcport_mgt_event { - FCME_RELOGIN = 1, - FCME_RSCN, - FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */ - FCME_PRLI_DONE, - FCME_GNL_DONE, - FCME_GPSC_DONE, - FCME_GPDB_DONE, - FCME_GPNID_DONE, - FCME_GFFID_DONE, - FCME_ADISC_DONE, - FCME_GNNID_DONE, - FCME_GFPNID_DONE, - FCME_ELS_PLOGI_DONE, -}; - enum rscn_addr_format { RSCN_PORT_ADDR, RSCN_AREA_ADDR, @@ -2515,7 +2499,6 @@ typedef struct fc_port { #define QLA_FCPORT_FOUND 2 struct event_arg { - enum fcport_mgt_event event; fc_port_t *fcport; srb_t *sp; port_id_t id; diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 7ef6ca1ee..dc90f9357 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -98,7 +98,11 @@ extern int qla2x00_init_rings(scsi_qla_host_t *); extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *, int, int, bool); extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *); -void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *); +void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea); +void qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, + struct event_arg *ea); +void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, + struct event_arg *ea); int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8); int qla24xx_async_prli(struct scsi_qla_host *, fc_port_t *); int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *, diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index b503c18ec..e4f64b0c0 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3030,11 +3030,10 @@ static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res) be16_to_cpu(ct_rsp->rsp.gpsc.speed)); } memset(&ea, 0, sizeof(ea)); - ea.event = FCME_GPSC_DONE; ea.rc = res; ea.fcport = fcport; ea.sp = sp; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gpsc_event(vha, &ea); done: sp->free(sp); @@ -3278,7 +3277,6 @@ static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res) ea.sp = sp; ea.id = be_to_port_id(ct_req->req.port_id.port_id); ea.rc = res; - ea.event = FCME_GPNID_DONE; spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); list_del(&sp->elem); @@ -3297,7 +3295,7 @@ static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res) return; } - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gpnid_event(vha, &ea); e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); if (!e) { @@ -3475,9 +3473,8 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res) ea.sp = sp; ea.fcport = sp->fcport; ea.rc = res; - ea.event = FCME_GFFID_DONE; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gffid_event(vha, &ea); sp->free(sp); } diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 0afdd8f56..d08d7fee7 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -36,8 +36,8 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); static int qla84xx_init_chip(scsi_qla_host_t *); static int qla25xx_init_queues(struct qla_hw_data *); static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *); -static void qla24xx_handle_plogi_done_event(struct scsi_qla_host *, - struct event_arg *); +static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, + struct event_arg *ea); static void qla24xx_handle_prli_done_event(struct scsi_qla_host *, struct event_arg *); static void __qla24xx_handle_gpdb_event(scsi_qla_host_t *, struct event_arg *); @@ -260,14 +260,13 @@ static void qla2x00_async_login_sp_done(srb_t *sp, int res) if (!test_bit(UNLOADING, &vha->dpc_flags)) { memset(&ea, 0, sizeof(ea)); - ea.event = FCME_PLOGI_DONE; ea.fcport = sp->fcport; ea.data[0] = lio->u.logio.data[0]; ea.data[1] = lio->u.logio.data[1]; ea.iop[0] = lio->u.logio.iop[0]; ea.iop[1] = lio->u.logio.iop[1]; ea.sp = sp; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_plogi_done_event(vha, &ea); } sp->free(sp); @@ -535,7 +534,6 @@ static void qla2x00_async_adisc_sp_done(srb_t *sp, int res) sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); memset(&ea, 0, sizeof(ea)); - ea.event = FCME_ADISC_DONE; ea.rc = res; ea.data[0] = lio->u.logio.data[0]; ea.data[1] = lio->u.logio.data[1]; @@ -544,7 +542,7 @@ static void qla2x00_async_adisc_sp_done(srb_t *sp, int res) ea.fcport = sp->fcport; ea.sp = sp; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_adisc_event(vha, &ea); sp->free(sp); } @@ -953,7 +951,6 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) memset(&ea, 0, sizeof(ea)); ea.sp = sp; ea.rc = res; - ea.event = FCME_GNL_DONE; if (sp->u.iocb_cmd.u.mbx.in_mb[1] >= sizeof(struct get_name_list_extended)) { @@ -992,7 +989,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); ea.fcport = fcport; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gnl_done_event(vha, &ea); } /* create new fcport if fw has knowledge of new sessions */ @@ -1136,11 +1133,10 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); memset(&ea, 0, sizeof(ea)); - ea.event = FCME_GPDB_DONE; ea.fcport = fcport; ea.sp = sp; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gpdb_event(vha, &ea); dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, sp->u.iocb_cmd.u.mbx.in_dma); @@ -1174,7 +1170,6 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res) if (!test_bit(UNLOADING, &vha->dpc_flags)) { memset(&ea, 0, sizeof(ea)); - ea.event = FCME_PRLI_DONE; ea.fcport = sp->fcport; ea.data[0] = lio->u.logio.data[0]; ea.data[1] = lio->u.logio.data[1]; @@ -1182,7 +1177,7 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res) ea.iop[1] = lio->u.logio.iop[1]; ea.sp = sp; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_prli_done_event(vha, &ea); } sp->free(sp); @@ -1645,12 +1640,34 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id, return qla2x00_post_work(vha, e); } -static +void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) +{ + fc_port_t *fcport; + unsigned long flags; + + fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); + if (fcport) { + fcport->scan_needed = 1; + fcport->rscn_gen++; + } + + spin_lock_irqsave(&vha->work_lock, flags); + if (vha->scan.scan_flags == 0) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__); + vha->scan.scan_flags |= SF_QUEUED; + schedule_delayed_work(&vha->scan.scan_work, 5); + } + spin_unlock_irqrestore(&vha->work_lock, flags); +} + void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, struct event_arg *ea) { fc_port_t *fcport = ea->fcport; + if (test_bit(UNLOADING, &vha->dpc_flags)) + return; + ql_dbg(ql_dbg_disc, vha, 0x2102, "%s %s DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n", __func__, wwn_to_str(fcport->port_name), fcport->disc_state, @@ -1781,10 +1798,9 @@ void qla_rscn_replay(fc_port_t *fcport) if (fcport->scan_needed) { memset(&ea, 0, sizeof(ea)); - ea.event = FCME_RSCN; ea.id = fcport->d_id; ea.id.b.rsvd_1 = RSCN_PORT_ADDR; - qla2x00_fcport_event_handler(fcport->vha, &ea); + qla2x00_handle_rscn(fcport->vha, &ea); } } @@ -1938,7 +1954,7 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) } } -static void +void qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) { port_id_t cid; /* conflict Nport id */ diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 4e6b8e2bb..76d8de104 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2762,8 +2762,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; ea.rc = res; - ea.event = FCME_ELS_PLOGI_DONE; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_plogi_done_event(vha, &ea); } e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 9b0947d0e..e8cc7d202 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1130,10 +1130,9 @@ global_port_update: struct event_arg ea; memset(&ea, 0, sizeof(ea)); - ea.event = FCME_RSCN; ea.id.b24 = rscn_entry; ea.id.b.rsvd_1 = rscn_entry >> 24; - qla2x00_fcport_event_handler(vha, &ea); + qla2x00_handle_rscn(vha, &ea); qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry); } break; diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 0908f2cb9..51dff760c 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5376,9 +5376,8 @@ void qla2x00_relogin(struct scsi_qla_host *vha) } else { if (vha->hw->current_topology != ISP_CFG_NL) { memset(&ea, 0, sizeof(ea)); - ea.event = FCME_RELOGIN; ea.fcport = fcport; - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_relogin_event(vha, &ea); } else if (vha->hw->current_topology == ISP_CFG_NL) { fcport->login_retry--; From 32aefe430726d416e660641ec5285772eacb5cdf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 02:45:48 +0000 Subject: [PATCH 35/44] qla2x00t-32gbit: Fix-up for r8552 git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8553 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 6 +-- qla2x00t-32gbit/qla_init.c | 81 -------------------------------------- 2 files changed, 2 insertions(+), 85 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index e4f64b0c0..c878ce06b 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -4254,14 +4254,13 @@ static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res) ea.fcport = fcport; ea.sp = sp; ea.rc = res; - ea.event = FCME_GNNID_DONE; ql_dbg(ql_dbg_disc, vha, 0x204f, "Async done-%s res %x, WWPN %s %s\n", sp->name, res, wwn_to_str(fcport->port_name), wwn_to_str(fcport->node_name)); - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gnnid_event(vha, &ea); sp->free(sp); } @@ -4386,14 +4385,13 @@ static void qla2x00_async_gfpnid_sp_done(srb_t *sp, int res) ea.fcport = fcport; ea.sp = sp; ea.rc = res; - ea.event = FCME_GFPNID_DONE; ql_dbg(ql_dbg_disc, vha, 0x204f, "Async done-%s res %x, WWPN %s %s\n", sp->name, res, wwn_to_str(fcport->port_name), wwn_to_str(fcport->fabric_port_name)); - qla2x00_fcport_event_handler(vha, &ea); + qla24xx_handle_gfpnid_event(vha, &ea); sp->free(sp); } diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index d08d7fee7..cd7cbf93b 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1700,87 +1700,6 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, } -static void qla_handle_els_plogi_done(scsi_qla_host_t *vha, - struct event_arg *ea) -{ - ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %s post PRLI\n", - __func__, __LINE__, wwn_to_str(ea->fcport->port_name)); - qla24xx_post_prli_work(vha, ea->fcport); -} - -void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) -{ - fc_port_t *fcport; - - switch (ea->event) { - case FCME_RELOGIN: - if (test_bit(UNLOADING, &vha->dpc_flags)) - return; - - qla24xx_handle_relogin_event(vha, ea); - break; - case FCME_RSCN: - if (test_bit(UNLOADING, &vha->dpc_flags)) - return; - { - unsigned long flags; - - fcport = qla2x00_find_fcport_by_nportid - (vha, &ea->id, 1); - if (fcport) { - fcport->scan_needed = 1; - fcport->rscn_gen++; - } - - spin_lock_irqsave(&vha->work_lock, flags); - if (vha->scan.scan_flags == 0) { - ql_dbg(ql_dbg_disc, vha, 0xffff, - "%s: schedule\n", __func__); - vha->scan.scan_flags |= SF_QUEUED; - schedule_delayed_work(&vha->scan.scan_work, 5); - } - spin_unlock_irqrestore(&vha->work_lock, flags); - } - break; - case FCME_GNL_DONE: - qla24xx_handle_gnl_done_event(vha, ea); - break; - case FCME_GPSC_DONE: - qla24xx_handle_gpsc_event(vha, ea); - break; - case FCME_PLOGI_DONE: /* Initiator side sent LLIOCB */ - qla24xx_handle_plogi_done_event(vha, ea); - break; - case FCME_PRLI_DONE: - qla24xx_handle_prli_done_event(vha, ea); - break; - case FCME_GPDB_DONE: - qla24xx_handle_gpdb_event(vha, ea); - break; - case FCME_GPNID_DONE: - qla24xx_handle_gpnid_event(vha, ea); - break; - case FCME_GFFID_DONE: - qla24xx_handle_gffid_event(vha, ea); - break; - case FCME_ADISC_DONE: - qla24xx_handle_adisc_event(vha, ea); - break; - case FCME_GNNID_DONE: - qla24xx_handle_gnnid_event(vha, ea); - break; - case FCME_GFPNID_DONE: - qla24xx_handle_gfpnid_event(vha, ea); - break; - case FCME_ELS_PLOGI_DONE: - qla_handle_els_plogi_done(vha, ea); - break; - default: - BUG_ON(1); - break; - } -} - /* * RSCN(s) came in for this fcport, but the RSCN(s) was not able * to be consumed by the fcport From d1367ce1245fb83fa93b81f41588fb44ccb9308d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:01:32 +0000 Subject: [PATCH 36/44] qla2x00t-32gbit: Fix two function headers git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8554 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 51dff760c..5c2c85573 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1060,8 +1060,8 @@ qc24_fail_command: * cmd = Scsi Command to wait on. * * Return: - * Not Found : 0 - * Found : 1 + * Completed in time : QLA_SUCCESS + * Did not complete in time : QLA_FUNCTION_FAILED */ static int qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) @@ -1357,6 +1357,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) return ret; } +/* + * Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED. + */ int qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, uint64_t l, enum nexus_wait_type type) From a3c05add05de7a97abed11a912b2092e5ac045e0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:02:27 +0000 Subject: [PATCH 37/44] qla2x00t-32gbit: Make sure that aborted commands are freed [ commit e43842016685a31d1a036891ffdbae647539aa27 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8555 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index d44f1c12a..b57dfda98 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -3237,7 +3237,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || (cmd->sess && cmd->sess->deleted)) { cmd->state = QLA_TGT_STATE_PROCESSED; - return 0; + res = 0; + goto free; } ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018, @@ -3248,9 +3249,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, &full_req_cnt); - if (unlikely(res != 0)) { - return res; - } + if (unlikely(res != 0)) + goto free; spin_lock_irqsave(qpair->qp_lock_ptr, flags); @@ -3270,7 +3270,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, vha->flags.online, qla2x00_reset_active(vha), cmd->reset_count, qpair->chip_reset); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - return 0; + res = 0; + goto free; } /* Does F/W have an IOCBs for this request */ @@ -3377,6 +3378,8 @@ out_unmap_unlock: qlt_unmap_sg(vha, cmd); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); +free: + vha->hw->tgt.tgt_ops->free_cmd(cmd); return res; } EXPORT_SYMBOL(qlt_xmit_response); From 0baeaf170cb1813c9651e20735150efd327e7487 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:02:56 +0000 Subject: [PATCH 38/44] qla2x00t-32gbit: Fix qla24xx_async_abort_cmd() git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8556 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index cd7cbf93b..efd1425ab 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -168,6 +168,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) wait_for_completion(&abt_iocb->u.abt.comp); rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ? QLA_SUCCESS : QLA_FUNCTION_FAILED; + sp->free(sp); } return rval; From b964872cb81460928a0bc5834e10d0cf1c8c0b36 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:03:55 +0000 Subject: [PATCH 39/44] qla2x00t-32gbit: Fix hang in fcport delete path A hang was observed in the fcport delete path when the device was responding slow and an issue-lip path (results in session termination) was taken. Fix this by issuing logo requests unconditionally. PID: 19491 TASK: ffff8e23e67bb150 CPU: 0 COMMAND: "kworker/0:0" #0 [ffff8e2370297bf8] __schedule at ffffffffb4f7dbb0 #1 [ffff8e2370297c88] schedule at ffffffffb4f7e199 #2 [ffff8e2370297c98] schedule_timeout at ffffffffb4f7ba68 #3 [ffff8e2370297d40] msleep at ffffffffb48ad9ff #4 [ffff8e2370297d58] qlt_free_session_done at ffffffffc0c32052 [qla2xxx] #5 [ffff8e2370297e20] process_one_work at ffffffffb48bcfdf #6 [ffff8e2370297e68] worker_thread at ffffffffb48bdca6 #7 [ffff8e2370297ec8] kthread at ffffffffb48c4f81 [ commit f00b3428a801 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8557 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index efd1425ab..8398615df 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -370,9 +370,6 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED; - if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) - return rval; - fcport->flags |= FCF_ASYNC_SENT; sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) From 51d92beed31d60fe3b69d5b03d5f545f6dea9c65 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:07:02 +0000 Subject: [PATCH 40/44] qla2x00t-32gbit: qla2x00_alloc_fw_dump: set ha->eft In qla2x00_alloc_fw_dump(), an existing EFT buffer (e.g. from previous invocation of qla2x00_alloc_offload_mem()) is freed. The buffer is then re-allocated, but without setting the eft and eft_dma fields to the new values. [ commit edbd56472a636ab396f5ee6783e8438fa725a6ee upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8558 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 8398615df..ffb800339 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -3199,6 +3199,8 @@ try_eft: ql_dbg(ql_dbg_init, vha, 0x00c3, "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); eft_size = EFT_SIZE; + ha->eft_dma = tc_dma; + ha->eft = tc; } if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { From 134a9fec1adaf99972713223dd8400463cb535d6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:08:18 +0000 Subject: [PATCH 41/44] qla2x00t-32gbit: Cleanup trace buffer initialization Avoid code duplication between qla2x00_alloc_offload_mem() and qla2x00_alloc_fw_dump() by moving the FCE and EFT buffer allocation and initialization to separate functions. Cleanly track failure and success by making sure that the ha->eft, ha->fce and respective eft_dma, fce_dma members are set if and only if the buffers are properly allocated and initialized. Avoid pointless buffer reallocation. Eliminate some goto statements. Make sure the fce_enabled flag is cleared when the FCE buffer is freed. [ commit 3cf92f4bfccbb3e378cd86dc46e09c2bc18cda26 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8559 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 220 +++++++++++++++++-------------------- qla2x00t-32gbit/qla_os.c | 1 + 2 files changed, 102 insertions(+), 119 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index ffb800339..0793ca48e 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -3034,103 +3034,113 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) } static void -qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) +qla2x00_init_fce_trace(scsi_qla_host_t *vha) { int rval; dma_addr_t tc_dma; void *tc; struct qla_hw_data *ha = vha->hw; + if (!IS_FWI2_CAPABLE(ha)) + return; + + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + return; + + if (ha->fce) { + ql_dbg(ql_dbg_init, vha, 0x00bd, + "%s: FCE Mem is already allocated.\n", + __func__); + return; + } + + /* Allocate memory for Fibre Channel Event Buffer. */ + tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, + GFP_KERNEL); + if (!tc) { + ql_log(ql_log_warn, vha, 0x00be, + "Unable to allocate (%d KB) for FCE.\n", + FCE_SIZE / 1024); + return; + } + + rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS, + ha->fce_mb, &ha->fce_bufs); + if (rval) { + ql_log(ql_log_warn, vha, 0x00bf, + "Unable to initialize FCE (%d).\n", rval); + dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma); + return; + } + + ql_dbg(ql_dbg_init, vha, 0x00c0, + "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024); + + ha->flags.fce_enabled = 1; + ha->fce_dma = tc_dma; + ha->fce = tc; +} + +static void +qla2x00_init_eft_trace(scsi_qla_host_t *vha) +{ + int rval; + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; + + if (!IS_FWI2_CAPABLE(ha)) + return; + if (ha->eft) { ql_dbg(ql_dbg_init, vha, 0x00bd, - "%s: Offload Mem is already allocated.\n", + "%s: EFT Mem is already allocated.\n", __func__); return; } - if (IS_FWI2_CAPABLE(ha)) { - /* Allocate memory for Fibre Channel Event Buffer. */ - if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && - !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) - goto try_eft; - - if (ha->fce) - dma_free_coherent(&ha->pdev->dev, - FCE_SIZE, ha->fce, ha->fce_dma); - - /* Allocate memory for Fibre Channel Event Buffer. */ - tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, - GFP_KERNEL); - if (!tc) { - ql_log(ql_log_warn, vha, 0x00be, - "Unable to allocate (%d KB) for FCE.\n", - FCE_SIZE / 1024); - goto try_eft; - } - - rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS, - ha->fce_mb, &ha->fce_bufs); - if (rval) { - ql_log(ql_log_warn, vha, 0x00bf, - "Unable to initialize FCE (%d).\n", rval); - dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, - tc_dma); - ha->flags.fce_enabled = 0; - goto try_eft; - } - ql_dbg(ql_dbg_init, vha, 0x00c0, - "Allocate (%d KB) for FCE...\n", FCE_SIZE / 1024); - - ha->flags.fce_enabled = 1; - ha->fce_dma = tc_dma; - ha->fce = tc; - -try_eft: - if (ha->eft) - dma_free_coherent(&ha->pdev->dev, - EFT_SIZE, ha->eft, ha->eft_dma); - - /* Allocate memory for Extended Trace Buffer. */ - tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, - GFP_KERNEL); - if (!tc) { - ql_log(ql_log_warn, vha, 0x00c1, - "Unable to allocate (%d KB) for EFT.\n", - EFT_SIZE / 1024); - goto eft_err; - } - - rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); - if (rval) { - ql_log(ql_log_warn, vha, 0x00c2, - "Unable to initialize EFT (%d).\n", rval); - dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, - tc_dma); - goto eft_err; - } - ql_dbg(ql_dbg_init, vha, 0x00c3, - "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); - - ha->eft_dma = tc_dma; - ha->eft = tc; + /* Allocate memory for Extended Trace Buffer. */ + tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, + GFP_KERNEL); + if (!tc) { + ql_log(ql_log_warn, vha, 0x00c1, + "Unable to allocate (%d KB) for EFT.\n", + EFT_SIZE / 1024); + return; } -eft_err: - return; + rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); + if (rval) { + ql_log(ql_log_warn, vha, 0x00c2, + "Unable to initialize EFT (%d).\n", rval); + dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma); + return; + } + + ql_dbg(ql_dbg_init, vha, 0x00c3, + "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); + + ha->eft_dma = tc_dma; + ha->eft = tc; +} + +static void +qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) +{ + qla2x00_init_fce_trace(vha); + qla2x00_init_eft_trace(vha); } void qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) { - int rval; uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, eft_size, fce_size, mq_size; struct qla_hw_data *ha = vha->hw; struct req_que *req = ha->req_q_map[0]; struct rsp_que *rsp = ha->rsp_q_map[0]; struct qla2xxx_fw_dump *fw_dump; - dma_addr_t tc_dma; - void *tc; dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; req_q_size = rsp_q_size = 0; @@ -3168,39 +3178,13 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) } if (ha->tgt.atio_ring) mq_size += ha->tgt.atio_q_length * sizeof(request_t); - /* Allocate memory for Fibre Channel Event Buffer. */ - if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && - !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) - goto try_eft; - fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; -try_eft: + qla2x00_init_fce_trace(vha); + if (ha->fce) + fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; + qla2x00_init_eft_trace(vha); if (ha->eft) - dma_free_coherent(&ha->pdev->dev, - EFT_SIZE, ha->eft, ha->eft_dma); - - /* Allocate memory for Extended Trace Buffer. */ - tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, - GFP_KERNEL); - if (!tc) { - ql_log(ql_log_warn, vha, 0x00c1, - "Unable to allocate (%d KB) for EFT.\n", - EFT_SIZE / 1024); - goto allocate; - } - - rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); - if (rval) { - ql_log(ql_log_warn, vha, 0x00c2, - "Unable to initialize EFT (%d).\n", rval); - dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, - tc_dma); - } - ql_dbg(ql_dbg_init, vha, 0x00c3, - "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); - eft_size = EFT_SIZE; - ha->eft_dma = tc_dma; - ha->eft = tc; + eft_size = EFT_SIZE; } if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { @@ -3222,24 +3206,22 @@ try_eft: j, fwdt->dump_size); dump_size += fwdt->dump_size; } - goto allocate; + } else { + req_q_size = req->length * sizeof(request_t); + rsp_q_size = rsp->length * sizeof(response_t); + dump_size = offsetof(struct qla2xxx_fw_dump, isp); + dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + + eft_size; + ha->chain_offset = dump_size; + dump_size += mq_size + fce_size; + if (ha->exchoffld_buf) + dump_size += sizeof(struct qla2xxx_offld_chain) + + ha->exchoffld_size; + if (ha->exlogin_buf) + dump_size += sizeof(struct qla2xxx_offld_chain) + + ha->exlogin_size; } - req_q_size = req->length * sizeof(request_t); - rsp_q_size = rsp->length * sizeof(response_t); - dump_size = offsetof(struct qla2xxx_fw_dump, isp); - dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size; - ha->chain_offset = dump_size; - dump_size += mq_size + fce_size; - - if (ha->exchoffld_buf) - dump_size += sizeof(struct qla2xxx_offld_chain) + - ha->exchoffld_size; - if (ha->exlogin_buf) - dump_size += sizeof(struct qla2xxx_offld_chain) + - ha->exlogin_size; - -allocate: if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) { ql_dbg(ql_dbg_init, vha, 0x00c5, diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 5c2c85573..0646ba1fe 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4624,6 +4624,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) ha->fce = NULL; ha->fce_dma = 0; + ha->flags.fce_enabled = 0; ha->eft = NULL; ha->eft_dma = 0; ha->fw_dumped = 0; From 787bd29c97cce222ec41c440f0b0a2027326b39e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:09:55 +0000 Subject: [PATCH 42/44] qla2xxx: Fix a NULL pointer dereference BUG: KASAN: null-ptr-deref in qla24xx_handle_plogi_done_event+0x134/0x9f0 [qla2xxx] Read of size 4 at addr 00000000000000a0 by task swapper/2/0 CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.2.0-dbg+ #1 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 Call Trace: dump_stack+0x8a/0xd6 __kasan_report.cold+0x5/0x41 kasan_report+0x16/0x20 __asan_load4+0x7e/0x80 qla24xx_handle_plogi_done_event+0x134/0x9f0 [qla2xxx] qla2x00_els_dcmd2_sp_done+0x15f/0x230 [qla2xxx] qla24xx_els_ct_entry+0x3b3/0x610 [qla2xxx] qla24xx_process_response_queue+0x514/0x10e0 [qla2xxx] qla24xx_msix_rsp_q+0x80/0x100 [qla2xxx] __handle_irq_event_percpu+0x72/0x450 handle_irq_event_percpu+0x74/0xf0 handle_irq_event+0x5e/0x8f handle_edge_irq+0x13a/0x320 handle_irq+0x30/0x40 do_IRQ+0x91/0x190 common_interrupt+0xf/0xf RIP: 0010:default_idle+0x31/0x230 [ commit d1436e456b840162eb4d162f99055d2adb79a566 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8560 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_iocb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 76d8de104..4a14f20fc 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2761,7 +2761,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) } else { memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; - ea.rc = res; + ea.data[0] = MBS_COMMAND_COMPLETE; + ea.sp = sp; qla24xx_handle_plogi_done_event(vha, &ea); } From 7970005b40c9ec1f5bd38c3b67f20368f5723a54 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:11:04 +0000 Subject: [PATCH 43/44] qla2x00t-32gbit: Check sp->fcport->deleted again in qla2xxx_eh_abort() git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8561 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 0646ba1fe..f6d2c3ff6 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1298,6 +1298,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) sp = scsi_cmd_priv(cmd); + if (sp->fcport && sp->fcport->deleted) + return SUCCESS; + /* Return if the command has already finished. */ if (sp_get(sp)) return SUCCESS; From 0dc0a43a08d8f93a28feef9dea9ae37ef28a3fd3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 25 Aug 2019 03:21:06 +0000 Subject: [PATCH 44/44] qla2x00t-32gbit: Minimize diffs with trunk git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8562 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 0793ca48e..a8a136edf 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1687,7 +1687,7 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, } if (fcport->last_rscn_gen != fcport->rscn_gen) { - ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %s post gidpn\n", + ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %s post gnl\n", __func__, __LINE__, wwn_to_str(fcport->port_name)); qla24xx_post_gnl_work(vha, fcport); @@ -1697,7 +1697,6 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, qla24xx_fcport_handle_login(vha, fcport); } - /* * RSCN(s) came in for this fcport, but the RSCN(s) was not able * to be consumed by the fcport