Skip to content

Commit 02ddfb9

Browse files
committed
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()
2 parents 30e2681 + b0b7ee3 commit 02ddfb9

File tree

8 files changed

+116
-10
lines changed

8 files changed

+116
-10
lines changed

drivers/scsi/mpi3mr/mpi3mr_fw.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ static void mpi3mr_print_event_data(struct mpi3mr_ioc *mrioc,
174174
char *desc = NULL;
175175
u16 event;
176176

177+
if (!(mrioc->logging_level & MPI3_DEBUG_EVENT))
178+
return;
179+
177180
event = event_reply->event;
178181

179182
switch (event) {
@@ -451,6 +454,7 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
451454
return 0;
452455
}
453456

457+
atomic_set(&mrioc->admin_pend_isr, 0);
454458
reply_desc = (struct mpi3_default_reply_descriptor *)mrioc->admin_reply_base +
455459
admin_reply_ci;
456460

@@ -565,7 +569,7 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
565569
WRITE_ONCE(op_req_q->ci, le16_to_cpu(reply_desc->request_queue_ci));
566570
mpi3mr_process_op_reply_desc(mrioc, reply_desc, &reply_dma,
567571
reply_qidx);
568-
atomic_dec(&op_reply_q->pend_ios);
572+
569573
if (reply_dma)
570574
mpi3mr_repost_reply_buf(mrioc, reply_dma);
571575
num_op_reply++;
@@ -2925,6 +2929,7 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc)
29252929
mrioc->admin_reply_ci = 0;
29262930
mrioc->admin_reply_ephase = 1;
29272931
atomic_set(&mrioc->admin_reply_q_in_use, 0);
2932+
atomic_set(&mrioc->admin_pend_isr, 0);
29282933

29292934
if (!mrioc->admin_req_base) {
29302935
mrioc->admin_req_base = dma_alloc_coherent(&mrioc->pdev->dev,
@@ -4653,6 +4658,7 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
46534658
if (mrioc->admin_reply_base)
46544659
memset(mrioc->admin_reply_base, 0, mrioc->admin_reply_q_sz);
46554660
atomic_set(&mrioc->admin_reply_q_in_use, 0);
4661+
atomic_set(&mrioc->admin_pend_isr, 0);
46564662

46574663
if (mrioc->init_cmds.reply) {
46584664
memset(mrioc->init_cmds.reply, 0, sizeof(*mrioc->init_cmds.reply));

drivers/scsi/scsi_lib.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -1253,8 +1253,12 @@ EXPORT_SYMBOL_GPL(scsi_alloc_request);
12531253
*/
12541254
static void scsi_cleanup_rq(struct request *rq)
12551255
{
1256+
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
1257+
1258+
cmd->flags = 0;
1259+
12561260
if (rq->rq_flags & RQF_DONTPREP) {
1257-
scsi_mq_uninit_cmd(blk_mq_rq_to_pdu(rq));
1261+
scsi_mq_uninit_cmd(cmd);
12581262
rq->rq_flags &= ~RQF_DONTPREP;
12591263
}
12601264
}

drivers/target/iscsi/iscsi_target.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4263,8 +4263,8 @@ int iscsit_close_connection(
42634263
spin_unlock(&iscsit_global->ts_bitmap_lock);
42644264

42654265
iscsit_stop_timers_for_cmds(conn);
4266-
iscsit_stop_nopin_response_timer(conn);
42674266
iscsit_stop_nopin_timer(conn);
4267+
iscsit_stop_nopin_response_timer(conn);
42684268

42694269
if (conn->conn_transport->iscsit_wait_conn)
42704270
conn->conn_transport->iscsit_wait_conn(conn);

drivers/ufs/core/ufs-mcq.c

+5-7
Original file line numberDiff line numberDiff line change
@@ -677,13 +677,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
677677
unsigned long flags;
678678
int err;
679679

680-
if (!ufshcd_cmd_inflight(lrbp->cmd)) {
681-
dev_err(hba->dev,
682-
"%s: skip abort. cmd at tag %d already completed.\n",
683-
__func__, tag);
684-
return FAILED;
685-
}
686-
687680
/* Skip task abort in case previous aborts failed and report failure */
688681
if (lrbp->req_abort_skip) {
689682
dev_err(hba->dev, "%s: skip abort. tag %d failed earlier\n",
@@ -692,6 +685,11 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
692685
}
693686

694687
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
688+
if (!hwq) {
689+
dev_err(hba->dev, "%s: skip abort. cmd at tag %d already completed.\n",
690+
__func__, tag);
691+
return FAILED;
692+
}
695693

696694
if (ufshcd_mcq_sqe_search(hba, hwq, tag)) {
697695
/*

drivers/ufs/core/ufshcd.c

+31
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ static const struct ufs_dev_quirk ufs_fixups[] = {
278278
.model = UFS_ANY_MODEL,
279279
.quirk = UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM |
280280
UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE |
281+
UFS_DEVICE_QUIRK_PA_HIBER8TIME |
281282
UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS },
282283
{ .wmanufacturerid = UFS_VENDOR_SKHYNIX,
283284
.model = UFS_ANY_MODEL,
@@ -5677,6 +5678,8 @@ static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba,
56775678
continue;
56785679

56795680
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
5681+
if (!hwq)
5682+
continue;
56805683

56815684
if (force_compl) {
56825685
ufshcd_mcq_compl_all_cqes_lock(hba, hwq);
@@ -8470,6 +8473,31 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba)
84708473
return ret;
84718474
}
84728475

8476+
/**
8477+
* ufshcd_quirk_override_pa_h8time - Ensures proper adjustment of PA_HIBERN8TIME.
8478+
* @hba: per-adapter instance
8479+
*
8480+
* Some UFS devices require specific adjustments to the PA_HIBERN8TIME parameter
8481+
* to ensure proper hibernation timing. This function retrieves the current
8482+
* PA_HIBERN8TIME value and increments it by 100us.
8483+
*/
8484+
static void ufshcd_quirk_override_pa_h8time(struct ufs_hba *hba)
8485+
{
8486+
u32 pa_h8time;
8487+
int ret;
8488+
8489+
ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME), &pa_h8time);
8490+
if (ret) {
8491+
dev_err(hba->dev, "Failed to get PA_HIBERN8TIME: %d\n", ret);
8492+
return;
8493+
}
8494+
8495+
/* Increment by 1 to increase hibernation time by 100 µs */
8496+
ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), pa_h8time + 1);
8497+
if (ret)
8498+
dev_err(hba->dev, "Failed updating PA_HIBERN8TIME: %d\n", ret);
8499+
}
8500+
84738501
static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
84748502
{
84758503
ufshcd_vops_apply_dev_quirks(hba);
@@ -8480,6 +8508,9 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
84808508

84818509
if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE)
84828510
ufshcd_quirk_tune_host_pa_tactivate(hba);
8511+
8512+
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_HIBER8TIME)
8513+
ufshcd_quirk_override_pa_h8time(hba);
84838514
}
84848515

84858516
static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)

drivers/ufs/host/ufs-qcom.c

+43
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
((((c) >> 16) & MCQ_QCFGPTR_MASK) * MCQ_QCFGPTR_UNIT)
3434
#define MCQ_QCFG_SIZE 0x40
3535

36+
/* De-emphasis for gear-5 */
37+
#define DEEMPHASIS_3_5_dB 0x04
38+
#define NO_DEEMPHASIS 0x0
39+
3640
enum {
3741
TSTBUS_UAWM,
3842
TSTBUS_UARM,
@@ -795,6 +799,23 @@ static int ufs_qcom_icc_update_bw(struct ufs_qcom_host *host)
795799
return ufs_qcom_icc_set_bw(host, bw_table.mem_bw, bw_table.cfg_bw);
796800
}
797801

802+
static void ufs_qcom_set_tx_hs_equalizer(struct ufs_hba *hba, u32 gear, u32 tx_lanes)
803+
{
804+
u32 equalizer_val;
805+
int ret, i;
806+
807+
/* Determine the equalizer value based on the gear */
808+
equalizer_val = (gear == 5) ? DEEMPHASIS_3_5_dB : NO_DEEMPHASIS;
809+
810+
for (i = 0; i < tx_lanes; i++) {
811+
ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HS_EQUALIZER, i),
812+
equalizer_val);
813+
if (ret)
814+
dev_err(hba->dev, "%s: failed equalizer lane %d\n",
815+
__func__, i);
816+
}
817+
}
818+
798819
static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
799820
enum ufs_notify_change_status status,
800821
const struct ufs_pa_layer_attr *dev_max_params,
@@ -846,6 +867,11 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
846867
dev_req_params->gear_tx,
847868
PA_INITIAL_ADAPT);
848869
}
870+
871+
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING)
872+
ufs_qcom_set_tx_hs_equalizer(hba,
873+
dev_req_params->gear_tx, dev_req_params->lane_tx);
874+
849875
break;
850876
case POST_CHANGE:
851877
if (ufs_qcom_cfg_timers(hba, false)) {
@@ -893,13 +919,26 @@ static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba)
893919
(pa_vs_config_reg1 | (1 << 12)));
894920
}
895921

922+
static void ufs_qcom_override_pa_tx_hsg1_sync_len(struct ufs_hba *hba)
923+
{
924+
int err;
925+
926+
err = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TX_HSG1_SYNC_LENGTH),
927+
PA_TX_HSG1_SYNC_LENGTH_VAL);
928+
if (err)
929+
dev_err(hba->dev, "Failed (%d) set PA_TX_HSG1_SYNC_LENGTH\n", err);
930+
}
931+
896932
static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
897933
{
898934
int err = 0;
899935

900936
if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME)
901937
err = ufs_qcom_quirk_host_pa_saveconfigtime(hba);
902938

939+
if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH)
940+
ufs_qcom_override_pa_tx_hsg1_sync_len(hba);
941+
903942
return err;
904943
}
905944

@@ -914,6 +953,10 @@ static struct ufs_dev_quirk ufs_qcom_dev_fixups[] = {
914953
{ .wmanufacturerid = UFS_VENDOR_WDC,
915954
.model = UFS_ANY_MODEL,
916955
.quirk = UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE },
956+
{ .wmanufacturerid = UFS_VENDOR_SAMSUNG,
957+
.model = UFS_ANY_MODEL,
958+
.quirk = UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH |
959+
UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING },
917960
{}
918961
};
919962

drivers/ufs/host/ufs-qcom.h

+18
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,11 @@ enum {
122122
TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN)
123123

124124
/* QUniPro Vendor specific attributes */
125+
#define PA_TX_HSG1_SYNC_LENGTH 0x1552
125126
#define PA_VS_CONFIG_REG1 0x9000
126127
#define DME_VS_CORE_CLK_CTRL 0xD002
128+
#define TX_HS_EQUALIZER 0x0037
129+
127130
/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
128131
#define CLK_1US_CYCLES_MASK_V4 GENMASK(27, 16)
129132
#define CLK_1US_CYCLES_MASK GENMASK(7, 0)
@@ -141,6 +144,21 @@ enum {
141144
#define UNIPRO_CORE_CLK_FREQ_201_5_MHZ 202
142145
#define UNIPRO_CORE_CLK_FREQ_403_MHZ 403
143146

147+
/* TX_HSG1_SYNC_LENGTH attr value */
148+
#define PA_TX_HSG1_SYNC_LENGTH_VAL 0x4A
149+
150+
/*
151+
* Some ufs device vendors need a different TSync length.
152+
* Enable this quirk to give an additional TX_HS_SYNC_LENGTH.
153+
*/
154+
#define UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH BIT(16)
155+
156+
/*
157+
* Some ufs device vendors need a different Deemphasis setting.
158+
* Enable this quirk to tune TX Deemphasis parameters.
159+
*/
160+
#define UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING BIT(17)
161+
144162
/* ICE allocator type to share AES engines among TX stream and RX stream */
145163
#define ICE_ALLOCATOR_TYPE 2
146164

include/ufs/ufs_quirks.h

+6
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,10 @@ struct ufs_dev_quirk {
107107
*/
108108
#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11)
109109

110+
/*
111+
* Some ufs devices may need more time to be in hibern8 before exiting.
112+
* Enable this quirk to give it an additional 100us.
113+
*/
114+
#define UFS_DEVICE_QUIRK_PA_HIBER8TIME (1 << 12)
115+
110116
#endif /* UFS_QUIRKS_H_ */

0 commit comments

Comments
 (0)