Merge git://www.linux-watchdog.org/linux-watchdog
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / comedi_fops.c
index bb2e7961ec3c143243a1695fad521934cbdc302d..727640e89c73ad53e39fcf1f720ae6e92fb3b0f0 100644 (file)
@@ -113,6 +113,18 @@ static void comedi_dev_kref_release(struct kref *kref)
        kfree(dev);
 }
 
+/**
+ * comedi_dev_put - release a use of a comedi device structure
+ * @dev: comedi_device struct
+ *
+ * Must be called when a user of a comedi device is finished with it.
+ * When the last user of the comedi device calls this function, the
+ * comedi device is destroyed.
+ *
+ * Return 1 if the comedi device is destroyed by this call or dev is
+ * NULL, otherwise return 0.  Callers must not assume the comedi
+ * device is still valid if this function returns 0.
+ */
 int comedi_dev_put(struct comedi_device *dev)
 {
        if (dev)
@@ -220,6 +232,18 @@ static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor)
        return dev;
 }
 
+/**
+ * comedi_dev_get_from_minor - get comedi device by minor device number
+ * @minor: minor device number
+ *
+ * Finds the comedi device associated by the minor device number, if any,
+ * and increments its reference count.  The comedi device is prevented from
+ * being freed until a matching call is made to comedi_dev_put().
+ *
+ * Return a pointer to the comedi device if it exists, with its usage
+ * reference incremented.  Return NULL if no comedi device exists with the
+ * specified minor device number.
+ */
 struct comedi_device *comedi_dev_get_from_minor(unsigned minor)
 {
        if (minor < COMEDI_NUM_BOARD_MINORS)
@@ -323,8 +347,7 @@ static int resize_async_buffer(struct comedi_device *dev,
                return -EBUSY;
        }
 
-       /* make sure buffer is an integral number of pages
-        * (we round up) */
+       /* make sure buffer is an integral number of pages (we round up) */
        new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
 
        retval = comedi_buf_alloc(dev, s, new_size);
@@ -600,6 +623,13 @@ static unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
        return runflags;
 }
 
+/**
+ * comedi_is_subdevice_running - check if async command running on subdevice
+ * @s: comedi_subdevice struct
+ *
+ * Return true if an asynchronous comedi command is active on the comedi
+ * subdevice, else return false.
+ */
 bool comedi_is_subdevice_running(struct comedi_subdevice *s)
 {
        unsigned runflags = comedi_get_subdevice_runflags(s);
@@ -640,7 +670,7 @@ void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
 EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
 
 /*
  This function restores a subdevice to an idle state.
* This function restores a subdevice to an idle state.
  */
 static void do_become_nonbusy(struct comedi_device *dev,
                              struct comedi_subdevice *s)
@@ -709,18 +739,18 @@ static int is_device_busy(struct comedi_device *dev)
 }
 
 /*
-       COMEDI_DEVCONFIG
-       device config ioctl
-
      arg:
-               pointer to devconfig structure
-
      reads:
-               devconfig structure at arg
-
      writes:
-               none
-*/
+ * COMEDI_DEVCONFIG ioctl
+ * attaches (and configures) or detaches a legacy device
+ *
* arg:
+ *     pointer to comedi_devconfig structure (NULL if detaching)
+ *
* reads:
+ *     comedi_devconfig structure (if attaching)
+ *
* writes:
+ *     nothing
+ */
 static int do_devconfig_ioctl(struct comedi_device *dev,
                              struct comedi_devconfig __user *arg)
 {
@@ -761,19 +791,18 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
 }
 
 /*
-       COMEDI_BUFCONFIG
-       buffer configuration ioctl
-
-       arg:
-               pointer to bufconfig structure
-
-       reads:
-               bufconfig at arg
-
-       writes:
-               modified bufconfig at arg
-
-*/
+ * COMEDI_BUFCONFIG ioctl
+ * buffer configuration
+ *
+ * arg:
+ *     pointer to comedi_bufconfig structure
+ *
+ * reads:
+ *     comedi_bufconfig structure
+ *
+ * writes:
+ *     modified comedi_bufconfig structure
+ */
 static int do_bufconfig_ioctl(struct comedi_device *dev,
                              struct comedi_bufconfig __user *arg)
 {
@@ -823,19 +852,18 @@ copyback:
 }
 
 /*
-       COMEDI_DEVINFO
-       device info ioctl
-
-       arg:
-               pointer to devinfo structure
-
-       reads:
-               none
-
-       writes:
-               devinfo structure
-
-*/
+ * COMEDI_DEVINFO ioctl
+ * device info
+ *
+ * arg:
+ *     pointer to comedi_devinfo structure
+ *
+ * reads:
+ *     nothing
+ *
+ * writes:
+ *     comedi_devinfo structure
+ */
 static int do_devinfo_ioctl(struct comedi_device *dev,
                            struct comedi_devinfo __user *arg,
                            struct file *file)
@@ -870,19 +898,18 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
 }
 
 /*
-       COMEDI_SUBDINFO
-       subdevice info ioctl
-
-       arg:
-               pointer to array of subdevice info structures
-
-       reads:
-               none
-
-       writes:
-               array of subdevice info structures at arg
-
-*/
+ * COMEDI_SUBDINFO ioctl
+ * subdevices info
+ *
+ * arg:
+ *     pointer to array of comedi_subdinfo structures
+ *
+ * reads:
+ *     nothing
+ *
+ * writes:
+ *     array of comedi_subdinfo structures
+ */
 static int do_subdinfo_ioctl(struct comedi_device *dev,
                             struct comedi_subdinfo __user *arg, void *file)
 {
@@ -944,19 +971,19 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
 }
 
 /*
-       COMEDI_CHANINFO
-       subdevice info ioctl
-
      arg:
              pointer to chaninfo structure
-
      reads:
-               chaninfo structure at arg
-
      writes:
-               arrays at elements of chaninfo structure
-
-*/
+ * COMEDI_CHANINFO ioctl
+ * subdevice channel info
+ *
* arg:
*     pointer to comedi_chaninfo structure
+ *
* reads:
+ *     comedi_chaninfo structure
+ *
* writes:
+ *     array of maxdata values to chaninfo->maxdata_list if requested
+ *     array of range table lengths to chaninfo->range_table_list if requested
+ */
 static int do_chaninfo_ioctl(struct comedi_device *dev,
                             struct comedi_chaninfo __user *arg)
 {
@@ -1004,20 +1031,19 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
        return 0;
 }
 
- /*
-    COMEDI_BUFINFO
-    buffer information ioctl
-
-    arg:
-    pointer to bufinfo structure
-
-    reads:
-    bufinfo at arg
-
-    writes:
-    modified bufinfo at arg
-
-  */
+/*
+ * COMEDI_BUFINFO ioctl
+ * buffer information
+ *
+ * arg:
+ *     pointer to comedi_bufinfo structure
+ *
+ * reads:
+ *     comedi_bufinfo structure
+ *
+ * writes:
+ *     modified comedi_bufinfo structure
+ */
 static int do_bufinfo_ioctl(struct comedi_device *dev,
                            struct comedi_bufinfo __user *arg, void *file)
 {
@@ -1135,8 +1161,10 @@ static int check_insn_config_length(struct comedi_insn *insn,
                if (insn->n == 6)
                        return 0;
                break;
-               /* by default we allow the insn since we don't have checks for
-                * all possible cases yet */
+               /*
+                * by default we allow the insn since we don't have checks for
+                * all possible cases yet
+                */
        default:
                pr_warn("No check for data length of config insn id %i is implemented\n",
                        data[0]);
@@ -1287,9 +1315,11 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                        if (insn->n != 2) {
                                ret = -EINVAL;
                        } else {
-                               /* Most drivers ignore the base channel in
+                               /*
+                                * Most drivers ignore the base channel in
                                 * insn->chanspec.  Fix this here if
-                                * the subdevice has <= 32 channels.  */
+                                * the subdevice has <= 32 channels.
+                                */
                                unsigned int orig_mask = data[0];
                                unsigned int shift = 0;
 
@@ -1326,19 +1356,19 @@ out:
 }
 
 /*
- *     COMEDI_INSNLIST
- *     synchronous instructions
+ * COMEDI_INSNLIST ioctl
+ * synchronous instruction list
  *
- *     arg:
- *             pointer to sync cmd structure
+ * arg:
+ *     pointer to comedi_insnlist structure
  *
- *     reads:
- *             sync cmd struct at arg
- *             instruction list
- *             data (for writes)
+ * reads:
+ *     comedi_insnlist structure
+ *     array of comedi_insn structures from insnlist->insns pointer
+ *     data (for writes) from insns[].data pointers
  *
- *     writes:
- *             data (for reads)
+ * writes:
+ *     data (for reads) to insns[].data pointers
  */
 /* arbitrary limits */
 #define MAX_SAMPLES 256
@@ -1415,18 +1445,18 @@ error:
 }
 
 /*
- *     COMEDI_INSN
- *     synchronous instructions
+ * COMEDI_INSN ioctl
+ * synchronous instruction
  *
- *     arg:
- *             pointer to insn
+ * arg:
+ *     pointer to comedi_insn structure
  *
- *     reads:
- *             struct comedi_insn struct at arg
- *             data (for writes)
+ * reads:
+ *     comedi_insn structure
+ *     data (for writes) from insn->data pointer
  *
- *     writes:
- *             data (for reads)
+ * writes:
+ *     data (for reads) to insn->data pointer
  */
 static int do_insn_ioctl(struct comedi_device *dev,
                         struct comedi_insn __user *arg, void *file)
@@ -1558,6 +1588,20 @@ static int __comedi_get_user_chanlist(struct comedi_device *dev,
        return 0;
 }
 
+/*
+ * COMEDI_CMD ioctl
+ * asynchronous acquisition command set-up
+ *
+ * arg:
+ *     pointer to comedi_cmd structure
+ *
+ * reads:
+ *     comedi_cmd structure
+ *     channel/range list from cmd->chanlist pointer
+ *
+ * writes:
+ *     possibly modified comedi_cmd structure (when -EAGAIN returned)
+ */
 static int do_cmd_ioctl(struct comedi_device *dev,
                        struct comedi_cmd __user *arg, void *file)
 {
@@ -1653,20 +1697,19 @@ cleanup:
 }
 
 /*
-       COMEDI_CMDTEST
-       command testing ioctl
-
-       arg:
-               pointer to cmd structure
-
-       reads:
-               cmd structure at arg
-               channel/range list
-
-       writes:
-               modified cmd structure at arg
-
-*/
+ * COMEDI_CMDTEST ioctl
+ * asynchronous aquisition command testing
+ *
+ * arg:
+ *     pointer to comedi_cmd structure
+ *
+ * reads:
+ *     comedi_cmd structure
+ *     channel/range list from cmd->chanlist pointer
+ *
+ * writes:
+ *     possibly modified comedi_cmd structure
+ */
 static int do_cmdtest_ioctl(struct comedi_device *dev,
                            struct comedi_cmd __user *arg, void *file)
 {
@@ -1709,20 +1752,18 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
 }
 
 /*
-       COMEDI_LOCK
-       lock subdevice
-
-       arg:
-               subdevice number
-
-       reads:
-               none
-
-       writes:
-               none
-
-*/
-
+ * COMEDI_LOCK ioctl
+ * lock subdevice
+ *
+ * arg:
+ *     subdevice number
+ *
+ * reads:
+ *     nothing
+ *
+ * writes:
+ *     nothing
+ */
 static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
                         void *file)
 {
@@ -1745,21 +1786,18 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
 }
 
 /*
-       COMEDI_UNLOCK
-       unlock subdevice
-
-       arg:
-               subdevice number
-
-       reads:
-               none
-
-       writes:
-               none
-
-       This function isn't protected by the semaphore, since
-       we already own the lock.
-*/
+ * COMEDI_UNLOCK ioctl
+ * unlock subdevice
+ *
+ * arg:
+ *     subdevice number
+ *
+ * reads:
+ *     nothing
+ *
+ * writes:
+ *     nothing
+ */
 static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
                           void *file)
 {
@@ -1782,19 +1820,18 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
 }
 
 /*
-       COMEDI_CANCEL
-       cancel acquisition ioctl
-
-       arg:
-               subdevice number
-
-       reads:
-               nothing
-
-       writes:
-               nothing
-
-*/
+ * COMEDI_CANCEL ioctl
+ * cancel asynchronous acquisition
+ *
+ * arg:
+ *     subdevice number
+ *
+ * reads:
+ *     nothing
+ *
+ * writes:
+ *     nothing
+ */
 static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
                           void *file)
 {
@@ -1816,19 +1853,18 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
 }
 
 /*
-       COMEDI_POLL ioctl
-       instructs driver to synchronize buffers
-
-       arg:
-               subdevice number
-
-       reads:
-               nothing
-
-       writes:
-               nothing
-
-*/
+ * COMEDI_POLL ioctl
+ * instructs driver to synchronize buffers
+ *
+ * arg:
+ *     subdevice number
+ *
+ * reads:
+ *     nothing
+ *
+ * writes:
+ *     nothing
+ */
 static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg,
                         void *file)
 {
@@ -1944,8 +1980,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
 
        mutex_lock(&dev->mutex);
 
-       /* Device config is special, because it must work on
-        * an unconfigured device. */
+       /*
+        * Device config is special, because it must work on
+        * an unconfigured device.
+        */
        if (cmd == COMEDI_DEVCONFIG) {
                if (minor >= COMEDI_NUM_BOARD_MINORS) {
                        /* Device config not appropriate on non-board minors. */
@@ -1957,8 +1995,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
                if (rc == 0) {
                        if (arg == 0 &&
                            dev->minor >= comedi_num_legacy_minors) {
-                               /* Successfully unconfigured a dynamically
-                                * allocated device.  Try and remove it. */
+                               /*
+                                * 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);
@@ -2584,6 +2624,17 @@ static const struct file_operations comedi_fops = {
        .llseek = noop_llseek,
 };
 
+/**
+ * comedi_event - handle events for asynchronous comedi command
+ * @dev: comedi_device struct
+ * @s: comedi_subdevice struct associated with dev
+ * Context: interrupt (usually), s->spin_lock spin-lock not held
+ *
+ * If an asynchronous comedi command is active on the subdevice, process
+ * any COMEDI_CB_... event flags that have been set, usually by an
+ * interrupt handler.  These may change the run state of the asynchronous
+ * command, wake a task, and/or send a SIGIO signal.
+ */
 void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct comedi_async *async = s->async;