Skip to content

Commit

Permalink
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "Seven small fixes, six in drivers and one in sd.

  The sd fix is so large because it changes a struct pointer to a struct
  but otherwise is fairly simple"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ufs: qcom-ufs: dt-bindings: Document the SM8650 UFS Controller
  scsi: sd: Fix sshdr use in sd_suspend_common()
  scsi: scsi_debug: Delete some bogus error checking
  scsi: scsi_debug: Fix some bugs in sdebug_error_write()
  scsi: ufs: core: Fix racing issue between ufshcd_mcq_abort() and ISR
  scsi: ufs: core: Expand MCQ queue slot to DeviceQueueDepth + 1
  scsi: qla2xxx: Fix system crash due to bad pointer access
  • Loading branch information
Linus Torvalds committed Nov 18, 2023
2 parents 2254005 + 2a0508d commit 037266a
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 41 deletions.
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ properties:
- qcom,sm8350-ufshc
- qcom,sm8450-ufshc
- qcom,sm8550-ufshc
- qcom,sm8650-ufshc
- const: qcom,ufshc
- const: jedec,ufs-2.0

Expand Down Expand Up @@ -122,6 +123,7 @@ allOf:
- qcom,sm8350-ufshc
- qcom,sm8450-ufshc
- qcom,sm8550-ufshc
- qcom,sm8650-ufshc
then:
properties:
clocks:
Expand Down
12 changes: 10 additions & 2 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -1837,8 +1837,16 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
}

spin_lock_irqsave(qp->qp_lock_ptr, *flags);
if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd)))
sp->done(sp, res);
switch (sp->type) {
case SRB_SCSI_CMD:
if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd)))
sp->done(sp, res);
break;
default:
if (ret_cmd)
sp->done(sp, res);
break;
}
} else {
sp->done(sp, res);
}
Expand Down
9 changes: 1 addition & 8 deletions drivers/scsi/scsi_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf,
struct sdebug_err_inject *inject;
struct scsi_device *sdev = (struct scsi_device *)file->f_inode->i_private;

buf = kmalloc(count, GFP_KERNEL);
buf = kzalloc(count + 1, GFP_KERNEL);
if (!buf)
return -ENOMEM;

