mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-03 22:57:21 -04:00
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "The single core change is an obvious bug fix (and falls within the LF guidelines for patches from sanctioned entities). The other driver changes are a bit larger but likewise pretty obvious" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: mpi3mr: Add level check to control event logging scsi: ufs: core: Add NULL check in ufshcd_mcq_compl_pending_transfer() scsi: core: Clear flags for scsi_cmnd that did not complete scsi: ufs: Introduce quirk to extend PA_HIBERN8TIME for UFS devices scsi: ufs: qcom: Add quirks for Samsung UFS devices scsi: target: iscsi: Fix timeout on deleted connection scsi: mpi3mr: Reset the pending interrupt flag scsi: mpi3mr: Fix pending I/O counter scsi: ufs: mcq: Add NULL check in ufshcd_mcq_abort()
This commit is contained in:
@@ -174,6 +174,9 @@ static void mpi3mr_print_event_data(struct mpi3mr_ioc *mrioc,
|
||||
char *desc = NULL;
|
||||
u16 event;
|
||||
|
||||
if (!(mrioc->logging_level & MPI3_DEBUG_EVENT))
|
||||
return;
|
||||
|
||||
event = event_reply->event;
|
||||
|
||||
switch (event) {
|
||||
@@ -451,6 +454,7 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
atomic_set(&mrioc->admin_pend_isr, 0);
|
||||
reply_desc = (struct mpi3_default_reply_descriptor *)mrioc->admin_reply_base +
|
||||
admin_reply_ci;
|
||||
|
||||
@@ -565,7 +569,7 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
|
||||
WRITE_ONCE(op_req_q->ci, le16_to_cpu(reply_desc->request_queue_ci));
|
||||
mpi3mr_process_op_reply_desc(mrioc, reply_desc, &reply_dma,
|
||||
reply_qidx);
|
||||
atomic_dec(&op_reply_q->pend_ios);
|
||||
|
||||
if (reply_dma)
|
||||
mpi3mr_repost_reply_buf(mrioc, reply_dma);
|
||||
num_op_reply++;
|
||||
@@ -2925,6 +2929,7 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc)
|
||||
mrioc->admin_reply_ci = 0;
|
||||
mrioc->admin_reply_ephase = 1;
|
||||
atomic_set(&mrioc->admin_reply_q_in_use, 0);
|
||||
atomic_set(&mrioc->admin_pend_isr, 0);
|
||||
|
||||
if (!mrioc->admin_req_base) {
|
||||
mrioc->admin_req_base = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
@@ -4653,6 +4658,7 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
|
||||
if (mrioc->admin_reply_base)
|
||||
memset(mrioc->admin_reply_base, 0, mrioc->admin_reply_q_sz);
|
||||
atomic_set(&mrioc->admin_reply_q_in_use, 0);
|
||||
atomic_set(&mrioc->admin_pend_isr, 0);
|
||||
|
||||
if (mrioc->init_cmds.reply) {
|
||||
memset(mrioc->init_cmds.reply, 0, sizeof(*mrioc->init_cmds.reply));
|
||||
|
||||
@@ -1253,8 +1253,12 @@ EXPORT_SYMBOL_GPL(scsi_alloc_request);
|
||||
*/
|
||||
static void scsi_cleanup_rq(struct request *rq)
|
||||
{
|
||||
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
|
||||
|
||||
cmd->flags = 0;
|
||||
|
||||
if (rq->rq_flags & RQF_DONTPREP) {
|
||||
scsi_mq_uninit_cmd(blk_mq_rq_to_pdu(rq));
|
||||
scsi_mq_uninit_cmd(cmd);
|
||||
rq->rq_flags &= ~RQF_DONTPREP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4263,8 +4263,8 @@ int iscsit_close_connection(
|
||||
spin_unlock(&iscsit_global->ts_bitmap_lock);
|
||||
|
||||
iscsit_stop_timers_for_cmds(conn);
|
||||
iscsit_stop_nopin_response_timer(conn);
|
||||
iscsit_stop_nopin_timer(conn);
|
||||
iscsit_stop_nopin_response_timer(conn);
|
||||
|
||||
if (conn->conn_transport->iscsit_wait_conn)
|
||||
conn->conn_transport->iscsit_wait_conn(conn);
|
||||
|
||||
@@ -677,13 +677,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
|
||||
unsigned long flags;
|
||||
int err;
|
||||
|
||||
if (!ufshcd_cmd_inflight(lrbp->cmd)) {
|
||||
dev_err(hba->dev,
|
||||
"%s: skip abort. cmd at tag %d already completed.\n",
|
||||
__func__, tag);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* Skip task abort in case previous aborts failed and report failure */
|
||||
if (lrbp->req_abort_skip) {
|
||||
dev_err(hba->dev, "%s: skip abort. tag %d failed earlier\n",
|
||||
@@ -692,6 +685,11 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
|
||||
}
|
||||
|
||||
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
|
||||
if (!hwq) {
|
||||
dev_err(hba->dev, "%s: skip abort. cmd at tag %d already completed.\n",
|
||||
__func__, tag);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (ufshcd_mcq_sqe_search(hba, hwq, tag)) {
|
||||
/*
|
||||
|
||||
@@ -278,6 +278,7 @@ static const struct ufs_dev_quirk ufs_fixups[] = {
|
||||
.model = UFS_ANY_MODEL,
|
||||
.quirk = UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM |
|
||||
UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE |
|
||||
UFS_DEVICE_QUIRK_PA_HIBER8TIME |
|
||||
UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS },
|
||||
{ .wmanufacturerid = UFS_VENDOR_SKHYNIX,
|
||||
.model = UFS_ANY_MODEL,
|
||||
@@ -5677,6 +5678,8 @@ static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba,
|
||||
continue;
|
||||
|
||||
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
|
||||
if (!hwq)
|
||||
continue;
|
||||
|
||||
if (force_compl) {
|
||||
ufshcd_mcq_compl_all_cqes_lock(hba, hwq);
|
||||
@@ -8470,6 +8473,31 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_quirk_override_pa_h8time - Ensures proper adjustment of PA_HIBERN8TIME.
|
||||
* @hba: per-adapter instance
|
||||
*
|
||||
* Some UFS devices require specific adjustments to the PA_HIBERN8TIME parameter
|
||||
* to ensure proper hibernation timing. This function retrieves the current
|
||||
* PA_HIBERN8TIME value and increments it by 100us.
|
||||
*/
|
||||
static void ufshcd_quirk_override_pa_h8time(struct ufs_hba *hba)
|
||||
{
|
||||
u32 pa_h8time;
|
||||
int ret;
|
||||
|
||||
ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME), &pa_h8time);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "Failed to get PA_HIBERN8TIME: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Increment by 1 to increase hibernation time by 100 µs */
|
||||
ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), pa_h8time + 1);
|
||||
if (ret)
|
||||
dev_err(hba->dev, "Failed updating PA_HIBERN8TIME: %d\n", ret);
|
||||
}
|
||||
|
||||
static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
|
||||
{
|
||||
ufshcd_vops_apply_dev_quirks(hba);
|
||||
@@ -8480,6 +8508,9 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
|
||||
|
||||
if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
|
||||
ufshcd_quirk_tune_host_pa_tactivate(hba);
|
||||
|
||||
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_HIBER8TIME)
|
||||
ufshcd_quirk_override_pa_h8time(hba);
|
||||
}
|
||||
|
||||
static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
((((c) >> 16) & MCQ_QCFGPTR_MASK) * MCQ_QCFGPTR_UNIT)
|
||||
#define MCQ_QCFG_SIZE 0x40
|
||||
|
||||
/* De-emphasis for gear-5 */
|
||||
#define DEEMPHASIS_3_5_dB 0x04
|
||||
#define NO_DEEMPHASIS 0x0
|
||||
|
||||
enum {
|
||||
TSTBUS_UAWM,
|
||||
TSTBUS_UARM,
|
||||
@@ -795,6 +799,23 @@ static int ufs_qcom_icc_update_bw(struct ufs_qcom_host *host)
|
||||
return ufs_qcom_icc_set_bw(host, bw_table.mem_bw, bw_table.cfg_bw);
|
||||
}
|
||||
|
||||
static void ufs_qcom_set_tx_hs_equalizer(struct ufs_hba *hba, u32 gear, u32 tx_lanes)
|
||||
{
|
||||
u32 equalizer_val;
|
||||
int ret, i;
|
||||
|
||||
/* Determine the equalizer value based on the gear */
|
||||
equalizer_val = (gear == 5) ? DEEMPHASIS_3_5_dB : NO_DEEMPHASIS;
|
||||
|
||||
for (i = 0; i < tx_lanes; i++) {
|
||||
ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HS_EQUALIZER, i),
|
||||
equalizer_val);
|
||||
if (ret)
|
||||
dev_err(hba->dev, "%s: failed equalizer lane %d\n",
|
||||
__func__, i);
|
||||
}
|
||||
}
|
||||
|
||||
static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
|
||||
enum ufs_notify_change_status status,
|
||||
const struct ufs_pa_layer_attr *dev_max_params,
|
||||
@@ -846,6 +867,11 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
|
||||
dev_req_params->gear_tx,
|
||||
PA_INITIAL_ADAPT);
|
||||
}
|
||||
|
||||
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING)
|
||||
ufs_qcom_set_tx_hs_equalizer(hba,
|
||||
dev_req_params->gear_tx, dev_req_params->lane_tx);
|
||||
|
||||
break;
|
||||
case POST_CHANGE:
|
||||
if (ufs_qcom_cfg_timers(hba, false)) {
|
||||
@@ -893,6 +919,16 @@ static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba)
|
||||
(pa_vs_config_reg1 | (1 << 12)));
|
||||
}
|
||||
|
||||
static void ufs_qcom_override_pa_tx_hsg1_sync_len(struct ufs_hba *hba)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TX_HSG1_SYNC_LENGTH),
|
||||
PA_TX_HSG1_SYNC_LENGTH_VAL);
|
||||
if (err)
|
||||
dev_err(hba->dev, "Failed (%d) set PA_TX_HSG1_SYNC_LENGTH\n", err);
|
||||
}
|
||||
|
||||
static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -900,6 +936,9 @@ static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
|
||||
if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME)
|
||||
err = ufs_qcom_quirk_host_pa_saveconfigtime(hba);
|
||||
|
||||
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH)
|
||||
ufs_qcom_override_pa_tx_hsg1_sync_len(hba);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -914,6 +953,10 @@ static struct ufs_dev_quirk ufs_qcom_dev_fixups[] = {
|
||||
{ .wmanufacturerid = UFS_VENDOR_WDC,
|
||||
.model = UFS_ANY_MODEL,
|
||||
.quirk = UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE },
|
||||
{ .wmanufacturerid = UFS_VENDOR_SAMSUNG,
|
||||
.model = UFS_ANY_MODEL,
|
||||
.quirk = UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH |
|
||||
UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -122,8 +122,11 @@ enum {
|
||||
TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN)
|
||||
|
||||
/* QUniPro Vendor specific attributes */
|
||||
#define PA_TX_HSG1_SYNC_LENGTH 0x1552
|
||||
#define PA_VS_CONFIG_REG1 0x9000
|
||||
#define DME_VS_CORE_CLK_CTRL 0xD002
|
||||
#define TX_HS_EQUALIZER 0x0037
|
||||
|
||||
/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
|
||||
#define CLK_1US_CYCLES_MASK_V4 GENMASK(27, 16)
|
||||
#define CLK_1US_CYCLES_MASK GENMASK(7, 0)
|
||||
@@ -141,6 +144,21 @@ enum {
|
||||
#define UNIPRO_CORE_CLK_FREQ_201_5_MHZ 202
|
||||
#define UNIPRO_CORE_CLK_FREQ_403_MHZ 403
|
||||
|
||||
/* TX_HSG1_SYNC_LENGTH attr value */
|
||||
#define PA_TX_HSG1_SYNC_LENGTH_VAL 0x4A
|
||||
|
||||
/*
|
||||
* Some ufs device vendors need a different TSync length.
|
||||
* Enable this quirk to give an additional TX_HS_SYNC_LENGTH.
|
||||
*/
|
||||
#define UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH BIT(16)
|
||||
|
||||
/*
|
||||
* Some ufs device vendors need a different Deemphasis setting.
|
||||
* Enable this quirk to tune TX Deemphasis parameters.
|
||||
*/
|
||||
#define UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING BIT(17)
|
||||
|
||||
/* ICE allocator type to share AES engines among TX stream and RX stream */
|
||||
#define ICE_ALLOCATOR_TYPE 2
|
||||
|
||||
|
||||
@@ -107,4 +107,10 @@ struct ufs_dev_quirk {
|
||||
*/
|
||||
#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11)
|
||||
|
||||
/*
|
||||
* Some ufs devices may need more time to be in hibern8 before exiting.
|
||||
* Enable this quirk to give it an additional 100us.
|
||||
*/
|
||||
#define UFS_DEVICE_QUIRK_PA_HIBER8TIME (1 << 12)
|
||||
|
||||
#endif /* UFS_QUIRKS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user