`comedi_alloc_subdevice_minor()` allocates and initializes a `struct
comedi_file_info` and assigns a subdevice minor device number (if there
are any available), storing a pointer to the allocated `struct
comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the
array index corresponding to the subdevice minor device number (indexed
by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`).
The information stored in the `struct comedi_file_info` can be derived
from the subdevice structure (`struct comedi_subdevice`) itself, so the
`struct comedi_file_info` is superfluous.
Change `comedi_subdevice_minor_table[]` to hold pointers to the actual
`struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer
needs to allocate a `struct comedi_file_info` and
`comedi_free_subdevice_info()` no longer has a `struct comedi_file_info`
to free.
Replace `comedi_file_info_from_minor()` with
`comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to
a `struct comedi_subdevice` from the table. This has knock-on effects
for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and
`comedi_write_subdevice()`. In particular, `comedi_read_subdevice()`
and `comedi_write_subdevice()` now need to check the subdevice flags to
see if the determine whether to override the comedi device's default
read/write subdevice.
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>
static DEFINE_MUTEX(comedi_subdevice_minor_table_lock);
/* Note: indexed by minor - COMEDI_NUM_BOARD_MINORS. */
static DEFINE_MUTEX(comedi_subdevice_minor_table_lock);
/* Note: indexed by minor - COMEDI_NUM_BOARD_MINORS. */
-static struct comedi_file_info
+static struct comedi_subdevice
*comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS];
static struct class *comedi_class;
*comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS];
static struct class *comedi_class;
-static struct comedi_file_info
-*comedi_file_info_from_subdevice_minor(unsigned minor)
+static struct comedi_subdevice
+*comedi_subdevice_from_minor(unsigned minor)
- struct comedi_file_info *info;
+ struct comedi_subdevice *s;
unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
mutex_lock(&comedi_subdevice_minor_table_lock);
unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
mutex_lock(&comedi_subdevice_minor_table_lock);
- info = comedi_subdevice_minor_table[i];
+ s = comedi_subdevice_minor_table[i];
mutex_unlock(&comedi_subdevice_minor_table_lock);
mutex_unlock(&comedi_subdevice_minor_table_lock);
}
static struct comedi_device *
}
static struct comedi_device *
static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor)
{
static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor)
{
- struct comedi_file_info *info;
+ struct comedi_subdevice *s;
- info = comedi_file_info_from_subdevice_minor(minor);
- return comedi_dev_from_file_info(info);
+ s = comedi_subdevice_from_minor(minor);
+ return s ? s->device : NULL;
}
struct comedi_device *comedi_dev_from_minor(unsigned minor)
}
struct comedi_device *comedi_dev_from_minor(unsigned minor)
static struct comedi_subdevice *
comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
{
static struct comedi_subdevice *
comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
{
- struct comedi_file_info *info;
+ struct comedi_subdevice *s;
if (minor >= COMEDI_NUM_BOARD_MINORS) {
if (minor >= COMEDI_NUM_BOARD_MINORS) {
- info = comedi_file_info_from_subdevice_minor(minor);
- if (!info || info->device != dev)
+ s = comedi_subdevice_from_minor(minor);
+ if (!s || s->device != dev)
- if (info->read_subdevice)
- return info->read_subdevice;
+ if (s->subdev_flags & SDF_CMD_READ)
+ return s;
}
return dev->read_subdev;
}
}
return dev->read_subdev;
}
static struct comedi_subdevice *
comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
{
static struct comedi_subdevice *
comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
{
- struct comedi_file_info *info;
+ struct comedi_subdevice *s;
if (minor >= COMEDI_NUM_BOARD_MINORS) {
if (minor >= COMEDI_NUM_BOARD_MINORS) {
- info = comedi_file_info_from_subdevice_minor(minor);
- if (!info || info->device != dev)
+ s = comedi_subdevice_from_minor(minor);
+ if (!s || s->device != dev)
- if (info->write_subdevice)
- return info->write_subdevice;
+ if (s->subdev_flags & SDF_CMD_WRITE)
+ return s;
}
return dev->write_subdev;
}
}
return dev->write_subdev;
}
int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
{
struct comedi_device *dev = s->device;
int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
{
struct comedi_device *dev = s->device;
- struct comedi_file_info *info;
struct device *csdev;
unsigned i;
struct device *csdev;
unsigned i;
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- info->device = dev;
- if (s->subdev_flags & SDF_CMD_READ)
- info->read_subdevice = s;
- if (s->subdev_flags & SDF_CMD_WRITE)
- info->write_subdevice = s;
mutex_lock(&comedi_subdevice_minor_table_lock);
for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
if (comedi_subdevice_minor_table[i] == NULL) {
mutex_lock(&comedi_subdevice_minor_table_lock);
for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
if (comedi_subdevice_minor_table[i] == NULL) {
- comedi_subdevice_minor_table[i] = info;
+ comedi_subdevice_minor_table[i] = s;
break;
}
}
mutex_unlock(&comedi_subdevice_minor_table_lock);
if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
break;
}
}
mutex_unlock(&comedi_subdevice_minor_table_lock);
if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
return -EBUSY;
}
pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
return -EBUSY;
}
void comedi_free_subdevice_minor(struct comedi_subdevice *s)
{
void comedi_free_subdevice_minor(struct comedi_subdevice *s)
{
- struct comedi_file_info *info;
unsigned int i;
if (s == NULL)
unsigned int i;
if (s == NULL)
i = s->minor - COMEDI_NUM_BOARD_MINORS;
mutex_lock(&comedi_subdevice_minor_table_lock);
i = s->minor - COMEDI_NUM_BOARD_MINORS;
mutex_lock(&comedi_subdevice_minor_table_lock);
- info = comedi_subdevice_minor_table[i];
- comedi_subdevice_minor_table[i] = NULL;
+ if (s == comedi_subdevice_minor_table[i])
+ comedi_subdevice_minor_table[i] = NULL;
mutex_unlock(&comedi_subdevice_minor_table_lock);
if (s->class_dev) {
device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
s->class_dev = NULL;
}
mutex_unlock(&comedi_subdevice_minor_table_lock);
if (s->class_dev) {
device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
s->class_dev = NULL;
}
}
static void comedi_cleanup_board_minors(void)
}
static void comedi_cleanup_board_minors(void)