Expand Down Expand Up @@ -1132,23 +1132,16 @@ static const struct file_operations sdebug_target_reset_fail_fops = {
static int sdebug_target_alloc(struct scsi_target *starget)
{
struct sdebug_target_info *targetip;
struct dentry *dentry;

targetip = kzalloc(sizeof(struct sdebug_target_info), GFP_KERNEL);
if (!targetip)
return -ENOMEM;

targetip->debugfs_entry = debugfs_create_dir(dev_name(&starget->dev),
sdebug_debugfs_root);
if (IS_ERR_OR_NULL(targetip->debugfs_entry))
pr_info("%s: failed to create debugfs directory for target %s\n",
__func__, dev_name(&starget->dev));

debugfs_create_file("fail_reset", 0600, targetip->debugfs_entry, starget,
&sdebug_target_reset_fail_fops);
if (IS_ERR_OR_NULL(dentry))
pr_info("%s: failed to create fail_reset file for target %s\n",
__func__, dev_name(&starget->dev));

starget->hostdata = targetip;

Expand Down
53 changes: 23 additions & 30 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1643,24 +1643,21 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
}

static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
static int sd_sync_cache(struct scsi_disk *sdkp)
{
int retries, res;
struct scsi_device *sdp = sdkp->device;
const int timeout = sdp->request_queue->rq_timeout
* SD_FLUSH_TIMEOUT_MULTIPLIER;
struct scsi_sense_hdr my_sshdr;
struct scsi_sense_hdr sshdr;
const struct scsi_exec_args exec_args = {
.req_flags = BLK_MQ_REQ_PM,
/* caller might not be interested in sense, but we need it */
.sshdr = sshdr ? : &my_sshdr,
.sshdr = &sshdr,
};

if (!scsi_device_online(sdp))
return -ENODEV;

sshdr = exec_args.sshdr;

for (retries = 3; retries > 0; --retries) {
unsigned char cmd[16] = { 0 };

Expand All @@ -1685,15 +1682,23 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
return res;

if (scsi_status_is_check_condition(res) &&
scsi_sense_valid(sshdr)) {
sd_print_sense_hdr(sdkp, sshdr);
scsi_sense_valid(&sshdr)) {
sd_print_sense_hdr(sdkp, &sshdr);

/* we need to evaluate the error return */
if (sshdr->asc == 0x3a || /* medium not present */
sshdr->asc == 0x20 || /* invalid command */
(sshdr->asc == 0x74 && sshdr->ascq == 0x71)) /* drive is password locked */
if (sshdr.asc == 0x3a || /* medium not present */
sshdr.asc == 0x20 || /* invalid command */
(sshdr.asc == 0x74 && sshdr.ascq == 0x71)) /* drive is password locked */
/* this is no error here */
return 0;
/*
* This drive doesn't support sync and there's not much
* we can do because this is called during shutdown
* or suspend so just return success so those operations
* can proceed.
*/
if (sshdr.sense_key == ILLEGAL_REQUEST)
return 0;
}

switch (host_byte(res)) {
Expand Down Expand Up @@ -3853,7 +3858,7 @@ static void sd_shutdown(struct device *dev)

if (sdkp->WCE && sdkp->media_present) {
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
sd_sync_cache(sdkp, NULL);
sd_sync_cache(sdkp);
}

if ((system_state != SYSTEM_RESTART &&
Expand All @@ -3874,7 +3879,6 @@ static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime)
static int sd_suspend_common(struct device *dev, bool runtime)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
struct scsi_sense_hdr sshdr;
int ret = 0;

if (!sdkp) /* E.g.: runtime suspend following sd_remove() */
Expand All @@ -3883,24 +3887,13 @@ static int sd_suspend_common(struct device *dev, bool runtime)
if (sdkp->WCE && sdkp->media_present) {
if (!sdkp->device->silence_suspend)
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
ret = sd_sync_cache(sdkp, &sshdr);

if (ret) {
/* ignore OFFLINE device */
if (ret == -ENODEV)
return 0;

if (!scsi_sense_valid(&sshdr) ||
sshdr.sense_key != ILLEGAL_REQUEST)
return ret;
ret = sd_sync_cache(sdkp);
/* ignore OFFLINE device */
if (ret == -ENODEV)
return 0;

/*
* sshdr.sense_key == ILLEGAL_REQUEST means this drive
* doesn't support sync. There's not much to do and
* suspend shouldn't fail.
*/
ret = 0;
}
if (ret)
return ret;
}

if (sd_do_start_stop(sdkp->device, runtime)) {
Expand Down
5 changes: 4 additions & 1 deletion drivers/ufs/core/ufs-mcq.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ int ufshcd_mcq_init(struct ufs_hba *hba)

for (i = 0; i < hba->nr_hw_queues; i++) {
hwq = &hba->uhq[i];
hwq->max_entries = hba->nutrs;
hwq->max_entries = hba->nutrs + 1;
spin_lock_init(&hwq->sq_lock);
spin_lock_init(&hwq->cq_lock);
mutex_init(&hwq->sq_mutex);
Expand Down Expand Up @@ -630,6 +630,7 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
int tag = scsi_cmd_to_rq(cmd)->tag;
struct ufshcd_lrb *lrbp = &hba->lrb[tag];
struct ufs_hw_queue *hwq;
unsigned long flags;
int err = FAILED;

if (!ufshcd_cmd_inflight(lrbp->cmd)) {
Expand Down Expand Up @@ -670,8 +671,10 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
}

err = SUCCESS;
spin_lock_irqsave(&hwq->cq_lock, flags);
if (ufshcd_cmd_inflight(lrbp->cmd))
ufshcd_release_scsi_cmd(hba, lrbp);
spin_unlock_irqrestore(&hwq->cq_lock, flags);

out:
return err;
Expand Down

0 comments on commit 037266a

Please sign in to comment.