This driver does not follow the standard (*attach) (*detach) flow of the other drivers in comedi. Comedi drivers do not 'cleanup' any of the allocations made during the (*attach) if failures are encountered. If the (*attach) fails, the comedi core will call the (*detach) to handle any clenaup. In this driver, the function free_resources() handles all the cleanup. Remove the calls to this function during the (*attach). Since the (*detach) is then the only caller, remove the function and just put all the cleanup in the (*detach) function. Use the new comedi_legacy_detach() helper in the (*detach) to release the I/O region. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/pcl812.c | 46 +++++++++++---------------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 86b29c5..50961c4 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1041,28 +1041,6 @@ static void start_pacer(struct comedi_device *dev, int mode, /* ============================================================================== */ -static void free_resources(struct comedi_device *dev) -{ - const struct pcl812_board *board = comedi_board(dev); - struct pcl812_private *devpriv = dev->private; - - if (devpriv) { - if (devpriv->dmabuf[0]) - free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); - if (devpriv->dmabuf[1]) - free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]); - if (devpriv->dma) - free_dma(devpriv->dma); - } - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->iobase) - release_region(dev->iobase, board->io_range); -} - -/* -============================================================================== -*/ static int pcl812_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1133,10 +1111,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) { - free_resources(dev); + if (!devpriv) return -ENOMEM; - } dev->private = devpriv; irq = 0; @@ -1190,7 +1166,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) * maybe experiment with try_to_free_pages() * will help .... */ - free_resources(dev); return -EBUSY; /* no buffer :-( */ } devpriv->dmapages[0] = pages; @@ -1199,7 +1174,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { printk(KERN_ERR ", unable to allocate DMA buffer, FAIL!\n"); - free_resources(dev); return -EBUSY; } devpriv->dmapages[1] = pages; @@ -1219,10 +1193,8 @@ no_dma: n_subdevices++; ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret) { - free_resources(dev); + if (ret) return ret; - } subdev = 0; @@ -1456,7 +1428,19 @@ no_dma: static void pcl812_detach(struct comedi_device *dev) { - free_resources(dev); + struct pcl812_private *devpriv = dev->private; + + if (devpriv) { + if (devpriv->dmabuf[0]) + free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); + if (devpriv->dmabuf[1]) + free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]); + if (devpriv->dma) + free_dma(devpriv->dma); + } + if (dev->irq) + free_irq(dev->irq, dev); + comedi_legacy_detach(dev); } static const struct pcl812_board boardtypes[] = { -- 1.8.1.4 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel