mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
SCSI fixes on 20250822
All fixes in drivers. The largest diffstat in ufs is caused by the doc update with the next being the qcom null pointer deref fix. Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCaKhBSSYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pisheYBAP9IwgCR ANnFXfILBJ0vGkZiVsV7lZPtcUChbTT0stGCXAD/axlU11QwE673mlxkVK5JuFGc fnCdTAt0iM1AqiGiCeI= =+twj -----END PGP SIGNATURE----- Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI fixes from James Bottomley: "All fixes in drivers. The largest diffstat in ufs is caused by the doc update with the next being the qcom null pointer deref fix" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ufs: ufs-qcom: Fix ESI null pointer dereference scsi: ufs: core: Rename ufshcd_wait_for_doorbell_clr() scsi: ufs: core: Fix the return value documentation scsi: ufs: core: Remove WARN_ON_ONCE() call from ufshcd_uic_cmd_compl() scsi: ufs: core: Fix IRQ lock inversion for the SCSI host lock scsi: qla4xxx: Prevent a potential error pointer dereference scsi: ufs: ufs-pci: Add support for Intel Wildcat Lake scsi: fnic: Remove a useless struct mempool forward declaration
This commit is contained in:
commit
edeee68c42
@ -323,8 +323,6 @@ enum fnic_state {
|
||||
FNIC_IN_ETH_TRANS_FC_MODE,
|
||||
};
|
||||
|
||||
struct mempool;
|
||||
|
||||
enum fnic_role_e {
|
||||
FNIC_ROLE_FCP_INITIATOR = 0,
|
||||
};
|
||||
|
@ -6606,6 +6606,8 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,
|
||||
|
||||
ep = qla4xxx_ep_connect(ha->host, (struct sockaddr *)dst_addr, 0);
|
||||
vfree(dst_addr);
|
||||
if (IS_ERR(ep))
|
||||
return NULL;
|
||||
return ep;
|
||||
}
|
||||
|
||||
|
@ -1303,7 +1303,7 @@ static u32 ufshcd_pending_cmds(struct ufs_hba *hba)
|
||||
*
|
||||
* Return: 0 upon success; -EBUSY upon timeout.
|
||||
*/
|
||||
static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
|
||||
static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba,
|
||||
u64 wait_timeout_us)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -1431,7 +1431,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
|
||||
down_write(&hba->clk_scaling_lock);
|
||||
|
||||
if (!hba->clk_scaling.is_allowed ||
|
||||
ufshcd_wait_for_doorbell_clr(hba, timeout_us)) {
|
||||
ufshcd_wait_for_pending_cmds(hba, timeout_us)) {
|
||||
ret = -EBUSY;
|
||||
up_write(&hba->clk_scaling_lock);
|
||||
mutex_unlock(&hba->wb_mutex);
|
||||
@ -3199,7 +3199,8 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return: 0 upon success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
|
||||
struct ufshcd_lrb *lrbp, int max_timeout)
|
||||
@ -3275,7 +3276,6 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3294,7 +3294,8 @@ static void ufshcd_dev_man_unlock(struct ufs_hba *hba)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return: 0 upon success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_issue_dev_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
|
||||
const u32 tag, int timeout)
|
||||
@ -3317,7 +3318,8 @@ static int ufshcd_issue_dev_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
|
||||
* @cmd_type: specifies the type (NOP, Query...)
|
||||
* @timeout: timeout in milliseconds
|
||||
*
|
||||
* Return: 0 upon success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*
|
||||
* NOTE: Since there is only one available tag for device management commands,
|
||||
* it is expected you hold the hba->dev_cmd.lock mutex.
|
||||
@ -3363,6 +3365,10 @@ static inline void ufshcd_init_query(struct ufs_hba *hba,
|
||||
(*request)->upiu_req.selector = selector;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_query_flag_retry(struct ufs_hba *hba,
|
||||
enum query_opcode opcode, enum flag_idn idn, u8 index, bool *flag_res)
|
||||
{
|
||||
@ -3383,7 +3389,6 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba,
|
||||
dev_err(hba->dev,
|
||||
"%s: query flag, opcode %d, idn %d, failed with error %d after %d retries\n",
|
||||
__func__, opcode, idn, ret, retries);
|
||||
WARN_ONCE(ret > 0, "Incorrect return value %d > 0\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3395,7 +3400,8 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba,
|
||||
* @index: flag index to access
|
||||
* @flag_res: the flag value after the query request completes
|
||||
*
|
||||
* Return: 0 for success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
|
||||
enum flag_idn idn, u8 index, bool *flag_res)
|
||||
@ -3451,7 +3457,6 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
|
||||
|
||||
out_unlock:
|
||||
ufshcd_dev_man_unlock(hba);
|
||||
WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3464,8 +3469,9 @@ out_unlock:
|
||||
* @selector: selector field
|
||||
* @attr_val: the attribute value after the query request completes
|
||||
*
|
||||
* Return: 0 upon success; < 0 upon failure.
|
||||
*/
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
|
||||
enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
|
||||
{
|
||||
@ -3513,7 +3519,6 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
|
||||
|
||||
out_unlock:
|
||||
ufshcd_dev_man_unlock(hba);
|
||||
WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3528,8 +3533,9 @@ out_unlock:
|
||||
* @attr_val: the attribute value after the query request
|
||||
* completes
|
||||
*
|
||||
* Return: 0 for success; < 0 upon failure.
|
||||
*/
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_query_attr_retry(struct ufs_hba *hba,
|
||||
enum query_opcode opcode, enum attr_idn idn, u8 index, u8 selector,
|
||||
u32 *attr_val)
|
||||
@ -3551,12 +3557,12 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba,
|
||||
dev_err(hba->dev,
|
||||
"%s: query attribute, idn %d, failed with error %d after %d retries\n",
|
||||
__func__, idn, ret, QUERY_REQ_RETRIES);
|
||||
WARN_ONCE(ret > 0, "Incorrect return value %d > 0\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return: 0 if successful; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int __ufshcd_query_descriptor(struct ufs_hba *hba,
|
||||
enum query_opcode opcode, enum desc_idn idn, u8 index,
|
||||
@ -3615,7 +3621,6 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba,
|
||||
out_unlock:
|
||||
hba->dev_cmd.query.descriptor = NULL;
|
||||
ufshcd_dev_man_unlock(hba);
|
||||
WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3632,7 +3637,8 @@ out_unlock:
|
||||
* The buf_len parameter will contain, on return, the length parameter
|
||||
* received on the response.
|
||||
*
|
||||
* Return: 0 for success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
|
||||
enum query_opcode opcode,
|
||||
@ -3650,7 +3656,6 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
|
||||
break;
|
||||
}
|
||||
|
||||
WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3663,7 +3668,8 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
|
||||
* @param_read_buf: pointer to buffer where parameter would be read
|
||||
* @param_size: sizeof(param_read_buf)
|
||||
*
|
||||
* Return: 0 in case of success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_read_desc_param(struct ufs_hba *hba,
|
||||
enum desc_idn desc_id,
|
||||
@ -3730,7 +3736,6 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
|
||||
out:
|
||||
if (is_kmalloc)
|
||||
kfree(desc_buf);
|
||||
WARN_ONCE(ret > 0, "Incorrect return value %d > 0\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -4781,7 +4786,8 @@ EXPORT_SYMBOL_GPL(ufshcd_config_pwr_mode);
|
||||
*
|
||||
* Set fDeviceInit flag and poll until device toggles it.
|
||||
*
|
||||
* Return: 0 upon success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_complete_dev_init(struct ufs_hba *hba)
|
||||
{
|
||||
@ -5135,7 +5141,8 @@ out:
|
||||
* not respond with NOP IN UPIU within timeout of %NOP_OUT_TIMEOUT
|
||||
* and we retry sending NOP OUT for %NOP_OUT_RETRIES iterations.
|
||||
*
|
||||
* Return: 0 upon success; < 0 upon failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_verify_dev_init(struct ufs_hba *hba)
|
||||
{
|
||||
@ -5559,9 +5566,9 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)
|
||||
irqreturn_t retval = IRQ_NONE;
|
||||
struct uic_command *cmd;
|
||||
|
||||
spin_lock(hba->host->host_lock);
|
||||
guard(spinlock_irqsave)(hba->host->host_lock);
|
||||
cmd = hba->active_uic_cmd;
|
||||
if (WARN_ON_ONCE(!cmd))
|
||||
if (!cmd)
|
||||
goto unlock;
|
||||
|
||||
if (ufshcd_is_auto_hibern8_error(hba, intr_status))
|
||||
@ -5586,8 +5593,6 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)
|
||||
ufshcd_add_uic_command_trace(hba, cmd, UFS_CMD_COMP);
|
||||
|
||||
unlock:
|
||||
spin_unlock(hba->host->host_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -5869,7 +5874,8 @@ static inline int ufshcd_enable_ee(struct ufs_hba *hba, u16 mask)
|
||||
* as the device is allowed to manage its own way of handling background
|
||||
* operations.
|
||||
*
|
||||
* Return: zero on success, non-zero on failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_enable_auto_bkops(struct ufs_hba *hba)
|
||||
{
|
||||
@ -5908,7 +5914,8 @@ out:
|
||||
* host is idle so that BKOPS are managed effectively without any negative
|
||||
* impacts.
|
||||
*
|
||||
* Return: zero on success, non-zero on failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
static int ufshcd_disable_auto_bkops(struct ufs_hba *hba)
|
||||
{
|
||||
@ -6058,6 +6065,10 @@ out:
|
||||
__func__, err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_read_device_lvl_exception_id(struct ufs_hba *hba, u64 *exception_id)
|
||||
{
|
||||
struct utp_upiu_query_v4_0 *upiu_resp;
|
||||
@ -6920,7 +6931,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
|
||||
bool queue_eh_work = false;
|
||||
irqreturn_t retval = IRQ_NONE;
|
||||
|
||||
spin_lock(hba->host->host_lock);
|
||||
guard(spinlock_irqsave)(hba->host->host_lock);
|
||||
hba->errors |= UFSHCD_ERROR_MASK & intr_status;
|
||||
|
||||
if (hba->errors & INT_FATAL_ERRORS) {
|
||||
@ -6979,7 +6990,7 @@ 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);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -7454,7 +7465,8 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
|
||||
* @sg_list: Pointer to SG list when DATA IN/OUT UPIU is required in ARPMB operation
|
||||
* @dir: DMA direction
|
||||
*
|
||||
* Return: zero on success, non-zero on failure.
|
||||
* Return: 0 upon success; > 0 in case the UFS device reported an OCS error;
|
||||
* < 0 if another error occurred.
|
||||
*/
|
||||
int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *req_upiu,
|
||||
struct utp_upiu_req *rsp_upiu, struct ufs_ehs *req_ehs,
|
||||
|
@ -2070,17 +2070,6 @@ static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void ufs_qcom_irq_free(struct ufs_qcom_irq *uqi)
|
||||
{
|
||||
for (struct ufs_qcom_irq *q = uqi; q->irq; q++)
|
||||
devm_free_irq(q->hba->dev, q->irq, q->hba);
|
||||
|
||||
platform_device_msi_free_irqs_all(uqi->hba->dev);
|
||||
devm_kfree(uqi->hba->dev, uqi);
|
||||
}
|
||||
|
||||
DEFINE_FREE(ufs_qcom_irq, struct ufs_qcom_irq *, if (_T) ufs_qcom_irq_free(_T))
|
||||
|
||||
static int ufs_qcom_config_esi(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
|
||||
@ -2095,18 +2084,18 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
|
||||
*/
|
||||
nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL];
|
||||
|
||||
struct ufs_qcom_irq *qi __free(ufs_qcom_irq) =
|
||||
devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL);
|
||||
if (!qi)
|
||||
return -ENOMEM;
|
||||
/* Preset so __free() has a pointer to hba in all error paths */
|
||||
qi[0].hba = hba;
|
||||
|
||||
ret = platform_device_msi_init_and_alloc_irqs(hba->dev, nr_irqs,
|
||||
ufs_qcom_write_msi_msg);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "Failed to request Platform MSI %d\n", ret);
|
||||
return ret;
|
||||
dev_warn(hba->dev, "Platform MSI not supported or failed, continuing without ESI\n");
|
||||
return ret; /* Continue without ESI */
|
||||
}
|
||||
|
||||
struct ufs_qcom_irq *qi = devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL);
|
||||
|
||||
if (!qi) {
|
||||
platform_device_msi_free_irqs_all(hba->dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < nr_irqs; idx++) {
|
||||
@ -2117,15 +2106,17 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
|
||||
ret = devm_request_irq(hba->dev, qi[idx].irq, ufs_qcom_mcq_esi_handler,
|
||||
IRQF_SHARED, "qcom-mcq-esi", qi + idx);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "%s: Fail to request IRQ for %d, err = %d\n",
|
||||
dev_err(hba->dev, "%s: Failed to request IRQ for %d, err = %d\n",
|
||||
__func__, qi[idx].irq, ret);
|
||||
qi[idx].irq = 0;
|
||||
/* Free previously allocated IRQs */
|
||||
for (int j = 0; j < idx; j++)
|
||||
devm_free_irq(hba->dev, qi[j].irq, qi + j);
|
||||
platform_device_msi_free_irqs_all(hba->dev);
|
||||
devm_kfree(hba->dev, qi);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
retain_and_null_ptr(qi);
|
||||
|
||||
if (host->hw_ver.major >= 6) {
|
||||
ufshcd_rmwl(hba, ESI_VEC_MASK, FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1),
|
||||
REG_UFS_CFG3);
|
||||
|
@ -630,6 +630,7 @@ static const struct pci_device_id ufshcd_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xA847), (kernel_ulong_t)&ufs_intel_mtl_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0x7747), (kernel_ulong_t)&ufs_intel_mtl_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0xE447), (kernel_ulong_t)&ufs_intel_mtl_hba_vops },
|
||||
{ PCI_VDEVICE(INTEL, 0x4D47), (kernel_ulong_t)&ufs_intel_mtl_hba_vops },
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user