added replacement for recognize that can report valid board names
authorFrank Mori Hess <fmhess@speakeasy.net>
Sun, 28 Jan 2001 20:46:16 +0000 (20:46 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sun, 28 Jan 2001 20:46:16 +0000 (20:46 +0000)
comedi/drivers.c
comedi/drivers/das800.c
comedi/drivers/skel.c
include/linux/comedidev.h

index c6cc7cc8b405e0c05727de0c0770c8df58d0942c..ee4231bb6e6439de36a93354138eb1589e7dd1d0 100644 (file)
@@ -46,6 +46,8 @@ static int insn_emulate_bits(comedi_device *dev,comedi_subdevice *s,
 static int insn_inval(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
 static int mode0_emulate(comedi_device *dev,comedi_subdevice *s,comedi_trig *trig);
 static int mode0_emulate_config(comedi_device *dev,comedi_subdevice *s,comedi_trig *trig);
+static int comedi_recognize(comedi_driver *driv, const char *name);
+static void comedi_report_boards(comedi_driver *driv);
 
 comedi_driver *comedi_drivers;
 
@@ -106,7 +108,10 @@ int comedi_device_attach(comedi_device *dev,comedi_devconfig *it)
        dev->write_subdev=-1;
 
        for(driv=comedi_drivers;driv;driv=driv->next){
-               if(driv->recognize){
+               if(driv->register_boards && driv->num_boards){
+                       i=comedi_recognize(driv, it->board_name);
+                       if(i < 0) continue;
+               }else if(driv->recognize){
                        i=driv->recognize(it->board_name);
                        if(i<0)continue;
                }else{
@@ -125,6 +130,11 @@ int comedi_device_attach(comedi_device *dev,comedi_devconfig *it)
                goto attached;
        }
 
+       // recognize has failed if we get here
+       // report valid board names before returning error
+       for(driv=comedi_drivers;driv;driv=driv->next){
+               comedi_report_boards(driv);
+       }
        return -EIO;
 
 attached:
@@ -150,9 +160,21 @@ attached:
 
 int comedi_driver_register(comedi_driver *driver)
 {
+       int ret;
+
        driver->next=comedi_drivers;
        comedi_drivers=driver;
 
+       if(driver->register_boards)
+       {
+               ret = driver->register_boards();
+               if(ret < 0)
+               {
+                       DPRINTK("failed to register supported board names\n");
+                       driver->num_boards = 0;
+               }
+       }
+
        return 0;
 }
 
@@ -173,6 +195,14 @@ int comedi_driver_unregister(comedi_driver *driver)
                }
        }
 
+       // deallocate arrays
+       if(driver->board_name){
+               kfree(driver->board_name);
+       }
+       if(driver->board_id){
+               kfree(driver->board_id);
+       }
+
        if(comedi_drivers==driver){
                comedi_drivers=driver->next;
                return 0;
@@ -291,6 +321,35 @@ static void postconfig(comedi_device *dev)
 
 }
 
+// generic recognize function for drivers that register their supported board names
+int comedi_recognize(comedi_driver *driv, const char *name)
+{
+       unsigned int i = 0;
+
+       for(i = 0; i < driv->num_boards; i++)
+       {
+               if(strcmp(driv->board_name[i], name) == 0)
+                       return driv->board_id[i];
+       }
+
+       return -1;
+}
+
+void comedi_report_boards(comedi_driver *driv)
+{
+       unsigned int i;
+
+       if(driv->num_boards == 0) return;
+
+       printk("comedi: valid board names for %s driver are:\n", driv->driver_name);
+       for(i = 0; i < driv->num_boards; i++)
+       {
+               printk(" %s\n", driv->board_name[i]);
+       }
+
+       return;
+}
+
 /* helper functions for drivers */
 
 int di_unpack(unsigned int bits,comedi_trig *it)
index 416c7070e6791a45f96e8de9005e30f35d9f6423..5d94515dbbce3c9cfc7a1dda36c869655704489c 100644 (file)
@@ -101,6 +101,7 @@ NOTES:
 
 typedef struct das800_board_struct{
        char *name;
+       int id;
        int ai_speed;
 }das800_board;
 
@@ -110,26 +111,32 @@ das800_board das800_boards[] =
 {
        {
                name:   "das-800",
+               id:     das800,
                ai_speed:       25000,
        },
        {
                name:   "cio-das800",
+               id:     ciodas800,
                ai_speed:       20000,
        },
        {
                name:           "das-801",
+               id:     das801,
                ai_speed:       25000,
        },
        {
                name:   "cio-das801",
+               id:     ciodas801,
                ai_speed:       20000,
        },
        {
                name:           "das-802",
+               id:     das802,
                ai_speed:       25000,
        },
        {
                name:   "cio-das802",
+               id:     ciodas802,
                ai_speed:       20000,
        },
 };
@@ -213,6 +220,7 @@ static comedi_lrange *das800_range_lkup[] = {
 static int das800_attach(comedi_device *dev,comedi_devconfig *it);
 static int das800_detach(comedi_device *dev);
 static int das800_recognize(char *name);
+static int das800_register_boards(void);
 static int das800_cancel(comedi_device *dev, comedi_subdevice *s);
 
 comedi_driver driver_das800={
@@ -221,6 +229,7 @@ comedi_driver driver_das800={
        attach:         das800_attach,
        detach:         das800_detach,
        recognize:              das800_recognize,
+       register_boards:                das800_register_boards,
 };
 
 static void das800_interrupt(int irq, void *d, struct pt_regs *regs);
@@ -237,6 +246,37 @@ int das800_probe(comedi_device *dev);
 int das800_set_frequency(comedi_device *dev);
 int das800_load_counter(unsigned int counterNumber, unsigned int counterValue, comedi_device *dev);
 
+static int das800_register_boards(void)
+{
+       unsigned int i;
+       unsigned int num_boards = sizeof(das800_boards) / sizeof(das800_boards[0]);
+       char **board_name;
+       int *board_id;
+
+       board_name = kmalloc(num_boards * sizeof(char*), GFP_KERNEL);
+       if(board_name == NULL)
+               return -ENOMEM;
+
+       board_id = kmalloc(num_boards * sizeof(int), GFP_KERNEL);
+       if(board_id == NULL)
+       {
+               kfree(board_name);
+               return -ENOMEM;
+       }
+
+       for(i = 0; i < num_boards; i++)
+       {
+               board_name[i] = das800_boards[i].name;
+               board_id[i] = das800_boards[i].id;
+       }
+
+       driver_das800.num_boards = num_boards;
+       driver_das800.board_name = board_name;
+       driver_das800.board_id = board_id;
+
+       return 0;
+}
+
 static int das800_recognize(char *name)
 {
        if(!strcmp(name, "das-800") || !strcmp(name, "das800"))
@@ -417,6 +457,13 @@ static int das800_attach(comedi_device *dev, comedi_devconfig *it)
        }
        printk("\n");
 
+       dev->board = das800_probe(dev);
+       if(dev->board < 0)
+       {
+               printk("unable to determine board type\n");
+               return -ENODEV;
+       }
+
        if(iobase == 0)
        {
                printk("io base address required for das800\n");
@@ -449,13 +496,6 @@ static int das800_attach(comedi_device *dev, comedi_devconfig *it)
        }
        dev->irq = irq;
 
-       dev->board = das800_probe(dev);
-       if(dev->board < 0)
-       {
-               printk("unable to determine board type\n");
-               return -ENODEV;
-       }
-
        dev->board_ptr = das800_boards + dev->board;
        dev->board_name = thisboard->name;
 
@@ -815,11 +855,9 @@ static int das800_di_rbits(comedi_device *dev, comedi_subdevice *s, comedi_insn
 
 static int das800_do_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
 {
-       int mux_bits;
        int chan = CR_CHAN(insn->chanspec);
        unsigned long irq_flags;
 
-       mux_bits = inb(dev->iobase + DAS800_STATUS) & 0x7;
        // set channel to 1
        if(data[0])
                devpriv->do_bits |= (1 << (chan + 4)) & 0xf0;
@@ -829,7 +867,7 @@ static int das800_do_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn
 
        comedi_spin_lock_irqsave(&devpriv->spinlock, irq_flags);
        outb(CONTROL1, dev->iobase + DAS800_GAIN);      /* select dev->iobase + 2 to be control register 1 */
-       outb(devpriv->do_bits | CONTROL1_INTE | mux_bits, dev->iobase + DAS800_CONTROL1);
+       outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
        comedi_spin_unlock_irqrestore(&devpriv->spinlock, irq_flags);
 
        return 1;
@@ -837,11 +875,9 @@ static int das800_do_winsn(comedi_device *dev, comedi_subdevice *s, comedi_insn
 
 static int das800_do_wbits(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
 {
-       int mux_bits;
        int wbits;
        unsigned long irq_flags;
 
-       mux_bits = inb(dev->iobase + DAS800_STATUS) & 0x7;
 
        // only set bits that have been masked
        data[0] &= 0xf;
@@ -852,7 +888,7 @@ static int das800_do_wbits(comedi_device *dev, comedi_subdevice *s, comedi_insn
 
        comedi_spin_lock_irqsave(&devpriv->spinlock, irq_flags);
        outb(CONTROL1, dev->iobase + DAS800_GAIN);      /* select dev->iobase + 2 to be control register 1 */
-       outb(devpriv->do_bits | CONTROL1_INTE | mux_bits, dev->iobase + DAS800_CONTROL1);
+       outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
        comedi_spin_unlock_irqrestore(&devpriv->spinlock, irq_flags);
 
        data[1] = wbits;
index b059011a2065ffe0556c5c1dfa22ecc1573ebda8..0fedfa11759fb449899dcb3a5f3c8b13563ca3f1 100644 (file)
@@ -97,13 +97,15 @@ typedef struct{
  */
 static int skel_attach(comedi_device *dev,comedi_devconfig *it);
 static int skel_detach(comedi_device *dev);
-static int skel_recognize(char *name);
+//static int skel_recognize(char *name);
+static int skel_register_boards(void);
 comedi_driver driver_skel={
        driver_name:    "dummy",
        module:         THIS_MODULE,
        attach:         skel_attach,
        detach:         skel_detach,
-       recognize:      skel_recognize,
+//     recognize:      skel_recognize,
+       register_boards:        skel_register_boards,   // replacement for recognize
 };
 
 static int skel_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
@@ -119,6 +121,8 @@ static int skel_ns_to_timer(unsigned int *ns,int round);
  * driver can service, then a non-negative index should be returned.
  * This index is put into dev->board, and then _attach() is called.
  */
+
+/*
 static int skel_recognize(char *name)
 {
        if(!strcmp("skel-100",name))return 0;
@@ -126,6 +130,46 @@ static int skel_recognize(char *name)
 
        return -1;
 }
+*/
+
+/* The function register_boards() is a replacement for recognize
+ * that allows comedi to report back valid board names when it doesn't
+ * recognize a board name.  The job of register_boards is to
+ * initialize the board_name, board_id and num_boards members of
+ * the the comedi_driver_struct for this driver.  The arrays
+ * don't need to be deallocated as that is done in
+ * comedi_driver_unregister() in the drivers.c file
+ */
+static int skel_register_boards(void)
+{
+       unsigned int i;
+       unsigned int num_boards = sizeof(skel_boards) / sizeof(skel_board);
+       char **board_name;
+       int *board_id;
+
+       board_name = kmalloc(num_boards * sizeof(char*), GFP_KERNEL);
+       if(board_name == NULL)
+               return -ENOMEM;
+
+       board_id = kmalloc(num_boards * sizeof(int), GFP_KERNEL);
+       if(board_id == NULL)
+       {
+               kfree(board_name);
+               return -ENOMEM;
+       }
+
+       for(i = 0; i < num_boards; i++)
+       {
+               board_name[i] = skel_boards[i].name;
+               board_id[i] = i;
+       }
+
+       driver_skel.num_boards = num_boards;
+       driver_skel.board_name = board_name;
+       driver_skel.board_id = board_id;
+
+       return 0;
+}
 
 /*
  * Attach is called by the Comedi core to configure the driver
@@ -205,6 +249,8 @@ static int skel_attach(comedi_device *dev,comedi_devconfig *it)
                s->type = COMEDI_SUBD_UNUSED;
        }
        
+       printk("attached\n");
+
        return 1;
 }
 
index a40207c0322341861646a01982c24146c07bf6af..59b444153e4daeecb99d75433c629ec2c6a2e371 100644 (file)
@@ -131,6 +131,15 @@ struct comedi_driver_struct{
        int (*attach)(comedi_device *,comedi_devconfig *);
        int (*detach)(comedi_device *);
        int (*recognize)(char *name);
+
+       /* register_boards, board_name, board_id, num_boards provide alternative
+        * to recognize which allows reporting back to user recognized board
+        * names
+        */
+       int (*register_boards)(void);   // initializes board_name and board_id arrays
+       char **board_name;
+       int *board_id;
+       unsigned int num_boards;        // number of elements in board_name and board_id arrays
 };
 
 struct comedi_device_struct{