From 39fcd58d489382805171b5d6ed8a1b6bbbdefa7a Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Mon, 12 Jan 2004 00:28:40 +0000 Subject: [PATCH] be more careful about subdevice allocation/free --- comedi/comedi_fops.c | 18 +++++++++-------- comedi/drivers.c | 46 +++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index da333e94..f419650b 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -1662,17 +1662,19 @@ static int comedi_close_v22(struct inode *inode,struct file *file) comedi_subdevice *s = NULL; int i; - for(i=0;in_subdevices;i++){ - s=dev->subdevices+i; + if(dev->subdevices) + { + for(i=0;in_subdevices;i++){ + s=dev->subdevices+i; - if(s->busy==file){ - do_cancel(dev,s); - } - if(s->lock==file){ - s->lock=NULL; + if(s->busy==file){ + do_cancel(dev,s); + } + if(s->lock==file){ + s->lock=NULL; + } } } - if(dev->attached && dev->use_count==1 && dev->close){ dev->close(dev); } diff --git a/comedi/drivers.c b/comedi/drivers.c index af8a7590..1ccf1e25 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -56,11 +56,35 @@ int comedi_modprobe(int minor) return -EINVAL; } -int comedi_device_detach(comedi_device *dev) +static void cleanup_device_allocations(comedi_device *dev) { int i; comedi_subdevice *s; + if(dev->subdevices) + { + for(i = 0; i < dev->n_subdevices; i++) + { + s = dev->subdevices + i; + if(s->async) + { + comedi_buf_alloc(dev, s, 0); + if(s->buf_change) s->buf_change(dev, s, 0); + kfree(s->async); + } + } + kfree(dev->subdevices); + dev->subdevices = NULL; + } + if(dev->private) + { + kfree(dev->private); + dev->private = NULL; + } +} + +int comedi_device_detach(comedi_device *dev) +{ if(!dev->attached) return 0; @@ -69,24 +93,13 @@ int comedi_device_detach(comedi_device *dev) dev->attached=0; - for(i=0;in_subdevices;i++){ - s=dev->subdevices+i; - if(s->async){ - comedi_buf_alloc(dev, s, 0); - if(s->buf_change) s->buf_change(dev,s,0); - kfree(s->async); - } - } - if(dev->driver){ dev->driver->detach(dev); }else{ printk("BUG: dev->driver=NULL in comedi_device_detach()\n"); } - if(dev->subdevices)kfree(dev->subdevices); - if(dev->private)kfree(dev->private); - + cleanup_device_allocations(dev); return 0; } @@ -130,8 +143,7 @@ int comedi_device_attach(comedi_device *dev,comedi_devconfig *it) ret=driv->attach(dev,it); if(ret<0){ driv->detach(dev); - if(dev->subdevices)kfree(dev->subdevices); - if(dev->private)kfree(dev->private); + cleanup_device_allocations(dev); module_put( driv->module ); return ret; } @@ -158,9 +170,7 @@ attached: if(ret < 0) { driv->detach(dev); - if(dev->subdevices)kfree(dev->subdevices); - if(dev->private)kfree(dev->private); - + cleanup_device_allocations(dev); return ret; } -- 2.26.2