2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
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.
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.
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/vmalloc.h>
15 #include <linux/uaccess.h>
16 #include <linux/module.h>
17 #include <linux/fcntl.h>
18 #include <linux/async.h>
19 #include <linux/ndctl.h>
20 #include <linux/sched.h>
21 #include <linux/slab.h>
30 static int nvdimm_bus_major
;
31 static struct class *nd_class
;
33 static int to_nd_device_type(struct device
*dev
)
36 return ND_DEVICE_DIMM
;
37 else if (is_nd_pmem(dev
))
38 return ND_DEVICE_REGION_PMEM
;
39 else if (is_nd_blk(dev
))
40 return ND_DEVICE_REGION_BLK
;
41 else if (is_nd_pmem(dev
->parent
) || is_nd_blk(dev
->parent
))
42 return nd_region_to_nstype(to_nd_region(dev
->parent
));
47 static int nvdimm_bus_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
49 return add_uevent_var(env
, "MODALIAS=" ND_DEVICE_MODALIAS_FMT
,
50 to_nd_device_type(dev
));
53 static int nvdimm_bus_match(struct device
*dev
, struct device_driver
*drv
)
55 struct nd_device_driver
*nd_drv
= to_nd_device_driver(drv
);
57 return test_bit(to_nd_device_type(dev
), &nd_drv
->type
);
60 static struct module
*to_bus_provider(struct device
*dev
)
62 /* pin bus providers while regions are enabled */
63 if (is_nd_pmem(dev
) || is_nd_blk(dev
)) {
64 struct nvdimm_bus
*nvdimm_bus
= walk_to_nvdimm_bus(dev
);
66 return nvdimm_bus
->module
;
71 static void nvdimm_bus_probe_start(struct nvdimm_bus
*nvdimm_bus
)
73 nvdimm_bus_lock(&nvdimm_bus
->dev
);
74 nvdimm_bus
->probe_active
++;
75 nvdimm_bus_unlock(&nvdimm_bus
->dev
);
78 static void nvdimm_bus_probe_end(struct nvdimm_bus
*nvdimm_bus
)
80 nvdimm_bus_lock(&nvdimm_bus
->dev
);
81 if (--nvdimm_bus
->probe_active
== 0)
82 wake_up(&nvdimm_bus
->probe_wait
);
83 nvdimm_bus_unlock(&nvdimm_bus
->dev
);
86 static int nvdimm_bus_probe(struct device
*dev
)
88 struct nd_device_driver
*nd_drv
= to_nd_device_driver(dev
->driver
);
89 struct module
*provider
= to_bus_provider(dev
);
90 struct nvdimm_bus
*nvdimm_bus
= walk_to_nvdimm_bus(dev
);
93 if (!try_module_get(provider
))
96 nvdimm_bus_probe_start(nvdimm_bus
);
97 rc
= nd_drv
->probe(dev
);
99 nd_region_probe_success(nvdimm_bus
, dev
);
101 nd_region_disable(nvdimm_bus
, dev
);
102 nvdimm_bus_probe_end(nvdimm_bus
);
104 dev_dbg(&nvdimm_bus
->dev
, "%s.probe(%s) = %d\n", dev
->driver
->name
,
107 module_put(provider
);
111 static int nvdimm_bus_remove(struct device
*dev
)
113 struct nd_device_driver
*nd_drv
= to_nd_device_driver(dev
->driver
);
114 struct module
*provider
= to_bus_provider(dev
);
115 struct nvdimm_bus
*nvdimm_bus
= walk_to_nvdimm_bus(dev
);
118 rc
= nd_drv
->remove(dev
);
119 nd_region_disable(nvdimm_bus
, dev
);
121 dev_dbg(&nvdimm_bus
->dev
, "%s.remove(%s) = %d\n", dev
->driver
->name
,
123 module_put(provider
);
127 static struct bus_type nvdimm_bus_type
= {
129 .uevent
= nvdimm_bus_uevent
,
130 .match
= nvdimm_bus_match
,
131 .probe
= nvdimm_bus_probe
,
132 .remove
= nvdimm_bus_remove
,
135 static ASYNC_DOMAIN_EXCLUSIVE(nd_async_domain
);
137 void nd_synchronize(void)
139 async_synchronize_full_domain(&nd_async_domain
);
141 EXPORT_SYMBOL_GPL(nd_synchronize
);
143 static void nd_async_device_register(void *d
, async_cookie_t cookie
)
145 struct device
*dev
= d
;
147 if (device_add(dev
) != 0) {
148 dev_err(dev
, "%s: failed\n", __func__
);
154 static void nd_async_device_unregister(void *d
, async_cookie_t cookie
)
156 struct device
*dev
= d
;
158 device_unregister(dev
);
162 void nd_device_register(struct device
*dev
)
164 dev
->bus
= &nvdimm_bus_type
;
165 device_initialize(dev
);
167 async_schedule_domain(nd_async_device_register
, dev
,
170 EXPORT_SYMBOL(nd_device_register
);
172 void nd_device_unregister(struct device
*dev
, enum nd_async_mode mode
)
177 async_schedule_domain(nd_async_device_unregister
, dev
,
182 device_unregister(dev
);
186 EXPORT_SYMBOL(nd_device_unregister
);
189 * __nd_driver_register() - register a region or a namespace driver
190 * @nd_drv: driver to register
191 * @owner: automatically set by nd_driver_register() macro
192 * @mod_name: automatically set by nd_driver_register() macro
194 int __nd_driver_register(struct nd_device_driver
*nd_drv
, struct module
*owner
,
195 const char *mod_name
)
197 struct device_driver
*drv
= &nd_drv
->drv
;
200 pr_debug("driver type bitmask not set (%pf)\n",
201 __builtin_return_address(0));
205 if (!nd_drv
->probe
|| !nd_drv
->remove
) {
206 pr_debug("->probe() and ->remove() must be specified\n");
210 drv
->bus
= &nvdimm_bus_type
;
212 drv
->mod_name
= mod_name
;
214 return driver_register(drv
);
216 EXPORT_SYMBOL(__nd_driver_register
);
218 static ssize_t
modalias_show(struct device
*dev
, struct device_attribute
*attr
,
221 return sprintf(buf
, ND_DEVICE_MODALIAS_FMT
"\n",
222 to_nd_device_type(dev
));
224 static DEVICE_ATTR_RO(modalias
);
226 static ssize_t
devtype_show(struct device
*dev
, struct device_attribute
*attr
,
229 return sprintf(buf
, "%s\n", dev
->type
->name
);
231 static DEVICE_ATTR_RO(devtype
);
233 static struct attribute
*nd_device_attributes
[] = {
234 &dev_attr_modalias
.attr
,
235 &dev_attr_devtype
.attr
,
240 * nd_device_attribute_group - generic attributes for all devices on an nd bus
242 struct attribute_group nd_device_attribute_group
= {
243 .attrs
= nd_device_attributes
,
245 EXPORT_SYMBOL_GPL(nd_device_attribute_group
);
247 int nvdimm_bus_create_ndctl(struct nvdimm_bus
*nvdimm_bus
)
249 dev_t devt
= MKDEV(nvdimm_bus_major
, nvdimm_bus
->id
);
252 dev
= device_create(nd_class
, &nvdimm_bus
->dev
, devt
, nvdimm_bus
,
253 "ndctl%d", nvdimm_bus
->id
);
256 dev_dbg(&nvdimm_bus
->dev
, "failed to register ndctl%d: %ld\n",
257 nvdimm_bus
->id
, PTR_ERR(dev
));
263 void nvdimm_bus_destroy_ndctl(struct nvdimm_bus
*nvdimm_bus
)
265 device_destroy(nd_class
, MKDEV(nvdimm_bus_major
, nvdimm_bus
->id
));
268 static const struct nd_cmd_desc __nd_cmd_dimm_descs
[] = {
269 [ND_CMD_IMPLEMENTED
] = { },
272 .out_sizes
= { 4, 8, },
274 [ND_CMD_SMART_THRESHOLD
] = {
276 .out_sizes
= { 4, 8, },
278 [ND_CMD_DIMM_FLAGS
] = {
280 .out_sizes
= { 4, 4 },
282 [ND_CMD_GET_CONFIG_SIZE
] = {
284 .out_sizes
= { 4, 4, 4, },
286 [ND_CMD_GET_CONFIG_DATA
] = {
288 .in_sizes
= { 4, 4, },
290 .out_sizes
= { 4, UINT_MAX
, },
292 [ND_CMD_SET_CONFIG_DATA
] = {
294 .in_sizes
= { 4, 4, UINT_MAX
, },
300 .in_sizes
= { 4, 4, UINT_MAX
, },
302 .out_sizes
= { 4, 4, UINT_MAX
, },
306 const struct nd_cmd_desc
*nd_cmd_dimm_desc(int cmd
)
308 if (cmd
< ARRAY_SIZE(__nd_cmd_dimm_descs
))
309 return &__nd_cmd_dimm_descs
[cmd
];
312 EXPORT_SYMBOL_GPL(nd_cmd_dimm_desc
);
314 static const struct nd_cmd_desc __nd_cmd_bus_descs
[] = {
315 [ND_CMD_IMPLEMENTED
] = { },
318 .in_sizes
= { 8, 8, },
320 .out_sizes
= { 4, 4, },
322 [ND_CMD_ARS_START
] = {
324 .in_sizes
= { 8, 8, 2, 6, },
328 [ND_CMD_ARS_STATUS
] = {
330 .out_sizes
= { 4, UINT_MAX
, },
334 const struct nd_cmd_desc
*nd_cmd_bus_desc(int cmd
)
336 if (cmd
< ARRAY_SIZE(__nd_cmd_bus_descs
))
337 return &__nd_cmd_bus_descs
[cmd
];
340 EXPORT_SYMBOL_GPL(nd_cmd_bus_desc
);
342 u32
nd_cmd_in_size(struct nvdimm
*nvdimm
, int cmd
,
343 const struct nd_cmd_desc
*desc
, int idx
, void *buf
)
345 if (idx
>= desc
->in_num
)
348 if (desc
->in_sizes
[idx
] < UINT_MAX
)
349 return desc
->in_sizes
[idx
];
351 if (nvdimm
&& cmd
== ND_CMD_SET_CONFIG_DATA
&& idx
== 2) {
352 struct nd_cmd_set_config_hdr
*hdr
= buf
;
354 return hdr
->in_length
;
355 } else if (nvdimm
&& cmd
== ND_CMD_VENDOR
&& idx
== 2) {
356 struct nd_cmd_vendor_hdr
*hdr
= buf
;
358 return hdr
->in_length
;
363 EXPORT_SYMBOL_GPL(nd_cmd_in_size
);
365 u32
nd_cmd_out_size(struct nvdimm
*nvdimm
, int cmd
,
366 const struct nd_cmd_desc
*desc
, int idx
, const u32
*in_field
,
367 const u32
*out_field
)
369 if (idx
>= desc
->out_num
)
372 if (desc
->out_sizes
[idx
] < UINT_MAX
)
373 return desc
->out_sizes
[idx
];
375 if (nvdimm
&& cmd
== ND_CMD_GET_CONFIG_DATA
&& idx
== 1)
377 else if (nvdimm
&& cmd
== ND_CMD_VENDOR
&& idx
== 2)
379 else if (!nvdimm
&& cmd
== ND_CMD_ARS_STATUS
&& idx
== 1)
380 return ND_CMD_ARS_STATUS_MAX
;
384 EXPORT_SYMBOL_GPL(nd_cmd_out_size
);
386 void wait_nvdimm_bus_probe_idle(struct device
*dev
)
388 struct nvdimm_bus
*nvdimm_bus
= walk_to_nvdimm_bus(dev
);
391 if (nvdimm_bus
->probe_active
== 0)
393 nvdimm_bus_unlock(&nvdimm_bus
->dev
);
394 wait_event(nvdimm_bus
->probe_wait
,
395 nvdimm_bus
->probe_active
== 0);
396 nvdimm_bus_lock(&nvdimm_bus
->dev
);
400 /* set_config requires an idle interleave set */
401 static int nd_cmd_clear_to_send(struct nvdimm
*nvdimm
, unsigned int cmd
)
403 struct nvdimm_bus
*nvdimm_bus
;
405 if (!nvdimm
|| cmd
!= ND_CMD_SET_CONFIG_DATA
)
408 nvdimm_bus
= walk_to_nvdimm_bus(&nvdimm
->dev
);
409 wait_nvdimm_bus_probe_idle(&nvdimm_bus
->dev
);
411 if (atomic_read(&nvdimm
->busy
))
416 static int __nd_ioctl(struct nvdimm_bus
*nvdimm_bus
, struct nvdimm
*nvdimm
,
417 int read_only
, unsigned int ioctl_cmd
, unsigned long arg
)
419 struct nvdimm_bus_descriptor
*nd_desc
= nvdimm_bus
->nd_desc
;
420 size_t buf_len
= 0, in_len
= 0, out_len
= 0;
421 static char out_env
[ND_CMD_MAX_ENVELOPE
];
422 static char in_env
[ND_CMD_MAX_ENVELOPE
];
423 const struct nd_cmd_desc
*desc
= NULL
;
424 unsigned int cmd
= _IOC_NR(ioctl_cmd
);
425 void __user
*p
= (void __user
*) arg
;
426 struct device
*dev
= &nvdimm_bus
->dev
;
427 const char *cmd_name
, *dimm_name
;
428 unsigned long dsm_mask
;
433 desc
= nd_cmd_dimm_desc(cmd
);
434 cmd_name
= nvdimm_cmd_name(cmd
);
435 dsm_mask
= nvdimm
->dsm_mask
? *(nvdimm
->dsm_mask
) : 0;
436 dimm_name
= dev_name(&nvdimm
->dev
);
438 desc
= nd_cmd_bus_desc(cmd
);
439 cmd_name
= nvdimm_bus_cmd_name(cmd
);
440 dsm_mask
= nd_desc
->dsm_mask
;
444 if (!desc
|| (desc
->out_num
+ desc
->in_num
== 0) ||
445 !test_bit(cmd
, &dsm_mask
))
448 /* fail write commands (when read-only) */
451 case ND_IOCTL_VENDOR
:
452 case ND_IOCTL_SET_CONFIG_DATA
:
453 case ND_IOCTL_ARS_START
:
454 dev_dbg(&nvdimm_bus
->dev
, "'%s' command while read-only.\n",
455 nvdimm
? nvdimm_cmd_name(cmd
)
456 : nvdimm_bus_cmd_name(cmd
));
462 /* process an input envelope */
463 for (i
= 0; i
< desc
->in_num
; i
++) {
466 in_size
= nd_cmd_in_size(nvdimm
, cmd
, desc
, i
, in_env
);
467 if (in_size
== UINT_MAX
) {
468 dev_err(dev
, "%s:%s unknown input size cmd: %s field: %d\n",
469 __func__
, dimm_name
, cmd_name
, i
);
472 if (!access_ok(VERIFY_READ
, p
+ in_len
, in_size
))
474 if (in_len
< sizeof(in_env
))
475 copy
= min_t(u32
, sizeof(in_env
) - in_len
, in_size
);
478 if (copy
&& copy_from_user(&in_env
[in_len
], p
+ in_len
, copy
))
483 /* process an output envelope */
484 for (i
= 0; i
< desc
->out_num
; i
++) {
485 u32 out_size
= nd_cmd_out_size(nvdimm
, cmd
, desc
, i
,
486 (u32
*) in_env
, (u32
*) out_env
);
489 if (out_size
== UINT_MAX
) {
490 dev_dbg(dev
, "%s:%s unknown output size cmd: %s field: %d\n",
491 __func__
, dimm_name
, cmd_name
, i
);
494 if (!access_ok(VERIFY_WRITE
, p
+ in_len
+ out_len
, out_size
))
496 if (out_len
< sizeof(out_env
))
497 copy
= min_t(u32
, sizeof(out_env
) - out_len
, out_size
);
500 if (copy
&& copy_from_user(&out_env
[out_len
],
501 p
+ in_len
+ out_len
, copy
))
506 buf_len
= out_len
+ in_len
;
507 if (!access_ok(VERIFY_WRITE
, p
, sizeof(buf_len
)))
510 if (buf_len
> ND_IOCTL_MAX_BUFLEN
) {
511 dev_dbg(dev
, "%s:%s cmd: %s buf_len: %zu > %d\n", __func__
,
512 dimm_name
, cmd_name
, buf_len
,
513 ND_IOCTL_MAX_BUFLEN
);
517 buf
= vmalloc(buf_len
);
521 if (copy_from_user(buf
, p
, buf_len
)) {
526 nvdimm_bus_lock(&nvdimm_bus
->dev
);
527 rc
= nd_cmd_clear_to_send(nvdimm
, cmd
);
531 rc
= nd_desc
->ndctl(nd_desc
, nvdimm
, cmd
, buf
, buf_len
);
534 if (copy_to_user(p
, buf
, buf_len
))
537 nvdimm_bus_unlock(&nvdimm_bus
->dev
);
543 static long nd_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
545 long id
= (long) file
->private_data
;
546 int rc
= -ENXIO
, read_only
;
547 struct nvdimm_bus
*nvdimm_bus
;
549 read_only
= (O_RDWR
!= (file
->f_flags
& O_ACCMODE
));
550 mutex_lock(&nvdimm_bus_list_mutex
);
551 list_for_each_entry(nvdimm_bus
, &nvdimm_bus_list
, list
) {
552 if (nvdimm_bus
->id
== id
) {
553 rc
= __nd_ioctl(nvdimm_bus
, NULL
, read_only
, cmd
, arg
);
557 mutex_unlock(&nvdimm_bus_list_mutex
);
562 static int match_dimm(struct device
*dev
, void *data
)
564 long id
= (long) data
;
566 if (is_nvdimm(dev
)) {
567 struct nvdimm
*nvdimm
= to_nvdimm(dev
);
569 return nvdimm
->id
== id
;
575 static long nvdimm_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
577 int rc
= -ENXIO
, read_only
;
578 struct nvdimm_bus
*nvdimm_bus
;
580 read_only
= (O_RDWR
!= (file
->f_flags
& O_ACCMODE
));
581 mutex_lock(&nvdimm_bus_list_mutex
);
582 list_for_each_entry(nvdimm_bus
, &nvdimm_bus_list
, list
) {
583 struct device
*dev
= device_find_child(&nvdimm_bus
->dev
,
584 file
->private_data
, match_dimm
);
585 struct nvdimm
*nvdimm
;
590 nvdimm
= to_nvdimm(dev
);
591 rc
= __nd_ioctl(nvdimm_bus
, nvdimm
, read_only
, cmd
, arg
);
595 mutex_unlock(&nvdimm_bus_list_mutex
);
600 static int nd_open(struct inode
*inode
, struct file
*file
)
602 long minor
= iminor(inode
);
604 file
->private_data
= (void *) minor
;
608 static const struct file_operations nvdimm_bus_fops
= {
609 .owner
= THIS_MODULE
,
611 .unlocked_ioctl
= nd_ioctl
,
612 .compat_ioctl
= nd_ioctl
,
613 .llseek
= noop_llseek
,
616 static const struct file_operations nvdimm_fops
= {
617 .owner
= THIS_MODULE
,
619 .unlocked_ioctl
= nvdimm_ioctl
,
620 .compat_ioctl
= nvdimm_ioctl
,
621 .llseek
= noop_llseek
,
624 int __init
nvdimm_bus_init(void)
628 rc
= bus_register(&nvdimm_bus_type
);
632 rc
= register_chrdev(0, "ndctl", &nvdimm_bus_fops
);
635 nvdimm_bus_major
= rc
;
637 rc
= register_chrdev(0, "dimmctl", &nvdimm_fops
);
639 goto err_dimm_chrdev
;
642 nd_class
= class_create(THIS_MODULE
, "nd");
643 if (IS_ERR(nd_class
))
649 unregister_chrdev(nvdimm_major
, "dimmctl");
651 unregister_chrdev(nvdimm_bus_major
, "ndctl");
653 bus_unregister(&nvdimm_bus_type
);
658 void nvdimm_bus_exit(void)
660 class_destroy(nd_class
);
661 unregister_chrdev(nvdimm_bus_major
, "ndctl");
662 unregister_chrdev(nvdimm_major
, "dimmctl");
663 bus_unregister(&nvdimm_bus_type
);