Re: [PATCH v2] media: pt3: Switch to using functions pcim_* and devm_*

From: Andy Shevchenko
Date: Sat Aug 14 2021 - 15:54:53 EST


On Sat, Aug 14, 2021 at 6:57 PM Evgeny Novikov <novikov@xxxxxxxxx> wrote:
>
> pt3_probe() did not free one of IO mappings in case when one of them was
> successful while another one failed. The patch fixed that by using
> functions pcim_*. Also, it simplifies error handling through switching
> to devm_* functions.
>
> Found by Linux Driver Verification project (linuxtesting.org).

Looks good to me, though I can't test this myself either (I have no hardware).
Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>

> Signed-off-by: Evgeny Novikov <novikov@xxxxxxxxx>
> Co-developed-by: Kirill Shilimanov <kirill.shilimanov@xxxxxxxxxx>
> Signed-off-by: Kirill Shilimanov <kirill.shilimanov@xxxxxxxxxx>
> ---
> v2: Use functions pcim_* and devm_* to simplify code (Andy Shevchenko)
> ---
> drivers/media/pci/pt3/pt3.c | 58 +++++++++----------------------------
> 1 file changed, 14 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c
> index c0bc86793355..0d51bdf01f43 100644
> --- a/drivers/media/pci/pt3/pt3.c
> +++ b/drivers/media/pci/pt3/pt3.c
> @@ -685,12 +685,6 @@ static void pt3_remove(struct pci_dev *pdev)
> for (i = PT3_NUM_FE - 1; i >= 0; i--)
> pt3_cleanup_adapter(pt3, i);
> i2c_del_adapter(&pt3->i2c_adap);
> - kfree(pt3->i2c_buf);
> - pci_iounmap(pt3->pdev, pt3->regs[0]);
> - pci_iounmap(pt3->pdev, pt3->regs[1]);
> - pci_release_regions(pdev);
> - pci_disable_device(pdev);
> - kfree(pt3);
> }
>
> static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> @@ -704,14 +698,14 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> if (pci_read_config_byte(pdev, PCI_REVISION_ID, &rev) || rev != 1)
> return -ENODEV;
>
> - ret = pci_enable_device(pdev);
> + ret = pcim_enable_device(pdev);
> if (ret < 0)
> return -ENODEV;
> pci_set_master(pdev);
>
> - ret = pci_request_regions(pdev, DRV_NAME);
> + ret = pcim_iomap_regions(pdev, BIT(0) | BIT(2), DRV_NAME);
> if (ret < 0)
> - goto err_disable_device;
> + return ret;
>
> ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
> if (ret == 0)
> @@ -722,42 +716,32 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> else {
> dev_err(&pdev->dev, "Failed to set DMA mask\n");
> - goto err_release_regions;
> + return ret;
> }
> dev_info(&pdev->dev, "Use 32bit DMA\n");
> }
>
> - pt3 = kzalloc(sizeof(*pt3), GFP_KERNEL);
> - if (!pt3) {
> - ret = -ENOMEM;
> - goto err_release_regions;
> - }
> + pt3 = devm_kzalloc(&pdev->dev, sizeof(*pt3), GFP_KERNEL);
> + if (!pt3)
> + return -ENOMEM;
> pci_set_drvdata(pdev, pt3);
> pt3->pdev = pdev;
> mutex_init(&pt3->lock);
> - pt3->regs[0] = pci_ioremap_bar(pdev, 0);
> - pt3->regs[1] = pci_ioremap_bar(pdev, 2);
> - if (pt3->regs[0] == NULL || pt3->regs[1] == NULL) {
> - dev_err(&pdev->dev, "Failed to ioremap\n");
> - ret = -ENOMEM;
> - goto err_kfree;
> - }
> + pt3->regs[0] = pcim_iomap_table(pdev)[0];
> + pt3->regs[1] = pcim_iomap_table(pdev)[2];
>
> ver = ioread32(pt3->regs[0] + REG_VERSION);
> if ((ver >> 16) != 0x0301) {
> dev_warn(&pdev->dev, "PT%d, I/F-ver.:%d not supported\n",
> ver >> 24, (ver & 0x00ff0000) >> 16);
> - ret = -ENODEV;
> - goto err_iounmap;
> + return -ENODEV;
> }
>
> pt3->num_bufs = clamp_val(num_bufs, MIN_DATA_BUFS, MAX_DATA_BUFS);
>
> - pt3->i2c_buf = kmalloc(sizeof(*pt3->i2c_buf), GFP_KERNEL);
> - if (pt3->i2c_buf == NULL) {
> - ret = -ENOMEM;
> - goto err_iounmap;
> - }
> + pt3->i2c_buf = devm_kmalloc(&pdev->dev, sizeof(*pt3->i2c_buf), GFP_KERNEL);
> + if (!pt3->i2c_buf)
> + return -ENOMEM;
> i2c = &pt3->i2c_adap;
> i2c->owner = THIS_MODULE;
> i2c->algo = &pt3_i2c_algo;
> @@ -767,7 +751,7 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> i2c_set_adapdata(i2c, pt3);
> ret = i2c_add_adapter(i2c);
> if (ret < 0)
> - goto err_i2cbuf;
> + return ret;
>
> for (i = 0; i < PT3_NUM_FE; i++) {
> ret = pt3_alloc_adapter(pt3, i);
> @@ -799,21 +783,7 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> while (i >= 0)
> pt3_cleanup_adapter(pt3, i--);
> i2c_del_adapter(i2c);
> -err_i2cbuf:
> - kfree(pt3->i2c_buf);
> -err_iounmap:
> - if (pt3->regs[0])
> - pci_iounmap(pdev, pt3->regs[0]);
> - if (pt3->regs[1])
> - pci_iounmap(pdev, pt3->regs[1]);
> -err_kfree:
> - kfree(pt3);
> -err_release_regions:
> - pci_release_regions(pdev);
> -err_disable_device:
> - pci_disable_device(pdev);
> return ret;
> -
> }
>
> static const struct pci_device_id pt3_id_table[] = {
> --
> 2.26.2
>


--
With Best Regards,
Andy Shevchenko