diff options
author | Ian Abbott | 2015-04-21 14:18:10 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2015-04-30 17:15:59 +0200 |
commit | 8fc369ae38ff281d38e9ea11805a5cae862989bc (patch) | |
tree | 3677462a15709e6d62632df9cbf804c890c5c309 /drivers | |
parent | staging: comedi: serial2002: fix Coverity "Explicit null dereference" (diff) | |
download | kernel-qcow2-linux-8fc369ae38ff281d38e9ea11805a5cae862989bc.tar.gz kernel-qcow2-linux-8fc369ae38ff281d38e9ea11805a5cae862989bc.tar.xz kernel-qcow2-linux-8fc369ae38ff281d38e9ea11805a5cae862989bc.zip |
staging: comedi: wrap COMEDI_SRF_FREE_SPRIV usage
The `COMEDI_SRF_FREE_SPRIV` flag in the `runflags` member of `struct
comedi_subdevice` indicates that the memory pointed to by the `private`
member can be automatically freed by the comedi core on subdevice
clean-up (when the low-level comedi device is being "detached"). the
flag doesn't really belong in `runflags`, but it was somewhere
convenient to keep it without having to add a new member to the
structure.
Rather than access the `COMEDI_SRF_FREE_SPRIV` flag directly, use some
new wrapper functions:
* comedi_can_auto_free_spriv(s) - checks whether the subdevice's
`s->private` points to memory that can be freed automatically.
* comedi_set_spriv_auto_free(s) - marks the subdevice as having a
`s->private` that points to memory that can be freed automatically.
Export `comedi_set_spriv_auto_free()` for use by the low-level comedi
driver modules, in particular the "amplc_dio200_common" module.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 24 | ||||
-rw-r--r-- | drivers/staging/comedi/comedi_internal.h | 1 | ||||
-rw-r--r-- | drivers/staging/comedi/comedidev.h | 1 | ||||
-rw-r--r-- | drivers/staging/comedi/drivers.c | 2 | ||||
-rw-r--r-- | drivers/staging/comedi/drivers/amplc_dio200_common.c | 6 |
5 files changed, 28 insertions, 6 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e78ddbe5a954..fc339c5c50fc 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -679,8 +679,28 @@ static bool comedi_is_subdevice_idle(struct comedi_subdevice *s) return !(runflags & COMEDI_SRF_BUSY_MASK); } +bool comedi_can_auto_free_spriv(struct comedi_subdevice *s) +{ + unsigned runflags = __comedi_get_subdevice_runflags(s); + + return runflags & COMEDI_SRF_FREE_SPRIV; +} + +/** + * comedi_set_spriv_auto_free - mark subdevice private data as freeable + * @s: comedi_subdevice struct + * + * Mark the subdevice as having a pointer to private data that can be + * automatically freed by the comedi core during the detach. + */ +void comedi_set_spriv_auto_free(struct comedi_subdevice *s) +{ + __comedi_set_subdevice_runflags(s, COMEDI_SRF_FREE_SPRIV); +} +EXPORT_SYMBOL_GPL(comedi_set_spriv_auto_free); + /** - * comedi_alloc_spriv() - Allocate memory for the subdevice private data. + * comedi_alloc_spriv - Allocate memory for the subdevice private data. * @s: comedi_subdevice struct * @size: size of the memory to allocate * @@ -691,7 +711,7 @@ void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size) { s->private = kzalloc(size, GFP_KERNEL); if (s->private) - s->runflags |= COMEDI_SRF_FREE_SPRIV; + comedi_set_spriv_auto_free(s); return s->private; } EXPORT_SYMBOL_GPL(comedi_alloc_spriv); diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index 3b918538847e..cd9437f72c35 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -33,6 +33,7 @@ struct comedi_buf_map *comedi_buf_map_from_subdev_get( struct comedi_subdevice *s); unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s); void comedi_device_cancel_all(struct comedi_device *dev); +bool comedi_can_auto_free_spriv(struct comedi_subdevice *s); extern unsigned int comedi_default_buf_size_kb; extern unsigned int comedi_default_buf_maxsize_kb; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index dfab5a84b011..52071f7494c4 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -323,6 +323,7 @@ int comedi_dev_put(struct comedi_device *dev); bool comedi_is_subdevice_running(struct comedi_subdevice *s); void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size); +void comedi_set_spriv_auto_free(struct comedi_subdevice *s); int comedi_check_chanlist(struct comedi_subdevice *s, int n, diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 57dcffe00204..ed0b60c925de 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -125,7 +125,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev) if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; - if (s->runflags & COMEDI_SRF_FREE_SPRIV) + if (comedi_can_auto_free_spriv(s)) kfree(s->private); comedi_free_subdevice_minor(s); if (s->async) { diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index d15a3dc1216a..3a8b3f27b525 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -593,10 +593,10 @@ static int dio200_subdev_8254_init(struct comedi_device *dev, * There could be multiple timers so this driver does not * use dev->pacer to save the i8254 pointer. Instead, * comedi_8254_subdevice_init() saved the i8254 pointer in - * s->private. Set the runflag bit so that the core will - * automatically free it when the driver is detached. + * s->private. Mark the subdevice as having private data + * to be automatically freed when the device is detached. */ - s->runflags |= COMEDI_SRF_FREE_SPRIV; + comedi_set_spriv_auto_free(s); /* Initialize channels. */ if (board->has_clk_gat_sce) { |