Commit 037266a5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/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
parents 2254005e 2a0508d9
...@@ -36,6 +36,7 @@ properties: ...@@ -36,6 +36,7 @@ properties:
- qcom,sm8350-ufshc - qcom,sm8350-ufshc
- qcom,sm8450-ufshc - qcom,sm8450-ufshc
- qcom,sm8550-ufshc - qcom,sm8550-ufshc
- qcom,sm8650-ufshc
- const: qcom,ufshc - const: qcom,ufshc
- const: jedec,ufs-2.0 - const: jedec,ufs-2.0
...@@ -122,6 +123,7 @@ allOf: ...@@ -122,6 +123,7 @@ allOf:
- qcom,sm8350-ufshc - qcom,sm8350-ufshc
- qcom,sm8450-ufshc - qcom,sm8450-ufshc
- qcom,sm8550-ufshc - qcom,sm8550-ufshc
- qcom,sm8650-ufshc
then: then:
properties: properties:
clocks: clocks:
......
...@@ -1837,8 +1837,16 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, ...@@ -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); spin_lock_irqsave(qp->qp_lock_ptr, *flags);
switch (sp->type) {
case SRB_SCSI_CMD:
if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd))) if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd)))
sp->done(sp, res); sp->done(sp, res);
break;
default:
if (ret_cmd)
sp->done(sp, res);
break;
}
} else { } else {
sp->done(sp, res); sp->done(sp, res);
} }
......
...@@ -1019,7 +1019,7 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf, ...@@ -1019,7 +1019,7 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf,
struct sdebug_err_inject *inject; struct sdebug_err_inject *inject;
struct scsi_device *sdev = (struct scsi_device *)file->f_inode->i_private; 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) if (!buf)
return -ENOMEM; return -ENOMEM;
...@@ -1132,7 +1132,6 @@ static const struct file_operations sdebug_target_reset_fail_fops = { ...@@ -1132,7 +1132,6 @@ static const struct file_operations sdebug_target_reset_fail_fops = {
static int sdebug_target_alloc(struct scsi_target *starget) static int sdebug_target_alloc(struct scsi_target *starget)
{ {
struct sdebug_target_info *targetip; struct sdebug_target_info *targetip;
struct dentry *dentry;
targetip = kzalloc(sizeof(struct sdebug_target_info), GFP_KERNEL); targetip = kzalloc(sizeof(struct sdebug_target_info), GFP_KERNEL);
if (!targetip) if (!targetip)
...@@ -1140,15 +1139,9 @@ static int sdebug_target_alloc(struct scsi_target *starget) ...@@ -1140,15 +1139,9 @@ static int sdebug_target_alloc(struct scsi_target *starget)
targetip->debugfs_entry = debugfs_create_dir(dev_name(&starget->dev), targetip->debugfs_entry = debugfs_create_dir(dev_name(&starget->dev),
sdebug_debugfs_root); 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, debugfs_create_file("fail_reset", 0600, targetip->debugfs_entry, starget,
&sdebug_target_reset_fail_fops); &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; starget->hostdata = targetip;
......
...@@ -1643,24 +1643,21 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) ...@@ -1643,24 +1643,21 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0; 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; int retries, res;
struct scsi_device *sdp = sdkp->device; struct scsi_device *sdp = sdkp->device;
const int timeout = sdp->request_queue->rq_timeout const int timeout = sdp->request_queue->rq_timeout
* SD_FLUSH_TIMEOUT_MULTIPLIER; * SD_FLUSH_TIMEOUT_MULTIPLIER;
struct scsi_sense_hdr my_sshdr; struct scsi_sense_hdr sshdr;
const struct scsi_exec_args exec_args = { const struct scsi_exec_args exec_args = {
.req_flags = BLK_MQ_REQ_PM, .req_flags = BLK_MQ_REQ_PM,
/* caller might not be interested in sense, but we need it */ .sshdr = &sshdr,
.sshdr = sshdr ? : &my_sshdr,
}; };
if (!scsi_device_online(sdp)) if (!scsi_device_online(sdp))
return -ENODEV; return -ENODEV;
sshdr = exec_args.sshdr;
for (retries = 3; retries > 0; --retries) { for (retries = 3; retries > 0; --retries) {
unsigned char cmd[16] = { 0 }; unsigned char cmd[16] = { 0 };
...@@ -1685,15 +1682,23 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) ...@@ -1685,15 +1682,23 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
return res; return res;
if (scsi_status_is_check_condition(res) && if (scsi_status_is_check_condition(res) &&
scsi_sense_valid(sshdr)) { scsi_sense_valid(&sshdr)) {
sd_print_sense_hdr(sdkp, sshdr); sd_print_sense_hdr(sdkp, &sshdr);
/* we need to evaluate the error return */ /* we need to evaluate the error return */
if (sshdr->asc == 0x3a || /* medium not present */ if (sshdr.asc == 0x3a || /* medium not present */
sshdr->asc == 0x20 || /* invalid command */ sshdr.asc == 0x20 || /* invalid command */
(sshdr->asc == 0x74 && sshdr->ascq == 0x71)) /* drive is password locked */ (sshdr.asc == 0x74 && sshdr.ascq == 0x71)) /* drive is password locked */
/* this is no error here */ /* this is no error here */
return 0; 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)) { switch (host_byte(res)) {
...@@ -3853,7 +3858,7 @@ static void sd_shutdown(struct device *dev) ...@@ -3853,7 +3858,7 @@ static void sd_shutdown(struct device *dev)
if (sdkp->WCE && sdkp->media_present) { if (sdkp->WCE && sdkp->media_present) {
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
sd_sync_cache(sdkp, NULL); sd_sync_cache(sdkp);
} }
if ((system_state != SYSTEM_RESTART && if ((system_state != SYSTEM_RESTART &&
...@@ -3874,7 +3879,6 @@ static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) ...@@ -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) static int sd_suspend_common(struct device *dev, bool runtime)
{ {
struct scsi_disk *sdkp = dev_get_drvdata(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
struct scsi_sense_hdr sshdr;
int ret = 0; int ret = 0;
if (!sdkp) /* E.g.: runtime suspend following sd_remove() */ if (!sdkp) /* E.g.: runtime suspend following sd_remove() */
...@@ -3883,24 +3887,13 @@ static int sd_suspend_common(struct device *dev, bool runtime) ...@@ -3883,24 +3887,13 @@ static int sd_suspend_common(struct device *dev, bool runtime)
if (sdkp->WCE && sdkp->media_present) { if (sdkp->WCE && sdkp->media_present) {
if (!sdkp->device->silence_suspend) if (!sdkp->device->silence_suspend)
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
ret = sd_sync_cache(sdkp, &sshdr); ret = sd_sync_cache(sdkp);
if (ret) {
/* ignore OFFLINE device */ /* ignore OFFLINE device */
if (ret == -ENODEV) if (ret == -ENODEV)
return 0; return 0;
if (!scsi_sense_valid(&sshdr) || if (ret)
sshdr.sense_key != ILLEGAL_REQUEST)
return ret; return ret;
/*
* 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 (sd_do_start_stop(sdkp->device, runtime)) { if (sd_do_start_stop(sdkp->device, runtime)) {
......
...@@ -436,7 +436,7 @@ int ufshcd_mcq_init(struct ufs_hba *hba) ...@@ -436,7 +436,7 @@ int ufshcd_mcq_init(struct ufs_hba *hba)
for (i = 0; i < hba->nr_hw_queues; i++) { for (i = 0; i < hba->nr_hw_queues; i++) {
hwq = &hba->uhq[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->sq_lock);
spin_lock_init(&hwq->cq_lock); spin_lock_init(&hwq->cq_lock);
mutex_init(&hwq->sq_mutex); mutex_init(&hwq->sq_mutex);
...@@ -630,6 +630,7 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd) ...@@ -630,6 +630,7 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
int tag = scsi_cmd_to_rq(cmd)->tag; int tag = scsi_cmd_to_rq(cmd)->tag;
struct ufshcd_lrb *lrbp = &hba->lrb[tag]; struct ufshcd_lrb *lrbp = &hba->lrb[tag];
struct ufs_hw_queue *hwq; struct ufs_hw_queue *hwq;
unsigned long flags;
int err = FAILED; int err = FAILED;
if (!ufshcd_cmd_inflight(lrbp->cmd)) { if (!ufshcd_cmd_inflight(lrbp->cmd)) {
...@@ -670,8 +671,10 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd) ...@@ -670,8 +671,10 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
} }
err = SUCCESS; err = SUCCESS;
spin_lock_irqsave(&hwq->cq_lock, flags);
if (ufshcd_cmd_inflight(lrbp->cmd)) if (ufshcd_cmd_inflight(lrbp->cmd))
ufshcd_release_scsi_cmd(hba, lrbp); ufshcd_release_scsi_cmd(hba, lrbp);
spin_unlock_irqrestore(&hwq->cq_lock, flags);
out: out:
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment