Skip to content

Commit

Permalink
staging: comedi: add ioctls to set per-file read and write subdevice
Browse files Browse the repository at this point in the history
Now that Comedi has the structures in place to support setting the
current "read" and/or "write" subdevice on a per-file object basis, add
new ioctls to set them.  The newly chosen "read" ("write") subdevice
needs to support "read" ("write") commands, and the file cannot be busy
handling a "read" ("write") command on the previous subdevice (if any).

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>
  • Loading branch information
Ian Abbott authored and Greg Kroah-Hartman committed Nov 5, 2014
1 parent 20f083c commit c299a67
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/staging/comedi/comedi.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ enum comedi_support_level {
#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
#define COMEDI_POLL _IO(CIO, 15)
#define COMEDI_SETRSUBD _IO(CIO, 16)
#define COMEDI_SETWSUBD _IO(CIO, 17)

/* structures */

Expand Down
2 changes: 2 additions & 0 deletions drivers/staging/comedi/comedi_compat32.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ static inline int raw_ioctl(struct file *file, unsigned int cmd,
case COMEDI_UNLOCK:
case COMEDI_CANCEL:
case COMEDI_POLL:
case COMEDI_SETRSUBD:
case COMEDI_SETWSUBD:
/* No translation needed. */
rc = translated_ioctl(file, cmd, arg);
break;
Expand Down
90 changes: 90 additions & 0 deletions drivers/staging/comedi/comedi_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1847,6 +1847,90 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg,
return -EINVAL;
}

/*
* COMEDI_SETRSUBD ioctl
* sets the current "read" subdevice on a per-file basis
*
* arg:
* subdevice number
*
* reads:
* nothing
*
* writes:
* nothing
*/
static int do_setrsubd_ioctl(struct comedi_device *dev, unsigned long arg,
struct file *file)
{
struct comedi_file *cfp = file->private_data;
struct comedi_subdevice *s_old, *s_new;

if (arg >= dev->n_subdevices)
return -EINVAL;

s_new = &dev->subdevices[arg];
s_old = comedi_file_read_subdevice(file);
if (s_old == s_new)
return 0; /* no change */

if (!(s_new->subdev_flags & SDF_CMD_READ))
return -EINVAL;

/*
* Check the file isn't still busy handling a "read" command on the
* old subdevice (if any).
*/
if (s_old && s_old->busy == file && s_old->async &&
!(s_old->async->cmd.flags & CMDF_WRITE))
return -EBUSY;

ACCESS_ONCE(cfp->read_subdev) = s_new;
return 0;
}

/*
* COMEDI_SETWSUBD ioctl
* sets the current "write" subdevice on a per-file basis
*
* arg:
* subdevice number
*
* reads:
* nothing
*
* writes:
* nothing
*/
static int do_setwsubd_ioctl(struct comedi_device *dev, unsigned long arg,
struct file *file)
{
struct comedi_file *cfp = file->private_data;
struct comedi_subdevice *s_old, *s_new;

if (arg >= dev->n_subdevices)
return -EINVAL;

s_new = &dev->subdevices[arg];
s_old = comedi_file_write_subdevice(file);
if (s_old == s_new)
return 0; /* no change */

if (!(s_new->subdev_flags & SDF_CMD_WRITE))
return -EINVAL;

/*
* Check the file isn't still busy handling a "write" command on the
* old subdevice (if any).
*/
if (s_old && s_old->busy == file && s_old->async &&
(s_old->async->cmd.flags & CMDF_WRITE))
return -EBUSY;

ACCESS_ONCE(cfp->write_subdev) = s_new;
return 0;
}

static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
Expand Down Expand Up @@ -1941,6 +2025,12 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
case COMEDI_POLL:
rc = do_poll_ioctl(dev, arg, file);
break;
case COMEDI_SETRSUBD:
rc = do_setrsubd_ioctl(dev, arg, file);
break;
case COMEDI_SETWSUBD:
rc = do_setwsubd_ioctl(dev, arg, file);
break;
default:
rc = -ENOTTY;
break;
Expand Down

0 comments on commit c299a67

Please sign in to comment.