diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2014-08-25 17:55:54 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-08-30 13:25:51 -0700 |
commit | d558c5967741e6c551883c58441d29f5440a4ab2 (patch) | |
tree | 57fc34ac148cce0be26d39d3db7a3133fc52976d /drivers/staging/comedi/drivers/gsc_hpdi.c | |
parent | f9804323a84017d370b5bd048a3ddd3069500955 (diff) |
staging: comedi: gsc_hpdi: tidy up freeing of the dma buffers
Factor the freeing of the dma buffers out of the (*detach).
Move the freeing of the buffers so that it occurs after the PCI device
has been disabled to avoid any race condition.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/drivers/gsc_hpdi.c')
-rw-r--r-- | drivers/staging/comedi/drivers/gsc_hpdi.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index c1939102a820..b8975a4606ea 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -505,6 +505,32 @@ static int gsc_hpdi_dio_insn_config(struct comedi_device *dev, return insn->n; } +static void gsc_hpdi_free_dma(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct hpdi_private *devpriv = dev->private; + int i; + + if (!devpriv) + return; + + /* free pci dma buffers */ + for (i = 0; i < NUM_DMA_BUFFERS; i++) { + if (devpriv->dio_buffer[i]) + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->dio_buffer[i], + devpriv->dio_buffer_phys_addr[i]); + } + /* free dma descriptors */ + if (devpriv->dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + devpriv->dma_desc, + devpriv->dma_desc_phys_addr); +} + static int gsc_hpdi_init(struct comedi_device *dev) { struct hpdi_private *devpriv = dev->private; @@ -679,9 +705,7 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, static void gsc_hpdi_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct hpdi_private *devpriv = dev->private; - unsigned int i; if (dev->irq) free_irq(dev->irq, dev); @@ -692,24 +716,9 @@ static void gsc_hpdi_detach(struct comedi_device *dev) } if (dev->mmio) iounmap(dev->mmio); - /* free pci dma buffers */ - for (i = 0; i < NUM_DMA_BUFFERS; i++) { - if (devpriv->dio_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - devpriv->dio_buffer[i], - devpriv-> - dio_buffer_phys_addr[i]); - } - /* free dma descriptors */ - if (devpriv->dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - NUM_DMA_DESCRIPTORS, - devpriv->dma_desc, - devpriv->dma_desc_phys_addr); } comedi_pci_disable(dev); + gsc_hpdi_free_dma(dev); } static struct comedi_driver gsc_hpdi_driver = { |