Skip to content

Commit 2d51cb1

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: "ufs driver plus two core fixes. One core fix makes the unit attention counters atomic (just in case multiple commands detect them) and the other is fixing a merge window regression caused by changes in the block tree" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: core: Fix the unit attention counter implementation scsi: ufs: core: Declare tx_lanes witout initialization scsi: ufs: core: Initialize value of an attribute returned by uic cmd scsi: ufs: core: Fix error handler host_sem issue scsi: core: Fix a regression triggered by scsi_host_busy()
2 parents d127176 + d54c676 commit 2d51cb1

File tree

4 files changed

+26
-21
lines changed

4 files changed

+26
-21
lines changed

drivers/scsi/hosts.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,9 @@ int scsi_host_busy(struct Scsi_Host *shost)
611611
{
612612
int cnt = 0;
613613

614-
blk_mq_tagset_busy_iter(&shost->tag_set,
615-
scsi_host_check_in_flight, &cnt);
614+
if (shost->tag_set.ops)
615+
blk_mq_tagset_busy_iter(&shost->tag_set,
616+
scsi_host_check_in_flight, &cnt);
616617
return cnt;
617618
}
618619
EXPORT_SYMBOL(scsi_host_busy);

drivers/scsi/scsi_error.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,9 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
554554
* happened, even if someone else gets the sense data.
555555
*/
556556
if (sshdr.asc == 0x28)
557-
scmd->device->ua_new_media_ctr++;
557+
atomic_inc(&sdev->ua_new_media_ctr);
558558
else if (sshdr.asc == 0x29)
559-
scmd->device->ua_por_ctr++;
559+
atomic_inc(&sdev->ua_por_ctr);
560560
}
561561

562562
if (scsi_sense_is_deferred(&sshdr))

drivers/ufs/core/ufshcd.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,8 +4282,8 @@ int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
42824282
get, UIC_GET_ATTR_ID(attr_sel),
42834283
UFS_UIC_COMMAND_RETRIES - retries);
42844284

4285-
if (mib_val && !ret)
4286-
*mib_val = uic_cmd.argument3;
4285+
if (mib_val)
4286+
*mib_val = ret == 0 ? uic_cmd.argument3 : 0;
42874287

42884288
if (peer && (hba->quirks & UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE)
42894289
&& pwr_mode_change)
@@ -4999,7 +4999,7 @@ EXPORT_SYMBOL_GPL(ufshcd_hba_enable);
49994999

50005000
static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)
50015001
{
5002-
int tx_lanes = 0, i, err = 0;
5002+
int tx_lanes, i, err = 0;
50035003

50045004
if (!peer)
50055005
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
@@ -6673,6 +6673,20 @@ static void ufshcd_err_handler(struct work_struct *work)
66736673
hba->saved_uic_err, hba->force_reset,
66746674
ufshcd_is_link_broken(hba) ? "; link is broken" : "");
66756675

6676+
/*
6677+
* Use ufshcd_rpm_get_noresume() here to safely perform link recovery
6678+
* even if an error occurs during runtime suspend or runtime resume.
6679+
* This avoids potential deadlocks that could happen if we tried to
6680+
* resume the device while a PM operation is already in progress.
6681+
*/
6682+
ufshcd_rpm_get_noresume(hba);
6683+
if (hba->pm_op_in_progress) {
6684+
ufshcd_link_recovery(hba);
6685+
ufshcd_rpm_put(hba);
6686+
return;
6687+
}
6688+
ufshcd_rpm_put(hba);
6689+
66766690
down(&hba->host_sem);
66776691
spin_lock_irqsave(hba->host->host_lock, flags);
66786692
if (ufshcd_err_handling_should_stop(hba)) {
@@ -6684,14 +6698,6 @@ static void ufshcd_err_handler(struct work_struct *work)
66846698
}
66856699
spin_unlock_irqrestore(hba->host->host_lock, flags);
66866700

6687-
ufshcd_rpm_get_noresume(hba);
6688-
if (hba->pm_op_in_progress) {
6689-
ufshcd_link_recovery(hba);
6690-
ufshcd_rpm_put(hba);
6691-
return;
6692-
}
6693-
ufshcd_rpm_put(hba);
6694-
66956701
ufshcd_err_handling_prepare(hba);
66966702

66976703
spin_lock_irqsave(hba->host->host_lock, flags);

include/scsi/scsi_device.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ struct scsi_device {
252252
unsigned int queue_stopped; /* request queue is quiesced */
253253
bool offline_already; /* Device offline message logged */
254254

255-
unsigned int ua_new_media_ctr; /* Counter for New Media UNIT ATTENTIONs */
256-
unsigned int ua_por_ctr; /* Counter for Power On / Reset UAs */
255+
atomic_t ua_new_media_ctr; /* Counter for New Media UNIT ATTENTIONs */
256+
atomic_t ua_por_ctr; /* Counter for Power On / Reset UAs */
257257

258258
atomic_t disk_events_disable_depth; /* disable depth for disk events */
259259

@@ -693,10 +693,8 @@ static inline int scsi_device_busy(struct scsi_device *sdev)
693693
}
694694

695695
/* Macros to access the UNIT ATTENTION counters */
696-
#define scsi_get_ua_new_media_ctr(sdev) \
697-
((const unsigned int)(sdev->ua_new_media_ctr))
698-
#define scsi_get_ua_por_ctr(sdev) \
699-
((const unsigned int)(sdev->ua_por_ctr))
696+
#define scsi_get_ua_new_media_ctr(sdev) atomic_read(&sdev->ua_new_media_ctr)
697+
#define scsi_get_ua_por_ctr(sdev) atomic_read(&sdev->ua_por_ctr)
700698

701699
#define MODULE_ALIAS_SCSI_DEVICE(type) \
702700
MODULE_ALIAS("scsi:t-" __stringify(type) "*")

0 commit comments

Comments
 (0)