Commit 7308e927 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:
 "Eleven small fixes, ten in drivers.

  Of the two fixes marked core, one is in the raid helper class (used by
  some raid device drivers) and the other one is the /proc/scsi/scsi
  parsing fix for potential reads beyond the end of the buffer"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: qedf: Fix firmware halt over suspend and resume
  scsi: qedi: Fix firmware halt over suspend and resume
  scsi: qedi: Fix potential deadlock on &qedi_percpu->p_work_lock
  scsi: lpfc: Remove reftag check in DIF paths
  scsi: ufs: renesas: Fix private allocation
  scsi: snic: Fix possible memory leak if device_add() fails
  scsi: core: Fix possible memory leak if device_add() fails
  scsi: core: Fix legacy /proc parsing buffer overflow
  scsi: 53c700: Check that command slot is not NULL
  scsi: fnic: Replace return codes in fnic_clean_pending_aborts()
  scsi: storvsc: Fix handling of virtual Fibre Channel timeouts
parents a785fd28 ef222f55
...@@ -1598,7 +1598,7 @@ NCR_700_intr(int irq, void *dev_id) ...@@ -1598,7 +1598,7 @@ NCR_700_intr(int irq, void *dev_id)
printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG))); printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
#endif #endif
resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch; resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
} else if(dsp >= to32bit(&slot->pSG[0].ins) && } else if (slot && dsp >= to32bit(&slot->pSG[0].ins) &&
dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) { dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) {
int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff; int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List); int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define DRV_NAME "fnic" #define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.6.0.54" #define DRV_VERSION "1.6.0.55"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: " #define DFX DRV_NAME "%d: "
......
...@@ -2139,7 +2139,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, ...@@ -2139,7 +2139,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
bool new_sc) bool new_sc)
{ {
int ret = SUCCESS; int ret = 0;
struct fnic_pending_aborts_iter_data iter_data = { struct fnic_pending_aborts_iter_data iter_data = {
.fnic = fnic, .fnic = fnic,
.lun_dev = lr_sc->device, .lun_dev = lr_sc->device,
...@@ -2159,9 +2159,11 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, ...@@ -2159,9 +2159,11 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
/* walk again to check, if IOs are still pending in fw */ /* walk again to check, if IOs are still pending in fw */
if (fnic_is_abts_pending(fnic, lr_sc)) if (fnic_is_abts_pending(fnic, lr_sc))
ret = FAILED; ret = 1;
clean_pending_aborts_end: clean_pending_aborts_end:
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"%s: exit status: %d\n", __func__, ret);
return ret; return ret;
} }
......
...@@ -109,8 +109,6 @@ lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba, ...@@ -109,8 +109,6 @@ lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba,
} }
} }
#define LPFC_INVALID_REFTAG ((u32)-1)
/** /**
* lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread
* @phba: The Hba for which this call is being executed. * @phba: The Hba for which this call is being executed.
...@@ -978,8 +976,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -978,8 +976,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
sgpe = scsi_prot_sglist(sc); sgpe = scsi_prot_sglist(sc);
lba = scsi_prot_ref_tag(sc); lba = scsi_prot_ref_tag(sc);
if (lba == LPFC_INVALID_REFTAG)
return 0;
/* First check if we need to match the LBA */ /* First check if we need to match the LBA */
if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) {
...@@ -1560,8 +1556,6 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -1560,8 +1556,6 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
/* extract some info from the scsi command for pde*/ /* extract some info from the scsi command for pde*/
reftag = scsi_prot_ref_tag(sc); reftag = scsi_prot_ref_tag(sc);
if (reftag == LPFC_INVALID_REFTAG)
goto out;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);
...@@ -1723,8 +1717,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -1723,8 +1717,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
/* extract some info from the scsi command */ /* extract some info from the scsi command */
blksize = scsi_prot_interval(sc); blksize = scsi_prot_interval(sc);
reftag = scsi_prot_ref_tag(sc); reftag = scsi_prot_ref_tag(sc);
if (reftag == LPFC_INVALID_REFTAG)
goto out;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);
...@@ -1953,8 +1945,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -1953,8 +1945,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
/* extract some info from the scsi command for pde*/ /* extract some info from the scsi command for pde*/
reftag = scsi_prot_ref_tag(sc); reftag = scsi_prot_ref_tag(sc);
if (reftag == LPFC_INVALID_REFTAG)
goto out;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);
...@@ -2154,8 +2144,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -2154,8 +2144,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
/* extract some info from the scsi command */ /* extract some info from the scsi command */
blksize = scsi_prot_interval(sc); blksize = scsi_prot_interval(sc);
reftag = scsi_prot_ref_tag(sc); reftag = scsi_prot_ref_tag(sc);
if (reftag == LPFC_INVALID_REFTAG)
goto out;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);
...@@ -2746,8 +2734,6 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) ...@@ -2746,8 +2734,6 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
src = (struct scsi_dif_tuple *)sg_virt(sgpe); src = (struct scsi_dif_tuple *)sg_virt(sgpe);
start_ref_tag = scsi_prot_ref_tag(cmd); start_ref_tag = scsi_prot_ref_tag(cmd);
if (start_ref_tag == LPFC_INVALID_REFTAG)
goto out;
start_app_tag = src->app_tag; start_app_tag = src->app_tag;
len = sgpe->length; len = sgpe->length;
while (src && protsegcnt) { while (src && protsegcnt) {
...@@ -3493,11 +3479,11 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, ...@@ -3493,11 +3479,11 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
scsi_cmnd->sc_data_direction); scsi_cmnd->sc_data_direction);
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
"9084 Cannot setup S/G List for HBA" "9084 Cannot setup S/G List for HBA "
"IO segs %d/%d SGL %d SCSI %d: %d %d\n", "IO segs %d/%d SGL %d SCSI %d: %d %d %d\n",
lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt,
phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt,
prot_group_type, num_sge); prot_group_type, num_sge, ret);
lpfc_cmd->seg_cnt = 0; lpfc_cmd->seg_cnt = 0;
lpfc_cmd->prot_seg_cnt = 0; lpfc_cmd->prot_seg_cnt = 0;
......
...@@ -31,6 +31,7 @@ static void qedf_remove(struct pci_dev *pdev); ...@@ -31,6 +31,7 @@ static void qedf_remove(struct pci_dev *pdev);
static void qedf_shutdown(struct pci_dev *pdev); static void qedf_shutdown(struct pci_dev *pdev);
static void qedf_schedule_recovery_handler(void *dev); static void qedf_schedule_recovery_handler(void *dev);
static void qedf_recovery_handler(struct work_struct *work); static void qedf_recovery_handler(struct work_struct *work);
static int qedf_suspend(struct pci_dev *pdev, pm_message_t state);
/* /*
* Driver module parameters. * Driver module parameters.
...@@ -3271,6 +3272,7 @@ static struct pci_driver qedf_pci_driver = { ...@@ -3271,6 +3272,7 @@ static struct pci_driver qedf_pci_driver = {
.probe = qedf_probe, .probe = qedf_probe,
.remove = qedf_remove, .remove = qedf_remove,
.shutdown = qedf_shutdown, .shutdown = qedf_shutdown,
.suspend = qedf_suspend,
}; };
static int __qedf_probe(struct pci_dev *pdev, int mode) static int __qedf_probe(struct pci_dev *pdev, int mode)
...@@ -4000,6 +4002,22 @@ static void qedf_shutdown(struct pci_dev *pdev) ...@@ -4000,6 +4002,22 @@ static void qedf_shutdown(struct pci_dev *pdev)
__qedf_remove(pdev, QEDF_MODE_NORMAL); __qedf_remove(pdev, QEDF_MODE_NORMAL);
} }
static int qedf_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct qedf_ctx *qedf;
if (!pdev) {
QEDF_ERR(NULL, "pdev is NULL.\n");
return -ENODEV;
}
qedf = pci_get_drvdata(pdev);
QEDF_ERR(&qedf->dbg_ctx, "%s: Device does not support suspend operation\n", __func__);
return -EPERM;
}
/* /*
* Recovery handler code * Recovery handler code
*/ */
......
...@@ -69,6 +69,7 @@ static struct nvm_iscsi_block *qedi_get_nvram_block(struct qedi_ctx *qedi); ...@@ -69,6 +69,7 @@ static struct nvm_iscsi_block *qedi_get_nvram_block(struct qedi_ctx *qedi);
static void qedi_recovery_handler(struct work_struct *work); static void qedi_recovery_handler(struct work_struct *work);
static void qedi_schedule_hw_err_handler(void *dev, static void qedi_schedule_hw_err_handler(void *dev,
enum qed_hw_err_type err_type); enum qed_hw_err_type err_type);
static int qedi_suspend(struct pci_dev *pdev, pm_message_t state);
static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle) static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle)
{ {
...@@ -1976,8 +1977,9 @@ static int qedi_cpu_offline(unsigned int cpu) ...@@ -1976,8 +1977,9 @@ static int qedi_cpu_offline(unsigned int cpu)
struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu); struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu);
struct qedi_work *work, *tmp; struct qedi_work *work, *tmp;
struct task_struct *thread; struct task_struct *thread;
unsigned long flags;
spin_lock_bh(&p->p_work_lock); spin_lock_irqsave(&p->p_work_lock, flags);
thread = p->iothread; thread = p->iothread;
p->iothread = NULL; p->iothread = NULL;
...@@ -1988,7 +1990,7 @@ static int qedi_cpu_offline(unsigned int cpu) ...@@ -1988,7 +1990,7 @@ static int qedi_cpu_offline(unsigned int cpu)
kfree(work); kfree(work);
} }
spin_unlock_bh(&p->p_work_lock); spin_unlock_irqrestore(&p->p_work_lock, flags);
if (thread) if (thread)
kthread_stop(thread); kthread_stop(thread);
return 0; return 0;
...@@ -2510,6 +2512,22 @@ static void qedi_shutdown(struct pci_dev *pdev) ...@@ -2510,6 +2512,22 @@ static void qedi_shutdown(struct pci_dev *pdev)
__qedi_remove(pdev, QEDI_MODE_SHUTDOWN); __qedi_remove(pdev, QEDI_MODE_SHUTDOWN);
} }
static int qedi_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct qedi_ctx *qedi;
if (!pdev) {
QEDI_ERR(NULL, "pdev is NULL.\n");
return -ENODEV;
}
qedi = pci_get_drvdata(pdev);
QEDI_ERR(&qedi->dbg_ctx, "%s: Device does not support suspend operation\n", __func__);
return -EPERM;
}
static int __qedi_probe(struct pci_dev *pdev, int mode) static int __qedi_probe(struct pci_dev *pdev, int mode)
{ {
struct qedi_ctx *qedi; struct qedi_ctx *qedi;
...@@ -2868,6 +2886,7 @@ static struct pci_driver qedi_pci_driver = { ...@@ -2868,6 +2886,7 @@ static struct pci_driver qedi_pci_driver = {
.remove = qedi_remove, .remove = qedi_remove,
.shutdown = qedi_shutdown, .shutdown = qedi_shutdown,
.err_handler = &qedi_err_handler, .err_handler = &qedi_err_handler,
.suspend = qedi_suspend,
}; };
static int __init qedi_init(void) static int __init qedi_init(void)
......
...@@ -248,6 +248,7 @@ int raid_component_add(struct raid_template *r,struct device *raid_dev, ...@@ -248,6 +248,7 @@ int raid_component_add(struct raid_template *r,struct device *raid_dev,
return 0; return 0;
err_out: err_out:
put_device(&rc->dev);
list_del(&rc->node); list_del(&rc->node);
rd->component_count--; rd->component_count--;
put_device(component_dev); put_device(component_dev);
......
...@@ -406,7 +406,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, ...@@ -406,7 +406,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
size_t length, loff_t *ppos) size_t length, loff_t *ppos)
{ {
int host, channel, id, lun; int host, channel, id, lun;
char *buffer, *p; char *buffer, *end, *p;
int err; int err;
if (!buf || length > PAGE_SIZE) if (!buf || length > PAGE_SIZE)
...@@ -421,10 +421,14 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, ...@@ -421,10 +421,14 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
goto out; goto out;
err = -EINVAL; err = -EINVAL;
if (length < PAGE_SIZE) if (length < PAGE_SIZE) {
buffer[length] = '\0'; end = buffer + length;
else if (buffer[PAGE_SIZE-1]) *end = '\0';
} else {
end = buffer + PAGE_SIZE - 1;
if (*end)
goto out; goto out;
}
/* /*
* Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi
...@@ -433,10 +437,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, ...@@ -433,10 +437,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
if (!strncmp("scsi add-single-device", buffer, 22)) { if (!strncmp("scsi add-single-device", buffer, 22)) {
p = buffer + 23; p = buffer + 23;
host = simple_strtoul(p, &p, 0); host = (p < end) ? simple_strtoul(p, &p, 0) : 0;
channel = simple_strtoul(p + 1, &p, 0); channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
id = simple_strtoul(p + 1, &p, 0); id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
lun = simple_strtoul(p + 1, &p, 0); lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
err = scsi_add_single_device(host, channel, id, lun); err = scsi_add_single_device(host, channel, id, lun);
...@@ -447,10 +451,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, ...@@ -447,10 +451,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
} else if (!strncmp("scsi remove-single-device", buffer, 25)) { } else if (!strncmp("scsi remove-single-device", buffer, 25)) {
p = buffer + 26; p = buffer + 26;
host = simple_strtoul(p, &p, 0); host = (p < end) ? simple_strtoul(p, &p, 0) : 0;
channel = simple_strtoul(p + 1, &p, 0); channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
id = simple_strtoul(p + 1, &p, 0); id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
lun = simple_strtoul(p + 1, &p, 0); lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0;
err = scsi_remove_single_device(host, channel, id, lun); err = scsi_remove_single_device(host, channel, id, lun);
} }
......
...@@ -303,6 +303,7 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) ...@@ -303,6 +303,7 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid)
"Snic Tgt: device_add, with err = %d\n", "Snic Tgt: device_add, with err = %d\n",
ret); ret);
put_device(&tgt->dev);
put_device(&snic->shost->shost_gendev); put_device(&snic->shost->shost_gendev);
spin_lock_irqsave(snic->shost->host_lock, flags); spin_lock_irqsave(snic->shost->host_lock, flags);
list_del(&tgt->list); list_del(&tgt->list);
......
...@@ -1674,10 +1674,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) ...@@ -1674,10 +1674,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
*/ */
static enum scsi_timeout_action storvsc_eh_timed_out(struct scsi_cmnd *scmnd) static enum scsi_timeout_action storvsc_eh_timed_out(struct scsi_cmnd *scmnd)
{ {
#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
if (scmnd->device->host->transportt == fc_transport_template)
return fc_eh_timed_out(scmnd);
#endif
return SCSI_EH_RESET_TIMER; return SCSI_EH_RESET_TIMER;
} }
......
...@@ -359,7 +359,7 @@ static int ufs_renesas_init(struct ufs_hba *hba) ...@@ -359,7 +359,7 @@ static int ufs_renesas_init(struct ufs_hba *hba)
{ {
struct ufs_renesas_priv *priv; struct ufs_renesas_priv *priv;
priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(hba->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
ufshcd_set_variant(hba, priv); ufshcd_set_variant(hba, priv);
......
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