In the implementation of gsc_hpdi_auto_attach(), the allocated dma description is leaks in case of alignment error, or failure of gsc_hpdi_setup_dma_descriptors() or comedi_alloc_subdevices(). Release devpriv->dma_desc via dma_free_coherent(). Signed-off-by: Navid Emamdoost <navid.emamdoost@xxxxxxxxx> --- drivers/staging/comedi/drivers/gsc_hpdi.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 4bdf44d82879..c0c7047a6d1b 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -633,16 +633,17 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, if (devpriv->dma_desc_phys_addr & 0xf) { dev_warn(dev->class_dev, " dma descriptors not quad-word aligned (bug)\n"); - return -EIO; + retval = -EIO; + goto release_dma_desc; } retval = gsc_hpdi_setup_dma_descriptors(dev, 0x1000); if (retval < 0) - return retval; + goto release_dma_desc; retval = comedi_alloc_subdevices(dev, 1); if (retval) - return retval; + goto release_dma_desc; /* Digital I/O subdevice */ s = &dev->subdevices[0]; @@ -660,6 +661,15 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, s->cancel = gsc_hpdi_cancel; return gsc_hpdi_init(dev); + +release_dma_desc: + if (devpriv->dma_desc) + dma_free_coherent(&pcidev->dev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + devpriv->dma_desc, + devpriv->dma_desc_phys_addr); + return retval; } static void gsc_hpdi_detach(struct comedi_device *dev) -- 2.17.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel