driver->next=comedi_drivers;
comedi_drivers=driver;
- if(driver->register_boards)
+ if(driver->register_boards && driver->num_boards)
{
- ret = driver->register_boards();
- if(ret < 0)
+ driver->board_name = kmalloc(driver->num_boards * sizeof(char*), GFP_KERNEL);
+ if(driver->board_name == NULL)
{
- DPRINTK("failed to register supported board names\n");
- driver->num_boards = 0;
+ printk(KERN_ERR "comedi: memory allocation failure.\n");
+ ret = -ENOMEM;
+ goto cleanup;
}
+ driver->board_id = kmalloc(driver->num_boards * sizeof(int), GFP_KERNEL);
+ if(driver->board_id == NULL)
+ {
+ printk(KERN_ERR "comedi: memory allocation failure.\n");
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ driver->register_boards();
}
return 0;
+
+cleanup:
+
+ // deallocate arrays
+ if(driver->board_name){
+ kfree(driver->board_name);
+ }
+ if(driver->board_id){
+ kfree(driver->board_id);
+ }
+
+ comedi_drivers = driver->next;
+
+ return ret;
}
int comedi_driver_unregister(comedi_driver *driver)
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 void das800_register_boards(void);
static int das800_cancel(comedi_device *dev, comedi_subdevice *s);
comedi_driver driver_das800={
detach: das800_detach,
recognize: das800_recognize,
register_boards: das800_register_boards,
+ num_boards: sizeof(das800_boards) / sizeof(das800_board),
};
static void das800_interrupt(int irq, void *d, struct pt_regs *regs);
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)
+static void 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)
+ for(i = 0; i < driver_das800.num_boards; i++)
{
- kfree(board_name);
- return -ENOMEM;
+ driver_das800.board_name[i] = das800_boards[i].name;
+ driver_das800.board_id[i] = i;
}
- for(i = 0; i < num_boards; i++)
- {
- board_name[i] = das800_boards[i].name;
- board_id[i] = i;
- }
-
- driver_das800.num_boards = num_boards;
- driver_das800.board_name = board_name;
- driver_das800.board_id = board_id;
-
- return 0;
+ return;
}
static int das800_recognize(char *name)
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_register_boards(void);
+static void skel_register_boards(void);
comedi_driver driver_skel={
driver_name: "dummy",
module: THIS_MODULE,
detach: skel_detach,
// recognize: skel_recognize,
register_boards: skel_register_boards, // replacement for recognize
+ /* comedi uses num_boards to allocate the board_name and board_id members
+ * of this struct
+ */
+ num_boards: sizeof(skel_boards) / sizeof(skel_board),
};
static int skel_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
/* 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
+ * initialize the board_name and board_id 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
+ * will have already been allocated with num_boards elements
+ * (your driver must initialize the num_boards member of your
+ * comedi_driver struct)
+ * by comedi_driver_register() in the drivers.c file.
*/
-static int skel_register_boards(void)
+static void 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++)
+ for(i = 0; i < driver_skel.num_boards; i++)
{
- board_name[i] = skel_boards[i].name;
- board_id[i] = i;
+ driver_skel.board_name[i] = skel_boards[i].name;
+ driver_skel.board_id[i] = i;
}
- driver_skel.num_boards = num_boards;
- driver_skel.board_name = board_name;
- driver_skel.board_id = board_id;
-
- return 0;
+ return;
}
/*
#ifdef MODULE
#define COMEDI_INITCLEANUP(x) \
- int init_module(void){comedi_driver_register(&(x));return 0;} \
+ int init_module(void){return comedi_driver_register(&(x));} \
void cleanup_module(void){comedi_driver_unregister(&(x));}
#else
#define COMEDI_INITCLEANUP(x)
* to recognize which allows reporting back to user recognized board
* names
*/
- int (*register_boards)(void); // initializes board_name and board_id arrays
+ void (*register_boards)(void); // initializes board_name and board_id arrays
+ // number of elements in board_name and board_id arrays
+ unsigned int num_boards;
+ /* board_name and board_id arrays are allocated by comedi_driver_register()
+ * using the value of num_boards for the number of elements
+ */
char **board_name;
int *board_id;
- unsigned int num_boards; // number of elements in board_name and board_id arrays
};
struct comedi_device_struct{