Commit 70ce2440 authored by Anton Vasilyev's avatar Anton Vasilyev Committed by Greg Kroah-Hartman

staging: rts5208: add error handling into rtsx_probe

If rtsx_probe() fails to allocate dev->chip, then release_everything()
will crash on uninitialized dev->cmnd_ready complete.

Patch adds error handling into rtsx_probe.

Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: default avatarAnton Vasilyev <vasilyev@ispras.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3a29f43c
...@@ -857,7 +857,7 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -857,7 +857,7 @@ static int rtsx_probe(struct pci_dev *pci,
dev->chip = kzalloc(sizeof(*dev->chip), GFP_KERNEL); dev->chip = kzalloc(sizeof(*dev->chip), GFP_KERNEL);
if (!dev->chip) { if (!dev->chip) {
err = -ENOMEM; err = -ENOMEM;
goto errout; goto chip_alloc_fail;
} }
spin_lock_init(&dev->reg_lock); spin_lock_init(&dev->reg_lock);
...@@ -879,7 +879,7 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -879,7 +879,7 @@ static int rtsx_probe(struct pci_dev *pci,
if (!dev->remap_addr) { if (!dev->remap_addr) {
dev_err(&pci->dev, "ioremap error\n"); dev_err(&pci->dev, "ioremap error\n");
err = -ENXIO; err = -ENXIO;
goto errout; goto ioremap_fail;
} }
/* /*
...@@ -894,7 +894,7 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -894,7 +894,7 @@ static int rtsx_probe(struct pci_dev *pci,
if (!dev->rtsx_resv_buf) { if (!dev->rtsx_resv_buf) {
dev_err(&pci->dev, "alloc dma buffer fail\n"); dev_err(&pci->dev, "alloc dma buffer fail\n");
err = -ENXIO; err = -ENXIO;
goto errout; goto dma_alloc_fail;
} }
dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; dev->chip->host_cmds_ptr = dev->rtsx_resv_buf;
dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr;
...@@ -915,7 +915,7 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -915,7 +915,7 @@ static int rtsx_probe(struct pci_dev *pci,
if (rtsx_acquire_irq(dev) < 0) { if (rtsx_acquire_irq(dev) < 0) {
err = -EBUSY; err = -EBUSY;
goto errout; goto irq_acquire_fail;
} }
pci_set_master(pci); pci_set_master(pci);
...@@ -935,14 +935,14 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -935,14 +935,14 @@ static int rtsx_probe(struct pci_dev *pci,
if (IS_ERR(th)) { if (IS_ERR(th)) {
dev_err(&pci->dev, "Unable to start control thread\n"); dev_err(&pci->dev, "Unable to start control thread\n");
err = PTR_ERR(th); err = PTR_ERR(th);
goto errout; goto control_thread_fail;
} }
dev->ctl_thread = th; dev->ctl_thread = th;
err = scsi_add_host(host, &pci->dev); err = scsi_add_host(host, &pci->dev);
if (err) { if (err) {
dev_err(&pci->dev, "Unable to add the scsi host\n"); dev_err(&pci->dev, "Unable to add the scsi host\n");
goto errout; goto scsi_add_host_fail;
} }
/* Start up the thread for delayed SCSI-device scanning */ /* Start up the thread for delayed SCSI-device scanning */
...@@ -950,18 +950,16 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -950,18 +950,16 @@ static int rtsx_probe(struct pci_dev *pci,
if (IS_ERR(th)) { if (IS_ERR(th)) {
dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); dev_err(&pci->dev, "Unable to start the device-scanning thread\n");
complete(&dev->scanning_done); complete(&dev->scanning_done);
quiesce_and_remove_host(dev);
err = PTR_ERR(th); err = PTR_ERR(th);
goto errout; goto scan_thread_fail;
} }
/* Start up the thread for polling thread */ /* Start up the thread for polling thread */
th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling");
if (IS_ERR(th)) { if (IS_ERR(th)) {
dev_err(&pci->dev, "Unable to start the device-polling thread\n"); dev_err(&pci->dev, "Unable to start the device-polling thread\n");
quiesce_and_remove_host(dev);
err = PTR_ERR(th); err = PTR_ERR(th);
goto errout; goto scan_thread_fail;
} }
dev->polling_thread = th; dev->polling_thread = th;
...@@ -970,9 +968,25 @@ static int rtsx_probe(struct pci_dev *pci, ...@@ -970,9 +968,25 @@ static int rtsx_probe(struct pci_dev *pci,
return 0; return 0;
/* We come here if there are any problems */ /* We come here if there are any problems */
errout: scan_thread_fail:
quiesce_and_remove_host(dev);
scsi_add_host_fail:
complete(&dev->cmnd_ready);
wait_for_completion(&dev->control_exit);
control_thread_fail:
free_irq(dev->irq, (void *)dev);
rtsx_release_chip(dev->chip);
irq_acquire_fail:
dev->chip->host_cmds_ptr = NULL;
dev->chip->host_sg_tbl_ptr = NULL;
if (dev->chip->msi_en)
pci_disable_msi(dev->pci);
dma_alloc_fail:
iounmap(dev->remap_addr);
ioremap_fail:
kfree(dev->chip);
chip_alloc_fail:
dev_err(&pci->dev, "%s failed\n", __func__); dev_err(&pci->dev, "%s failed\n", __func__);
release_everything(dev);
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