From 8f610f6f1407f0f4bb341263edc21c56c57709f5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 02:08:49 +0000 Subject: [PATCH 01/13] nightly build: Update kernel versions git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8326 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- nightly/conf/nightly.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nightly/conf/nightly.conf b/nightly/conf/nightly.conf index 23a926057..a0131879b 100644 --- a/nightly/conf/nightly.conf +++ b/nightly/conf/nightly.conf @@ -28,7 +28,7 @@ ABT_KERNELS=" \ 3.19.8-nc \ 3.18.139-nc \ 3.17.8-nc \ -3.16.65-nc \ +3.16.66-nc \ 3.15.10-nc \ 3.14.79-nc \ 3.13.11-nc \ From ce3a4e22b51b3127541c4c922cd8b380f7075ae0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 02:09:47 +0000 Subject: [PATCH 02/13] qla2x00t-32gbit: Fix session lookup in qlt_abort_work() Pass the correct session ID to find_sess_by_s_id() instead of passing an uninitialized variable. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8327 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 1d94287e0..681585d39 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -6302,7 +6302,6 @@ static void qlt_abort_work(struct qla_tgt *tgt, struct qla_hw_data *ha = vha->hw; struct fc_port *sess = NULL; unsigned long flags = 0, flags2 = 0; - uint32_t be_s_id; uint8_t s_id[3]; int rc; @@ -6315,8 +6314,7 @@ static void qlt_abort_work(struct qla_tgt *tgt, s_id[1] = prm->abts.fcp_hdr_le.s_id[1]; s_id[2] = prm->abts.fcp_hdr_le.s_id[0]; - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, - (unsigned char *)&be_s_id); + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); if (!sess) { spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); From d70d9127d4dce732ccfa3d85b03bc375c9aedc6e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 02:11:45 +0000 Subject: [PATCH 03/13] qla2x00t-32gbit: Reduce the number of casts This patch makes the code easier to read but does not change the behavior of the modified code. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8328 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dfs.c | 9 +++------ qla2x00t-32gbit/qla_init.c | 18 ++++++++---------- qla2x00t-32gbit/qla_target.c | 9 +++------ 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index 006849590..6c39e64dd 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -57,10 +57,9 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) { scsi_qla_host_t *vha = s->private; struct qla_hw_data *ha = vha->hw; - struct gid_list_info *gid_list; + struct gid_list_info *gid_list, *gid; dma_addr_t gid_list_dma; fc_port_t fc_port; - char *id_iter; int rc, i; uint16_t entries, loop_id; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; @@ -82,13 +81,11 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) if (rc != QLA_SUCCESS) goto out_free_id_list; - id_iter = (char *)gid_list; + gid = gid_list; seq_puts(s, "Port Name Port ID Loop ID\n"); for (i = 0; i < entries; i++) { - struct gid_list_info *gid = - (struct gid_list_info *)id_iter; loop_id = le16_to_cpu(gid->loop_id); memset(&fc_port, 0, sizeof(fc_port_t)); @@ -99,7 +96,7 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) wwn_to_str(fc_port.port_name), fc_port.d_id.b.domain, fc_port.d_id.b.area, fc_port.d_id.b.al_pa, fc_port.loop_id); - id_iter += ha->gid_list_info_size; + gid = (void *)gid + ha->gid_list_info_size; } out_free_id_list: dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 8a22e23b3..8a44e476e 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5054,7 +5054,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) uint16_t index; uint16_t entries; - char *id_iter; + struct gid_list_info *gid; uint16_t loop_id; uint8_t domain, area, al_pa; struct qla_hw_data *ha = vha->hw; @@ -5129,18 +5129,16 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) new_fcport->flags &= ~FCF_FABRIC_DEVICE; /* Add devices to port list. */ - id_iter = (char *)ha->gid_list; + gid = ha->gid_list; for (index = 0; index < entries; index++) { - domain = ((struct gid_list_info *)id_iter)->domain; - area = ((struct gid_list_info *)id_iter)->area; - al_pa = ((struct gid_list_info *)id_iter)->al_pa; + domain = gid->domain; + area = gid->area; + al_pa = gid->al_pa; if (IS_QLA2100(ha) || IS_QLA2200(ha)) - loop_id = (uint16_t) - ((struct gid_list_info *)id_iter)->loop_id_2100; + loop_id = gid->loop_id_2100; else - loop_id = le16_to_cpu( - ((struct gid_list_info *)id_iter)->loop_id); - id_iter += ha->gid_list_info_size; + loop_id = le16_to_cpu(gid->loop_id); + gid = (void *)gid + ha->gid_list_info_size; /* Bypass reserved domain fields. */ if ((domain & 0xf0) == 0xf0) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 681585d39..9c39d58f9 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1308,8 +1308,7 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, { struct qla_hw_data *ha = vha->hw; dma_addr_t gid_list_dma; - struct gid_list_info *gid_list; - char *id_iter; + struct gid_list_info *gid_list, *gid; int res, rc, i; uint16_t entries; @@ -1332,11 +1331,9 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, goto out_free_id_list; } - id_iter = (char *)gid_list; + gid = gid_list; res = -ENOENT; for (i = 0; i < entries; i++) { - struct gid_list_info *gid = (struct gid_list_info *)id_iter; - if ((gid->al_pa == s_id[2]) && (gid->area == s_id[1]) && (gid->domain == s_id[0])) { @@ -1344,7 +1341,7 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, res = 0; break; } - id_iter += ha->gid_list_info_size; + gid = (void *)gid + ha->gid_list_info_size; } out_free_id_list: From 9b5227ceb907d29e79c994655237aa68bedec129 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:04:50 +0000 Subject: [PATCH 04/13] qla2x00t-32gbit: Introduce the be_id_t and le_id_t data types for FC src/dst IDs Introduce the be_id_t and le_id_t data types for Fibre Channel source and destination ID formats supported by the firmware instead of using an uint8_t[3] array. Introduce functions for converting from and to the port_id_t data types. An advantage of this patch is that it makes the compiler verify the endianness of Fibre Channel IDs. This patch changes the behavior of the following functions: - qlt_abort_work(). Instead of passing the address of an uninitialized variable to find_sess_by_s_id(), pass the S_ID. - qlt_24xx_retry_term_exchange(). Store a little endian ID in the initiator_id field of type 7 CTIO packets instead of a big endian ID since other qla2xxx code also stores a little endan ID in this field. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8329 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c | 8 +- qla2x00t-32gbit/qla_def.h | 59 ++++++++ qla2x00t-32gbit/qla_nvme.h | 2 +- qla2x00t-32gbit/qla_target.c | 129 ++++++------------ qla2x00t-32gbit/qla_target.h | 33 ++--- 5 files changed, 120 insertions(+), 111 deletions(-) diff --git a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c index a0f1e1771..a9bdf3b2f 100644 --- a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c +++ b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c @@ -801,7 +801,7 @@ free_sess: } static struct fc_port *sqa_qla2xxx_find_sess_by_s_id(scsi_qla_host_t *vha, - const uint8_t *s_id) + be_id_t s_id) { struct fc_port *sess; @@ -812,9 +812,9 @@ static struct fc_port *sqa_qla2xxx_find_sess_by_s_id(scsi_qla_host_t *vha, s_id[1], s_id[2]); #endif list_for_each_entry(sess, &vha->vp_fcports, list) { - if ((sess->d_id.b.al_pa == s_id[2]) && - (sess->d_id.b.area == s_id[1]) && - (sess->d_id.b.domain == s_id[0]) && + if (sess->d_id.b.al_pa == s_id.al_pa && + sess->d_id.b.area == s_id.area && + sess->d_id.b.domain == s_id.domain && !sess->deleted && sess->se_sess) return sess; } diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index b1257674d..4f78539dd 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -48,6 +48,20 @@ #define NEW_LIBFC_API #endif +/* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */ +typedef struct { + uint8_t domain; + uint8_t area; + uint8_t al_pa; +} be_id_t; + +/* Little endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */ +typedef struct { + uint8_t al_pa; + uint8_t area; + uint8_t domain; +} le_id_t; + #include "qla_bsg.h" #include "qla_dsd.h" #include "qla_nx.h" @@ -357,6 +371,51 @@ typedef union { } port_id_t; #define INVALID_PORT_ID 0xFFFFFF +static inline le_id_t be_id_to_le(be_id_t id) +{ + le_id_t res; + + res.domain = id.domain; + res.area = id.area; + res.al_pa = id.al_pa; + + return res; +} + +static inline be_id_t le_id_to_be(le_id_t id) +{ + be_id_t res; + + res.domain = id.domain; + res.area = id.area; + res.al_pa = id.al_pa; + + return res; +} + +static inline port_id_t be_to_port_id(be_id_t id) +{ + port_id_t res; + + res.b.domain = id.domain; + res.b.area = id.area; + res.b.al_pa = id.al_pa; + res.b.rsvd_1 = 0; + + return res; +} + +static inline be_id_t port_id_to_be_id(port_id_t port_id) +{ + be_id_t res; + + res.domain = port_id.b.domain; + res.area = port_id.b.area; + res.al_pa = port_id.b.al_pa; + + return res; +} + struct els_logo_payload { uint8_t opcode; uint8_t rsvd[3]; diff --git a/qla2x00t-32gbit/qla_nvme.h b/qla2x00t-32gbit/qla_nvme.h index cb18c32d0..8d26bb6b2 100644 --- a/qla2x00t-32gbit/qla_nvme.h +++ b/qla2x00t-32gbit/qla_nvme.h @@ -120,7 +120,7 @@ struct pt_ls4_rx_unsol { uint32_t exchange_address; uint8_t d_id[3]; uint8_t r_ctl; - uint8_t s_id[3]; + be_id_t s_id; uint8_t cs_ctl; uint8_t f_ctl[3]; uint8_t type; diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 9c39d58f9..7e4d04384 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -210,18 +210,19 @@ static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked) static inline struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, - uint8_t *d_id) + be_id_t d_id) { struct scsi_qla_host *host; uint32_t key = 0; - if ((vha->d_id.b.area == d_id[1]) && (vha->d_id.b.domain == d_id[0]) && - (vha->d_id.b.al_pa == d_id[2])) + if (vha->d_id.b.area == d_id.area && + vha->d_id.b.domain == d_id.domain && + vha->d_id.b.al_pa == d_id.al_pa) return vha; - key = (uint32_t)d_id[0] << 16; - key |= (uint32_t)d_id[1] << 8; - key |= (uint32_t)d_id[2]; + key = d_id.domain << 16; + key |= d_id.area << 8; + key |= d_id.al_pa; host = btree_lookup32(&vha->hw->tgt.host_map, key); if (!host) @@ -379,9 +380,9 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, ql_dbg(ql_dbg_tgt, vha, 0xe03e, "qla_target(%d): Received ATIO_TYPE7 " "with unknown d_id %x:%x:%x\n", vha->vp_idx, - atio->u.isp24.fcp_hdr.d_id[0], - atio->u.isp24.fcp_hdr.d_id[1], - atio->u.isp24.fcp_hdr.d_id[2]); + atio->u.isp24.fcp_hdr.d_id.domain, + atio->u.isp24.fcp_hdr.d_id.area, + atio->u.isp24.fcp_hdr.d_id.al_pa); qlt_queue_unknown_atio(vha, atio, ha_locked); @@ -1303,7 +1304,7 @@ static void qlt_clear_tgt_db(struct qla_tgt *tgt) /* At this point tgt could be already dead */ } -static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, +static int qla24xx_get_loop_id(struct scsi_qla_host *vha, be_id_t s_id, uint16_t *loop_id) { struct qla_hw_data *ha = vha->hw; @@ -1334,9 +1335,9 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, gid = gid_list; res = -ENOENT; for (i = 0; i < entries; i++) { - if ((gid->al_pa == s_id[2]) && - (gid->area == s_id[1]) && - (gid->domain == s_id[0])) { + if (gid->al_pa == s_id.al_pa && + gid->area == s_id.area && + gid->domain == s_id.domain) { *loop_id = le16_to_cpu(gid->loop_id); res = 0; break; @@ -1787,12 +1788,8 @@ static int qlt_build_abts_resp_iocb(struct qla_tgt_mgmt_cmd *mcmd) resp->fcp_hdr_le.f_ctl[1] = *p++; resp->fcp_hdr_le.f_ctl[2] = *p; - resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.s_id[0]; - resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.s_id[1]; - resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.s_id[2]; - resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.d_id[0]; - resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.d_id[1]; - resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.d_id[2]; + resp->fcp_hdr_le.d_id = abts->fcp_hdr_le.s_id; + resp->fcp_hdr_le.s_id = abts->fcp_hdr_le.d_id; resp->exchange_addr_to_abort = abts->exchange_addr_to_abort; if (mcmd->fc_tm_rsp == FCP_TMF_CMPL) { @@ -1863,19 +1860,11 @@ static void qlt_24xx_send_abts_resp(struct qla_qpair *qpair, resp->fcp_hdr_le.f_ctl[1] = *p++; resp->fcp_hdr_le.f_ctl[2] = *p; if (ids_reversed) { - resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.d_id[0]; - resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.d_id[1]; - resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.d_id[2]; - resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.s_id[0]; - resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.s_id[1]; - resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.s_id[2]; + resp->fcp_hdr_le.d_id = abts->fcp_hdr_le.d_id; + resp->fcp_hdr_le.s_id = abts->fcp_hdr_le.s_id; } else { - resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.s_id[0]; - resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.s_id[1]; - resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.s_id[2]; - resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.d_id[0]; - resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.d_id[1]; - resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.d_id[2]; + resp->fcp_hdr_le.d_id = abts->fcp_hdr_le.s_id; + resp->fcp_hdr_le.s_id = abts->fcp_hdr_le.d_id; } resp->exchange_addr_to_abort = abts->exchange_addr_to_abort; if (status == FCP_TMF_CMPL) { @@ -1942,18 +1931,14 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, tmp = (CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_TERMINATE); if (mcmd) { - ctio->initiator_id[0] = entry->fcp_hdr_le.s_id[0]; - ctio->initiator_id[1] = entry->fcp_hdr_le.s_id[1]; - ctio->initiator_id[2] = entry->fcp_hdr_le.s_id[2]; + ctio->initiator_id = entry->fcp_hdr_le.s_id; if (mcmd->flags & QLA24XX_MGMT_ABORT_IO_ATTR_VALID) tmp |= (mcmd->abort_io_attr << 9); else if (qpair->retry_term_cnt & 1) tmp |= (0x4 << 9); } else { - ctio->initiator_id[0] = entry->fcp_hdr_le.d_id[0]; - ctio->initiator_id[1] = entry->fcp_hdr_le.d_id[1]; - ctio->initiator_id[2] = entry->fcp_hdr_le.d_id[2]; + ctio->initiator_id = entry->fcp_hdr_le.d_id; if (qpair->retry_term_cnt & 1) tmp |= (0x4 << 9); @@ -1987,8 +1972,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, * XXX does not go through the list of other port (which may have cmds * for the same lun) */ -static void abort_cmds_for_lun(struct scsi_qla_host *vha, - u64 lun, uint8_t *s_id) +static void abort_cmds_for_lun(struct scsi_qla_host *vha, u64 lun, be_id_t s_id) { struct qla_tgt_sess_op *op; struct qla_tgt_cmd *cmd; @@ -2172,7 +2156,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, struct qla_hw_data *ha = vha->hw; struct fc_port *sess; uint32_t tag = abts->exchange_addr_to_abort; - uint8_t s_id[3]; + be_id_t s_id; int rc; unsigned long flags; @@ -2196,13 +2180,11 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf011, "qla_target(%d): task abort (s_id=%x:%x:%x, " - "tag=%d, param=%x)\n", vha->vp_idx, abts->fcp_hdr_le.s_id[2], - abts->fcp_hdr_le.s_id[1], abts->fcp_hdr_le.s_id[0], tag, + "tag=%d, param=%x)\n", vha->vp_idx, abts->fcp_hdr_le.s_id.domain, + abts->fcp_hdr_le.s_id.area, abts->fcp_hdr_le.s_id.al_pa, tag, le32_to_cpu(abts->fcp_hdr_le.parameter)); - s_id[0] = abts->fcp_hdr_le.s_id[2]; - s_id[1] = abts->fcp_hdr_le.s_id[1]; - s_id[2] = abts->fcp_hdr_le.s_id[0]; + s_id = le_id_to_be(abts->fcp_hdr_le.s_id); spin_lock_irqsave(&ha->tgt.sess_lock, flags); sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); @@ -2266,9 +2248,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct qla_qpair *qpair, ctio->nport_handle = mcmd->sess->loop_id; ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); ctio->vp_index = ha->vp_idx; - ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; + ctio->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); ctio->exchange_addr = atio->u.isp24.exchange_addr; temp = (atio->u.isp24.attr << 9)| CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS; @@ -2325,9 +2305,7 @@ void qlt_send_resp_ctio(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, ctio->nport_handle = cmd->sess->loop_id; ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); ctio->vp_index = vha->vp_idx; - ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; + ctio->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); ctio->exchange_addr = atio->u.isp24.exchange_addr; temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS; @@ -2635,9 +2613,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair, pkt->handle |= CTIO_COMPLETION_HANDLE_MARK; pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id); pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); - pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; + pkt->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); pkt->exchange_addr = atio->u.isp24.exchange_addr; temp = atio->u.isp24.attr << 9; pkt->u.status0.flags |= cpu_to_le16(temp); @@ -3151,9 +3127,7 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) pkt->handle |= CTIO_COMPLETION_HANDLE_MARK; pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id); pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); - pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; + pkt->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); pkt->exchange_addr = atio->u.isp24.exchange_addr; /* silence compile warning */ @@ -3725,9 +3699,7 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair, ctio24->nport_handle = CTIO7_NHANDLE_UNRECOGNIZED; ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); ctio24->vp_index = vha->vp_idx; - ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; + ctio24->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); ctio24->exchange_addr = atio->u.isp24.exchange_addr; temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_TERMINATE; @@ -4195,8 +4167,7 @@ static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha, return fcp_task_attr; } -static struct fc_port *qlt_make_local_sess(struct scsi_qla_host *, - uint8_t *); +static struct fc_port *qlt_make_local_sess(struct scsi_qla_host *, be_id_t); /* * Process context for I/O path into tcm_qla2xxx code */ @@ -4436,9 +4407,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, return -ENODEV; } - id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2]; - id.b.area = atio->u.isp24.fcp_hdr.s_id[1]; - id.b.domain = atio->u.isp24.fcp_hdr.s_id[0]; + id = be_to_port_id(atio->u.isp24.fcp_hdr.s_id); if (IS_SW_RESV_ADDR(id)) return -EBUSY; @@ -5410,10 +5379,7 @@ static int __qlt_send_busy(struct qla_qpair *qpair, u16 temp; port_id_t id; - id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2]; - id.b.area = atio->u.isp24.fcp_hdr.s_id[1]; - id.b.domain = atio->u.isp24.fcp_hdr.s_id[0]; - id.b.rsvd_1 = 0; + id = be_to_port_id(atio->u.isp24.fcp_hdr.s_id); spin_lock_irqsave(&ha->tgt.sess_lock, flags); sess = qla2x00_find_fcport_by_nportid(vha, &id, 1); @@ -5441,9 +5407,7 @@ static int __qlt_send_busy(struct qla_qpair *qpair, ctio24->nport_handle = sess->loop_id; ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); ctio24->vp_index = vha->vp_idx; - ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; + ctio24->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); ctio24->exchange_addr = atio->u.isp24.exchange_addr; temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS | @@ -6223,21 +6187,21 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, /* Must be called under tgt_mutex */ static struct fc_port *qlt_make_local_sess(struct scsi_qla_host *vha, - uint8_t *s_id) + be_id_t s_id) { struct fc_port *sess = NULL; fc_port_t *fcport = NULL; int rc, global_resets; uint16_t loop_id = 0; - if ((s_id[0] == 0xFF) && (s_id[1] == 0xFC)) { + if (s_id.domain == 0xFF && s_id.area == 0xFC) { /* * This is Domain Controller, so it should be * OK to drop SCSI commands from it. */ ql_dbg(ql_dbg_tgt_mgt, vha, 0xf042, "Unable to find initiator with S_ID %x:%x:%x", - s_id[0], s_id[1], s_id[2]); + s_id.domain, s_id.area, s_id.al_pa); return NULL; } @@ -6254,13 +6218,12 @@ retry: ql_log(ql_log_info, vha, 0xf071, "qla_target(%d): Unable to find " "initiator with S_ID %x:%x:%x", - vha->vp_idx, s_id[0], s_id[1], - s_id[2]); + vha->vp_idx, s_id.domain, s_id.area, s_id.al_pa); if (rc == -ENOENT) { qlt_port_logo_t logo; - sid_to_portid(s_id, &logo.id); + logo.id = be_to_port_id(s_id); logo.cmd_count = 1; qlt_send_first_logo(vha, &logo); } @@ -6299,7 +6262,7 @@ static void qlt_abort_work(struct qla_tgt *tgt, struct qla_hw_data *ha = vha->hw; struct fc_port *sess = NULL; unsigned long flags = 0, flags2 = 0; - uint8_t s_id[3]; + be_id_t s_id; int rc; spin_lock_irqsave(&ha->tgt.sess_lock, flags2); @@ -6307,9 +6270,7 @@ static void qlt_abort_work(struct qla_tgt *tgt, if (tgt->tgt_stop) goto out_term2; - s_id[0] = prm->abts.fcp_hdr_le.s_id[2]; - s_id[1] = prm->abts.fcp_hdr_le.s_id[1]; - s_id[2] = prm->abts.fcp_hdr_le.s_id[0]; + s_id = le_id_to_be(prm->abts.fcp_hdr_le.s_id); sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); if (!sess) { @@ -6366,7 +6327,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt, struct qla_hw_data *ha = vha->hw; struct fc_port *sess; unsigned long flags; - uint8_t *s_id = NULL; /* to hide compiler warnings */ + be_id_t s_id; int rc; u64 unpacked_lun; int fn; @@ -6915,7 +6876,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, + &pkt->u.isp24.fcp_hdr.s_id.domain, be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id), le32_to_cpu(pkt->u.isp24.exchange_addr), pkt); diff --git a/qla2x00t-32gbit/qla_target.h b/qla2x00t-32gbit/qla_target.h index cee4e9cb5..3dc079ee3 100644 --- a/qla2x00t-32gbit/qla_target.h +++ b/qla2x00t-32gbit/qla_target.h @@ -283,9 +283,9 @@ struct ctio_to_2xxx { struct fcp_hdr { uint8_t r_ctl; - uint8_t d_id[3]; + be_id_t d_id; uint8_t cs_ctl; - uint8_t s_id[3]; + be_id_t s_id; uint8_t type; uint8_t f_ctl[3]; uint8_t seq_id; @@ -297,9 +297,9 @@ struct fcp_hdr { } __packed; struct fcp_hdr_le { - uint8_t d_id[3]; + le_id_t d_id; uint8_t r_ctl; - uint8_t s_id[3]; + le_id_t s_id; uint8_t cs_ctl; uint8_t f_ctl[3]; uint8_t type; @@ -438,7 +438,7 @@ struct ctio7_to_24xx { uint16_t dseg_count; /* Data segment count. */ uint8_t vp_index; uint8_t add_flags; - uint8_t initiator_id[3]; + le_id_t initiator_id; uint8_t reserved; uint32_t exchange_addr; union { @@ -534,7 +534,7 @@ struct ctio_crc2_to_fw { uint8_t add_flags; /* additional flags */ #define CTIO_CRC2_AF_DIF_DSD_ENA BIT_3 - uint8_t initiator_id[3]; /* initiator ID */ + le_id_t initiator_id; /* initiator ID */ uint8_t reserved1; uint32_t exchange_addr; /* rcv exchange address */ uint16_t reserved2; @@ -719,7 +719,7 @@ struct qla_tgt_func_tmpl { struct fc_port *(*find_sess_by_loop_id)(struct scsi_qla_host *, const uint16_t); struct fc_port *(*find_sess_by_s_id)(struct scsi_qla_host *, - const uint8_t *); + const be_id_t); void (*clear_nacl_from_fcport_map)(struct fc_port *); void (*put_sess)(struct fc_port *); void (*shutdown_sess)(struct fc_port *); @@ -1085,22 +1085,11 @@ static inline bool qla_dual_mode_enabled(struct scsi_qla_host *ha) return (ha->host->active_mode == MODE_DUAL); } -static inline uint32_t sid_to_key(const uint8_t *s_id) +static inline uint32_t sid_to_key(const be_id_t s_id) { - uint32_t key; - - key = (((unsigned long)s_id[0] << 16) | - ((unsigned long)s_id[1] << 8) | - (unsigned long)s_id[2]); - return key; -} - -static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p) -{ - memset(p, 0, sizeof(*p)); - p->b.domain = s_id[0]; - p->b.area = s_id[1]; - p->b.al_pa = s_id[2]; + return s_id.domain << 16 | + s_id.area << 8 | + s_id.al_pa; } /* From 6fdebad49e1713cb756e66f2d1388ae159514baf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:05:36 +0000 Subject: [PATCH 05/13] qla2x00t-32gbit, target: Fix offline port handling and host reset handling git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8330 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 9 ++------ qla2x00t-32gbit/qla_target.c | 41 ++++-------------------------------- qla2x00t-32gbit/qla_target.h | 11 +++++++--- 3 files changed, 14 insertions(+), 47 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 84bc3e73b..6d057e3f6 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1849,15 +1849,10 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) continue; } cmd = (struct qla_tgt_cmd *)sp; - qlt_abort_cmd_on_host_reset(cmd->vha, cmd); + cmd->aborted = 1; break; case TYPE_TGT_TMCMD: - /* - * Currently, only ABTS response gets on the - * outstanding_cmds[] - */ - ha->tgt.tgt_ops->free_mcmd( - (struct qla_tgt_mgmt_cmd *)sp); + /* Skip task management functions. */ break; default: break; diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 7e4d04384..d4085a501 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -3245,7 +3245,6 @@ 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; - qlt_abort_cmd_on_host_reset(cmd->vha, cmd); return 0; } @@ -3274,7 +3273,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, * previous life, just abort the processing. */ cmd->state = QLA_TGT_STATE_PROCESSED; - qlt_abort_cmd_on_host_reset(cmd->vha, cmd); ql_dbg_qp(ql_dbg_async, qpair, 0xe101, "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n", vha->flags.online, qla2x00_reset_active(vha), @@ -3419,8 +3417,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) * Either the port is not online or this request was from * previous life, just abort the processing. */ - cmd->state = QLA_TGT_STATE_NEED_DATA; - qlt_abort_cmd_on_host_reset(cmd->vha, cmd); + cmd->aborted = 1; + cmd->write_data_transferred = 0; + cmd->state = QLA_TGT_STATE_DATA_IN; + vha->hw->tgt.tgt_ops->handle_data(cmd); ql_dbg_qp(ql_dbg_async, qpair, 0xe102, "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n", vha->flags.online, qla2x00_reset_active(vha), @@ -3953,39 +3953,6 @@ static void *qlt_ctio_to_cmd(struct scsi_qla_host *vha, return cmd; } -/* hardware_lock should be held by caller. */ -void -qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) -{ - struct qla_hw_data *ha = vha->hw; - - if (cmd->sg_mapped) - qlt_unmap_sg(vha, cmd); - - /* TODO: fix debug message type and ids. */ - if (cmd->state == QLA_TGT_STATE_PROCESSED) { - ql_dbg(ql_dbg_io, vha, 0xff00, - "HOST-ABORT: state=PROCESSED.\n"); - } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { - cmd->write_data_transferred = 0; - cmd->state = QLA_TGT_STATE_DATA_IN; - - ql_dbg(ql_dbg_io, vha, 0xff01, - "HOST-ABORT: state=DATA_IN.\n"); - - ha->tgt.tgt_ops->handle_data(cmd); - return; - } else { - ql_dbg(ql_dbg_io, vha, 0xff03, - "HOST-ABORT: state=BAD(%d).\n", - cmd->state); - dump_stack(); - } - - cmd->trc_flags |= TRC_FLUSH; - ha->tgt.tgt_ops->free_cmd(cmd); -} - /* * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire */ diff --git a/qla2x00t-32gbit/qla_target.h b/qla2x00t-32gbit/qla_target.h index 3dc079ee3..c32df252b 100644 --- a/qla2x00t-32gbit/qla_target.h +++ b/qla2x00t-32gbit/qla_target.h @@ -929,9 +929,16 @@ struct qla_tgt_cmd { unsigned int term_exchg:1; unsigned int cmd_sent_to_fw:1; unsigned int cmd_in_wq:1; - unsigned int aborted:1; unsigned int released:1; + /* + * This variable may be set from outside the LIO and I/O completion + * callback functions. Do not declare this member variable as a + * bitfield to avoid a read-modify-write operation when this variable + * is set. + */ + unsigned int aborted; + struct scatterlist *sg; /* cmd data buffer SG vector */ int sg_cnt; /* SG segments count */ int bufflen; /* cmd buffer length */ @@ -1135,7 +1142,5 @@ extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); void qlt_send_resp_ctio(struct qla_qpair *, struct qla_tgt_cmd *, uint8_t, uint8_t, uint8_t, uint8_t); -extern void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *, - struct qla_tgt_cmd *); #endif /* __QLA_TARGET_H */ From b51d8572b4a8841056a92dd09ea83536cd713205 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:06:06 +0000 Subject: [PATCH 06/13] qla2x00t-32gbit: qla2xxx_eh_abort(): Minimize diffs with upstream git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8331 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 6d057e3f6..22f8e42cb 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1338,7 +1338,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) ret = fc_block_scsi_eh(cmd); if (ret != 0) return ret; - ret = SUCCESS; sp = (srb_t *) CMD_SP(cmd); if (!sp) @@ -1350,10 +1349,13 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) 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); @@ -1368,8 +1370,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); - /* Get a reference to the sp and drop the lock.*/ - ret = SUCCESS; rval = ha->isp_ops->abort_command(sp); ql_dbg(ql_dbg_taskm, vha, 0x8003, @@ -1377,7 +1377,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) switch (rval) { case QLA_SUCCESS: - /* The command has been aborted. */ + /* + * The command has been aborted. That means that the firmware + * won't report a completion. + */ sp->done(sp, DID_ABORT << 16); break; case QLA_FUNCTION_PARAMETER_ERROR: From 3e0f29be4427959a69c584171d205f7f1b5af01b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:06:33 +0000 Subject: [PATCH 07/13] qla2x00t-32gbit: qla2x00_sp_compl(): Minimize diffs with upstream git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8332 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 22f8e42cb..3104433a3 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -742,7 +742,7 @@ qla2x00_sp_compl(void *ptr, int res) struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; - if (WARN_ON(atomic_read(&sp->ref_count) == 0)) + if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) return; atomic_dec(&sp->ref_count); @@ -849,7 +849,7 @@ qla2xxx_qpair_sp_compl(void *ptr, int res) struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; - if (WARN_ON(atomic_read(&sp->ref_count) == 0)) + if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) return; atomic_dec(&sp->ref_count); From 3944c80f4b1818c5706e0e00401ed5bc3ba9ac26 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:07:03 +0000 Subject: [PATCH 08/13] qla2x00t-32gbit, target: Remove an unused member variable git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8333 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.h | 1 - 1 file changed, 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_target.h b/qla2x00t-32gbit/qla_target.h index c32df252b..17bde2b5d 100644 --- a/qla2x00t-32gbit/qla_target.h +++ b/qla2x00t-32gbit/qla_target.h @@ -929,7 +929,6 @@ struct qla_tgt_cmd { unsigned int term_exchg:1; unsigned int cmd_sent_to_fw:1; unsigned int cmd_in_wq:1; - unsigned int released:1; /* * This variable may be set from outside the LIO and I/O completion From 3d3163759bd36e1acf8a55f87de2b9ff9c2fa7ce Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:08:12 +0000 Subject: [PATCH 09/13] qla2x00t-32gbit, target: Remove unnecessary locking from the target code All callbacks from the target core into the qla2xxx driver and also all I/O completion functions are serialized per command. Since .cmd_sent_to_fw and .trc_flags are only modified from inside these functions it is not necessary to protect it with locking. Remove the superfluous locking. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8334 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index d4085a501..b13b04a6b 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -3368,9 +3368,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */ - spin_lock(&cmd->cmd_lock); cmd->cmd_sent_to_fw = 1; - spin_unlock(&cmd->cmd_lock); cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags); /* Memory Barrier */ @@ -3455,9 +3453,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) qlt_load_data_segments(&prm); cmd->state = QLA_TGT_STATE_NEED_DATA; - spin_lock(&cmd->cmd_lock); cmd->cmd_sent_to_fw = 1; - spin_unlock(&cmd->cmd_lock); cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags); /* Memory Barrier */ From eb6a71a76bb4a47a3ffce9be47dbd1b469e84d47 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:08:45 +0000 Subject: [PATCH 10/13] qla2x00t-32gbit: Make qla24xx_async_abort_cmd() static Since qla24xx_async_abort_cmd() is only called from inside qla_init.c, declare that function static. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8335 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gbl.h | 1 - qla2x00t-32gbit/qla_init.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index f303a7935..b58428f16 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -224,7 +224,6 @@ extern void qla24xx_sched_upd_fcport(fc_port_t *); void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, uint16_t *); int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); -int qla24xx_async_abort_cmd(srb_t *, bool); int qla24xx_post_relogin_work(struct scsi_qla_host *vha); void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *); diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 8a44e476e..48ca26288 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -115,7 +115,7 @@ static void qla24xx_abort_sp_done(void *ptr, int res) sp->free(sp); } -int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) +static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) { scsi_qla_host_t *vha = cmd_sp->vha; struct srb_iocb *abt_iocb; From 302850c3b119ce93778dbc00ad025a09cb9a5bba Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:09:32 +0000 Subject: [PATCH 11/13] qla2x00t-32gbit, qla2x00_set_fcport_state(): Minimize diffs with upstream git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8336 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 48ca26288..ef4c3abcc 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4818,11 +4818,10 @@ void qla2x00_set_fcport_state(fc_port_t *fcport, int state) /* Don't print state transitions during initial allocation of fcport */ if (old_state && old_state != state) { ql_dbg(ql_dbg_disc, fcport->vha, 0x207d, - "FCPort %s state transitioned from %s to %s - " - "portid=%02x%02x%02x.\n", wwn_to_str(fcport->port_name), - port_state_str[old_state], port_state_str[state], - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); + "FCPort %8phC state transitioned from %s to %s - portid=%02x%02x%02x.\n", + fcport->port_name, port_state_str[old_state], + port_state_str[state], fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa); } } From 6c9dddf26fc6e0720d5488197a38e4eabe476ca5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:10:54 +0000 Subject: [PATCH 12/13] qla2xxx-32gbit: Move the qla2x00_rel_sp() calls from *_free_dma() into *_sp_compl() See also upstream commit 711a08d79f71 ("scsi: qla2xxx: Change abort wait_loop from msleep to wait_event_timeout"). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8337 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 - qla2x00t-32gbit/qla_os.c | 19 +++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 4f78539dd..5d19ce746 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -4837,5 +4837,4 @@ struct sff_8247_a0 { #include "qla_gbl.h" #include "qla_dbg.h" #include "qla_inline.h" - #endif diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 3104433a3..a2d46572a 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -702,7 +702,7 @@ qla2x00_sp_free_dma(void *ptr) } if (!ctx) - goto end; + return; if (sp->flags & SRB_CRC_CTX_DSD_VALID) { /* List assured to be having elements */ @@ -727,12 +727,6 @@ qla2x00_sp_free_dma(void *ptr) ha->gbl_dsd_avail += ctx1->dsd_use_cnt; mempool_free(ctx1, ha->ctx_mempool); } - -end: - if (sp->type != SRB_NVME_CMD && sp->type != SRB_NVME_LS) { - CMD_SP(cmd) = NULL; - qla2x00_rel_sp(sp); - } } void @@ -749,9 +743,11 @@ qla2x00_sp_compl(void *ptr, int res) sp->free(sp); cmd->result = res; + CMD_SP(cmd) = NULL; cmd->scsi_done(cmd); if (comp) complete(comp); + qla2x00_rel_sp(sp); } void @@ -774,7 +770,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr) } if (!ctx) - goto end; + return; if (sp->flags & SRB_CRC_CTX_DSD_VALID) { /* List assured to be having elements */ @@ -836,10 +832,6 @@ qla2xxx_qpair_sp_free_dma(void *ptr) dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma); sp->flags &= ~SRB_CRC_CTX_DMA_VALID; } - -end: - CMD_SP(cmd) = NULL; - qla2xxx_rel_qpair_sp(sp->qpair, sp); } void @@ -855,9 +847,12 @@ qla2xxx_qpair_sp_compl(void *ptr, int res) atomic_dec(&sp->ref_count); sp->free(sp); + cmd->result = res; + CMD_SP(cmd) = NULL; 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 From 0277a113c497327f6826a3371231dd9fa854752b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 May 2019 03:11:59 +0000 Subject: [PATCH 13/13] qla2x00t-32gbit: Fix another race related to aborting commands See also upstream commit 219d27d7147e ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands"). ---- git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8338 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 28 -------------------- qla2x00t-32gbit/qla_nvme.h | 6 ----- qla2x00t-32gbit/qla_os.c | 52 ++++++++++++++++---------------------- 3 files changed, 22 insertions(+), 64 deletions(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index bb0074ba1..58a7d6dd1 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -595,34 +595,6 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = { .fcprqst_priv_sz = sizeof(struct nvme_private), }; -#define NVME_ABORT_POLLING_PERIOD 2 -static int qla_nvme_wait_on_command(srb_t *sp) -{ - int ret = QLA_SUCCESS; - - wait_event_timeout(sp->nvme_ls_waitq, (atomic_read(&sp->ref_count) > 1), - NVME_ABORT_POLLING_PERIOD*HZ); - - if (atomic_read(&sp->ref_count) > 1) - ret = QLA_FUNCTION_FAILED; - - return ret; -} - -void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp, int res) -{ - int rval; - - if (ha->flags.fw_started) { - rval = ha->isp_ops->abort_command(sp); - if (!rval && !qla_nvme_wait_on_command(sp)) - ql_log(ql_log_warn, NULL, 0x2112, - "timed out waiting on sp=%p\n", sp); - } else { - sp->done(sp, res); - } -} - static void qla_nvme_unregister_remote_port(struct work_struct *work) { struct fc_port *fcport = container_of(work, struct fc_port, diff --git a/qla2x00t-32gbit/qla_nvme.h b/qla2x00t-32gbit/qla_nvme.h index 8d26bb6b2..21a6c257a 100644 --- a/qla2x00t-32gbit/qla_nvme.h +++ b/qla2x00t-32gbit/qla_nvme.h @@ -144,7 +144,6 @@ struct pt_ls4_rx_unsol { int qla_nvme_register_hba(struct scsi_qla_host *); int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *); void qla_nvme_delete(struct scsi_qla_host *); -void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res); #else static inline int qla_nvme_register_hba(struct scsi_qla_host *vha) { @@ -160,11 +159,6 @@ static inline int qla_nvme_register_remote(struct scsi_qla_host *vha, static inline void qla_nvme_delete(struct scsi_qla_host *vha) { } - -static inline void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp, - int res) -{ -} #endif void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *, diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index a2d46572a..2ff8f4a0f 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1776,42 +1776,34 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, __releases(qp->qp_lock_ptr) __acquires(qp->qp_lock_ptr) { + DECLARE_COMPLETION_ONSTACK(comp); scsi_qla_host_t *vha = qp->vha; struct qla_hw_data *ha = vha->hw; + int rval; - if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS) { - if (!sp_get(sp)) { - /* got sp */ - spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); - qla_nvme_abort(ha, sp, res); - spin_lock_irqsave(qp->qp_lock_ptr, *flags); - } - } else if (GET_CMD_SP(sp) && !ha->flags.eeh_busy && - !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && - !qla2x00_isp_reg_stat(ha) && sp->type == SRB_SCSI_CMD) { - /* - * Don't abort commands in adapter during EEH recovery as it's - * not accessible/responding. - * - * Get a reference to the sp and drop the lock. The reference - * ensures this sp->done() call and not the call in - * qla2xxx_eh_abort() ends the SCSI cmd (with result 'res'). - */ - if (!sp_get(sp)) { - int status; + if (sp_get(sp)) + return; - spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); - status = qla2xxx_eh_abort(GET_CMD_SP(sp)); - spin_lock_irqsave(qp->qp_lock_ptr, *flags); - /* - * Get rid of extra reference caused - * by early exit from qla2xxx_eh_abort - */ - if (status == FAST_IO_FAIL) - atomic_dec(&sp->ref_count); + if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || + (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && + !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && + !qla2x00_isp_reg_stat(ha))) { + sp->comp = ∁ + rval = ha->isp_ops->abort_command(sp); + spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); + + switch (rval) { + case QLA_SUCCESS: + sp->done(sp, res); + break; + case QLA_FUNCTION_PARAMETER_ERROR: + wait_for_completion(&comp); + break; } + + spin_lock_irqsave(qp->qp_lock_ptr, *flags); + sp->comp = NULL; } - sp->done(sp, res); } static void