From 6a2ea0d34af1ca807d5ba6a8350a037ff3cd35cc Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 17 Aug 2021 16:55:31 -0700 Subject: [PATCH 01/43] scsi: st: Add missing break in switch statement in st_ioctl() Clang + -Wimplicit-fallthrough warns: drivers/scsi/st.c:3831:2: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough] default: ^ drivers/scsi/st.c:3831:2: note: insert 'break;' to avoid fall-through default: ^ break; 1 warning generated. Clang's -Wimplicit-fallthrough is a little bit more pedantic than GCC's, requiring every case block to end in break, return, or fallthrough, rather than allowing implicit fallthroughs to cases that just contain break or return. Add a break so that there is no more warning, as has been done all over the tree already. Link: https://lore.kernel.org/r/20210817235531.172995-1-nathan@kernel.org Fixes: 2e27f576abc6 ("scsi: scsi_ioctl: Call scsi_cmd_ioctl() from scsi_ioctl()") Reviewed-by: Gustavo A. R. Silva Signed-off-by: Nathan Chancellor Signed-off-by: Martin K. Petersen --- drivers/scsi/st.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9d04929f03a1..ae8636d3780b 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3823,6 +3823,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) case CDROM_SEND_PACKET: if (!capable(CAP_SYS_RAWIO)) return -EPERM; + break; default: break; } From 96fafe7c6523886308605d30ec92c7936abe7c2c Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 30 Aug 2021 16:10:50 -0700 Subject: [PATCH 02/43] scsi: elx: efct: Fix void-pointer-to-enum-cast warning for efc_nport_topology The kernel test robot flagged an warning for ".../efc_device.c:932:6: warning: cast to smaller integer type 'enum efc_nport_topology' from 'void *'" For the topology events, the "arg" field is generically defined as a void * and is used to pass different arguments. Most of the arguments are pointers to data structures. But for the EFC_EVT_NPORT_TOPOLOGY_NOTIFY event, the argument is an enum value, and the code is typecasting the void * to an enum generating the warning. Fix by converting the EFC_EVT_NPORT_TOPOLOGY_NOTIFY event to pass a pointer to the enum, thus it's a straight-forward pointer dereference in the event handler. Link: https://lore.kernel.org/r/20210830231050.5951-1-jsmart2021@gmail.com Fixes: 202bfdffae27 ("scsi: elx: libefc: FC node ELS and state handling") Reported-by: kernel test robot Co-developed-by: Ram Vegesna Signed-off-by: Ram Vegesna Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/libefc/efc_device.c | 7 +++---- drivers/scsi/elx/libefc/efc_fabric.c | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/elx/libefc/efc_device.c b/drivers/scsi/elx/libefc/efc_device.c index 725ca2a23fb2..52be01333c6e 100644 --- a/drivers/scsi/elx/libefc/efc_device.c +++ b/drivers/scsi/elx/libefc/efc_device.c @@ -928,22 +928,21 @@ __efc_d_wait_topology_notify(struct efc_sm_ctx *ctx, break; case EFC_EVT_NPORT_TOPOLOGY_NOTIFY: { - enum efc_nport_topology topology = - (enum efc_nport_topology)arg; + enum efc_nport_topology *topology = arg; WARN_ON(node->nport->domain->attached); WARN_ON(node->send_ls_acc != EFC_NODE_SEND_LS_ACC_PLOGI); node_printf(node, "topology notification, topology=%d\n", - topology); + *topology); /* At the time the PLOGI was received, the topology was unknown, * so we didn't know which node would perform the domain attach: * 1. The node from which the PLOGI was sent (p2p) or * 2. The node to which the FLOGI was sent (fabric). */ - if (topology == EFC_NPORT_TOPO_P2P) { + if (*topology == EFC_NPORT_TOPO_P2P) { /* if this is p2p, need to attach to the domain using * the d_id from the PLOGI received */ diff --git a/drivers/scsi/elx/libefc/efc_fabric.c b/drivers/scsi/elx/libefc/efc_fabric.c index d397220d9e54..3270ce40196c 100644 --- a/drivers/scsi/elx/libefc/efc_fabric.c +++ b/drivers/scsi/elx/libefc/efc_fabric.c @@ -107,7 +107,6 @@ void efc_fabric_notify_topology(struct efc_node *node) { struct efc_node *tmp_node; - enum efc_nport_topology topology = node->nport->topology; unsigned long index; /* @@ -118,7 +117,7 @@ efc_fabric_notify_topology(struct efc_node *node) if (tmp_node != node) { efc_node_post_event(tmp_node, EFC_EVT_NPORT_TOPOLOGY_NOTIFY, - (void *)topology); + &node->nport->topology); } } } From 59936430e6a6acb0ef943e9306506b2e9c2e45a8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 30 Aug 2021 16:12:43 -0700 Subject: [PATCH 03/43] scsi: lpfc: Fix CPU to/from endian warnings introduced by ELS processing The kernel test robot reported the following sparse warning: ".../lpfc_els.c:3984:25: sparse: sparse: cast from restricted __be16" For the error being flagged, using be32_to_cpu() on a be16 data type, it was simple enough. But a review of other elements and warnings were also evaluated. This patch corrected several items in the original patch: - Using be32_to_cpu() on a be16 data type - cpu_to_le32() used on a std uint32_t (CPU) data type. Note: This is a byte array, but stored in LE layout by hardware at 32-bit boundaries. So it possibly needed conversion. - Using cpu_to_le32() on a std uint16_t and assigned to a char typeA - Using le32_to_cpu() on a le16 type - Missing cpu_to_le16() on an assignment Link: https://lore.kernel.org/r/20210830231243.6227-1-jsmart2021@gmail.com Fixes: 9064aeb2df8e ("scsi: lpfc: Add EDC ELS support") Reported-by: kernel test robot Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 8 ++++---- drivers/scsi/lpfc/lpfc_hw4.h | 2 +- drivers/scsi/lpfc/lpfc_init.c | 16 ++++++++-------- drivers/scsi/lpfc/lpfc_sli.c | 5 +++-- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 1254a575fd47..f3fc79b99165 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4015,11 +4015,11 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, be32_to_cpu(pcgd->desc_tag), be32_to_cpu(pcgd->desc_len), be32_to_cpu(pcgd->xmt_signal_capability), - be32_to_cpu(pcgd->xmt_signal_frequency.count), - be32_to_cpu(pcgd->xmt_signal_frequency.units), + be16_to_cpu(pcgd->xmt_signal_frequency.count), + be16_to_cpu(pcgd->xmt_signal_frequency.units), be32_to_cpu(pcgd->rcv_signal_capability), - be32_to_cpu(pcgd->rcv_signal_frequency.count), - be32_to_cpu(pcgd->rcv_signal_frequency.units)); + be16_to_cpu(pcgd->rcv_signal_frequency.count), + be16_to_cpu(pcgd->rcv_signal_frequency.units)); /* Compare driver and Fport capabilities and choose * least common. diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 79a4872c2edb..7359505e6041 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1167,7 +1167,7 @@ struct lpfc_mbx_read_object { /* Version 0 */ #define lpfc_mbx_rd_object_rlen_MASK 0x00FFFFFF #define lpfc_mbx_rd_object_rlen_WORD word0 uint32_t rd_object_offset; - uint32_t rd_object_name[LPFC_MBX_OBJECT_NAME_LEN_DW]; + __le32 rd_object_name[LPFC_MBX_OBJECT_NAME_LEN_DW]; #define LPFC_OBJ_NAME_SZ 104 /* 26 x sizeof(uint32_t) is 104. */ uint32_t rd_object_cnt; struct lpfc_mbx_host_buf rd_object_hbuf[4]; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0ec322f0e3cb..597e5a1ef060 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5518,7 +5518,7 @@ lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag) if (phba->cgn_fpin_frequency && phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) { value = LPFC_CGN_TIMER_TO_MIN / phba->cgn_fpin_frequency; - cp->cgn_stat_npm = cpu_to_le32(value); + cp->cgn_stat_npm = value; } value = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED); @@ -5547,9 +5547,9 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) uint32_t mbps; uint32_t dvalue, wvalue, lvalue, avalue; uint64_t latsum; - uint16_t *ptr; - uint32_t *lptr; - uint16_t *mptr; + __le16 *ptr; + __le32 *lptr; + __le16 *mptr; /* Make sure we have a congestion info buffer */ if (!phba->cgn_i) @@ -5570,7 +5570,7 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) if (phba->cgn_fpin_frequency && phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) { value = LPFC_CGN_TIMER_TO_MIN / phba->cgn_fpin_frequency; - cp->cgn_stat_npm = cpu_to_le32(value); + cp->cgn_stat_npm = value; } /* Read and clear the latency counters for this minute */ @@ -5753,7 +5753,7 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) dvalue += le32_to_cpu(cp->cgn_drvr_hr[i]); wvalue += le32_to_cpu(cp->cgn_warn_hr[i]); lvalue += le32_to_cpu(cp->cgn_latency_hr[i]); - mbps += le32_to_cpu(cp->cgn_bw_hr[i]); + mbps += le16_to_cpu(cp->cgn_bw_hr[i]); avalue += le32_to_cpu(cp->cgn_alarm_hr[i]); } if (lvalue) /* Avg of latency averages */ @@ -13411,8 +13411,8 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba) /* last used Index initialized to 0xff already */ - cp->cgn_warn_freq = LPFC_FPIN_INIT_FREQ; - cp->cgn_alarm_freq = LPFC_FPIN_INIT_FREQ; + cp->cgn_warn_freq = cpu_to_le16(LPFC_FPIN_INIT_FREQ); + cp->cgn_alarm_freq = cpu_to_le16(LPFC_FPIN_INIT_FREQ); crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED); cp->cgn_info_crc = cpu_to_le32(crc); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ffd8a140638c..78ce38d7251c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -22090,6 +22090,7 @@ lpfc_read_object(struct lpfc_hba *phba, char *rdobject, uint32_t *datap, uint32_t shdr_status, shdr_add_status; union lpfc_sli4_cfg_shdr *shdr; struct lpfc_dmabuf *pcmd; + u32 rd_object_name[LPFC_MBX_OBJECT_NAME_LEN_DW] = {0}; /* sanity check on queue memory */ if (!datap) @@ -22113,10 +22114,10 @@ lpfc_read_object(struct lpfc_hba *phba, char *rdobject, uint32_t *datap, memset((void *)read_object->u.request.rd_object_name, 0, LPFC_OBJ_NAME_SZ); - sprintf((uint8_t *)read_object->u.request.rd_object_name, rdobject); + scnprintf((char *)rd_object_name, sizeof(rd_object_name), rdobject); for (j = 0; j < strlen(rdobject); j++) read_object->u.request.rd_object_name[j] = - cpu_to_le32(read_object->u.request.rd_object_name[j]); + cpu_to_le32(rd_object_name[j]); pcmd = kmalloc(sizeof(*pcmd), GFP_KERNEL); if (pcmd) From 37e384095f20cca728500fe5344cd308aa6fd7ff Mon Sep 17 00:00:00 2001 From: James Smart Date: Tue, 7 Sep 2021 22:09:27 -0700 Subject: [PATCH 04/43] scsi: lpfc: Fix compilation errors on kernels with no CONFIG_DEBUG_FS The Kernel test robot flagged the following warning: ".../lpfc_init.c:7788:35: error: 'struct lpfc_sli4_hba' has no member named 'c_stat'" Reviewing this issue highlighted that one of the recent patches caused the driver to no longer compile cleanly if CONFIG_DEBUG_FS is not set. Correct the different areas that are failing to compile. Link: https://lore.kernel.org/r/20210908050927.37275-1-jsmart2021@gmail.com Fixes: 02243836ad6f ("scsi: lpfc: Add support for the CM framework") Reviewed-by: Nathan Chancellor Build-tested-by: Nathan Chancellor Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 4 ++-- drivers/scsi/lpfc/lpfc_nvme.c | 2 -- drivers/scsi/lpfc/lpfc_scsi.c | 6 +----- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 597e5a1ef060..195169badb37 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8277,11 +8277,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) return 0; out_free_hba_hdwq_info: - free_percpu(phba->sli4_hba.c_stat); #ifdef CONFIG_SCSI_LPFC_DEBUG_FS + free_percpu(phba->sli4_hba.c_stat); out_free_hba_idle_stat: - kfree(phba->sli4_hba.idle_stat); #endif + kfree(phba->sli4_hba.idle_stat); out_free_hba_eq_info: free_percpu(phba->sli4_hba.eq_info); out_free_hba_cpu_map: diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 73a3568ff17e..479b3eed6208 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1489,9 +1489,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, struct lpfc_nvme_qhandle *lpfc_queue_info; struct lpfc_nvme_fcpreq_priv *freqpriv; struct nvme_common_command *sqe; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint64_t start = 0; -#endif /* Validate pointers. LLDD fault handling with transport does * have timing races. diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 0fde1e874c7a..63d8ac9f68a7 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5578,12 +5578,8 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); int err, idx; u8 *uuid = NULL; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS - uint64_t start = 0L; + uint64_t start; - if (phba->ktime_on) - start = ktime_get_ns(); -#endif start = ktime_get_ns(); rdata = lpfc_rport_data_from_scsi_device(cmnd->device); From 5d1e15108b8d058d537f19cdef4170d2ae4eed08 Mon Sep 17 00:00:00 2001 From: Chi Minghao Date: Tue, 31 Aug 2021 04:40:58 -0700 Subject: [PATCH 05/43] scsi: lpfc: Remove unneeded variable Fix the following coccicheck REVIEW: ./drivers/scsi/lpfc/lpfc_scsi.c:1498:9-12 REVIEW Unneeded variable Link: https://lore.kernel.org/r/20210831114058.17817-1-lv.ruyi@zte.com.cn Reported-by: Zeal Robot Reviewed-by: James Smart Signed-off-by: Chi Minghao Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 63d8ac9f68a7..befdf864c43b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1495,7 +1495,6 @@ static int lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint8_t *txop, uint8_t *rxop) { - uint8_t ret = 0; if (sc->prot_flags & SCSI_PROT_IP_CHECKSUM) { switch (scsi_get_prot_op(sc)) { @@ -1548,7 +1547,7 @@ lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, } } - return ret; + return 0; } #endif From 65ef27f7798b57138351d28fd2f61f2afa164400 Mon Sep 17 00:00:00 2001 From: ChanWoo Lee Date: Wed, 1 Sep 2021 11:56:17 +0900 Subject: [PATCH 06/43] scsi: ufs: ufshpb: Remove unused parameters The following parameters are not used in the function. Remove them. *func(): ufshpb_set_hpb_read_to_upiu -> struct ufshpb_lu *hpb -> u32 lpn Link: https://lore.kernel.org/r/20210901025617.31174-1-cw9316.lee@samsung.com Reviewed-by: Daejun Park Reviewed-by: Bart Van Assche Signed-off-by: ChanWoo Lee Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 02fb51ae8b25..589af5f6b940 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -333,9 +333,8 @@ ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, unsigned long lpn, int *rgn_idx, } static void -ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshpb_lu *hpb, - struct ufshcd_lrb *lrbp, u32 lpn, __be64 ppn, - u8 transfer_len, int read_id) +ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, + __be64 ppn, u8 transfer_len, int read_id) { unsigned char *cdb = lrbp->cmd->cmnd; __be64 ppn_tmp = ppn; @@ -703,8 +702,7 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) } } - ufshpb_set_hpb_read_to_upiu(hba, hpb, lrbp, lpn, ppn, transfer_len, - read_id); + ufshpb_set_hpb_read_to_upiu(hba, lrbp, ppn, transfer_len, read_id); hpb->stats.hit_cnt++; return 0; From 4e28550829258f7dab97383acaa477bd724c0ff4 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Wed, 1 Sep 2021 16:53:36 +0800 Subject: [PATCH 07/43] scsi: iscsi: Adjust iface sysfs attr detection ISCSI_NET_PARAM_IFACE_ENABLE belongs to enum iscsi_net_param instead of iscsi_iface_param so move it to ISCSI_NET_PARAM. Otherwise, when we call into the driver, we might not match and return that we don't want attr visible in sysfs. Found in code review. Link: https://lore.kernel.org/r/20210901085336.2264295-1-libaokun1@huawei.com Fixes: e746f3451ec7 ("scsi: iscsi: Fix iface sysfs attr detection") Reviewed-by: Lee Duncan Signed-off-by: Baokun Li Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_iscsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index d8b05d8b5470..922e4c7bd88e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -441,9 +441,7 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, struct iscsi_transport *t = iface->transport; int param = -1; - if (attr == &dev_attr_iface_enabled.attr) - param = ISCSI_NET_PARAM_IFACE_ENABLE; - else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) + if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO; else if (attr == &dev_attr_iface_header_digest.attr) param = ISCSI_IFACE_PARAM_HDRDGST_EN; @@ -483,7 +481,9 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, if (param != -1) return t->attr_is_visible(ISCSI_IFACE_PARAM, param); - if (attr == &dev_attr_iface_vlan_id.attr) + if (attr == &dev_attr_iface_enabled.attr) + param = ISCSI_NET_PARAM_IFACE_ENABLE; + else if (attr == &dev_attr_iface_vlan_id.attr) param = ISCSI_NET_PARAM_VLAN_ID; else if (attr == &dev_attr_iface_vlan_priority.attr) param = ISCSI_NET_PARAM_VLAN_PRIORITY; From e4953a93104c1fb1ef7989541f9867cc276467f9 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 1 Sep 2021 20:55:42 +0530 Subject: [PATCH 08/43] scsi: mpt3sas: Call cpu_relax() before calling udelay() Call cpu_relax() while waiting for the current blk-mq polling instance to complete. Link: https://lore.kernel.org/r/20210901152542.27866-1-sreekanth.reddy@broadcom.com Reviewed-by: Bart Van Assche Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 6c82435bc9cc..27eb652b564f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -1582,8 +1582,10 @@ mpt3sas_base_pause_mq_polling(struct MPT3SAS_ADAPTER *ioc) * wait for current poll to complete. */ for (qid = 0; qid < iopoll_q_count; qid++) { - while (atomic_read(&ioc->io_uring_poll_queues[qid].busy)) + while (atomic_read(&ioc->io_uring_poll_queues[qid].busy)) { + cpu_relax(); udelay(500); + } } } From 265dfe8ebbabae7959060bd1c3f75c2473b697ed Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 6 Sep 2021 17:01:12 +0800 Subject: [PATCH 09/43] scsi: sd: Free scsi_disk device via put_device() After a device is initialized via device_initialize() it should be freed via put_device(). sd_probe() currently gets this wrong, fix it up. Link: https://lore.kernel.org/r/20210906090112.531442-1-ming.lei@redhat.com Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index cbd9999f93a6..a8039beb5a02 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3401,15 +3401,16 @@ static int sd_probe(struct device *dev) } device_initialize(&sdkp->dev); - sdkp->dev.parent = dev; + sdkp->dev.parent = get_device(dev); sdkp->dev.class = &sd_disk_class; dev_set_name(&sdkp->dev, "%s", dev_name(dev)); error = device_add(&sdkp->dev); - if (error) - goto out_free_index; + if (error) { + put_device(&sdkp->dev); + goto out; + } - get_device(dev); dev_set_drvdata(dev, sdkp); gd->major = sd_major((index & 0xf0) >> 4); From 7215e909814fed7cda33c954943a4050d8348204 Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Mon, 6 Sep 2021 23:06:42 +0900 Subject: [PATCH 10/43] scsi: sd_zbc: Ensure buffer size is aligned to SECTOR_SIZE Reporting zones on a SCSI device sometimes fail with the following error: [76248.516390] ata16.00: invalid transfer count 131328 [76248.523618] sd 15:0:0:0: [sda] REPORT ZONES start lba 536870912 failed The error (from drivers/ata/libata-scsi.c:ata_scsi_zbc_in_xlat()) indicates that buffer size is not aligned to SECTOR_SIZE. This happens when the __vmalloc() failed. Consider we are reporting 4096 zones, then we will have "bufsize = roundup((4096 + 1) * 64, SECTOR_SIZE)" = (513 * 512) = 262656. Then, __vmalloc() failure halves the bufsize to 131328, which is no longer aligned to SECTOR_SIZE. Use rounddown() to ensure the size is always aligned to SECTOR_SIZE and fix the comment as well. Link: https://lore.kernel.org/r/20210906140642.2267569-1-naohiro.aota@wdc.com Fixes: 23a50861adda ("scsi: sd_zbc: Cleanup sd_zbc_alloc_report_buffer()") Cc: stable@vger.kernel.org # 5.5+ Reviewed-by: Johannes Thumshirn Reviewed-by: Damien Le Moal Reviewed-by: Himanshu Madhani Signed-off-by: Naohiro Aota Signed-off-by: Martin K. Petersen --- drivers/scsi/sd_zbc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index b9757f24b0d6..8197d31a81f9 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -154,8 +154,8 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, /* * Report zone buffer size should be at most 64B times the number of - * zones requested plus the 64B reply header, but should be at least - * SECTOR_SIZE for ATA devices. + * zones requested plus the 64B reply header, but should be aligned + * to SECTOR_SIZE for ATA devices. * Make sure that this size does not exceed the hardware capabilities. * Furthermore, since the report zone command cannot be split, make * sure that the allocated buffer can always be mapped by limiting the @@ -174,7 +174,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, *buflen = bufsize; return buf; } - bufsize >>= 1; + bufsize = rounddown(bufsize >> 1, SECTOR_SIZE); } return NULL; From ef7ae7f746e95c6fa4ec2bcfacb949c36263da78 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Mon, 6 Sep 2021 17:18:09 +0200 Subject: [PATCH 11/43] scsi: target: Fix the pgr/alua_support_store functions Commit 356ba2a8bc8d ("scsi: target: tcmu: Make pgr_support and alua_support attributes writable") introduced support for changeable alua_support and pgr_support target attributes. These can only be changed if the backstore is user-backed, otherwise the kernel returns -EINVAL. This triggers a warning in the targetcli/rtslib code when performing a target restore that includes non-userbacked backstores: # targetctl restore Storage Object block/storage1: Cannot set attribute alua_support: [Errno 22] Invalid argument, skipped Storage Object block/storage1: Cannot set attribute pgr_support: [Errno 22] Invalid argument, skipped Fix this warning by returning an error code only if we are really going to flip the PGR/ALUA bit in the transport_flags field, otherwise we will do nothing and return success. Return ENOSYS instead of EINVAL if the pgr/alua attributes can not be changed, this way it will be possible for userspace to understand if the operation failed because an invalid value has been passed to strtobool() or because the attributes are fixed. Fixes: 356ba2a8bc8d ("scsi: target: tcmu: Make pgr_support and alua_support attributes writable") Link: https://lore.kernel.org/r/20210906151809.52811-1-mlombard@redhat.com Reviewed-by: Bodo Stroesser Signed-off-by: Maurizio Lombardi Signed-off-by: Martin K. Petersen --- drivers/target/target_core_configfs.c | 32 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 102ec644bc8a..023bd4516a68 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -1110,20 +1110,24 @@ static ssize_t alua_support_store(struct config_item *item, { struct se_dev_attrib *da = to_attrib(item); struct se_device *dev = da->da_dev; - bool flag; + bool flag, oldflag; int ret; + ret = strtobool(page, &flag); + if (ret < 0) + return ret; + + oldflag = !(dev->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA); + if (flag == oldflag) + return count; + if (!(dev->transport->transport_flags_changeable & TRANSPORT_FLAG_PASSTHROUGH_ALUA)) { pr_err("dev[%p]: Unable to change SE Device alua_support:" " alua_support has fixed value\n", dev); - return -EINVAL; + return -ENOSYS; } - ret = strtobool(page, &flag); - if (ret < 0) - return ret; - if (flag) dev->transport_flags &= ~TRANSPORT_FLAG_PASSTHROUGH_ALUA; else @@ -1145,20 +1149,24 @@ static ssize_t pgr_support_store(struct config_item *item, { struct se_dev_attrib *da = to_attrib(item); struct se_device *dev = da->da_dev; - bool flag; + bool flag, oldflag; int ret; + ret = strtobool(page, &flag); + if (ret < 0) + return ret; + + oldflag = !(dev->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR); + if (flag == oldflag) + return count; + if (!(dev->transport->transport_flags_changeable & TRANSPORT_FLAG_PASSTHROUGH_PGR)) { pr_err("dev[%p]: Unable to change SE Device pgr_support:" " pgr_support has fixed value\n", dev); - return -EINVAL; + return -ENOSYS; } - ret = strtobool(page, &flag); - if (ret < 0) - return ret; - if (flag) dev->transport_flags &= ~TRANSPORT_FLAG_PASSTHROUGH_PGR; else From 450907424d9ebcc28fab42a065c3cddce49ee97d Mon Sep 17 00:00:00 2001 From: James Smart Date: Tue, 7 Sep 2021 09:52:25 -0700 Subject: [PATCH 12/43] scsi: elx: efct: Do not hold lock while calling fc_vport_terminate() Smatch checker reported the following error: drivers/base/power/sysfs.c:833 dpm_sysfs_remove() warn: sleeping in atomic context With a calling sequence of: efct_lio_npiv_drop_nport() <- disables preempt -> fc_vport_terminate() -> device_del() -> dpm_sysfs_remove() Issue is efct_lio_npiv_drop_nport() is making the fc_vport_terminate() call while holding a lock w/ ipl raised. It is unnecessary to hold the lock over this call, shift where the lock is taken. Link: https://lore.kernel.org/r/20210907165225.10821-1-jsmart2021@gmail.com Reported-by: Dan Carpenter Co-developed-by: Ram Vegesna Signed-off-by: Ram Vegesna Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/efct/efct_lio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/elx/efct/efct_lio.c b/drivers/scsi/elx/efct/efct_lio.c index bb3b460dc0bc..4d73e92909ab 100644 --- a/drivers/scsi/elx/efct/efct_lio.c +++ b/drivers/scsi/elx/efct/efct_lio.c @@ -880,11 +880,11 @@ efct_lio_npiv_drop_nport(struct se_wwn *wwn) struct efct *efct = lio_vport->efct; unsigned long flags = 0; - spin_lock_irqsave(&efct->tgt_efct.efct_lio_lock, flags); - if (lio_vport->fc_vport) fc_vport_terminate(lio_vport->fc_vport); + spin_lock_irqsave(&efct->tgt_efct.efct_lio_lock, flags); + list_for_each_entry_safe(vport, next_vport, &efct->tgt_efct.vport_list, list_entry) { if (vport->lio_vport == lio_vport) { From 1f97c29beee774e407839768439b7f51831c3ea1 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 7 Sep 2021 23:00:44 +0200 Subject: [PATCH 13/43] scsi: ncr53c8xx: Remove unused retrieve_from_waiting_list() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop retrieve_from_waiting_list() to avoid this warning: drivers/scsi/ncr53c8xx.c:8000:26: warning: ‘retrieve_from_waiting_list’ defined but not used [-Wunused-function] Link: https://lore.kernel.org/r/YTfS/LH5vCN6afDW@ls3530 Fixes: 1c22e327545c ("scsi: ncr53c8xx: Remove unused code") Reviewed-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Helge Deller Signed-off-by: Martin K. Petersen --- drivers/scsi/ncr53c8xx.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 7a4f5d4dd670..2b8c6fa5e775 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -1939,11 +1939,8 @@ static void ncr_start_next_ccb (struct ncb *np, struct lcb * lp, int maxn); static void ncr_put_start_queue(struct ncb *np, struct ccb *cp); static void insert_into_waiting_list(struct ncb *np, struct scsi_cmnd *cmd); -static struct scsi_cmnd *retrieve_from_waiting_list(int to_remove, struct ncb *np, struct scsi_cmnd *cmd); static void process_waiting_list(struct ncb *np, int sts); -#define remove_from_waiting_list(np, cmd) \ - retrieve_from_waiting_list(1, (np), (cmd)) #define requeue_waiting_list(np) process_waiting_list((np), DID_OK) #define reset_waiting_list(np) process_waiting_list((np), DID_RESET) @@ -7997,26 +7994,6 @@ static void insert_into_waiting_list(struct ncb *np, struct scsi_cmnd *cmd) } } -static struct scsi_cmnd *retrieve_from_waiting_list(int to_remove, struct ncb *np, struct scsi_cmnd *cmd) -{ - struct scsi_cmnd **pcmd = &np->waiting_list; - - while (*pcmd) { - if (cmd == *pcmd) { - if (to_remove) { - *pcmd = (struct scsi_cmnd *) cmd->next_wcmd; - cmd->next_wcmd = NULL; - } -#ifdef DEBUG_WAITING_LIST - printk("%s: cmd %lx retrieved from waiting list\n", ncr_name(np), (u_long) cmd); -#endif - return cmd; - } - pcmd = (struct scsi_cmnd **) &(*pcmd)->next_wcmd; - } - return NULL; -} - static void process_waiting_list(struct ncb *np, int sts) { struct scsi_cmnd *waiting_list, *wcmd; From 17dfd54d391ea9f8d136fb137962987cb2c6444c Mon Sep 17 00:00:00 2001 From: jing yangyang Date: Thu, 19 Aug 2021 20:08:05 -0700 Subject: [PATCH 14/43] scsi: megaraid: Fix Coccinelle warning WARNING !A || A && B is equivalent to !A || B This issue was detected with the help of Coccinelle. Link: https://lore.kernel.org/r/20210820030805.12383-1-jing.yangyang@zte.com.cn Reported-by: Zeal Robot Acked-by: Sumit Saxena Signed-off-by: jing yangyang Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index e4298bf4a482..17c87ac8bb51 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -8773,8 +8773,7 @@ int megasas_update_device_list(struct megasas_instance *instance, if (event_type & SCAN_VD_CHANNEL) { if (!instance->requestorId || - (instance->requestorId && - megasas_get_ld_vf_affiliation(instance, 0))) { + megasas_get_ld_vf_affiliation(instance, 0)) { dcmd_ret = megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST); if (dcmd_ret != DCMD_SUCCESS) From fc13fc07490982c89f5d9d8d671ec29a39cddc85 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 3 Sep 2021 08:11:39 -0600 Subject: [PATCH 15/43] scsi: Remove SCSI CDROM MAINTAINERS entry There's little point in keeping this one separately maintained these days, so just remove the entry and it'll fall under the SCSI subsystem where it belongs. Link: https://lore.kernel.org/r/c5e12bd1-10de-634c-d6b3-dac79ed01af5@kernel.dk Signed-off-by: Jens Axboe Signed-off-by: Martin K. Petersen --- MAINTAINERS | 7 ------- 1 file changed, 7 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index eeb4c70b3d5b..fd12a39f92ef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16650,13 +16650,6 @@ M: Lubomir Rintel S: Supported F: drivers/char/pcmcia/scr24x_cs.c -SCSI CDROM DRIVER -M: Jens Axboe -L: linux-scsi@vger.kernel.org -S: Maintained -W: http://www.kernel.dk -F: drivers/scsi/sr* - SCSI RDMA PROTOCOL (SRP) INITIATOR M: Bart Van Assche L: linux-rdma@vger.kernel.org From e699a4e1d37314eb842ba9de19a7ccee7f75da10 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 26 Aug 2021 12:57:14 +0100 Subject: [PATCH 16/43] scsi: sr: Fix spelling mistake "does'nt" -> "doesn't" There is a spelling mistake in a literal string. Fix it. Link: https://lore.kernel.org/r/20210826115714.11844-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/sr_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 79d9aa2df528..ddd00efc4882 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -523,7 +523,7 @@ static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest return rc; cd->readcd_known = 0; sr_printk(KERN_INFO, cd, - "CDROM does'nt support READ CD (0xbe) command\n"); + "CDROM doesn't support READ CD (0xbe) command\n"); /* fall & retry the other way */ } /* ... if this fails, we switch the blocksize using MODE SELECT */ From 655a68b2203e44912afe462dff9d83d68ac88333 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 2 Sep 2021 23:36:43 +0100 Subject: [PATCH 17/43] scsi: megaraid: Clean up some inconsistent indenting There are a few statements where the indentation is not correct, clean these up. Link: https://lore.kernel.org/r/20210902223643.56979-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 17c87ac8bb51..39d8754e63ac 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1916,7 +1916,7 @@ void megasas_set_dynamic_target_properties(struct scsi_device *sdev, raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + blk_queue_update_dma_alignment(sdev->request_queue, 0x7); mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; @@ -8033,7 +8033,7 @@ skip_firing_dcmds: if (instance->adapter_type != MFI_SERIES) { megasas_release_fusion(instance); - pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + + pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1)); for (i = 0; i < 2 ; i++) { From 04c260bdaeede8c703bddc21099e4da96f2909e2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 2 Sep 2021 23:42:15 +0100 Subject: [PATCH 18/43] scsi: mpt3sas: Clean up some inconsistent indenting There are a couple of statements where the indentation is not correct, clean these up. Remove a redundant break statement. Link: https://lore.kernel.org/r/20210902224215.57286-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 770b241d7bb2..1b79f01f03a4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -2178,7 +2178,7 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, mpt3sas_check_cmd_timeout(ioc, ioc->ctl_cmds.status, mpi_request, sizeof(Mpi2DiagReleaseRequest_t)/4, reset_needed); - *issue_reset = reset_needed; + *issue_reset = reset_needed; rc = -EFAULT; goto out; } diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 2f82b1e629af..d383d4a03436 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -10749,8 +10749,7 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: _scsih_pcie_topology_change_event(ioc, fw_event); ioc->current_event = NULL; - return; - break; + return; } out: fw_event_work_put(fw_event); From 1cbc9ad3eecd492be33b727b4606ae75bc880676 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 31 Aug 2021 17:53:17 +0300 Subject: [PATCH 19/43] scsi: ufs: ufs-pci: Fix Intel LKF link stability Intel LKF can experience link errors. Make fixes to increase link stability, especially when switching to high speed modes. Link: https://lore.kernel.org/r/20210831145317.26306-1-adrian.hunter@intel.com Fixes: b2c57925df1f ("scsi: ufs: ufs-pci: Add support for Intel LKF") Cc: stable@vger.kernel.org Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd-pci.c | 78 +++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd.c | 3 +- drivers/scsi/ufs/ufshcd.h | 1 + 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index b3bcc5c882da..149c1aa09103 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -128,6 +128,81 @@ static int ufs_intel_link_startup_notify(struct ufs_hba *hba, return err; } +static int ufs_intel_set_lanes(struct ufs_hba *hba, u32 lanes) +{ + struct ufs_pa_layer_attr pwr_info = hba->pwr_info; + int ret; + + pwr_info.lane_rx = lanes; + pwr_info.lane_tx = lanes; + ret = ufshcd_config_pwr_mode(hba, &pwr_info); + if (ret) + dev_err(hba->dev, "%s: Setting %u lanes, err = %d\n", + __func__, lanes, ret); + return ret; +} + +static int ufs_intel_lkf_pwr_change_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status, + struct ufs_pa_layer_attr *dev_max_params, + struct ufs_pa_layer_attr *dev_req_params) +{ + int err = 0; + + switch (status) { + case PRE_CHANGE: + if (ufshcd_is_hs_mode(dev_max_params) && + (hba->pwr_info.lane_rx != 2 || hba->pwr_info.lane_tx != 2)) + ufs_intel_set_lanes(hba, 2); + memcpy(dev_req_params, dev_max_params, sizeof(*dev_req_params)); + break; + case POST_CHANGE: + if (ufshcd_is_hs_mode(dev_req_params)) { + u32 peer_granularity; + + usleep_range(1000, 1250); + err = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_GRANULARITY), + &peer_granularity); + } + break; + default: + break; + } + + return err; +} + +static int ufs_intel_lkf_apply_dev_quirks(struct ufs_hba *hba) +{ + u32 granularity, peer_granularity; + u32 pa_tactivate, peer_pa_tactivate; + int ret; + + ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY), &granularity); + if (ret) + goto out; + + ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_GRANULARITY), &peer_granularity); + if (ret) + goto out; + + ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_TACTIVATE), &pa_tactivate); + if (ret) + goto out; + + ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_TACTIVATE), &peer_pa_tactivate); + if (ret) + goto out; + + if (granularity == peer_granularity) { + u32 new_peer_pa_tactivate = pa_tactivate + 2; + + ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TACTIVATE), new_peer_pa_tactivate); + } +out: + return ret; +} + #define INTEL_ACTIVELTR 0x804 #define INTEL_IDLELTR 0x808 @@ -351,6 +426,7 @@ static int ufs_intel_lkf_init(struct ufs_hba *hba) struct ufs_host *ufs_host; int err; + hba->nop_out_timeout = 200; hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; hba->caps |= UFSHCD_CAP_CRYPTO; err = ufs_intel_common_init(hba); @@ -381,6 +457,8 @@ static struct ufs_hba_variant_ops ufs_intel_lkf_hba_vops = { .exit = ufs_intel_common_exit, .hce_enable_notify = ufs_intel_hce_enable_notify, .link_startup_notify = ufs_intel_link_startup_notify, + .pwr_change_notify = ufs_intel_lkf_pwr_change_notify, + .apply_dev_quirks = ufs_intel_lkf_apply_dev_quirks, .resume = ufs_intel_resume, .device_reset = ufs_intel_device_reset, }; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3841ab49f556..67889d74761c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4776,7 +4776,7 @@ static int ufshcd_verify_dev_init(struct ufs_hba *hba) mutex_lock(&hba->dev_cmd.lock); for (retries = NOP_OUT_RETRIES; retries > 0; retries--) { err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_NOP, - NOP_OUT_TIMEOUT); + hba->nop_out_timeout); if (!err || err == -ETIMEDOUT) break; @@ -9483,6 +9483,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) hba->host = host; hba->dev = dev; hba->dev_ref_clk_freq = REF_CLK_FREQ_INVAL; + hba->nop_out_timeout = NOP_OUT_TIMEOUT; INIT_LIST_HEAD(&hba->clk_list_head); spin_lock_init(&hba->outstanding_lock); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 52ea6f350b18..4723f27a55d1 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -858,6 +858,7 @@ struct ufs_hba { /* Device management request data */ struct ufs_dev_cmd dev_cmd; ktime_t last_dme_cmd_tstamp; + int nop_out_timeout; /* Keeps information of the UFS device connected to this host */ struct ufs_dev_info dev_info; From 4521428c48118b0f5f7a637ce7dedd76c29bcdaa Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 11 Sep 2021 14:11:59 +0200 Subject: [PATCH 20/43] scsi: sd: Make sd_spinup_disk() less noisy sd_spinup_disk() is a little bit noisy after commit 848ade90ba9c ("scsi: sd: Do not exit sd_spinup_disk() quietly"): scsi 0:0:0:0: Direct-Access Multiple Card Reader 1.00 PQ: 0 ANSI: 0 sd 0:0:0:0: Attached scsi generic sg0 type 0 sd 0:0:0:0: [sda] Media removed, stopped polling sd 0:0:0:0: [sda] Media removed, stopped polling sd 0:0:0:0: [sda] Attached SCSI removable disk sd 0:0:0:0: [sda] Media removed, stopped polling There's not really a benefit in printing the same message multiple times. Therefore print it only if media_present was previously set. Link: https://lore.kernel.org/r/a2d0a249-6035-9697-626a-e14ec50ef6ee@gmail.com Reviewed-by: Bart Van Assche Signed-off-by: Heiner Kallweit Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a8039beb5a02..523bf2fdc253 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2124,6 +2124,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) retries = 0; do { + bool media_was_present = sdkp->media_present; + cmd[0] = TEST_UNIT_READY; memset((void *) &cmd[1], 0, 9); @@ -2138,7 +2140,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) * with any more polling. */ if (media_not_present(sdkp, &sshdr)) { - sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n"); + if (media_was_present) + sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n"); return; } From 1a0db7744e453844aa2db3f2959aea4a378025ea Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Sat, 11 Sep 2021 18:53:06 +0800 Subject: [PATCH 21/43] scsi: bsg: Fix device unregistration device_initialize() is used to take a refcount on the device. However, put_device() is not called during device teardown. This leads to a leak of private data of the driver core, dev_name(), etc. This is reported by kmemleak at boot time if we compile kernel with DEBUG_TEST_DRIVER_REMOVE. Fix memory leaks during unregistration and implement a release function. Link: https://lore.kernel.org/r/20210911105306.1511-1-yuzenghui@huawei.com Fixes: ead09dd3aed5 ("scsi: bsg: Simplify device registration") Reviewed-by: Johan Hovold Signed-off-by: Zenghui Yu Signed-off-by: Martin K. Petersen --- block/bsg.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index 351095193788..882f56bff14f 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -165,13 +165,20 @@ static const struct file_operations bsg_fops = { .llseek = default_llseek, }; +static void bsg_device_release(struct device *dev) +{ + struct bsg_device *bd = container_of(dev, struct bsg_device, device); + + ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); + kfree(bd); +} + void bsg_unregister_queue(struct bsg_device *bd) { if (bd->queue->kobj.sd) sysfs_remove_link(&bd->queue->kobj, "bsg"); cdev_device_del(&bd->cdev, &bd->device); - ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); - kfree(bd); + put_device(&bd->device); } EXPORT_SYMBOL_GPL(bsg_unregister_queue); @@ -193,11 +200,13 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, if (ret < 0) { if (ret == -ENOSPC) dev_err(parent, "bsg: too many bsg devices\n"); - goto out_kfree; + kfree(bd); + return ERR_PTR(ret); } bd->device.devt = MKDEV(bsg_major, ret); bd->device.class = bsg_class; bd->device.parent = parent; + bd->device.release = bsg_device_release; dev_set_name(&bd->device, "%s", name); device_initialize(&bd->device); @@ -205,7 +214,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, bd->cdev.owner = THIS_MODULE; ret = cdev_device_add(&bd->cdev, &bd->device); if (ret) - goto out_ida_remove; + goto out_put_device; if (q->kobj.sd) { ret = sysfs_create_link(&q->kobj, &bd->device.kobj, "bsg"); @@ -217,10 +226,8 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, out_device_del: cdev_device_del(&bd->cdev, &bd->device); -out_ida_remove: - ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); -out_kfree: - kfree(bd); +out_put_device: + put_device(&bd->device); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(bsg_register_queue); From 88b099006d83b0bf452379cad4ce494329084726 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 17 Sep 2021 17:43:49 +0300 Subject: [PATCH 22/43] scsi: ufs: core: Revert "scsi: ufs: Synchronize SCSI and UFS error handling" This reverts commit a113eaaf86373362b053279049907ff82b5df6c8. There are a couple of issues with the commit: 1. It causes deadlocks. 2. It causes the shost->eh_cmd_q list of failed requests not to be processed, ever. So revert it. 1. Deadlocks The SCSI error handler runs with requests blocked beginning when scsi_schedule_eh() sets SHOST_RECOVERY state, continuing through scsi_error_handler() callback ->eh_strategy_handler() until scsi_restart_operations() is called. By setting eh_strategy_handler to ufshcd_err_handler, the patch changed the UFS error handler to run with requests blocked, including PM requests, for the entire run of the error handler. That conflicts with UFS error handler existing synchronization with UFS device PM operations. The UFS error handler synchronizes with runtime PM by doing pm_runtime_get_sync() prior to blocking requests itself. It synchronizes with system PM by use of hba->host_sem, again before blocking requests itself. However, if requests are already blocked, then PM operations will block. So: the UFS error handler blocks waiting on PM + PM blocks waiting on SCSI PM requests to process or fail + PM requests are blocked waiting on error handling to finish = deadlock This happens both for runtime PM and system PM. Prior to the patch, these deadlocks could not happen even if SCSI error handling was running, because the presence of requests in shost->eh_cmd_q would mean the queues could not be suspended, which would mean that, should the UFS error handler run at the same time, it would not need to wait for PM or vice versa. Please note these scenarios are not just theoretical, they were found during testing on a Samsung Galaxy Book S. 2. ->eh_strategy_handler() must process shost->eh_cmd_q list of failed requests, as all other eh_strategy_handler's do except UFS error handler. Refer for example: scsi_unjam_host(), ata_scsi_error() and sas_scsi_recover_host(). Link: https://lore.kernel.org/r/20210917144349.14058-1-adrian.hunter@intel.com Fixes: a113eaaf8637 ("scsi: ufs: Synchronize SCSI and UFS error handling") Reviewed-by: Bart Van Assche Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 111 +++++++++++++++++++------------------- drivers/scsi/ufs/ufshcd.h | 4 ++ 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 67889d74761c..a3df5804b2c7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include "../scsi_transport_api.h" #include "ufshcd.h" #include "ufs_quirks.h" #include "unipro.h" @@ -237,6 +235,7 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up); static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, struct ufs_pa_layer_attr *pwr_mode); +static void ufshcd_schedule_eh_work(struct ufs_hba *hba); static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on); static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on); static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, @@ -2759,8 +2758,13 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) out: up_read(&hba->clk_scaling_lock); - if (ufs_trigger_eh()) - scsi_schedule_eh(hba->host); + if (ufs_trigger_eh()) { + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_schedule_eh_work(hba); + spin_unlock_irqrestore(hba->host->host_lock, flags); + } return err; } @@ -3919,35 +3923,6 @@ out: } EXPORT_SYMBOL_GPL(ufshcd_dme_get_attr); -static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba) -{ - lockdep_assert_held(hba->host->host_lock); - - return (hba->saved_uic_err & UFSHCD_UIC_DL_PA_INIT_ERROR) || - (hba->saved_err & (INT_FATAL_ERRORS | UFSHCD_UIC_HIBERN8_MASK)); -} - -static void ufshcd_schedule_eh(struct ufs_hba *hba) -{ - bool schedule_eh = false; - unsigned long flags; - - spin_lock_irqsave(hba->host->host_lock, flags); - /* handle fatal errors only when link is not in error state */ - if (hba->ufshcd_state != UFSHCD_STATE_ERROR) { - if (hba->force_reset || ufshcd_is_link_broken(hba) || - ufshcd_is_saved_err_fatal(hba)) - hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_FATAL; - else - hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_NON_FATAL; - schedule_eh = true; - } - spin_unlock_irqrestore(hba->host->host_lock, flags); - - if (schedule_eh) - scsi_schedule_eh(hba->host); -} - /** * ufshcd_uic_pwr_ctrl - executes UIC commands (which affects the link power * state) and waits for it to take effect. @@ -3968,7 +3943,6 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) { DECLARE_COMPLETION_ONSTACK(uic_async_done); unsigned long flags; - bool schedule_eh = false; u8 status; int ret; bool reenable_intr = false; @@ -4038,14 +4012,10 @@ out: ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); if (ret) { ufshcd_set_link_broken(hba); - schedule_eh = true; + ufshcd_schedule_eh_work(hba); } - out_unlock: spin_unlock_irqrestore(hba->host->host_lock, flags); - - if (schedule_eh) - ufshcd_schedule_eh(hba); mutex_unlock(&hba->uic_cmd_mutex); return ret; @@ -5911,6 +5881,27 @@ out: return err_handling; } +/* host lock must be held before calling this func */ +static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba) +{ + return (hba->saved_uic_err & UFSHCD_UIC_DL_PA_INIT_ERROR) || + (hba->saved_err & (INT_FATAL_ERRORS | UFSHCD_UIC_HIBERN8_MASK)); +} + +/* host lock must be held before calling this func */ +static inline void ufshcd_schedule_eh_work(struct ufs_hba *hba) +{ + /* handle fatal errors only when link is not in error state */ + if (hba->ufshcd_state != UFSHCD_STATE_ERROR) { + if (hba->force_reset || ufshcd_is_link_broken(hba) || + ufshcd_is_saved_err_fatal(hba)) + hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_FATAL; + else + hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_NON_FATAL; + queue_work(hba->eh_wq, &hba->eh_work); + } +} + static void ufshcd_clk_scaling_allow(struct ufs_hba *hba, bool allow) { down_write(&hba->clk_scaling_lock); @@ -6044,11 +6035,11 @@ static bool ufshcd_is_pwr_mode_restore_needed(struct ufs_hba *hba) /** * ufshcd_err_handler - handle UFS errors that require s/w attention - * @host: SCSI host pointer + * @work: pointer to work structure */ -static void ufshcd_err_handler(struct Scsi_Host *host) +static void ufshcd_err_handler(struct work_struct *work) { - struct ufs_hba *hba = shost_priv(host); + struct ufs_hba *hba; unsigned long flags; bool err_xfer = false; bool err_tm = false; @@ -6056,9 +6047,10 @@ static void ufshcd_err_handler(struct Scsi_Host *host) int tag; bool needs_reset = false, needs_restore = false; + hba = container_of(work, struct ufs_hba, eh_work); + down(&hba->host_sem); spin_lock_irqsave(hba->host->host_lock, flags); - hba->host->host_eh_scheduled = 0; if (ufshcd_err_handling_should_stop(hba)) { if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; @@ -6371,6 +6363,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) "host_regs: "); ufshcd_print_pwr_info(hba); } + ufshcd_schedule_eh_work(hba); retval |= IRQ_HANDLED; } /* @@ -6382,10 +6375,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) hba->errors = 0; hba->uic_error = 0; spin_unlock(hba->host->host_lock); - - if (queue_eh_work) - ufshcd_schedule_eh(hba); - return retval; } @@ -7048,17 +7037,15 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) * will be to send LU reset which, again, is a spec violation. * To avoid these unnecessary/illegal steps, first we clean up * the lrb taken by this cmd and re-set it in outstanding_reqs, - * then queue the error handler and bail. + * then queue the eh_work and bail. */ if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); spin_lock_irqsave(host->host_lock, flags); hba->force_reset = true; + ufshcd_schedule_eh_work(hba); spin_unlock_irqrestore(host->host_lock, flags); - - ufshcd_schedule_eh(hba); - goto release; } @@ -7191,10 +7178,11 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) spin_lock_irqsave(hba->host->host_lock, flags); hba->force_reset = true; + ufshcd_schedule_eh_work(hba); dev_err(hba->dev, "%s: reset in progress - 1\n", __func__); spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_err_handler(hba->host); + flush_work(&hba->eh_work); spin_lock_irqsave(hba->host->host_lock, flags); if (hba->ufshcd_state == UFSHCD_STATE_ERROR) @@ -8604,6 +8592,8 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) if (hba->is_powered) { ufshcd_exit_clk_scaling(hba); ufshcd_exit_clk_gating(hba); + if (hba->eh_wq) + destroy_workqueue(hba->eh_wq); ufs_debugfs_hba_exit(hba); ufshcd_variant_hba_exit(hba); ufshcd_setup_vreg(hba, false); @@ -9448,10 +9438,6 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba) return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32)); } -static struct scsi_transport_template ufshcd_transport_template = { - .eh_strategy_handler = ufshcd_err_handler, -}; - /** * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) * @dev: pointer to device handle @@ -9478,7 +9464,6 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) err = -ENOMEM; goto out_error; } - host->transportt = &ufshcd_transport_template; hba = shost_priv(host); hba->host = host; hba->dev = dev; @@ -9518,6 +9503,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) int err; struct Scsi_Host *host = hba->host; struct device *dev = hba->dev; + char eh_wq_name[sizeof("ufs_eh_wq_00")]; if (!mmio_base) { dev_err(hba->dev, @@ -9571,6 +9557,17 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) hba->max_pwr_info.is_valid = false; + /* Initialize work queues */ + snprintf(eh_wq_name, sizeof(eh_wq_name), "ufs_eh_wq_%d", + hba->host->host_no); + hba->eh_wq = create_singlethread_workqueue(eh_wq_name); + if (!hba->eh_wq) { + dev_err(hba->dev, "%s: failed to create eh workqueue\n", + __func__); + err = -ENOMEM; + goto out_disable; + } + INIT_WORK(&hba->eh_work, ufshcd_err_handler); INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); sema_init(&hba->host_sem, 1); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 4723f27a55d1..f0da5d3db1fa 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -741,6 +741,8 @@ struct ufs_hba_monitor { * @is_powered: flag to check if HBA is powered * @shutting_down: flag to check if shutdown has been invoked * @host_sem: semaphore used to serialize concurrent contexts + * @eh_wq: Workqueue that eh_work works on + * @eh_work: Worker to handle UFS errors that require s/w attention * @eeh_work: Worker to handle exception events * @errors: HBA errors * @uic_error: UFS interconnect layer error status @@ -843,6 +845,8 @@ struct ufs_hba { struct semaphore host_sem; /* Work Queues */ + struct workqueue_struct *eh_wq; + struct work_struct eh_work; struct work_struct eeh_work; /* HBA Errors */ From 1d479e6c9cb2b40abfb455863a4e9335db882e33 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 17 Sep 2021 14:23:14 -0700 Subject: [PATCH 23/43] scsi: sd_zbc: Support disks with more than 2**32 logical blocks This patch addresses the following Coverity report about the zno * sdkp->zone_blocks expression: CID 1475514 (#1 of 1): Unintentional integer overflow (OVERFLOW_BEFORE_WIDEN) overflow_before_widen: Potentially overflowing expression zno * sdkp->zone_blocks with type unsigned int (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type sector_t (64 bits, unsigned). Link: https://lore.kernel.org/r/20210917212314.2362324-1-bvanassche@acm.org Fixes: 5795eb443060 ("scsi: sd_zbc: emulate ZONE_APPEND commands") Cc: Johannes Thumshirn Cc: Damien Le Moal Cc: Hannes Reinecke Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Himanshu Madhani Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sd_zbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 8197d31a81f9..ed06798983f8 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -280,7 +280,7 @@ static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) { struct scsi_disk *sdkp; unsigned long flags; - unsigned int zno; + sector_t zno; int ret; sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); From d04a968c33684b15d1206e23fc1119ce0f0587fb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 16 Sep 2021 10:54:04 -0700 Subject: [PATCH 24/43] scsi: ufs: core: Unbreak the reset handler A command tag is passed as the second argument of the __ufshcd_transfer_req_compl() call in ufshcd_eh_device_reset_handler() instead of a bitmask. Fix this by passing a bitmask as argument instead of a command tag. Link: https://lore.kernel.org/r/20210916175408.2260084-1-bvanassche@acm.org Fixes: a45f937110fa ("scsi: ufs: Optimize host lock on transfer requests send/compl paths") Cc: Can Guo Reviewed-by: Avri Altman Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a3df5804b2c7..029c9631ec2b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6865,7 +6865,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) err = ufshcd_clear_cmd(hba, pos); if (err) break; - __ufshcd_transfer_req_compl(hba, pos, /*retry_requests=*/true); + __ufshcd_transfer_req_compl(hba, 1U << pos, false); } } From 5f8579038842d77e6ce05e1df6bf9dd493b0e3ef Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Wed, 15 Sep 2021 18:32:39 +0300 Subject: [PATCH 25/43] scsi: qla2xxx: Restore initiator in dual mode In dual mode in case of disabling the target, the whole port goes offline and initiator is turned off too. Fix restoring initiator mode after disabling target in dual mode. Link: https://lore.kernel.org/r/20210915153239.8035-1-d.bogdanov@yadro.com Fixes: 0645cb8350cd ("scsi: qla2xxx: Add mode control for each physical port") Reviewed-by: Himanshu Madhani Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1e4e3e83b5c7..5fc7697f0af4 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -7169,7 +7169,8 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) return 0; break; case QLA2XXX_INI_MODE_DUAL: - if (!qla_dual_mode_enabled(vha)) + if (!qla_dual_mode_enabled(vha) && + !qla_ini_mode_enabled(vha)) return 0; break; case QLA2XXX_INI_MODE_ENABLED: From bc41fcbffd5759c9610f7de211420eae6b379503 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 15 Sep 2021 17:07:13 +0800 Subject: [PATCH 26/43] scsi: fas216: Kill scmd->tag The driver is attempting to allocate a tag internally which is a no-go with blk-mq. Switch the driver to use the request tag and kill usage of scmd->tag and scmd->device->current_tag. [jpg: Change to use scsi_cmd_to_rq()] Link: https://lore.kernel.org/r/1631696835-136198-2-git-send-email-john.garry@huawei.com Signed-off-by: Hannes Reinecke Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/fas216.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 9c4458a99025..cf71ef488e36 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -77,7 +77,6 @@ * I was thinking that this was a good chip until I found this restriction ;( */ #define SCSI2_SYNC -#undef SCSI2_TAG #undef DEBUG_CONNECT #undef DEBUG_MESSAGES @@ -990,7 +989,7 @@ fas216_reselected_intr(FAS216_Info *info) info->scsi.disconnectable = 0; if (info->SCpnt->device->id == target && info->SCpnt->device->lun == lun && - info->SCpnt->tag == tag) { + scsi_cmd_to_rq(info->SCpnt)->tag == tag) { fas216_log(info, LOG_CONNECT, "reconnected previously executing command"); } else { queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt); @@ -1791,8 +1790,9 @@ static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt) /* * add tag message if required */ - if (SCpnt->tag) - msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag); + if (SCpnt->device->simple_tags) + msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, + scsi_cmd_to_rq(SCpnt)->tag); do { #ifdef SCSI2_SYNC @@ -1815,20 +1815,8 @@ static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt) static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt) { -#ifdef SCSI2_TAG - /* - * tagged queuing - allocate a new tag to this command - */ - if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE && - SCpnt->cmnd[0] != INQUIRY) { - SCpnt->device->current_tag += 1; - if (SCpnt->device->current_tag == 0) - SCpnt->device->current_tag = 1; - SCpnt->tag = SCpnt->device->current_tag; - } else -#endif - set_bit(SCpnt->device->id * 8 + - (u8)(SCpnt->device->lun & 0x7), info->busyluns); + set_bit(SCpnt->device->id * 8 + + (u8)(SCpnt->device->lun & 0x7), info->busyluns); info->stats.removes += 1; switch (SCpnt->cmnd[0]) { @@ -2117,7 +2105,6 @@ request_sense: init_SCp(SCpnt); SCpnt->SCp.Message = 0; SCpnt->SCp.Status = 0; - SCpnt->tag = 0; SCpnt->host_scribble = (void *)fas216_rq_sns_done; /* @@ -2223,7 +2210,6 @@ static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt, init_SCp(SCpnt); info->stats.queues += 1; - SCpnt->tag = 0; spin_lock(&info->host_lock); @@ -3003,9 +2989,8 @@ void fas216_print_devices(FAS216_Info *info, struct seq_file *m) dev = &info->device[scd->id]; seq_printf(m, " %d/%llu ", scd->id, scd->lun); if (scd->tagged_supported) - seq_printf(m, "%3sabled(%3d) ", - scd->simple_tags ? "en" : "dis", - scd->current_tag); + seq_printf(m, "%3sabled ", + scd->simple_tags ? "en" : "dis"); else seq_puts(m, "unsupported "); From 756fb6a895afbf1f0615d93ebdd14863a00b1198 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 15 Sep 2021 17:07:14 +0800 Subject: [PATCH 27/43] scsi: acornscsi: Remove tagged queuing vestiges The acornscsi driver has a config option to enable tagged queuing, but this option gets disabled in the driver itself with the comment 'needs to be debugged'. As this is a _really_ old driver I doubt anyone will be wanting to invest time here, so remove the tagged queue vestiges and make our lives easier. [jpg: Use scsi_cmd_to_rq()] Link: https://lore.kernel.org/r/1631696835-136198-3-git-send-email-john.garry@huawei.com Signed-off-by: Hannes Reinecke Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/Kconfig | 11 ---- drivers/scsi/arm/acornscsi.c | 103 ++++++++--------------------------- drivers/scsi/arm/queue.c | 2 +- 3 files changed, 23 insertions(+), 93 deletions(-) diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig index f34badc75196..9f64133f976a 100644 --- a/drivers/scsi/arm/Kconfig +++ b/drivers/scsi/arm/Kconfig @@ -10,17 +10,6 @@ config SCSI_ACORNSCSI_3 This enables support for the Acorn SCSI card (aka30). If you have an Acorn system with one of these, say Y. If unsure, say N. -config SCSI_ACORNSCSI_TAGGED_QUEUE - bool "Support SCSI 2 Tagged queueing" - depends on SCSI_ACORNSCSI_3 - help - Say Y here to enable tagged queuing support on the Acorn SCSI card. - - This is a feature of SCSI-2 which improves performance: the host - adapter can send several SCSI commands to a device's queue even if - previous commands haven't finished yet. Some SCSI devices don't - implement this properly, so the safe answer is N. - config SCSI_ACORNSCSI_SYNC bool "Support SCSI 2 Synchronous Transfers" depends on SCSI_ACORNSCSI_3 diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 4a84599ff491..b4cb5fb19998 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -52,12 +52,8 @@ * You can tell if you have a device that supports tagged queueing my * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported * as '2 TAG'. - * - * Also note that CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE is normally set in the config - * scripts, but disabled here. Once debugged, remove the #undef, otherwise to debug, - * comment out the undef. */ -#undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE + /* * SCSI-II Synchronous transfer support. * @@ -171,7 +167,7 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result); static int acornscsi_reconnect_finish(AS_Host *host); static void acornscsi_dma_cleanup(AS_Host *host); -static void acornscsi_abortcmd(AS_Host *host, unsigned char tag); +static void acornscsi_abortcmd(AS_Host *host); /* ==================================================================================== * Miscellaneous @@ -741,17 +737,6 @@ intr_ret_t acornscsi_kick(AS_Host *host) #endif if (from_queue) { -#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - /* - * tagged queueing - allocate a new tag to this command - */ - if (SCpnt->device->simple_tags) { - SCpnt->device->current_tag += 1; - if (SCpnt->device->current_tag == 0) - SCpnt->device->current_tag = 1; - SCpnt->tag = SCpnt->device->current_tag; - } else -#endif set_bit(SCpnt->device->id * 8 + (u8)(SCpnt->device->lun & 0x07), host->busyluns); @@ -1192,7 +1177,7 @@ void acornscsi_dma_intr(AS_Host *host) * the device recognises the attention. */ if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) { - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); dmac_write(host, DMAC_TXCNTLO, 0); dmac_write(host, DMAC_TXCNTHI, 0); @@ -1560,23 +1545,6 @@ void acornscsi_message(AS_Host *host) acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); switch (host->scsi.last_message) { -#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - case HEAD_OF_QUEUE_TAG: - case ORDERED_QUEUE_TAG: - case SIMPLE_QUEUE_TAG: - /* - * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17) - * If a target does not implement tagged queuing and a queue tag - * message is received, it shall respond with a MESSAGE REJECT - * message and accept the I/O process as if it were untagged. - */ - printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n", - host->host->host_no, acornscsi_target(host)); - host->SCpnt->device->simple_tags = 0; - set_bit(host->SCpnt->device->id * 8 + - (u8)(host->SCpnt->device->lun & 0x7), host->busyluns); - break; -#endif case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8): /* * Target can't handle synchronous transfers @@ -1687,24 +1655,11 @@ void acornscsi_buildmessages(AS_Host *host) #if 0 /* does the device need the current command aborted */ if (cmd_aborted) { - acornscsi_abortcmd(host->SCpnt->tag); + acornscsi_abortcmd(host); return; } #endif -#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - if (host->SCpnt->tag) { - unsigned int tag_type; - - if (host->SCpnt->cmnd[0] == REQUEST_SENSE || - host->SCpnt->cmnd[0] == TEST_UNIT_READY || - host->SCpnt->cmnd[0] == INQUIRY) - tag_type = HEAD_OF_QUEUE_TAG; - else - tag_type = SIMPLE_QUEUE_TAG; - msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag); - } -#endif #ifdef CONFIG_SCSI_ACORNSCSI_SYNC if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) { @@ -1798,7 +1753,7 @@ int acornscsi_reconnect(AS_Host *host) "to reconnect with\n", host->host->host_no, '0' + target); acornscsi_dumplog(host, target); - acornscsi_abortcmd(host, 0); + acornscsi_abortcmd(host); if (host->SCpnt) { queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); host->SCpnt = NULL; @@ -1821,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host) host->scsi.disconnectable = 0; if (host->SCpnt->device->id == host->scsi.reconnected.target && host->SCpnt->device->lun == host->scsi.reconnected.lun && - host->SCpnt->tag == host->scsi.reconnected.tag) { + scsi_cmd_to_tag(host->SCpnt) == host->scsi.reconnected.tag) { #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) DBG(host->SCpnt, printk("scsi%d.%c: reconnected", host->host->host_no, acornscsi_target(host))); @@ -1848,7 +1803,7 @@ int acornscsi_reconnect_finish(AS_Host *host) } if (!host->SCpnt) - acornscsi_abortcmd(host, host->scsi.reconnected.tag); + acornscsi_abortcmd(host); else { /* * Restore data pointer from SAVED pointers. @@ -1889,21 +1844,15 @@ void acornscsi_disconnect_unexpected(AS_Host *host) * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag) * Purpose : abort a currently executing command * Params : host - host with connected command to abort - * tag - tag to abort */ static -void acornscsi_abortcmd(AS_Host *host, unsigned char tag) +void acornscsi_abortcmd(AS_Host *host) { host->scsi.phase = PHASE_ABORTED; sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN); msgqueue_flush(&host->scsi.msgs); -#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - if (tag) - msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag); - else -#endif - msgqueue_addmsg(&host->scsi.msgs, 1, ABORT); + msgqueue_addmsg(&host->scsi.msgs, 1, ABORT); } /* ========================================================================================== @@ -1993,7 +1942,7 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n", host->host->host_no, acornscsi_target(host), ssr); acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); } return INTR_PROCESSING; @@ -2029,7 +1978,7 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n", host->host->host_no, acornscsi_target(host), ssr); acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); } return INTR_PROCESSING; @@ -2075,20 +2024,20 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) case 0x18: /* -> PHASE_DATAOUT */ /* COMMAND -> DATA OUT */ if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len) - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); acornscsi_dma_setup(host, DMA_OUT); if (!acornscsi_starttransfer(host)) - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); host->scsi.phase = PHASE_DATAOUT; return INTR_IDLE; case 0x19: /* -> PHASE_DATAIN */ /* COMMAND -> DATA IN */ if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len) - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); acornscsi_dma_setup(host, DMA_IN); if (!acornscsi_starttransfer(host)) - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); host->scsi.phase = PHASE_DATAIN; return INTR_IDLE; @@ -2156,7 +2105,7 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) /* MESSAGE IN -> DATA OUT */ acornscsi_dma_setup(host, DMA_OUT); if (!acornscsi_starttransfer(host)) - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); host->scsi.phase = PHASE_DATAOUT; return INTR_IDLE; @@ -2165,7 +2114,7 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) /* MESSAGE IN -> DATA IN */ acornscsi_dma_setup(host, DMA_IN); if (!acornscsi_starttransfer(host)) - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); host->scsi.phase = PHASE_DATAIN; return INTR_IDLE; @@ -2206,7 +2155,7 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) switch (ssr) { case 0x19: /* -> PHASE_DATAIN */ case 0x89: /* -> PHASE_DATAIN */ - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); return INTR_IDLE; case 0x1b: /* -> PHASE_STATUSIN */ @@ -2255,7 +2204,7 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) switch (ssr) { case 0x18: /* -> PHASE_DATAOUT */ case 0x88: /* -> PHASE_DATAOUT */ - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); return INTR_IDLE; case 0x1b: /* -> PHASE_STATUSIN */ @@ -2482,7 +2431,6 @@ static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt, SCpnt->scsi_done = done; SCpnt->host_scribble = NULL; SCpnt->result = 0; - SCpnt->tag = 0; SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]); SCpnt->SCp.sent_command = 0; SCpnt->SCp.scsi_xferred = 0; @@ -2581,7 +2529,7 @@ static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt) break; default: - acornscsi_abortcmd(host, host->SCpnt->tag); + acornscsi_abortcmd(host); res = res_snooze; } local_irq_restore(flags); @@ -2747,9 +2695,6 @@ char *acornscsi_info(struct Scsi_Host *host) #ifdef CONFIG_SCSI_ACORNSCSI_SYNC " SYNC" #endif -#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - " TAG" -#endif #if (DEBUG & DEBUG_NO_WRITE) " NOWRITE (" __stringify(NO_WRITE) ")" #endif @@ -2770,9 +2715,6 @@ static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance) #ifdef CONFIG_SCSI_ACORNSCSI_SYNC " SYNC" #endif -#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - " TAG" -#endif #if (DEBUG & DEBUG_NO_WRITE) " NOWRITE (" __stringify(NO_WRITE) ")" #endif @@ -2827,9 +2769,8 @@ static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance) seq_printf(m, "Device/Lun TaggedQ Sync\n"); seq_printf(m, " %d/%llu ", scd->id, scd->lun); if (scd->tagged_supported) - seq_printf(m, "%3sabled(%3d) ", - scd->simple_tags ? "en" : "dis", - scd->current_tag); + seq_printf(m, "%3sabled ", + scd->simple_tags ? "en" : "dis"); else seq_printf(m, "unsupported "); diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c index e5559f27669d..c6f71a7d1b8e 100644 --- a/drivers/scsi/arm/queue.c +++ b/drivers/scsi/arm/queue.c @@ -214,7 +214,7 @@ struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target, int lun, list_for_each(l, &queue->head) { QE_t *q = list_entry(l, QE_t, list); if (q->SCpnt->device->id == target && q->SCpnt->device->lun == lun && - q->SCpnt->tag == tag) { + scsi_cmd_to_rq(q->SCpnt)->tag == tag) { SCpnt = __queue_remove(queue, l); break; } From a4869faf9642518145a8aa4b52e0d5ab0e7ee896 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 15 Sep 2021 17:07:15 +0800 Subject: [PATCH 28/43] scsi: core: Remove 'current_tag' The 'current_tag' field in struct scsi_device is unused now; remove it. Link: https://lore.kernel.org/r/1631696835-136198-4-git-send-email-john.garry@huawei.com Reviewed-by: Bart Van Assche Signed-off-by: Hannes Reinecke Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- include/scsi/scsi_device.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 09a17f6e93a7..b97e142a7ca9 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -146,7 +146,6 @@ struct scsi_device { struct scsi_vpd __rcu *vpd_pg83; struct scsi_vpd __rcu *vpd_pg80; struct scsi_vpd __rcu *vpd_pg89; - unsigned char current_tag; /* current tag */ struct scsi_target *sdev_target; blist_flags_t sdev_bflags; /* black/white flags as also found in From cdbc16c552f27ac211a44f9959d813b4f3188223 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 16 Sep 2021 16:22:51 +0300 Subject: [PATCH 29/43] scsi: lpfc: Fix sprintf() overflow in lpfc_display_fpin_wwpn() This scnprintf() uses the wrong limit. It should be "LPFC_FPIN_WWPN_LINE_SZ - len" instead of LPFC_FPIN_WWPN_LINE_SZ. Link: https://lore.kernel.org/r/20210916132251.GD25094@kili Fixes: 428569e66fa7 ("scsi: lpfc: Expand FPIN and RDF receive logging") Reviewed-by: James Smart Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f3fc79b99165..052c0e5b1119 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -9387,7 +9387,7 @@ lpfc_display_fpin_wwpn(struct lpfc_hba *phba, __be64 *wwnlist, u32 cnt) /* Extract the next WWPN from the payload */ wwn = *wwnlist++; wwpn = be64_to_cpu(wwn); - len += scnprintf(buf + len, LPFC_FPIN_WWPN_LINE_SZ, + len += scnprintf(buf + len, LPFC_FPIN_WWPN_LINE_SZ - len, " %016llx", wwpn); /* Log a message if we are on the last WWPN From 6dacc371b77f473770ec646e220303a84fe96c11 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 16 Sep 2021 16:23:31 +0300 Subject: [PATCH 30/43] scsi: lpfc: Use correct scnprintf() limit The limit should be "PAGE_SIZE - len" instead of "PAGE_SIZE". We're not going to hit the limit so this fix will not affect runtime. Link: https://lore.kernel.org/r/20210916132331.GE25094@kili Fixes: 5b9e70b22cc5 ("scsi: lpfc: raise sg count for nvme to use available sg resources") Reviewed-by: James Smart Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b35bf70a8c0d..1e5a30eb04de 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -6204,7 +6204,8 @@ lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr, len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n", phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt); - len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n", + len += scnprintf(buf + len, PAGE_SIZE - len, + "Cfg: %d SCSI: %d NVME: %d\n", phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt, phba->cfg_nvme_seg_cnt); return len; From a38923f2d088d1a5cbaa86818abe039b2f87093d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Sep 2021 11:56:22 +0200 Subject: [PATCH 31/43] scsi: lpfc: Fix gcc -Wstringop-overread warning, again I fixed a stringop-overread warning earlier this year, now a second copy of the original code was added and the warning came back: drivers/scsi/lpfc/lpfc_attr.c: In function 'lpfc_cmf_info_show': drivers/scsi/lpfc/lpfc_attr.c:289:25: error: 'strnlen' specified bound 4095 exceeds source size 24 [-Werror=stringop-overread] 289 | strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1), | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix it the same way as the other copy. Link: https://lore.kernel.org/r/20210920095628.1191676-1-arnd@kernel.org Fixes: ada48ba70f6b ("scsi: lpfc: Fix gcc -Wstringop-overread warning") Fixes: 74a7baa2a3ee ("scsi: lpfc: Add cmf_info sysfs entry") Reviewed-by: James Smart Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 1e5a30eb04de..ebe417921dac 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -285,11 +285,8 @@ buffer_done: "6312 Catching potential buffer " "overflow > PAGE_SIZE = %lu bytes\n", PAGE_SIZE); - strscpy(buf + PAGE_SIZE - 1 - - strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1), - LPFC_INFO_MORE_STR, - strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1) - + 1); + strscpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_INFO_MORE_STR), + LPFC_INFO_MORE_STR, sizeof(LPFC_INFO_MORE_STR) + 1); } return len; } From 9a8ef2c73c727a3c64b70c01697c578c7b10fed2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 20 Sep 2021 19:32:06 +0100 Subject: [PATCH 32/43] scsi: target: Fix spelling mistake "CONFLIFT" -> "CONFLICT" There is a spelling mistake in a dev_err message. Fix it. Link: https://lore.kernel.org/r/20210920183206.17477-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/target/target_core_pr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 4b94b085625b..3829b61b56c1 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -269,7 +269,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) spin_lock(&dev->dev_reservation_lock); if (dev->reservation_holder && dev->reservation_holder->se_node_acl != sess->se_node_acl) { - pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n", + pr_err("SCSI-2 RESERVATION CONFLICT for %s fabric\n", tpg->se_tpg_tfo->fabric_name); pr_err("Original reserver LUN: %llu %s\n", cmd->se_lun->unpacked_lun, From fbdac19e642899455b4e64c63aafe2325df7aafa Mon Sep 17 00:00:00 2001 From: Wen Xiong Date: Thu, 16 Sep 2021 22:24:21 -0500 Subject: [PATCH 33/43] scsi: ses: Retry failed Send/Receive Diagnostic commands Setting SCSI logging level with error=3, we saw some errors from enclosues: [108017.360833] ses 0:0:9:0: tag#641 Done: NEEDS_RETRY Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK cmd_age=0s [108017.360838] ses 0:0:9:0: tag#641 CDB: Receive Diagnostic 1c 01 01 00 20 00 [108017.427778] ses 0:0:9:0: Power-on or device reset occurred [108017.427784] ses 0:0:9:0: tag#641 Done: SUCCESS Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s [108017.427788] ses 0:0:9:0: tag#641 CDB: Receive Diagnostic 1c 01 01 00 20 00 [108017.427791] ses 0:0:9:0: tag#641 Sense Key : Unit Attention [current] [108017.427793] ses 0:0:9:0: tag#641 Add. Sense: Bus device reset function occurred [108017.427801] ses 0:0:9:0: Failed to get diagnostic page 0x1 [108017.427804] ses 0:0:9:0: Failed to bind enclosure -19 [108017.427895] ses 0:0:10:0: Attached Enclosure device [108017.427942] ses 0:0:10:0: Attached scsi generic sg18 type 13 Retry if the Send/Receive Diagnostic commands complete with a transient error status (NOT_READY or UNIT_ATTENTION with ASC 0x29). Link: https://lore.kernel.org/r/1631849061-10210-2-git-send-email-wenxiong@linux.ibm.com Reviewed-by: Brian King Reviewed-by: James Bottomley Signed-off-by: Wen Xiong Signed-off-by: Martin K. Petersen --- drivers/scsi/ses.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index c2afba2a5414..43e682297fd5 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -87,9 +87,16 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code, 0 }; unsigned char recv_page_code; + unsigned int retries = SES_RETRIES; + struct scsi_sense_hdr sshdr; + + do { + ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, + &sshdr, SES_TIMEOUT, 1, NULL); + } while (ret > 0 && --retries && scsi_sense_valid(&sshdr) && + (sshdr.sense_key == NOT_READY || + (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29))); - ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, - NULL, SES_TIMEOUT, SES_RETRIES, NULL); if (unlikely(ret)) return ret; @@ -121,9 +128,16 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code, bufflen & 0xff, 0 }; + struct scsi_sense_hdr sshdr; + unsigned int retries = SES_RETRIES; + + do { + result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen, + &sshdr, SES_TIMEOUT, 1, NULL); + } while (result > 0 && --retries && scsi_sense_valid(&sshdr) && + (sshdr.sense_key == NOT_READY || + (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29))); - result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen, - NULL, SES_TIMEOUT, SES_RETRIES, NULL); if (result) sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n", result); From e8c2da7e329ce004fee748b921e4c765dc2fa338 Mon Sep 17 00:00:00 2001 From: Jonathan Hsu Date: Fri, 24 Sep 2021 16:58:48 +0800 Subject: [PATCH 34/43] scsi: ufs: Fix illegal offset in UPIU event trace Fix incorrect index for UTMRD reference in ufshcd_add_tm_upiu_trace(). Link: https://lore.kernel.org/r/20210924085848.25500-1-jonathan.hsu@mediatek.com Fixes: 4b42d557a8ad ("scsi: ufs: core: Fix wrong Task Tag used in task management request UPIUs") Cc: stable@vger.kernel.org Reviewed-by: Stanley Chu Reviewed-by: Bart Van Assche Signed-off-by: Jonathan Hsu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 029c9631ec2b..188de6f91050 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -318,8 +318,7 @@ static void ufshcd_add_query_upiu_trace(struct ufs_hba *hba, static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag, enum ufs_trace_str_t str_t) { - int off = (int)tag - hba->nutrs; - struct utp_task_req_desc *descp = &hba->utmrdl_base_addr[off]; + struct utp_task_req_desc *descp = &hba->utmrdl_base_addr[tag]; if (!trace_ufshcd_upiu_enabled()) return; From dd689ed5aa905daf4ba4c99319a52aad6ea0a796 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 24 Sep 2021 17:51:53 +0800 Subject: [PATCH 35/43] scsi: ses: Fix unsigned comparison with less than zero Fix the following coccicheck warning: ./drivers/scsi/ses.c:137:10-16: WARNING: Unsigned expression compared with zero: result > 0. Link: https://lore.kernel.org/r/1632477113-90378-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/ses.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 43e682297fd5..0a1734f34587 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -118,7 +118,7 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code, static int ses_send_diag(struct scsi_device *sdev, int page_code, void *buf, int bufflen) { - u32 result; + int result; unsigned char cmd[] = { SEND_DIAGNOSTIC, From cced4c0ec7c06f5230a2958907a409c849762293 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 25 Sep 2021 00:03:30 +0100 Subject: [PATCH 36/43] scsi: virtio_scsi: Fix spelling mistake "Unsupport" -> "Unsupported" There are a couple of spelling mistakes in pr_info and pr_err messages. Fix them. Link: https://lore.kernel.org/r/20210924230330.143785-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/virtio_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index c25ce8f0e0af..07d0250f17c3 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -300,7 +300,7 @@ static void virtscsi_handle_transport_reset(struct virtio_scsi *vscsi, } break; default: - pr_info("Unsupport virtio scsi event reason %x\n", event->reason); + pr_info("Unsupported virtio scsi event reason %x\n", event->reason); } } @@ -392,7 +392,7 @@ static void virtscsi_handle_event(struct work_struct *work) virtscsi_handle_param_change(vscsi, event); break; default: - pr_err("Unsupport virtio scsi event %x\n", event->event); + pr_err("Unsupported virtio scsi event %x\n", event->event); } virtscsi_kick_event(vscsi, event_node); } From 8e2d81c6b5be0d7629fb50b6f678fc07a4c58fae Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Fri, 24 Sep 2021 20:51:54 -0700 Subject: [PATCH 37/43] scsi: qla2xxx: Fix excessive messages during device logout Disable default logging of some I/O path messages. If desired, the messages can be turned back on by setting ql2xextended_error_logging. Link: https://lore.kernel.org/r/20210925035154.29815-1-njavali@marvell.com Reviewed-by: Ewan D. Milne Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_isr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ece60267b971..b26f2699adb2 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2634,7 +2634,7 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, } if (unlikely(logit)) - ql_log(ql_log_warn, fcport->vha, 0x5060, + ql_log(ql_dbg_io, fcport->vha, 0x5060, "NVME-%s ERR Handling - hdl=%x status(%x) tr_len:%x resid=%x ox_id=%x\n", sp->name, sp->handle, comp_status, fd->transferred_length, le32_to_cpu(sts->residual_len), @@ -3491,7 +3491,7 @@ check_scsi_status: out: if (logit) - ql_log(ql_log_warn, fcport->vha, 0x3022, + ql_log(ql_dbg_io, fcport->vha, 0x3022, "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu portid=%02x%02x%02x oxid=0x%x cdb=%10phN len=0x%x rsp_info=0x%x resid=0x%x fw_resid=0x%x sp=%p cp=%p.\n", comp_status, scsi_status, res, vha->host_no, cp->device->id, cp->device->lun, fcport->d_id.b.domain, From 79a7482249a7353bc86aff8127954d5febf02472 Mon Sep 17 00:00:00 2001 From: Rahul Lakkireddy Date: Mon, 27 Sep 2021 21:44:08 +0530 Subject: [PATCH 38/43] scsi: csiostor: Add module softdep on cxgb4 Both cxgb4 and csiostor drivers run on their own independent Physical Function. But when cxgb4 and csiostor are both being loaded in parallel via modprobe, there is a race when firmware upgrade is attempted by both the drivers. When the cxgb4 driver initiates the firmware upgrade, it halts the firmware and the chip until upgrade is complete. When the csiostor driver is coming up in parallel, the firmware mailbox communication fails with timeouts and the csiostor driver probe fails. Add a module soft dependency on cxgb4 driver to ensure loading csiostor triggers cxgb4 to load first when available to avoid the firmware upgrade race. Link: https://lore.kernel.org/r/1632759248-15382-1-git-send-email-rahul.lakkireddy@chelsio.com Fixes: a3667aaed569 ("[SCSI] csiostor: Chelsio FCoE offload driver") Signed-off-by: Rahul Lakkireddy Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 390b07bf92b9..ccbded3353bd 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -1254,3 +1254,4 @@ MODULE_DEVICE_TABLE(pci, csio_pci_tbl); MODULE_VERSION(CSIO_DRV_VERSION); MODULE_FIRMWARE(FW_FNAME_T5); MODULE_FIRMWARE(FW_FNAME_T6); +MODULE_SOFTDEP("pre: cxgb4"); From c5336400ca8b5f83123d965ce1eb9ac4a604cc95 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 30 Sep 2021 19:51:57 +0800 Subject: [PATCH 39/43] scsi: acornscsi: Remove scsi_cmd_to_tag() reference Commit 756fb6a895af ("scsi: acornscsi: Remove tagged queuing vestiges") mistakenly introduced a reference to function scsi_cmd_to_tag(). This function does not exist as it was removed from an earlier series version when I upstreamed the named commit - originally authored By Hannes - but this reference still remained. Fix by replacing the reference to scsi_cmd_to_tag() with scsi_cmd_to_rq(scsi_scmd)->tag, which scsi_cmd_to_tag() was a wrapper for. Link: https://lore.kernel.org/r/1633002717-79765-1-git-send-email-john.garry@huawei.com Fixes: 756fb6a895af ("scsi: acornscsi: Remove tagged queuing vestiges") Reported-by: Arnd Bergmann Tested-by: Arnd Bergmann Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/acornscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index b4cb5fb19998..0cc62c1b0825 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -1776,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host) host->scsi.disconnectable = 0; if (host->SCpnt->device->id == host->scsi.reconnected.target && host->SCpnt->device->lun == host->scsi.reconnected.lun && - scsi_cmd_to_tag(host->SCpnt) == host->scsi.reconnected.tag) { + scsi_cmd_to_rq(host->SCpnt)->tag == host->scsi.reconnected.tag) { #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) DBG(host->SCpnt, printk("scsi%d.%c: reconnected", host->host->host_no, acornscsi_target(host))); From f5ef336fd2e4c36dedae4e7ca66cf5349d6fda62 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 22 Sep 2021 12:10:59 +0300 Subject: [PATCH 40/43] scsi: ufs: core: Fix task management completion The UFS driver uses blk_mq_tagset_busy_iter() when identifying task management requests to complete, however blk_mq_tagset_busy_iter() doesn't work. blk_mq_tagset_busy_iter() only iterates requests dispatched by the block layer. That appears as if it might have started since commit 37f4a24c2469 ("blk-mq: centralise related handling into blk_mq_get_driver_tag") which removed 'data->hctx->tags->rqs[rq->tag] = rq' from blk_mq_rq_ctx_init() which gets called: blk_get_request blk_mq_alloc_request __blk_mq_alloc_request blk_mq_rq_ctx_init Since UFS task management requests are not dispatched by the block layer, hctx->tags->rqs[rq->tag] remains NULL, and since blk_mq_tagset_busy_iter() relies on finding requests using hctx->tags->rqs[rq->tag], UFS task management requests are never found by blk_mq_tagset_busy_iter(). By using blk_mq_tagset_busy_iter(), the UFS driver was relying on internal details of the block layer, which was fragile and subsequently got broken. Fix by removing the use of blk_mq_tagset_busy_iter() and having the driver keep track of task management requests. Link: https://lore.kernel.org/r/20210922091059.4040-1-adrian.hunter@intel.com Fixes: 1235fc569e0b ("scsi: ufs: core: Fix task management request completion timeout") Fixes: 69a6c269c097 ("scsi: ufs: Use blk_{get,put}_request() to allocate and free TMFs") Cc: stable@vger.kernel.org Tested-by: Bart Van Assche Reviewed-by: Bart Van Assche Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 52 +++++++++++++++++---------------------- drivers/scsi/ufs/ufshcd.h | 1 + 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 188de6f91050..95be7ecdfe10 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6377,27 +6377,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) return retval; } -struct ctm_info { - struct ufs_hba *hba; - unsigned long pending; - unsigned int ncpl; -}; - -static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) -{ - struct ctm_info *const ci = priv; - struct completion *c; - - WARN_ON_ONCE(reserved); - if (test_bit(req->tag, &ci->pending)) - return true; - ci->ncpl++; - c = req->end_io_data; - if (c) - complete(c); - return true; -} - /** * ufshcd_tmc_handler - handle task management function completion * @hba: per adapter instance @@ -6408,18 +6387,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) */ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) { - unsigned long flags; - struct request_queue *q = hba->tmf_queue; - struct ctm_info ci = { - .hba = hba, - }; + unsigned long flags, pending, issued; + irqreturn_t ret = IRQ_NONE; + int tag; + + pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); spin_lock_irqsave(hba->host->host_lock, flags); - ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); - blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); + issued = hba->outstanding_tasks & ~pending; + for_each_set_bit(tag, &issued, hba->nutmrs) { + struct request *req = hba->tmf_rqs[tag]; + struct completion *c = req->end_io_data; + + complete(c); + ret = IRQ_HANDLED; + } spin_unlock_irqrestore(hba->host->host_lock, flags); - return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; + return ret; } /** @@ -6542,9 +6527,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, ufshcd_hold(hba, false); spin_lock_irqsave(host->host_lock, flags); - blk_mq_start_request(req); task_tag = req->tag; + hba->tmf_rqs[req->tag] = req; treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag); memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); @@ -6585,6 +6570,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, } spin_lock_irqsave(hba->host->host_lock, flags); + hba->tmf_rqs[req->tag] = NULL; __clear_bit(task_tag, &hba->outstanding_tasks); spin_unlock_irqrestore(hba->host->host_lock, flags); @@ -9635,6 +9621,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) err = PTR_ERR(hba->tmf_queue); goto free_tmf_tag_set; } + hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs, + sizeof(*hba->tmf_rqs), GFP_KERNEL); + if (!hba->tmf_rqs) { + err = -ENOMEM; + goto free_tmf_queue; + } /* Reset the attached device */ ufshcd_device_reset(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index f0da5d3db1fa..41f6e06f9185 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -828,6 +828,7 @@ struct ufs_hba { struct blk_mq_tag_set tmf_tag_set; struct request_queue *tmf_queue; + struct request **tmf_rqs; struct uic_command *active_uic_cmd; struct mutex uic_cmd_mutex; From a013c71c6315d6e9d6364d12251b98c75c9a2861 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Oct 2021 13:38:51 +0300 Subject: [PATCH 41/43] scsi: elx: efct: Delete stray unlock statement It's not holding the lock at this stage and the IRQ "flags" are not correct so it would restore something bogus. Delete the unlock statement. Link: https://lore.kernel.org/r/20211004103851.GE25015@kili Fixes: 3e6414003bf9 ("scsi: elx: efct: SCSI I/O handling routines") Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/efct/efct_scsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/elx/efct/efct_scsi.c b/drivers/scsi/elx/efct/efct_scsi.c index 40fb3a724c76..cf2e41dd354c 100644 --- a/drivers/scsi/elx/efct/efct_scsi.c +++ b/drivers/scsi/elx/efct/efct_scsi.c @@ -32,7 +32,7 @@ efct_scsi_io_alloc(struct efct_node *node) struct efct *efct; struct efct_xport *xport; struct efct_io *io; - unsigned long flags = 0; + unsigned long flags; efct = node->efct; @@ -44,7 +44,6 @@ efct_scsi_io_alloc(struct efct_node *node) if (!io) { efc_log_err(efct, "IO alloc Failed\n"); atomic_add_return(1, &xport->io_alloc_failed_count); - spin_unlock_irqrestore(&node->active_ios_lock, flags); return NULL; } From 69a3a7bc7239170557dfc2c4ad5786a0c3d8759a Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 4 Oct 2021 16:12:10 -0700 Subject: [PATCH 42/43] scsi: lpfc: Fix memory overwrite during FC-GS I/O abort handling When an FC-GS I/O is aborted by lpfc, the driver requires a node pointer for a dereference operation. In the abort I/O routine, the driver miscasts a context pointer to the wrong data type and overwrites a single byte outside of the allocated space. This miscast is done in the abort I/O function handler because the handler works on both FC-GS and FC-LS commands. However, the code neglected to get the correct job location for the node. Fix this by acquiring the necessary node pointer from the correct job structure depending on the I/O type. Link: https://lore.kernel.org/r/20211004231210.35524-1-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 78ce38d7251c..026a1196a54d 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12292,12 +12292,12 @@ void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { - struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; + struct lpfc_nodelist *ndlp = NULL; IOCB_t *irsp = &rspiocb->iocb; /* ELS cmd tag completes */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "0139 Ignoring ELS cmd tag x%x completion Data: " + "0139 Ignoring ELS cmd code x%x completion Data: " "x%x x%x x%x\n", irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout); @@ -12305,10 +12305,13 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp * if exchange is busy. */ - if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) + if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) { + ndlp = cmdiocb->context_un.ndlp; lpfc_ct_free_iocb(phba, cmdiocb); - else + } else { + ndlp = (struct lpfc_nodelist *) cmdiocb->context1; lpfc_els_free_iocb(phba, cmdiocb); + } lpfc_nlp_put(ndlp); } From 258aad75c62146453d03028a44f2f1590d58e1f6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 4 Oct 2021 16:06:08 -0500 Subject: [PATCH 43/43] scsi: iscsi: Fix iscsi_task use after free Commit d39df158518c ("scsi: iscsi: Have abort handler get ref to conn") added iscsi_get_conn()/iscsi_put_conn() calls during abort handling but then also changed the handling of the case where we detect an already completed task where we now end up doing a goto to the common put/cleanup code. This results in a iscsi_task use after free, because the common cleanup code will do a put on the iscsi_task. This reverts the goto and moves the iscsi_get_conn() to after we've checked if the iscsi_task is valid. Link: https://lore.kernel.org/r/20211004210608.9962-1-michael.christie@oracle.com Fixes: d39df158518c ("scsi: iscsi: Have abort handler get ref to conn") Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/scsi/libiscsi.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4683c183e9d4..5bc91d34df63 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) return FAILED; } - conn = session->leadconn; - iscsi_get_conn(conn->cls_conn); - conn->eh_abort_cnt++; - age = session->age; - spin_lock(&session->back_lock); task = (struct iscsi_task *)sc->SCp.ptr; if (!task || !task->sc) { @@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); spin_unlock(&session->back_lock); - goto success; + spin_unlock_bh(&session->frwd_lock); + mutex_unlock(&session->eh_mutex); + return SUCCESS; } + + conn = session->leadconn; + iscsi_get_conn(conn->cls_conn); + conn->eh_abort_cnt++; + age = session->age; + ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt); __iscsi_get_task(task); spin_unlock(&session->back_lock);