Skip to content

Commit 1c8ac1c

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: "Four fixes, three in drivers. The two biggest fixes are ufs and the remaining driver and core fix are small and obvious (and the core fix is low risk)" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ufs: core: Fix a race condition related to device management scsi: core: Fix warning in scsi_alloc_sgtables() scsi: ufs: host: Hold reference returned by of_parse_phandle() scsi: mpt3sas: Stop fw fault watchdog work item during system shutdown
2 parents bb83c99 + f5c2976 commit 1c8ac1c

File tree

4 files changed

+55
-21
lines changed

4 files changed

+55
-21
lines changed

drivers/scsi/mpt3sas/mpt3sas_scsih.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11386,6 +11386,7 @@ scsih_shutdown(struct pci_dev *pdev)
1138611386
_scsih_ir_shutdown(ioc);
1138711387
_scsih_nvme_shutdown(ioc);
1138811388
mpt3sas_base_mask_interrupts(ioc);
11389+
mpt3sas_base_stop_watchdog(ioc);
1138911390
ioc->shost_recovery = 1;
1139011391
mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
1139111392
ioc->shost_recovery = 0;

drivers/scsi/scsi_ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
450450
goto out_put_request;
451451

452452
ret = 0;
453-
if (hdr->iovec_count) {
453+
if (hdr->iovec_count && hdr->dxfer_len) {
454454
struct iov_iter i;
455455
struct iovec *iov = NULL;
456456

drivers/ufs/core/ufshcd.c

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,37 +2953,59 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
29532953
static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
29542954
struct ufshcd_lrb *lrbp, int max_timeout)
29552955
{
2956-
int err = 0;
2957-
unsigned long time_left;
2956+
unsigned long time_left = msecs_to_jiffies(max_timeout);
29582957
unsigned long flags;
2958+
bool pending;
2959+
int err;
29592960

2961+
retry:
29602962
time_left = wait_for_completion_timeout(hba->dev_cmd.complete,
2961-
msecs_to_jiffies(max_timeout));
2963+
time_left);
29622964

2963-
spin_lock_irqsave(hba->host->host_lock, flags);
2964-
hba->dev_cmd.complete = NULL;
29652965
if (likely(time_left)) {
2966+
/*
2967+
* The completion handler called complete() and the caller of
2968+
* this function still owns the @lrbp tag so the code below does
2969+
* not trigger any race conditions.
2970+
*/
2971+
hba->dev_cmd.complete = NULL;
29662972
err = ufshcd_get_tr_ocs(lrbp);
29672973
if (!err)
29682974
err = ufshcd_dev_cmd_completion(hba, lrbp);
2969-
}
2970-
spin_unlock_irqrestore(hba->host->host_lock, flags);
2971-
2972-
if (!time_left) {
2975+
} else {
29732976
err = -ETIMEDOUT;
29742977
dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n",
29752978
__func__, lrbp->task_tag);
2976-
if (!ufshcd_clear_cmds(hba, 1U << lrbp->task_tag))
2979+
if (ufshcd_clear_cmds(hba, 1U << lrbp->task_tag) == 0) {
29772980
/* successfully cleared the command, retry if needed */
29782981
err = -EAGAIN;
2979-
/*
2980-
* in case of an error, after clearing the doorbell,
2981-
* we also need to clear the outstanding_request
2982-
* field in hba
2983-
*/
2984-
spin_lock_irqsave(&hba->outstanding_lock, flags);
2985-
__clear_bit(lrbp->task_tag, &hba->outstanding_reqs);
2986-
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
2982+
/*
2983+
* Since clearing the command succeeded we also need to
2984+
* clear the task tag bit from the outstanding_reqs
2985+
* variable.
2986+
*/
2987+
spin_lock_irqsave(&hba->outstanding_lock, flags);
2988+
pending = test_bit(lrbp->task_tag,
2989+
&hba->outstanding_reqs);
2990+
if (pending) {
2991+
hba->dev_cmd.complete = NULL;
2992+
__clear_bit(lrbp->task_tag,
2993+
&hba->outstanding_reqs);
2994+
}
2995+
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
2996+
2997+
if (!pending) {
2998+
/*
2999+
* The completion handler ran while we tried to
3000+
* clear the command.
3001+
*/
3002+
time_left = 1;
3003+
goto retry;
3004+
}
3005+
} else {
3006+
dev_err(hba->dev, "%s: failed to clear tag %d\n",
3007+
__func__, lrbp->task_tag);
3008+
}
29873009
}
29883010

29893011
return err;

drivers/ufs/host/ufshcd-pltfrm.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,20 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
108108
return ret;
109109
}
110110

111+
static bool phandle_exists(const struct device_node *np,
112+
const char *phandle_name, int index)
113+
{
114+
struct device_node *parse_np = of_parse_phandle(np, phandle_name, index);
115+
116+
if (parse_np)
117+
of_node_put(parse_np);
118+
119+
return parse_np != NULL;
120+
}
121+
111122
#define MAX_PROP_SIZE 32
112123
static int ufshcd_populate_vreg(struct device *dev, const char *name,
113-
struct ufs_vreg **out_vreg)
124+
struct ufs_vreg **out_vreg)
114125
{
115126
char prop_name[MAX_PROP_SIZE];
116127
struct ufs_vreg *vreg = NULL;
@@ -122,7 +133,7 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
122133
}
123134

124135
snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", name);
125-
if (!of_parse_phandle(np, prop_name, 0)) {
136+
if (!phandle_exists(np, prop_name, 0)) {
126137
dev_info(dev, "%s: Unable to find %s regulator, assuming enabled\n",
127138
__func__, prop_name);
128139
goto out;

0 commit comments

Comments
 (0)