From 47c5dd89c30af5e574b63a8a168133becf61f286 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Sun, 28 Jan 2001 20:46:16 +0000 Subject: [PATCH] added replacement for recognize that can report valid board names --- comedi/drivers.c | 61 +++++++++++++++++++++++++++++++++++++- comedi/drivers/das800.c | 62 +++++++++++++++++++++++++++++++-------- comedi/drivers/skel.c | 50 +++++++++++++++++++++++++++++-- include/linux/comedidev.h | 9 ++++++ 4 files changed, 166 insertions(+), 16 deletions(-) diff --git a/comedi/drivers.c b/comedi/drivers.c index c6cc7cc8..ee4231bb 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -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) diff --git a/comedi/drivers/das800.c b/comedi/drivers/das800.c index 416c7070..5d94515d 100644 --- a/comedi/drivers/das800.c +++ b/comedi/drivers/das800.c @@ -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; diff --git a/comedi/drivers/skel.c b/comedi/drivers/skel.c index b059011a..0fedfa11 100644 --- a/comedi/drivers/skel.c +++ b/comedi/drivers/skel.c @@ -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; } diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index a40207c0..59b44415 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -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{ -- 2.26.2