|
@@ -57,11 +57,13 @@
|
|
#include "device.h"
|
|
#include "device.h"
|
|
|
|
|
|
static struct class *class;
|
|
static struct class *class;
|
|
|
|
+static struct class *user_class;
|
|
static dev_t hfi1_dev;
|
|
static dev_t hfi1_dev;
|
|
|
|
|
|
int hfi1_cdev_init(int minor, const char *name,
|
|
int hfi1_cdev_init(int minor, const char *name,
|
|
const struct file_operations *fops,
|
|
const struct file_operations *fops,
|
|
- struct cdev *cdev, struct device **devp)
|
|
|
|
|
|
+ struct cdev *cdev, struct device **devp,
|
|
|
|
+ bool user_accessible)
|
|
{
|
|
{
|
|
const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor);
|
|
const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor);
|
|
struct device *device = NULL;
|
|
struct device *device = NULL;
|
|
@@ -78,7 +80,11 @@ int hfi1_cdev_init(int minor, const char *name,
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
|
|
- device = device_create(class, NULL, dev, NULL, "%s", name);
|
|
|
|
|
|
+ if (user_accessible)
|
|
|
|
+ device = device_create(user_class, NULL, dev, NULL, "%s", name);
|
|
|
|
+ else
|
|
|
|
+ device = device_create(class, NULL, dev, NULL, "%s", name);
|
|
|
|
+
|
|
if (!IS_ERR(device))
|
|
if (!IS_ERR(device))
|
|
goto done;
|
|
goto done;
|
|
ret = PTR_ERR(device);
|
|
ret = PTR_ERR(device);
|
|
@@ -110,6 +116,26 @@ const char *class_name(void)
|
|
return hfi1_class_name;
|
|
return hfi1_class_name;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static char *hfi1_devnode(struct device *dev, umode_t *mode)
|
|
|
|
+{
|
|
|
|
+ if (mode)
|
|
|
|
+ *mode = 0600;
|
|
|
|
+ return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const char *hfi1_class_name_user = "hfi1_user";
|
|
|
|
+const char *class_name_user(void)
|
|
|
|
+{
|
|
|
|
+ return hfi1_class_name_user;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static char *hfi1_user_devnode(struct device *dev, umode_t *mode)
|
|
|
|
+{
|
|
|
|
+ if (mode)
|
|
|
|
+ *mode = 0666;
|
|
|
|
+ return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
|
|
|
|
+}
|
|
|
|
+
|
|
int __init dev_init(void)
|
|
int __init dev_init(void)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
@@ -125,7 +151,22 @@ int __init dev_init(void)
|
|
ret = PTR_ERR(class);
|
|
ret = PTR_ERR(class);
|
|
pr_err("Could not create device class (err %d)\n", -ret);
|
|
pr_err("Could not create device class (err %d)\n", -ret);
|
|
unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
|
|
unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
|
|
|
|
+ goto done;
|
|
}
|
|
}
|
|
|
|
+ class->devnode = hfi1_devnode;
|
|
|
|
+
|
|
|
|
+ user_class = class_create(THIS_MODULE, class_name_user());
|
|
|
|
+ if (IS_ERR(user_class)) {
|
|
|
|
+ ret = PTR_ERR(user_class);
|
|
|
|
+ pr_err("Could not create device class for user accessible files (err %d)\n",
|
|
|
|
+ -ret);
|
|
|
|
+ class_destroy(class);
|
|
|
|
+ class = NULL;
|
|
|
|
+ user_class = NULL;
|
|
|
|
+ unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
|
|
|
|
+ goto done;
|
|
|
|
+ }
|
|
|
|
+ user_class->devnode = hfi1_user_devnode;
|
|
|
|
|
|
done:
|
|
done:
|
|
return ret;
|
|
return ret;
|
|
@@ -133,10 +174,11 @@ done:
|
|
|
|
|
|
void dev_cleanup(void)
|
|
void dev_cleanup(void)
|
|
{
|
|
{
|
|
- if (class) {
|
|
|
|
- class_destroy(class);
|
|
|
|
- class = NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ class_destroy(class);
|
|
|
|
+ class = NULL;
|
|
|
|
+
|
|
|
|
+ class_destroy(user_class);
|
|
|
|
+ user_class = NULL;
|
|
|
|
|
|
unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
|
|
unregister_chrdev_region(hfi1_dev, HFI1_NMINORS);
|
|
}
|
|
}
|