|
@@ -2205,91 +2205,6 @@ static void comedi_cleanup_legacy_minors(void)
|
|
|
comedi_free_board_minor(i);
|
|
|
}
|
|
|
|
|
|
-static int __init comedi_init(void)
|
|
|
-{
|
|
|
- int i;
|
|
|
- int retval;
|
|
|
-
|
|
|
- pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n");
|
|
|
-
|
|
|
- if (comedi_num_legacy_minors < 0 ||
|
|
|
- comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
|
|
|
- pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
|
|
|
- COMEDI_NUM_BOARD_MINORS);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * comedi is unusable if both comedi_autoconfig and
|
|
|
- * comedi_num_legacy_minors are zero, so we might as well adjust the
|
|
|
- * defaults in that case
|
|
|
- */
|
|
|
- if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
|
|
|
- comedi_num_legacy_minors = 16;
|
|
|
-
|
|
|
- memset(comedi_file_info_table, 0,
|
|
|
- sizeof(struct comedi_file_info *) * COMEDI_NUM_MINORS);
|
|
|
-
|
|
|
- retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
- COMEDI_NUM_MINORS, "comedi");
|
|
|
- if (retval)
|
|
|
- return -EIO;
|
|
|
- cdev_init(&comedi_cdev, &comedi_fops);
|
|
|
- comedi_cdev.owner = THIS_MODULE;
|
|
|
- kobject_set_name(&comedi_cdev.kobj, "comedi");
|
|
|
- if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) {
|
|
|
- unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
- COMEDI_NUM_MINORS);
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- comedi_class = class_create(THIS_MODULE, "comedi");
|
|
|
- if (IS_ERR(comedi_class)) {
|
|
|
- pr_err("comedi: failed to create class\n");
|
|
|
- cdev_del(&comedi_cdev);
|
|
|
- unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
- COMEDI_NUM_MINORS);
|
|
|
- return PTR_ERR(comedi_class);
|
|
|
- }
|
|
|
-
|
|
|
- comedi_class->dev_attrs = comedi_dev_attrs;
|
|
|
-
|
|
|
- /* XXX requires /proc interface */
|
|
|
- comedi_proc_init();
|
|
|
-
|
|
|
- /* create devices files for legacy/manual use */
|
|
|
- for (i = 0; i < comedi_num_legacy_minors; i++) {
|
|
|
- int minor;
|
|
|
- minor = comedi_alloc_board_minor(NULL);
|
|
|
- if (minor < 0) {
|
|
|
- comedi_cleanup_legacy_minors();
|
|
|
- cdev_del(&comedi_cdev);
|
|
|
- unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
- COMEDI_NUM_MINORS);
|
|
|
- return minor;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static void __exit comedi_cleanup(void)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- comedi_cleanup_legacy_minors();
|
|
|
- for (i = 0; i < COMEDI_NUM_MINORS; ++i)
|
|
|
- BUG_ON(comedi_file_info_table[i]);
|
|
|
-
|
|
|
- class_destroy(comedi_class);
|
|
|
- cdev_del(&comedi_cdev);
|
|
|
- unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
|
|
|
-
|
|
|
- comedi_proc_cleanup();
|
|
|
-}
|
|
|
-
|
|
|
-module_init(comedi_init);
|
|
|
-module_exit(comedi_cleanup);
|
|
|
-
|
|
|
void comedi_error(const struct comedi_device *dev, const char *s)
|
|
|
{
|
|
|
dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s);
|
|
@@ -2512,6 +2427,90 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s)
|
|
|
kfree(info);
|
|
|
}
|
|
|
|
|
|
+static int __init comedi_init(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ int retval;
|
|
|
+
|
|
|
+ pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n");
|
|
|
+
|
|
|
+ if (comedi_num_legacy_minors < 0 ||
|
|
|
+ comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
|
|
|
+ pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
|
|
|
+ COMEDI_NUM_BOARD_MINORS);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * comedi is unusable if both comedi_autoconfig and
|
|
|
+ * comedi_num_legacy_minors are zero, so we might as well adjust the
|
|
|
+ * defaults in that case
|
|
|
+ */
|
|
|
+ if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
|
|
|
+ comedi_num_legacy_minors = 16;
|
|
|
+
|
|
|
+ memset(comedi_file_info_table, 0,
|
|
|
+ sizeof(struct comedi_file_info *) * COMEDI_NUM_MINORS);
|
|
|
+
|
|
|
+ retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
+ COMEDI_NUM_MINORS, "comedi");
|
|
|
+ if (retval)
|
|
|
+ return -EIO;
|
|
|
+ cdev_init(&comedi_cdev, &comedi_fops);
|
|
|
+ comedi_cdev.owner = THIS_MODULE;
|
|
|
+ kobject_set_name(&comedi_cdev.kobj, "comedi");
|
|
|
+ if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) {
|
|
|
+ unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
+ COMEDI_NUM_MINORS);
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+ comedi_class = class_create(THIS_MODULE, "comedi");
|
|
|
+ if (IS_ERR(comedi_class)) {
|
|
|
+ pr_err("comedi: failed to create class\n");
|
|
|
+ cdev_del(&comedi_cdev);
|
|
|
+ unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
+ COMEDI_NUM_MINORS);
|
|
|
+ return PTR_ERR(comedi_class);
|
|
|
+ }
|
|
|
+
|
|
|
+ comedi_class->dev_attrs = comedi_dev_attrs;
|
|
|
+
|
|
|
+ /* XXX requires /proc interface */
|
|
|
+ comedi_proc_init();
|
|
|
+
|
|
|
+ /* create devices files for legacy/manual use */
|
|
|
+ for (i = 0; i < comedi_num_legacy_minors; i++) {
|
|
|
+ int minor;
|
|
|
+ minor = comedi_alloc_board_minor(NULL);
|
|
|
+ if (minor < 0) {
|
|
|
+ comedi_cleanup_legacy_minors();
|
|
|
+ cdev_del(&comedi_cdev);
|
|
|
+ unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
|
|
|
+ COMEDI_NUM_MINORS);
|
|
|
+ return minor;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+module_init(comedi_init);
|
|
|
+
|
|
|
+static void __exit comedi_cleanup(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ comedi_cleanup_legacy_minors();
|
|
|
+ for (i = 0; i < COMEDI_NUM_MINORS; ++i)
|
|
|
+ BUG_ON(comedi_file_info_table[i]);
|
|
|
+
|
|
|
+ class_destroy(comedi_class);
|
|
|
+ cdev_del(&comedi_cdev);
|
|
|
+ unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
|
|
|
+
|
|
|
+ comedi_proc_cleanup();
|
|
|
+}
|
|
|
+module_exit(comedi_cleanup);
|
|
|
+
|
|
|
MODULE_AUTHOR("http://www.comedi.org");
|
|
|
MODULE_DESCRIPTION("Comedi core module");
|
|
|
MODULE_LICENSE("GPL");
|