Hi Ian,
I've just tested it with a couple of legacy minors and it works fine.
You have already taken care of it. comedi_free_board_dev(dev) is only
called for autoconfigured devices. If they are legacy devices
comedi_free_board_dev won't be called:
-----------------------------comedi_fops.c--------------------------
if (arg == 0 &&
dev->minor >= comedi_num_legacy_minors) {
/* Successfully unconfigured a
dynamically
* allocated device. Try and remove it. */
if (comedi_clear_board_dev(dev)) {
mutex_unlock(&dev->mutex);
comedi_free_board_dev(dev);
return rc;
}
}
---------------------------------------------------------------------
I've tested it now with:
modprobe comedi comedi_num_legacy_minors=5
modprobe comedi_test
comedi_config /dev/comedi0 comedi_test
comedi_config -r /dev/comedi0
I'll add this to the commit message.
/Bernd
Ian Abbott wrote:
On 27/12/13 23:49, Bernd Porr wrote:
Signed-off-by: Bernd Porr <mail@xxxxxxxxxxxxxxx>
"Signed-off-by" should be after the description. :)
Merging un-registering of both the subdevices and the
main comedi device into one function and the module which
actually associated with it. The kernel oops observed before
was because the main device was un-registered first and
then the subdevices which were then no longer valid.
This has been also tested with 'comedi_config -r'.
It might work with 'comedi_config -r' for auto-configured devices, but I
don't think it will work for manually configured "legacy" devices (e.g.
a "comedi_test" device configured by 'comedi_config /dev/comedi0
comedi_test' when the 'comedi_num_legacy_minors' module parameter is
greater than 0). comedi_free_board_dev() wouldn't be called in that case
when the device is unconfigured later, because the legacy comedi devices
persist until the comedi module is unloaded, whereas the auto-configured
comedi devices only persist while the low-level device remains attached
(more or less - they now also persist while referenced by an unreleased
file object).
---
drivers/staging/comedi/comedi_fops.c | 19 +++++++++++++++++++
drivers/staging/comedi/drivers.c | 18 ------------------
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/staging/comedi/comedi_fops.c
b/drivers/staging/comedi/comedi_fops.c
index f3d59e2..2680b72 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -141,7 +141,26 @@ static struct comedi_device
*comedi_clear_board_minor(unsigned minor)
static void comedi_free_board_dev(struct comedi_device *dev)
{
+ int i;
+ struct comedi_subdevice *s;
+
if (dev) {
+ if (dev->subdevices) {
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = &dev->subdevices[i];
+ if (s->runflags & SRF_FREE_SPRIV)
+ kfree(s->private);
+ comedi_free_subdevice_minor(s);
+ if (s->async) {
+ comedi_buf_alloc(dev, s, 0);
+ kfree(s->async);
+ }
+ }
+ kfree(dev->subdevices);
+ dev->subdevices = NULL;
+ dev->n_subdevices = 0;
+ }
+
if (dev->class_dev) {
device_destroy(comedi_class,
MKDEV(COMEDI_MAJOR, dev->minor));
diff --git a/drivers/staging/comedi/drivers.c
b/drivers/staging/comedi/drivers.c
index 4964d2a..d6dc58a 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -97,24 +97,6 @@ EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);
static void cleanup_device(struct comedi_device *dev)
{
- int i;
- struct comedi_subdevice *s;
-
- if (dev->subdevices) {
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (s->runflags & SRF_FREE_SPRIV)
- kfree(s->private);
- comedi_free_subdevice_minor(s);
- if (s->async) {
- comedi_buf_alloc(dev, s, 0);
- kfree(s->async);
- }
- }
- kfree(dev->subdevices);
- dev->subdevices = NULL;
- dev->n_subdevices = 0;
- }
kfree(dev->private);
dev->private = NULL;
dev->driver = NULL;
--
http://www.berndporr.me.uk
http://www.linux-usb-daq.co.uk
http://www.imdb.com/name/nm3293421/
+44 (0)7840 340069
_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel