libnvdimm: control character device and nvdimm_bus sysfs attributes
[linux-2.6-block.git] / drivers / nvdimm / bus.c
1 /*
2  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  */
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/uaccess.h>
15 #include <linux/fcntl.h>
16 #include <linux/slab.h>
17 #include <linux/fs.h>
18 #include <linux/io.h>
19 #include "nd-core.h"
20
21 static int nvdimm_bus_major;
22 static struct class *nd_class;
23
24 int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus)
25 {
26         dev_t devt = MKDEV(nvdimm_bus_major, nvdimm_bus->id);
27         struct device *dev;
28
29         dev = device_create(nd_class, &nvdimm_bus->dev, devt, nvdimm_bus,
30                         "ndctl%d", nvdimm_bus->id);
31
32         if (IS_ERR(dev)) {
33                 dev_dbg(&nvdimm_bus->dev, "failed to register ndctl%d: %ld\n",
34                                 nvdimm_bus->id, PTR_ERR(dev));
35                 return PTR_ERR(dev);
36         }
37         return 0;
38 }
39
40 void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus)
41 {
42         device_destroy(nd_class, MKDEV(nvdimm_bus_major, nvdimm_bus->id));
43 }
44
45 static long nd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
46 {
47         return -ENXIO;
48 }
49
50 static const struct file_operations nvdimm_bus_fops = {
51         .owner = THIS_MODULE,
52         .open = nonseekable_open,
53         .unlocked_ioctl = nd_ioctl,
54         .compat_ioctl = nd_ioctl,
55         .llseek = noop_llseek,
56 };
57
58 int __init nvdimm_bus_init(void)
59 {
60         int rc;
61
62         rc = register_chrdev(0, "ndctl", &nvdimm_bus_fops);
63         if (rc < 0)
64                 return rc;
65         nvdimm_bus_major = rc;
66
67         nd_class = class_create(THIS_MODULE, "nd");
68         if (IS_ERR(nd_class))
69                 goto err_class;
70
71         return 0;
72
73  err_class:
74         unregister_chrdev(nvdimm_bus_major, "ndctl");
75
76         return rc;
77 }
78
79 void __exit nvdimm_bus_exit(void)
80 {
81         class_destroy(nd_class);
82         unregister_chrdev(nvdimm_bus_major, "ndctl");
83 }