Module: xenomai-head
Branch: master
Commit: 5a874f63cfd29fd46d05c2223a66a83029bb105d
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=5a874f63cfd29fd46d05c2223a66a83029bb105d

Author: Alexis Berlemont <alexis.berlem...@gmail.com>
Date:   Sat May 23 01:12:52 2009 +0200

Review the subdevice registration system: get closer from Comedi
upstream; Rework indentation in testing drivers; Remove useless
drivers management functions (comedi_init_drv(),
comedi_cleanup_drv())

---

 include/comedi/device.h                 |    3 +
 include/comedi/driver.h                 |   15 +-
 include/comedi/subdevice.h              |   10 +-
 ksrc/drivers/comedi/device.c            |   15 ++-
 ksrc/drivers/comedi/driver.c            |   33 +---
 ksrc/drivers/comedi/driver_facilities.c |   50 +----
 ksrc/drivers/comedi/subdevice.c         |   30 ++-
 ksrc/drivers/comedi/testing/fake.c      |  380 +++++++++++++++----------------
 ksrc/drivers/comedi/testing/loop.c      |  330 +++++++++++++++------------
 ksrc/drivers/comedi/transfer.c          |   28 +--
 10 files changed, 430 insertions(+), 464 deletions(-)

diff --git a/include/comedi/device.h b/include/comedi/device.h
index 405d87d..9c4d86f 100644
--- a/include/comedi/device.h
+++ b/include/comedi/device.h
@@ -47,6 +47,9 @@ struct comedi_device {
           procedure */
        comedi_drv_t *driver;
 
+       /* Hidden description stuff */
+       struct list_head subdvsq;
+
        /* TODO: transfer should not be a pointer */
        comedi_trf_t *transfer;
 
diff --git a/include/comedi/driver.h b/include/comedi/driver.h
index 2190bea..5609d90 100644
--- a/include/comedi/driver.h
+++ b/include/comedi/driver.h
@@ -31,8 +31,6 @@
 
 struct comedi_link_desc;
 
-#define COMEDI_DYNAMIC_DRV 0x1
-
 /** Structure containing driver declaration data.
  *
  *  @see rt_task_inquire()
@@ -54,10 +52,6 @@ struct comedi_driver {
        int privdata_size;
                       /**< Size of the driver's private data */
 
-       /* Hidden description stuff */
-       struct list_head subdvsq;
-                             /**< List containing the subdevices pointers */
-
        /* Init/destroy procedures */
        int (*attach) (comedi_cxt_t *, struct comedi_link_desc *);
                                                             /**< Attach 
procedure */
@@ -71,8 +65,8 @@ typedef struct comedi_driver comedi_drv_t;
 
 /* Driver list related functions */
 
-int comedi_add_drv(comedi_drv_t * drv);
-int comedi_rm_drv(comedi_drv_t * drv);
+int comedi_register_drv(comedi_drv_t * drv);
+int comedi_unregister_drv(comedi_drv_t * drv);
 int comedi_lct_drv(char *pin, comedi_drv_t ** pio);
 #ifdef CONFIG_PROC_FS
 int comedi_rdproc_drvs(char *page,
@@ -80,11 +74,6 @@ int comedi_rdproc_drvs(char *page,
                       off_t off, int count, int *eof, void *data);
 #endif /* CONFIG_PROC_FS */
 
-/* Driver related functions */
-
-int comedi_init_drv(comedi_drv_t * drv);
-int comedi_cleanup_drv(comedi_drv_t * drv);
-
 #endif /* !DOXYGEN_CPP */
 
 #endif /* __KERNEL__ */
diff --git a/include/comedi/subdevice.h b/include/comedi/subdevice.h
index 5127656..7cb5cdc 100644
--- a/include/comedi/subdevice.h
+++ b/include/comedi/subdevice.h
@@ -156,6 +156,9 @@ struct comedi_subdevice {
        struct list_head list;
                           /**< List stuff */
 
+       struct comedi_device *dev;
+                              /**< Containing device */
+
        /* Descriptors stuff */
        unsigned long flags;
                         /**< Type flags */
@@ -186,6 +189,8 @@ struct comedi_subdevice {
        int (*trigger) (comedi_cxt_t *, lsampl_t);
                                              /**< Callback for trigger 
operation */
 
+       char priv[0];
+                 /**< Private data */
 };
 typedef struct comedi_subdevice comedi_subd_t;
 
@@ -244,7 +249,10 @@ int comedi_check_chanlist(comedi_subd_t * subd,
                          unsigned char nb_chan, unsigned int *chans);
 
 /* --- Upper layer functions --- */
-int comedi_add_subd(struct comedi_driver *drv, comedi_subd_t * subd);
+
+comedi_subd_t * comedi_alloc_subd(int sizeof_priv,
+                                 void (*setup)(comedi_subd_t *));
+int comedi_add_subd(struct comedi_device *dev, comedi_subd_t * subd);
 int comedi_get_nbchan(struct comedi_device *dev, int subd_key);
 int comedi_ioctl_subdinfo(comedi_cxt_t * cxt, void *arg);
 int comedi_ioctl_chaninfo(comedi_cxt_t * cxt, void *arg);
diff --git a/ksrc/drivers/comedi/device.c b/ksrc/drivers/comedi/device.c
index f60dfcd..890786b 100644
--- a/ksrc/drivers/comedi/device.c
+++ b/ksrc/drivers/comedi/device.c
@@ -301,6 +301,9 @@ int comedi_assign_driver(comedi_cxt_t * cxt,
                comedi_loginfo
                    ("comedi_assign_driver: warning! the field priv will not be 
usable\n");
        else {
+
+               INIT_LIST_HEAD(&dev->subdvsq);
+       
                dev->priv = comedi_kmalloc(drv->privdata_size);
                if (dev->priv == NULL && drv->privdata_size != 0) {
                        comedi_logerr
@@ -343,10 +346,20 @@ int comedi_release_driver(comedi_cxt_t * cxt)
        if ((ret = dev->driver->detach(cxt)) != 0)
                goto out_release_driver;
 
-       /* Decreases module's count 
+       /* Decrease module's count 
           so as to allow module unloading */
        module_put(dev->driver->owner);
 
+       /* In case, the driver developer did not free the subdevices */
+       while (&dev->subdvsq != dev->subdvsq.next) {
+               struct list_head *this = dev->subdvsq.next;
+               comedi_subd_t *tmp = list_entry(this, comedi_subd_t, list);
+
+               list_del(this);
+               comedi_kfree(tmp);
+       }
+
+       /* Free the private field */ 
        comedi_kfree(dev->priv);
        dev->driver = NULL;
 
diff --git a/ksrc/drivers/comedi/driver.c b/ksrc/drivers/comedi/driver.c
index 45808eb..5ff934c 100644
--- a/ksrc/drivers/comedi/driver.c
+++ b/ksrc/drivers/comedi/driver.c
@@ -60,7 +60,7 @@ int comedi_lct_drv(char *pin, comedi_drv_t ** pio)
        return ret;
 }
 
-int comedi_add_drv(comedi_drv_t * drv)
+int comedi_register_drv(comedi_drv_t * drv)
 {
        comedi_loginfo("comedi_add_drv: name=%s\n", drv->board_name);
 
@@ -71,7 +71,7 @@ int comedi_add_drv(comedi_drv_t * drv)
                return -EINVAL;
 }
 
-int comedi_rm_drv(comedi_drv_t * drv)
+int comedi_unregister_drv(comedi_drv_t * drv)
 {
        comedi_loginfo("comedi_rm_drv: name=%s\n", drv->board_name);
 
@@ -127,33 +127,4 @@ int comedi_rdproc_drvs(char *page,
 
 #endif /* CONFIG_PROC_FS */
 
-/* --- Driver initialization / cleanup functions --- */
-
-int comedi_init_drv(comedi_drv_t * drv)
-{
-       if (drv == NULL)
-               return -EINVAL;
-
-       memset(drv, 0, sizeof(comedi_drv_t));
-       /* The linked list initialization is the only reason 
-          why comedi_init_drv() is mandatory before 
-          registering the driver */
-       INIT_LIST_HEAD(&drv->subdvsq);
-
-       return 0;
-}
-
-int comedi_cleanup_drv(comedi_drv_t * drv)
-{
-       while (&drv->subdvsq != drv->subdvsq.next) {
-               struct list_head *this = drv->subdvsq.next;
-               comedi_subd_t *tmp = list_entry(this, comedi_subd_t, list);
-
-               list_del(this);
-               comedi_kfree(tmp);
-       }
-
-       return 0;
-}
-
 #endif /* !DOXYGEN_CPP */
diff --git a/ksrc/drivers/comedi/driver_facilities.c 
b/ksrc/drivers/comedi/driver_facilities.c
index 44ba1e5..260c909 100644
--- a/ksrc/drivers/comedi/driver_facilities.c
+++ b/ksrc/drivers/comedi/driver_facilities.c
@@ -63,23 +63,11 @@
  * instead of registering a fops structure, a Comedi driver must
  * register some comedi_driver structure.
  *
- * Before registrations, the following steps must have been performed:
- * - Initialize the structure thanks to comedi_init_drv();
- * - At least, one subdevice descriptor has to declared into the
- *   driver thanks to comedi_add_subd();
- * 
- * Eventually, the driver must be inserted into the Comedi drivers set
- * thanks to comedi_add_drv().
- *
- * In the cleanup module function, the driver must be unregistered
- * thanks to comedi_rm_drv() and destroyed by calling
- * comedi_cleanup_drv().
- *
  * @{
  */
 
 /**
- * @brief Add a driver to the Comedi driver list
+ * @brief Register a Comedi driver
  *
  * After initialising a driver structure, the driver must be made
  * available so as to be attached.
@@ -89,11 +77,11 @@
  * @return 0 on success, otherwise negative error code.
  *
  */
-int comedi_add_drv(comedi_drv_t * drv);
-EXPORT_SYMBOL(comedi_add_drv);
+int comedi_register_drv(comedi_drv_t * drv);
+EXPORT_SYMBOL(comedi_register_drv);
 
 /**
- * @brief Remove a driver from the Comedi driver list
+ * @brief Unregister a Comedi driver
  *
  * This function removes the driver descriptor from the Comedi driver
  * list. The driver cannot be attached anymore.
@@ -103,30 +91,8 @@ EXPORT_SYMBOL(comedi_add_drv);
  * @return 0 on success, otherwise negative error code.
  *
  */
-int comedi_rm_drv(comedi_drv_t * drv);
-EXPORT_SYMBOL(comedi_rm_drv);
-
-/**
- * @brief Initialize the driver descriptor's structure
- *
- * @param[in] drv Driver descriptor structure
- *
- * @return 0 on success, otherwise negative error code.
- *
- */
-int comedi_init_drv(comedi_drv_t * drv);
-EXPORT_SYMBOL(comedi_init_drv);
-
-/**
- * @brief Clean the driver descriptor's structure up
- *
- * @param[in] drv Driver descriptor structure
- *
- * @return 0 on success, otherwise negative error code.
- *
- */
-int comedi_cleanup_drv(comedi_drv_t * drv);
-EXPORT_SYMBOL(comedi_cleanup_drv);
+int comedi_unregister_drv(comedi_drv_t * drv);
+EXPORT_SYMBOL(comedi_unregister_drv);
 
 /** @} */
 
@@ -181,14 +147,14 @@ EXPORT_SYMBOL(range_unknown);
  * comedi_add_subd() must be used so to add some subdevices to the
  * driver.
  *
- * @param[in] drv Driver descriptor structure
+ * @param[in] dev Device descriptor structure
  * @param[in] subd Subdevice descriptor structure
  *
  * @return the index with which the subdevice has been registered, in
  * case of error a negative error code is returned.
  *
  */
-int comedi_add_subd(comedi_drv_t * drv, comedi_subd_t * subd);
+int comedi_add_subd(comedi_dev_t * dev, comedi_subd_t * subd);
 EXPORT_SYMBOL(comedi_add_subd);
 
 /**
diff --git a/ksrc/drivers/comedi/subdevice.c b/ksrc/drivers/comedi/subdevice.c
index d813859..2fccf00 100644
--- a/ksrc/drivers/comedi/subdevice.c
+++ b/ksrc/drivers/comedi/subdevice.c
@@ -121,27 +121,33 @@ int comedi_get_nbchan(comedi_dev_t * dev, int subd_key)
        return dev->transfer->subds[subd_key]->chan_desc->length;
 }
 
-int comedi_add_subd(comedi_drv_t * drv, comedi_subd_t * subd)
+comedi_subd_t * comedi_alloc_subd(int sizeof_priv,
+                                 void (*setup)(comedi_subd_t *))
+{
+       comedi_subd_t *subd;
+       
+       subd = comedi_kmalloc(sizeof(comedi_subd_t) + sizeof_priv);
+
+       if(subd != NULL && setup != NULL)
+               setup(subd);
+
+       return subd;
+}
+
+int comedi_add_subd(comedi_dev_t * dev, comedi_subd_t * subd)
 {
        struct list_head *this;
-       comedi_subd_t *news;
        int i = 0;
 
        /* Basic checking */
-       if (drv == NULL || subd == NULL)
+       if (dev == NULL || subd == NULL)
                return -EINVAL;
 
-       /* The driver developer does not have to manage instances
-          of the subdevice structure; the allocation are done
-          in the Comedi layer */
-       news = comedi_kmalloc(sizeof(comedi_subd_t));
-       if (news == NULL)
-               return -ENOMEM;
-       memcpy(news, subd, sizeof(comedi_subd_t));
+       list_add_tail(&subd->list, &dev->subdvsq);
 
-       list_add_tail(&news->list, &drv->subdvsq);
+       subd->dev = dev;
 
-       list_for_each(this, &drv->subdvsq) {
+       list_for_each(this, &dev->subdvsq) {
                i++;
        }
 
diff --git a/ksrc/drivers/comedi/testing/fake.c 
b/ksrc/drivers/comedi/testing/fake.c
index 4129000..deba011 100644
--- a/ksrc/drivers/comedi/testing/fake.c
+++ b/ksrc/drivers/comedi/testing/fake.c
@@ -9,28 +9,28 @@
 /* Device private structure */
 struct test_priv {
 
-    /* Task descriptor */
-    comedi_task_t timer_task;
+       /* Task descriptor */
+       comedi_task_t timer_task;
   
-    /* Specific timing fields */
-    unsigned long scan_period_ns;
-    unsigned long convert_period_ns;
-    unsigned long current_ns;
-    unsigned long reminder_ns;
-    unsigned long long last_ns;
-
-    /* Misc fields */
-    unsigned long amplitude_div;
-    unsigned long quanta_cnt;
-    volatile int timer_running;
+       /* Specific timing fields */
+       unsigned long scan_period_ns;
+       unsigned long convert_period_ns;
+       unsigned long current_ns;
+       unsigned long reminder_ns;
+       unsigned long long last_ns;
+
+       /* Misc fields */
+       unsigned long amplitude_div;
+       unsigned long quanta_cnt;
+       volatile int timer_running;
 
 };
 typedef struct test_priv tstprv_t;
 
 /* Attach options structure */
 struct test_attach_arg {
-  unsigned long amplitude_div;
-  unsigned long quanta_cnt;
+       unsigned long amplitude_div;
+       unsigned long quanta_cnt;
 };
 typedef struct test_attach_arg tstattr_t;
 
@@ -38,58 +38,58 @@ typedef struct test_attach_arg tstattr_t;
 
 /* Channels descriptor */
 static comedi_chdesc_t test_chandesc = {
-  mode: COMEDI_CHAN_GLOBAL_CHANDESC,
-  length: 8,
-  chans: { 
-      {COMEDI_CHAN_AREF_GROUND, TEST_NB_BITS},
-  },
+       .mode = COMEDI_CHAN_GLOBAL_CHANDESC,
+       .length = 8,
+       .chans = { 
+               {COMEDI_CHAN_AREF_GROUND, TEST_NB_BITS},
+       },
 };
 
 /* Ranges tab */
 static comedi_rngtab_t test_rngtab = {
-    length: 2,
-    rngs: {
-       RANGE_V(-5,5),
-       RANGE_V(-10,10),
-    },
+       .length = 2,
+       .rngs = {
+               RANGE_V(-5,5),
+               RANGE_V(-10,10),
+       },
 };
 /* Ranges descriptor */
 comedi_rngdesc_t test_rngdesc = RNG_GLOBAL(test_rngtab);
 
 /* Command options mask */
 static comedi_cmd_t test_cmd_mask = {
-  idx_subd:0,
-  start_src:TRIG_NOW,
-  scan_begin_src:TRIG_TIMER,
-  convert_src:TRIG_NOW|TRIG_TIMER,
-  scan_end_src:TRIG_COUNT,
-  stop_src:TRIG_COUNT|TRIG_NONE,
+       .idx_subd = 0,
+       .start_src = TRIG_NOW,
+       .scan_begin_src = TRIG_TIMER,
+       .convert_src = TRIG_NOW|TRIG_TIMER,
+       .scan_end_src = TRIG_COUNT,
+       .stop_src = TRIG_COUNT|TRIG_NONE,
 };
 
 /* --- Analog input simulation --- */
 
 static sampl_t output_tab[8] = { 
-    0x0001, 0x2000, 0x4000, 0x6000, 
-    0x8000, 0xa000, 0xc000, 0xffff 
+       0x0001, 0x2000, 0x4000, 0x6000, 
+       0x8000, 0xa000, 0xc000, 0xffff 
 };
 static unsigned int output_idx;
 static comedi_lock_t output_lock = COMEDI_LOCK_UNLOCKED;
 
 static sampl_t test_output(tstprv_t *priv)
 {
-    unsigned long flags;
-    unsigned int idx;
+       unsigned long flags;
+       unsigned int idx;
     
-    comedi_lock_irqsave(&output_lock, flags);
+       comedi_lock_irqsave(&output_lock, flags);
 
-    output_idx += priv->quanta_cnt;
-    if(output_idx == 8)
-       output_idx = 0; 
-    idx = output_idx;
+       output_idx += priv->quanta_cnt;
+       if(output_idx == 8)
+               output_idx = 0; 
+       idx = output_idx;
 
-    comedi_unlock_irqrestore(&output_lock, flags);
+       comedi_unlock_irqrestore(&output_lock, flags);
     
-    return output_tab[idx] / priv->amplitude_div;
+       return output_tab[idx] / priv->amplitude_div;
 }
 
 /* --- Task part --- */
@@ -97,223 +97,221 @@ static sampl_t test_output(tstprv_t *priv)
 /* Timer task routine */
 static void test_task_proc(void *arg)
 {
-  comedi_dev_t *dev = (comedi_dev_t*)arg;
-  tstprv_t *priv = (tstprv_t *)dev->priv;
-  comedi_cmd_t *cmd = NULL;
-  u64 now_ns, elapsed_ns=0;
+       comedi_dev_t *dev = (comedi_dev_t*)arg;
+       tstprv_t *priv = (tstprv_t *)dev->priv;
+       comedi_cmd_t *cmd = NULL;
+       u64 now_ns, elapsed_ns=0;
 
-  while(!comedi_check_dev(dev))
-    comedi_task_sleep(TEST_TASK_PERIOD);
+       while(!comedi_check_dev(dev))
+               comedi_task_sleep(TEST_TASK_PERIOD);
 
-  while(1) {
-    if(priv->timer_running != 0)
-    {
-      int i = 0;
+       while(1) {
+               if(priv->timer_running != 0)
+               {
+                       int i = 0;
 
-      cmd = comedi_get_cmd(dev, COMEDI_BUF_PUT, 0);    
+                       cmd = comedi_get_cmd(dev, COMEDI_BUF_PUT, 0);    
 
-      now_ns = comedi_get_time();
-      elapsed_ns += now_ns - priv->last_ns + priv->reminder_ns;
-      priv->last_ns = now_ns;
+                       now_ns = comedi_get_time();
+                       elapsed_ns += now_ns - priv->last_ns + 
priv->reminder_ns;
+                       priv->last_ns = now_ns;
 
-      while(elapsed_ns >= priv->scan_period_ns)
-      {
-       int j;
+                       while(elapsed_ns >= priv->scan_period_ns)
+                       {
+                               int j;
 
-       for(j = 0; j < cmd->nb_chan; j++)
-       {
-         sampl_t value = test_output(priv);
+                               for(j = 0; j < cmd->nb_chan; j++)
+                               {
+                                       sampl_t value = test_output(priv);
 
-         comedi_buf_put(dev, &value, sizeof(sampl_t));
+                                       comedi_buf_put(dev, &value, 
sizeof(sampl_t));
 
-       }
+                               }
 
-       elapsed_ns -= priv->scan_period_ns;
-       i++;
+                               elapsed_ns -= priv->scan_period_ns;
+                               i++;
 
-      }
+                       }
 
-      priv->current_ns += i * priv->scan_period_ns;
-      priv->reminder_ns = elapsed_ns;
+                       priv->current_ns += i * priv->scan_period_ns;
+                       priv->reminder_ns = elapsed_ns;
 
-      comedi_buf_evt(dev, COMEDI_BUF_PUT, 0);
-    }
+                       comedi_buf_evt(dev, COMEDI_BUF_PUT, 0);
+               }
 
-    comedi_task_sleep(TEST_TASK_PERIOD);
+               comedi_task_sleep(TEST_TASK_PERIOD);
 
-  }
+       }
 }
 
 /* --- Comedi Callbacks --- */
 
-/* Attach callback */
-int test_attach(comedi_cxt_t *cxt,
-               comedi_lnkdesc_t *arg)
-{
-    int ret=0;  
-    comedi_dev_t *dev = comedi_get_dev(cxt);
-    tstprv_t *priv = (tstprv_t *)dev->priv;
-
-    if(arg->opts!=NULL) {
-       tstattr_t *attr = (tstattr_t*) arg->opts;
-
-       priv->amplitude_div = attr->amplitude_div;
-       priv->quanta_cnt = 
-           (attr->quanta_cnt > 7 || attr->quanta_cnt == 0) ? 
-           1 : attr->quanta_cnt;
-    }
-    else {
-       priv->amplitude_div = 1;
-       priv->quanta_cnt = 1;
-    }
-
-    priv->timer_running = 0;
-
-    ret = comedi_task_init(&priv->timer_task, 
-                          "comedi_test task", 
-                          test_task_proc, 
-                          dev, COMEDI_TASK_HIGHEST_PRIORITY);
-
-    return ret;
-}
-
-/* Detach callback */
-int test_detach(comedi_cxt_t *cxt)
-{
-    comedi_dev_t *dev = comedi_get_dev(cxt);
-    tstprv_t *priv = (tstprv_t *)dev->priv;
-
-    comedi_task_destroy(&priv->timer_task);
-
-    return 0;
-}
-
 /* Command callback */
 int test_cmd(comedi_cxt_t *cxt, int idx_subd)
 {
-  comedi_dev_t *dev=comedi_get_dev(cxt);
-  comedi_cmd_t *cmd=comedi_get_cmd(dev, 0, idx_subd);
-  tstprv_t *priv=(tstprv_t *)dev->priv;
+       comedi_dev_t *dev=comedi_get_dev(cxt);
+       comedi_cmd_t *cmd=comedi_get_cmd(dev, 0, idx_subd);
+       tstprv_t *priv=(tstprv_t *)dev->priv;
 
-  comedi_loginfo("test_cmd: begin (subd=%d)\n",idx_subd);
+       comedi_loginfo("test_cmd: begin (subd=%d)\n",idx_subd);
   
-  priv->scan_period_ns=cmd->scan_begin_arg;
-  priv->convert_period_ns=(cmd->convert_src==TRIG_TIMER)?
-    cmd->convert_arg:0;
+       priv->scan_period_ns=cmd->scan_begin_arg;
+       priv->convert_period_ns=(cmd->convert_src==TRIG_TIMER)?
+               cmd->convert_arg:0;
   
-  comedi_loginfo("test_cmd: scan_period=%luns convert_period=%luns\n",
-             priv->scan_period_ns, priv->convert_period_ns);
+       comedi_loginfo("test_cmd: scan_period=%luns convert_period=%luns\n",
+                      priv->scan_period_ns, priv->convert_period_ns);
 
-  priv->last_ns = comedi_get_time();
+       priv->last_ns = comedi_get_time();
 
-  priv->current_ns = ((unsigned long)priv->last_ns);
-  priv->reminder_ns = 0;
+       priv->current_ns = ((unsigned long)priv->last_ns);
+       priv->reminder_ns = 0;
   
-  priv->timer_running = 1;
+       priv->timer_running = 1;
   
-  return 0;
+       return 0;
   
 }
 
 /* Test command callback */
 int test_cmdtest(comedi_cxt_t *cxt, comedi_cmd_t *cmd)
 {
-  if(cmd->scan_begin_src==TRIG_TIMER)
-  {
-    if(cmd->scan_begin_arg < 1000)
-      return -EINVAL;
+       if(cmd->scan_begin_src==TRIG_TIMER)
+       {
+               if(cmd->scan_begin_arg < 1000)
+                       return -EINVAL;
 
-    if(cmd->convert_src==TRIG_TIMER &&
-       cmd->scan_begin_arg<(cmd->convert_arg*cmd->nb_chan))
-      return -EINVAL;
-  }
+               if(cmd->convert_src==TRIG_TIMER &&
+                  cmd->scan_begin_arg<(cmd->convert_arg*cmd->nb_chan))
+                       return -EINVAL;
+       }
 
-  return 0;
+       return 0;
 }
 
 /* Cancel callback */
 int test_cancel(comedi_cxt_t *cxt, int idx_subd)
 {
-  comedi_dev_t *dev = comedi_get_dev(cxt);
-  tstprv_t *priv = (tstprv_t *)dev->priv;
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       tstprv_t *priv = (tstprv_t *)dev->priv;
 
-  priv->timer_running = 0;
+       priv->timer_running = 0;
 
-  return 0;
+       return 0;
 }
 
 /* Read instruction callback */
 int test_ai_insn_read(comedi_cxt_t *cxt, comedi_kinsn_t *insn)
 {
-    comedi_dev_t *dev = comedi_get_dev(cxt);
-    tstprv_t *priv = (tstprv_t *)dev->priv;
-    int i;
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       tstprv_t *priv = (tstprv_t *)dev->priv;
+       int i;
 
-    for(i = 0; i < insn->data_size / sizeof(sampl_t); i++)
-       ((sampl_t*)insn->data)[i] = test_output(priv);
+       for(i = 0; i < insn->data_size / sizeof(sampl_t); i++)
+               ((sampl_t*)insn->data)[i] = test_output(priv);
 
-    return 0;
+       return 0;
 }
 
 /* Munge callback */
 void test_ai_munge(comedi_cxt_t *cxt, 
-                 int idx_subd, void *buf, unsigned long size)
+                  int idx_subd, void *buf, unsigned long size)
 {
-    int i;
+       int i;
 
-    for(i = 0; i < size / sizeof(sampl_t); i++)
-       ((sampl_t*)buf)[i] += 1;
+       for(i = 0; i < size / sizeof(sampl_t); i++)
+               ((sampl_t*)buf)[i] += 1;
 }
 
-/* --- Module part --- */
-
-static comedi_drv_t test_drv;
+void setup_test_subd(comedi_subd_t *subd)
+{
+       /* Initialize the subdevice structure */
+       memset(subd, 0, sizeof(comedi_subd_t));
+       
+       /* Fill the subdevice structure */
+       subd->flags |= COMEDI_SUBD_AI;
+       subd->flags |= COMEDI_SUBD_CMD;
+       subd->flags |= COMEDI_SUBD_MMAP;
+       subd->rng_desc = &test_rngdesc;
+       subd->chan_desc = &test_chandesc;
+       subd->do_cmd=test_cmd;
+       subd->do_cmdtest = test_cmdtest;
+       subd->cancel = test_cancel;
+       subd->munge = test_ai_munge;
+       subd->cmd_mask = &test_cmd_mask;
+       subd->insn_read = test_ai_insn_read;
+}
 
-static int __init comedi_fake_init(void)
+/* Attach callback */
+int test_attach(comedi_cxt_t *cxt,
+               comedi_lnkdesc_t *arg)
 {
-    int ret;
-    comedi_subd_t subd;
+       int ret = 0;  
+       comedi_subd_t *subd;
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       tstprv_t *priv = (tstprv_t *)dev->priv;
+
+       if(arg->opts!=NULL) {
+               tstattr_t *attr = (tstattr_t*) arg->opts;
+
+               priv->amplitude_div = attr->amplitude_div;
+               priv->quanta_cnt = 
+                       (attr->quanta_cnt > 7 || attr->quanta_cnt == 0) ? 
+                       1 : attr->quanta_cnt;
+       }
+       else {
+               priv->amplitude_div = 1;
+               priv->quanta_cnt = 1;
+       }
 
-    /* Initializes the driver structure */
-    ret = comedi_init_drv(&test_drv);
-    if(ret!=0)
-       return ret;
+       /* Adds the subdevice to the device */
+       subd = comedi_alloc_subd(0, setup_test_subd);
+       if(subd == NULL)
+               return -ENOMEM;
+
+       ret = comedi_add_subd(dev, subd);
+       if(ret < 0)
+               return ret;
+
+       priv->timer_running = 0;
+
+       ret = comedi_task_init(&priv->timer_task, 
+                              "comedi_test task", 
+                              test_task_proc, 
+                              dev, COMEDI_TASK_HIGHEST_PRIORITY);
 
-    /* Fills the driver structure main fields */
-    test_drv.owner = THIS_MODULE;
-    test_drv.board_name = "comedi_fake";
-    test_drv.attach = test_attach;
-    test_drv.detach = test_detach;
-    test_drv.privdata_size = sizeof(tstprv_t);
-
-    /* Initializes the subdevice structure */
-    memset(&subd, 0, sizeof(comedi_subd_t));
-
-    /* Fills the subdevice structure */
-    subd.flags |= COMEDI_SUBD_AI;
-    subd.flags |= COMEDI_SUBD_CMD;
-    subd.flags |= COMEDI_SUBD_MMAP;
-    subd.rng_desc = &test_rngdesc;
-    subd.chan_desc = &test_chandesc;
-    subd.do_cmd=test_cmd;
-    subd.do_cmdtest = test_cmdtest;
-    subd.cancel = test_cancel;
-    subd.munge = test_ai_munge;
-    subd.cmd_mask = &test_cmd_mask;
-    subd.insn_read = test_ai_insn_read;
-
-    /* Adds the subdevice to the driver */
-    ret = comedi_add_subd(&test_drv,&subd);
-    if(ret < 0)
        return ret;
+}
 
-    return comedi_add_drv(&test_drv);
+/* Detach callback */
+int test_detach(comedi_cxt_t *cxt)
+{
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       tstprv_t *priv = (tstprv_t *)dev->priv;
+
+       comedi_task_destroy(&priv->timer_task);
+
+       return 0;
+}
+
+/* --- Module part --- */
+
+static comedi_drv_t test_drv = {
+       .owner = THIS_MODULE,
+       .board_name = "comedi_fake",
+       .attach = test_attach,
+       .detach = test_detach,
+       .privdata_size = sizeof(tstprv_t),
+};
+
+static int __init comedi_fake_init(void)
+{
+       return comedi_register_drv(&test_drv);
 }
 
 static void __exit comedi_fake_cleanup(void)
 {
-    comedi_rm_drv(&test_drv);
-    comedi_cleanup_drv(&test_drv);
+       comedi_unregister_drv(&test_drv);
 }
 
 MODULE_DESCRIPTION("Comedi fake driver");
diff --git a/ksrc/drivers/comedi/testing/loop.c 
b/ksrc/drivers/comedi/testing/loop.c
index 9723fe5..892d075 100644
--- a/ksrc/drivers/comedi/testing/loop.c
+++ b/ksrc/drivers/comedi/testing/loop.c
@@ -4,190 +4,260 @@
 #define LOOP_TASK_PERIOD 1000000
 #define LOOP_NB_BITS 16
 
+/* Channels descriptor */
 static comedi_chdesc_t loop_chandesc = {
-  mode: COMEDI_CHAN_GLOBAL_CHANDESC,
-  length: 8,
-  chans: { 
-      {COMEDI_CHAN_AREF_GROUND, LOOP_NB_BITS},
-  },
+       .mode = COMEDI_CHAN_GLOBAL_CHANDESC,
+       .length = 8,
+       .chans = { 
+               {COMEDI_CHAN_AREF_GROUND, LOOP_NB_BITS},
+       },
 };
 
+/* Ranges tab */
 static comedi_rngtab_t loop_rngtab = {
-    length: 2,
-    rngs: {
-       RANGE_V(-5,5),
-       RANGE_V(-10,10),
-    },
+       .length =  2,
+       .rngs = {
+               RANGE_V(-5,5),
+               RANGE_V(-10,10),
+       },
 };
+/* Ranges descriptor */
 comedi_rngdesc_t loop_rngdesc = RNG_GLOBAL(loop_rngtab);
 
+/* Command options mask */
 static comedi_cmd_t loop_cmd_mask = {
-  idx_subd:0,
-
-  start_src:TRIG_NOW,
-  scan_begin_src:TRIG_TIMER,
-  convert_src:TRIG_NOW|TRIG_TIMER,
-  scan_end_src:TRIG_COUNT,
-  stop_src:TRIG_COUNT|TRIG_NONE,
+       .idx_subd = 0,
+       .start_src = TRIG_NOW,
+       .scan_begin_src = TRIG_TIMER,
+       .convert_src = TRIG_NOW|TRIG_TIMER,
+       .scan_end_src = TRIG_COUNT,
+       .stop_src = TRIG_COUNT|TRIG_NONE,
 };
 
-static comedi_drv_t loop_drv;
-
+/* Private data organization */
 struct loop_priv {
 
-    /* Task descriptor */
-    comedi_task_t loop_task;
+       /* Task descriptor */
+       comedi_task_t loop_task;
 
-    /* Misc fields */
-    volatile int loop_running:1;
-    sampl_t loop_insn_value;
+       /* Misc fields */
+       volatile int loop_running:1;
+       sampl_t loop_insn_value;
 };
 typedef struct loop_priv lpprv_t;
 
+/* Attach arguments contents */
 struct loop_attach_arg {
-  unsigned long period;
+       unsigned long period;
 };
 typedef struct loop_attach_arg lpattr_t;
 
 static void loop_task_proc(void *arg);
 
-int loop_attach(comedi_cxt_t *cxt,
-               comedi_lnkdesc_t *arg)
-{
-  int ret=0;  
-  comedi_dev_t *dev=comedi_get_dev(cxt);
-  lpprv_t *priv=(lpprv_t *)dev->priv;
+/* --- Task part --- */
 
-  priv->loop_running = 0;
-  priv->loop_insn_value = 0;
+/* Timer task routine  */
+static void loop_task_proc(void *arg)
+{
+       comedi_dev_t *dev = (comedi_dev_t*)arg;
+       lpprv_t *priv = (lpprv_t *)dev->priv;
+    
+       while(!comedi_check_dev(dev))
+               comedi_task_sleep(LOOP_TASK_PERIOD);
 
-  ret=comedi_task_init(&priv->loop_task, 
-                      "comedi_loop task", 
-                      loop_task_proc,
-                      dev, COMEDI_TASK_HIGHEST_PRIORITY);
+       while(1) {
+       
+               if(priv->loop_running) {
+                       sampl_t value;
+                       int ret=0;
+           
+                       while(ret==0) {
+               
+                               ret = comedi_buf_get(dev, 
+                                                    &value, sizeof(sampl_t));
 
-  return ret;
-}
+                               if(ret == 0) {
 
-int loop_detach(comedi_cxt_t *cxt)
-{
-  comedi_dev_t *dev=comedi_get_dev(cxt);
-  lpprv_t *priv=(lpprv_t *)dev->priv;
+                                       comedi_loginfo("loop_task_proc: "
+                                                      "data available\n");
 
-  comedi_task_destroy(&priv->loop_task);
+                                       comedi_buf_evt(dev, COMEDI_BUF_GET, 0);
+                   
+                                       ret=comedi_buf_put(dev, 
+                                                          &value, 
+                                                          sizeof(sampl_t));
+
+                                       if(ret==0)
+                                               comedi_buf_evt(dev, 
+                                                              COMEDI_BUF_PUT, 
+                                                              0);
+                               }
+                       }
+               }
 
-  return 0;
+               comedi_task_sleep(LOOP_TASK_PERIOD);
+       }
 }
 
+/* --- Comedi Callbacks --- */
+
+/* Command callback */
 int loop_cmd(comedi_cxt_t *cxt, int idx_subd)
 {
-  comedi_dev_t *dev=comedi_get_dev(cxt);
-  lpprv_t *priv=(lpprv_t *)dev->priv;
+       comedi_dev_t *dev=comedi_get_dev(cxt);
+       lpprv_t *priv=(lpprv_t *)dev->priv;
 
-  comedi_loginfo("loop_cmd: (subd=%d)\n",idx_subd);
+       comedi_loginfo("loop_cmd: (subd=%d)\n",idx_subd);
 
-  priv->loop_running = 1;
+       priv->loop_running = 1;
   
-  return 0;
+       return 0;
   
 }
 
+/* Cancel callback */
 int loop_cancel(comedi_cxt_t *cxt, int idx_subd)
 {
-  comedi_dev_t *dev=comedi_get_dev(cxt);
-  lpprv_t *priv=(lpprv_t *)dev->priv;
+       comedi_dev_t *dev=comedi_get_dev(cxt);
+       lpprv_t *priv=(lpprv_t *)dev->priv;
 
-  comedi_loginfo("loop_cancel: (subd=%d)\n",idx_subd);
+       comedi_loginfo("loop_cancel: (subd=%d)\n",idx_subd);
 
-  priv->loop_running=0;
+       priv->loop_running=0;
 
-  return 0;
+       return 0;
 }
 
+/* Read instruction callback */
 int loop_insn_read(comedi_cxt_t *cxt, comedi_kinsn_t *insn)
 {
-    comedi_dev_t *dev = comedi_get_dev(cxt);
-    lpprv_t *priv = (lpprv_t*)dev->priv;
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       lpprv_t *priv = (lpprv_t*)dev->priv;
 
-    /* Checks the buffer size */
-    if(insn->data_size!=sizeof(sampl_t))
-       return -EINVAL;
+       /* Checks the buffer size */
+       if(insn->data_size!=sizeof(sampl_t))
+               return -EINVAL;
 
-    /* Sets the memorized value */
-    insn->data[0]=priv->loop_insn_value;
+       /* Sets the memorized value */
+       insn->data[0]=priv->loop_insn_value;
     
-    return 0;
+       return 0;
 }
 
+/* Write instruction callback */
 int loop_insn_write(comedi_cxt_t *cxt, comedi_kinsn_t *insn)
 {
-    comedi_dev_t *dev = comedi_get_dev(cxt);
-    lpprv_t *priv = (lpprv_t*)dev->priv;
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       lpprv_t *priv = (lpprv_t*)dev->priv;
 
-    /* Checks the buffer size */
-    if(insn->data_size!=sizeof(sampl_t))
-       return -EINVAL;
+       /* Checks the buffer size */
+       if(insn->data_size!=sizeof(sampl_t))
+               return -EINVAL;
 
-    /* Retrieves the value to memorize */
-    priv->loop_insn_value=insn->data[0];
+       /* Retrieves the value to memorize */
+       priv->loop_insn_value=insn->data[0];
     
-    return 0;
+       return 0;
 }
 
+void setup_input_subd(comedi_subd_t *subd)
+{
+       memset(subd, 0, sizeof(comedi_subd_t));
+
+       subd->flags |= COMEDI_SUBD_AI;
+       subd->flags |= COMEDI_SUBD_CMD;
+       subd->flags |= COMEDI_SUBD_MMAP;
+       subd->rng_desc = &loop_rngdesc;
+       subd->chan_desc = &loop_chandesc;
+       subd->do_cmd = loop_cmd;
+       subd->do_cmdtest = NULL;
+       subd->cancel = loop_cancel;
+       subd->cmd_mask = &loop_cmd_mask;
+       subd->insn_read = loop_insn_read;
+       subd->insn_write = loop_insn_write;
+}
 
-int loop_init_drv(void)
+void setup_output_subd(comedi_subd_t *subd)
 {
-  int ret=0;
-  comedi_subd_t subd;
-  
-  memset(&subd, 0, sizeof(comedi_subd_t));
-  subd.flags |= COMEDI_SUBD_AI;
-  subd.flags |= COMEDI_SUBD_CMD;
-  subd.flags |= COMEDI_SUBD_MMAP;
-  subd.rng_desc = &loop_rngdesc;
-  subd.chan_desc = &loop_chandesc;
-  subd.do_cmd = loop_cmd;
-  subd.do_cmdtest = NULL;
-  subd.cancel = loop_cancel;
-  subd.cmd_mask = &loop_cmd_mask;
-  subd.insn_read = loop_insn_read;
-  subd.insn_write = loop_insn_write;
-  if((ret = comedi_add_subd(&loop_drv,&subd))<0)
-    return ret;
-    
-  subd.flags=COMEDI_SUBD_AO;
-  subd.flags|=COMEDI_SUBD_CMD;
-  subd.flags|=COMEDI_SUBD_MMAP;
-  subd.insn_read=loop_insn_read;
-  subd.insn_write=loop_insn_write;
-  ret=comedi_add_subd(&loop_drv,&subd);
-
-  return (ret < 0) ? ret : 0;
+       memset(subd, 0, sizeof(comedi_subd_t));
+
+       subd->flags = COMEDI_SUBD_AO;
+       subd->flags |= COMEDI_SUBD_CMD;
+       subd->flags |= COMEDI_SUBD_MMAP;
+       subd->insn_read = loop_insn_read;
+       subd->insn_write = loop_insn_write;
 }
 
-static int __init comedi_loop_init(void)
+/* Attach callback */
+int loop_attach(comedi_cxt_t *cxt,
+               comedi_lnkdesc_t *arg)
 {
-  int ret = comedi_init_drv(&loop_drv);
+       int ret = 0;
+       comedi_subd_t *subd;
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       lpprv_t *priv = (lpprv_t *)dev->priv;
+
+       /* Add the fake input subdevice */
+       subd = comedi_alloc_subd(0, setup_input_subd); 
+       if(subd == NULL)
+               return -ENOMEM;  
+
+       ret = comedi_add_subd(dev, subd);
+       if(ret < 0)
+               /* Let Comedi free the lately allocated subdevice */
+               return ret;
+
+       /* Add the fake output subdevice */
+       subd = comedi_alloc_subd(0, setup_output_subd); 
+       if(subd == NULL)
+               /* Let Comedi free the lately allocated subdevice */
+               return -ENOMEM;  
+
+       ret = comedi_add_subd(dev, subd);
+       if(ret < 0)
+               /* Let Comedi free the lately allocated subdevices */
+               return ret;
+
+       priv->loop_running = 0;
+       priv->loop_insn_value = 0;
+
+       ret = comedi_task_init(&priv->loop_task, 
+                              "comedi_loop task", 
+                              loop_task_proc,
+                              dev, COMEDI_TASK_HIGHEST_PRIORITY);
+
+       return ret;
+}
 
-  if(ret!=0)
-    return ret;
+/* Detach callback */
+int loop_detach(comedi_cxt_t *cxt)
+{
+       comedi_dev_t *dev = comedi_get_dev(cxt);
+       lpprv_t *priv = (lpprv_t *)dev->priv;
 
-  loop_drv.owner=THIS_MODULE;
-  loop_drv.board_name="comedi_loop";
-  loop_drv.attach=loop_attach;
-  loop_drv.detach=loop_detach;
-  loop_drv.privdata_size=sizeof(lpprv_t);
+       comedi_task_destroy(&priv->loop_task);
 
-  if((ret=loop_init_drv())!=0)
-    return ret;
+       return 0;
+}
+
+/* --- Module part --- */
+
+static comedi_drv_t loop_drv = {
+       .owner = THIS_MODULE,
+       .board_name = "comedi_loop",
+       .attach = loop_attach,
+       .detach = loop_detach,
+       .privdata_size = sizeof(lpprv_t),
+};
 
-  return comedi_add_drv(&loop_drv);
+static int __init comedi_loop_init(void)
+{
+       return comedi_register_drv(&loop_drv);
 }
 
 static void __exit comedi_loop_cleanup(void)
 {
-  comedi_rm_drv(&loop_drv);
-  comedi_cleanup_drv(&loop_drv);
+       comedi_unregister_drv(&loop_drv);
 }
 
 MODULE_DESCRIPTION("Comedi loop driver");
@@ -195,39 +265,3 @@ MODULE_LICENSE("GPL");
 
 module_init(comedi_loop_init);
 module_exit(comedi_loop_cleanup);
-
-static void loop_task_proc(void *arg)
-{
-    comedi_dev_t *dev = (comedi_dev_t*)arg;
-    lpprv_t *priv = (lpprv_t *)dev->priv;
-    
-    while(!comedi_check_dev(dev))
-       comedi_task_sleep(LOOP_TASK_PERIOD);
-
-    while(1) {
-       
-       if(priv->loop_running) {
-           sampl_t value;
-           int ret=0;
-           
-           while(ret==0) {
-               
-               ret = comedi_buf_get(dev, &value, sizeof(sampl_t));
-
-               if(ret == 0) {
-
-                   comedi_loginfo("loop_task_proc: data available\n");
-
-                   comedi_buf_evt(dev, COMEDI_BUF_GET, 0);
-                   
-                   ret=comedi_buf_put(dev, &value, sizeof(sampl_t));
-
-                   if(ret==0)
-                       comedi_buf_evt(dev, COMEDI_BUF_PUT, 0);
-               }
-           }
-       }
-
-       comedi_task_sleep(LOOP_TASK_PERIOD);
-    }
-}
diff --git a/ksrc/drivers/comedi/transfer.c b/ksrc/drivers/comedi/transfer.c
index e74433e..b86d3f1 100644
--- a/ksrc/drivers/comedi/transfer.c
+++ b/ksrc/drivers/comedi/transfer.c
@@ -71,16 +71,8 @@ int comedi_cleanup_transfer(comedi_cxt_t * cxt)
                comedi_kfree(tsf->bufs);
        }
 
+       /* Releases the pointers tab, if need be */
        if (tsf->subds != NULL) {
-
-               /* If the driver is dynamic, the subdevices
-                  structures must be freed at transfer cleanup time */
-               if ((dev->driver->flags & COMEDI_DYNAMIC_DRV) != 0) {
-                       for (i = 0; i < tsf->nb_subd; i++)
-                               comedi_kfree(tsf->subds[i]);
-               }
-
-               /* Releases the pointers tab */
                comedi_kfree(tsf->subds);
        }
 
@@ -94,7 +86,6 @@ int comedi_setup_transfer(comedi_cxt_t * cxt)
 {
        comedi_dev_t *dev = NULL;
        comedi_trf_t *tsf;
-       comedi_drv_t *drv;
        comedi_subd_t *subd;
        struct list_head *this;
        int i = 0, ret = 0;
@@ -103,7 +94,6 @@ int comedi_setup_transfer(comedi_cxt_t * cxt)
                       comedi_get_minor(cxt));
 
        dev = comedi_get_dev(cxt);
-       drv = dev->driver;
 
        /* Allocates the main structure */
        tsf = comedi_kmalloc(sizeof(comedi_trf_t));
@@ -125,7 +115,7 @@ int comedi_setup_transfer(comedi_cxt_t * cxt)
 
        /* Recovers the subdevices count 
           (as they are registered in a linked list */
-       list_for_each(this, &drv->subdvsq) {
+       list_for_each(this, &dev->subdvsq) {
                tsf->nb_subd++;
        }
 
@@ -138,7 +128,7 @@ int comedi_setup_transfer(comedi_cxt_t * cxt)
        }
 
        /* Recovers the subdevices pointers */
-       list_for_each(this, &drv->subdvsq) {
+       list_for_each(this, &dev->subdvsq) {
                subd = list_entry(this, comedi_subd_t, list);
 
                if (subd->flags & COMEDI_SUBD_AI)
@@ -189,18 +179,6 @@ int comedi_setup_transfer(comedi_cxt_t * cxt)
        if (ret != 0)
                comedi_cleanup_transfer(cxt);
 
-       /* If the driver is dynamic, the subdevices are 
-          added during attachment; then there must be no 
-          subdevices in the list for the next attachment */
-       if ((drv->flags & COMEDI_DYNAMIC_DRV) != 0) {
-               while (&drv->subdvsq != drv->subdvsq.next) {
-                       this = drv->subdvsq.next;
-                       subd = list_entry(this, comedi_subd_t, list);
-                       list_del(this);
-                       comedi_kfree(subd);
-               }
-       }
-
        return ret;
 }
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to