linux/drivers/nvdimm/bus.c
<<
>>
Prefs
   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/vmalloc.h>
  15#include <linux/uaccess.h>
  16#include <linux/module.h>
  17#include <linux/blkdev.h>
  18#include <linux/fcntl.h>
  19#include <linux/async.h>
  20#include <linux/genhd.h>
  21#include <linux/ndctl.h>
  22#include <linux/sched.h>
  23#include <linux/slab.h>
  24#include <linux/fs.h>
  25#include <linux/io.h>
  26#include <linux/mm.h>
  27#include <linux/nd.h>
  28#include "nd-core.h"
  29#include "nd.h"
  30
  31int nvdimm_major;
  32static int nvdimm_bus_major;
  33static struct class *nd_class;
  34
  35static int to_nd_device_type(struct device *dev)
  36{
  37        if (is_nvdimm(dev))
  38                return ND_DEVICE_DIMM;
  39        else if (is_nd_pmem(dev))
  40                return ND_DEVICE_REGION_PMEM;
  41        else if (is_nd_blk(dev))
  42                return ND_DEVICE_REGION_BLK;
  43        else if (is_nd_pmem(dev->parent) || is_nd_blk(dev->parent))
  44                return nd_region_to_nstype(to_nd_region(dev->parent));
  45
  46        return 0;
  47}
  48
  49static int nvdimm_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
  50{
  51        /*
  52         * Ensure that region devices always have their numa node set as
  53         * early as possible.
  54         */
  55        if (is_nd_pmem(dev) || is_nd_blk(dev))
  56                set_dev_node(dev, to_nd_region(dev)->numa_node);
  57        return add_uevent_var(env, "MODALIAS=" ND_DEVICE_MODALIAS_FMT,
  58                        to_nd_device_type(dev));
  59}
  60
  61static int nvdimm_bus_match(struct device *dev, struct device_driver *drv)
  62{
  63        struct nd_device_driver *nd_drv = to_nd_device_driver(drv);
  64
  65        return test_bit(to_nd_device_type(dev), &nd_drv->type);
  66}
  67
  68static struct module *to_bus_provider(struct device *dev)
  69{
  70        /* pin bus providers while regions are enabled */
  71        if (is_nd_pmem(dev) || is_nd_blk(dev)) {
  72                struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
  73
  74                return nvdimm_bus->module;
  75        }
  76        return NULL;
  77}
  78
  79static void nvdimm_bus_probe_start(struct nvdimm_bus *nvdimm_bus)
  80{
  81        nvdimm_bus_lock(&nvdimm_bus->dev);
  82        nvdimm_bus->probe_active++;
  83        nvdimm_bus_unlock(&nvdimm_bus->dev);
  84}
  85
  86static void nvdimm_bus_probe_end(struct nvdimm_bus *nvdimm_bus)
  87{
  88        nvdimm_bus_lock(&nvdimm_bus->dev);
  89        if (--nvdimm_bus->probe_active == 0)
  90                wake_up(&nvdimm_bus->probe_wait);
  91        nvdimm_bus_unlock(&nvdimm_bus->dev);
  92}
  93
  94static int nvdimm_bus_probe(struct device *dev)
  95{
  96        struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
  97        struct module *provider = to_bus_provider(dev);
  98        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
  99        int rc;
 100
 101        if (!try_module_get(provider))
 102                return -ENXIO;
 103
 104        nvdimm_bus_probe_start(nvdimm_bus);
 105        rc = nd_drv->probe(dev);
 106        if (rc == 0)
 107                nd_region_probe_success(nvdimm_bus, dev);
 108        else
 109                nd_region_disable(nvdimm_bus, dev);
 110        nvdimm_bus_probe_end(nvdimm_bus);
 111
 112        dev_dbg(&nvdimm_bus->dev, "%s.probe(%s) = %d\n", dev->driver->name,
 113                        dev_name(dev), rc);
 114
 115        if (rc != 0)
 116                module_put(provider);
 117        return rc;
 118}
 119
 120static int nvdimm_bus_remove(struct device *dev)
 121{
 122        struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
 123        struct module *provider = to_bus_provider(dev);
 124        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
 125        int rc;
 126
 127        rc = nd_drv->remove(dev);
 128        nd_region_disable(nvdimm_bus, dev);
 129
 130        dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name,
 131                        dev_name(dev), rc);
 132        module_put(provider);
 133        return rc;
 134}
 135
 136static struct bus_type nvdimm_bus_type = {
 137        .name = "nd",
 138        .uevent = nvdimm_bus_uevent,
 139        .match = nvdimm_bus_match,
 140        .probe = nvdimm_bus_probe,
 141        .remove = nvdimm_bus_remove,
 142};
 143
 144static ASYNC_DOMAIN_EXCLUSIVE(nd_async_domain);
 145
 146void nd_synchronize(void)
 147{
 148        async_synchronize_full_domain(&nd_async_domain);
 149}
 150EXPORT_SYMBOL_GPL(nd_synchronize);
 151
 152static void nd_async_device_register(void *d, async_cookie_t cookie)
 153{
 154        struct device *dev = d;
 155
 156        if (device_add(dev) != 0) {
 157                dev_err(dev, "%s: failed\n", __func__);
 158                put_device(dev);
 159        }
 160        put_device(dev);
 161}
 162
 163static void nd_async_device_unregister(void *d, async_cookie_t cookie)
 164{
 165        struct device *dev = d;
 166
 167        /* flush bus operations before delete */
 168        nvdimm_bus_lock(dev);
 169        nvdimm_bus_unlock(dev);
 170
 171        device_unregister(dev);
 172        put_device(dev);
 173}
 174
 175void __nd_device_register(struct device *dev)
 176{
 177        dev->bus = &nvdimm_bus_type;
 178        get_device(dev);
 179        async_schedule_domain(nd_async_device_register, dev,
 180                        &nd_async_domain);
 181}
 182
 183void nd_device_register(struct device *dev)
 184{
 185        device_initialize(dev);
 186        __nd_device_register(dev);
 187}
 188EXPORT_SYMBOL(nd_device_register);
 189
 190void nd_device_unregister(struct device *dev, enum nd_async_mode mode)
 191{
 192        switch (mode) {
 193        case ND_ASYNC:
 194                get_device(dev);
 195                async_schedule_domain(nd_async_device_unregister, dev,
 196                                &nd_async_domain);
 197                break;
 198        case ND_SYNC:
 199                nd_synchronize();
 200                device_unregister(dev);
 201                break;
 202        }
 203}
 204EXPORT_SYMBOL(nd_device_unregister);
 205
 206/**
 207 * __nd_driver_register() - register a region or a namespace driver
 208 * @nd_drv: driver to register
 209 * @owner: automatically set by nd_driver_register() macro
 210 * @mod_name: automatically set by nd_driver_register() macro
 211 */
 212int __nd_driver_register(struct nd_device_driver *nd_drv, struct module *owner,
 213                const char *mod_name)
 214{
 215        struct device_driver *drv = &nd_drv->drv;
 216
 217        if (!nd_drv->type) {
 218                pr_debug("driver type bitmask not set (%pf)\n",
 219                                __builtin_return_address(0));
 220                return -EINVAL;
 221        }
 222
 223        if (!nd_drv->probe || !nd_drv->remove) {
 224                pr_debug("->probe() and ->remove() must be specified\n");
 225                return -EINVAL;
 226        }
 227
 228        drv->bus = &nvdimm_bus_type;
 229        drv->owner = owner;
 230        drv->mod_name = mod_name;
 231
 232        return driver_register(drv);
 233}
 234EXPORT_SYMBOL(__nd_driver_register);
 235
 236int nvdimm_revalidate_disk(struct gendisk *disk)
 237{
 238        struct device *dev = disk->driverfs_dev;
 239        struct nd_region *nd_region = to_nd_region(dev->parent);
 240        const char *pol = nd_region->ro ? "only" : "write";
 241
 242        if (nd_region->ro == get_disk_ro(disk))
 243                return 0;
 244
 245        dev_info(dev, "%s read-%s, marking %s read-%s\n",
 246                        dev_name(&nd_region->dev), pol, disk->disk_name, pol);
 247        set_disk_ro(disk, nd_region->ro);
 248
 249        return 0;
 250
 251}
 252EXPORT_SYMBOL(nvdimm_revalidate_disk);
 253
 254static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 255                char *buf)
 256{
 257        return sprintf(buf, ND_DEVICE_MODALIAS_FMT "\n",
 258                        to_nd_device_type(dev));
 259}
 260static DEVICE_ATTR_RO(modalias);
 261
 262static ssize_t devtype_show(struct device *dev, struct device_attribute *attr,
 263                char *buf)
 264{
 265        return sprintf(buf, "%s\n", dev->type->name);
 266}
 267static DEVICE_ATTR_RO(devtype);
 268
 269static struct attribute *nd_device_attributes[] = {
 270        &dev_attr_modalias.attr,
 271        &dev_attr_devtype.attr,
 272        NULL,
 273};
 274
 275/**
 276 * nd_device_attribute_group - generic attributes for all devices on an nd bus
 277 */
 278struct attribute_group nd_device_attribute_group = {
 279        .attrs = nd_device_attributes,
 280};
 281EXPORT_SYMBOL_GPL(nd_device_attribute_group);
 282
 283static ssize_t numa_node_show(struct device *dev,
 284                struct device_attribute *attr, char *buf)
 285{
 286        return sprintf(buf, "%d\n", dev_to_node(dev));
 287}
 288static DEVICE_ATTR_RO(numa_node);
 289
 290static struct attribute *nd_numa_attributes[] = {
 291        &dev_attr_numa_node.attr,
 292        NULL,
 293};
 294
 295static umode_t nd_numa_attr_visible(struct kobject *kobj, struct attribute *a,
 296                int n)
 297{
 298        if (!IS_ENABLED(CONFIG_NUMA))
 299                return 0;
 300
 301        return a->mode;
 302}
 303
 304/**
 305 * nd_numa_attribute_group - NUMA attributes for all devices on an nd bus
 306 */
 307struct attribute_group nd_numa_attribute_group = {
 308        .attrs = nd_numa_attributes,
 309        .is_visible = nd_numa_attr_visible,
 310};
 311EXPORT_SYMBOL_GPL(nd_numa_attribute_group);
 312
 313int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus)
 314{
 315        dev_t devt = MKDEV(nvdimm_bus_major, nvdimm_bus->id);
 316        struct device *dev;
 317
 318        dev = device_create(nd_class, &nvdimm_bus->dev, devt, nvdimm_bus,
 319                        "ndctl%d", nvdimm_bus->id);
 320
 321        if (IS_ERR(dev)) {
 322                dev_dbg(&nvdimm_bus->dev, "failed to register ndctl%d: %ld\n",
 323                                nvdimm_bus->id, PTR_ERR(dev));
 324                return PTR_ERR(dev);
 325        }
 326        return 0;
 327}
 328
 329void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus)
 330{
 331        device_destroy(nd_class, MKDEV(nvdimm_bus_major, nvdimm_bus->id));
 332}
 333
 334static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = {
 335        [ND_CMD_IMPLEMENTED] = { },
 336        [ND_CMD_SMART] = {
 337                .out_num = 2,
 338                .out_sizes = { 4, 8, },
 339        },
 340        [ND_CMD_SMART_THRESHOLD] = {
 341                .out_num = 2,
 342                .out_sizes = { 4, 8, },
 343        },
 344        [ND_CMD_DIMM_FLAGS] = {
 345                .out_num = 2,
 346                .out_sizes = { 4, 4 },
 347        },
 348        [ND_CMD_GET_CONFIG_SIZE] = {
 349                .out_num = 3,
 350                .out_sizes = { 4, 4, 4, },
 351        },
 352        [ND_CMD_GET_CONFIG_DATA] = {
 353                .in_num = 2,
 354                .in_sizes = { 4, 4, },
 355                .out_num = 2,
 356                .out_sizes = { 4, UINT_MAX, },
 357        },
 358        [ND_CMD_SET_CONFIG_DATA] = {
 359                .in_num = 3,
 360                .in_sizes = { 4, 4, UINT_MAX, },
 361                .out_num = 1,
 362                .out_sizes = { 4, },
 363        },
 364        [ND_CMD_VENDOR] = {
 365                .in_num = 3,
 366                .in_sizes = { 4, 4, UINT_MAX, },
 367                .out_num = 3,
 368                .out_sizes = { 4, 4, UINT_MAX, },
 369        },
 370};
 371
 372const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd)
 373{
 374        if (cmd < ARRAY_SIZE(__nd_cmd_dimm_descs))
 375                return &__nd_cmd_dimm_descs[cmd];
 376        return NULL;
 377}
 378EXPORT_SYMBOL_GPL(nd_cmd_dimm_desc);
 379
 380static const struct nd_cmd_desc __nd_cmd_bus_descs[] = {
 381        [ND_CMD_IMPLEMENTED] = { },
 382        [ND_CMD_ARS_CAP] = {
 383                .in_num = 2,
 384                .in_sizes = { 8, 8, },
 385                .out_num = 2,
 386                .out_sizes = { 4, 4, },
 387        },
 388        [ND_CMD_ARS_START] = {
 389                .in_num = 4,
 390                .in_sizes = { 8, 8, 2, 6, },
 391                .out_num = 1,
 392                .out_sizes = { 4, },
 393        },
 394        [ND_CMD_ARS_STATUS] = {
 395                .out_num = 2,
 396                .out_sizes = { 4, UINT_MAX, },
 397        },
 398};
 399
 400const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd)
 401{
 402        if (cmd < ARRAY_SIZE(__nd_cmd_bus_descs))
 403                return &__nd_cmd_bus_descs[cmd];
 404        return NULL;
 405}
 406EXPORT_SYMBOL_GPL(nd_cmd_bus_desc);
 407
 408u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
 409                const struct nd_cmd_desc *desc, int idx, void *buf)
 410{
 411        if (idx >= desc->in_num)
 412                return UINT_MAX;
 413
 414        if (desc->in_sizes[idx] < UINT_MAX)
 415                return desc->in_sizes[idx];
 416
 417        if (nvdimm && cmd == ND_CMD_SET_CONFIG_DATA && idx == 2) {
 418                struct nd_cmd_set_config_hdr *hdr = buf;
 419
 420                return hdr->in_length;
 421        } else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2) {
 422                struct nd_cmd_vendor_hdr *hdr = buf;
 423
 424                return hdr->in_length;
 425        }
 426
 427        return UINT_MAX;
 428}
 429EXPORT_SYMBOL_GPL(nd_cmd_in_size);
 430
 431u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
 432                const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
 433                const u32 *out_field)
 434{
 435        if (idx >= desc->out_num)
 436                return UINT_MAX;
 437
 438        if (desc->out_sizes[idx] < UINT_MAX)
 439                return desc->out_sizes[idx];
 440
 441        if (nvdimm && cmd == ND_CMD_GET_CONFIG_DATA && idx == 1)
 442                return in_field[1];
 443        else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2)
 444                return out_field[1];
 445        else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 1)
 446                return ND_CMD_ARS_STATUS_MAX;
 447
 448        return UINT_MAX;
 449}
 450EXPORT_SYMBOL_GPL(nd_cmd_out_size);
 451
 452void wait_nvdimm_bus_probe_idle(struct device *dev)
 453{
 454        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
 455
 456        do {
 457                if (nvdimm_bus->probe_active == 0)
 458                        break;
 459                nvdimm_bus_unlock(&nvdimm_bus->dev);
 460                wait_event(nvdimm_bus->probe_wait,
 461                                nvdimm_bus->probe_active == 0);
 462                nvdimm_bus_lock(&nvdimm_bus->dev);
 463        } while (true);
 464}
 465
 466/* set_config requires an idle interleave set */
 467static int nd_cmd_clear_to_send(struct nvdimm *nvdimm, unsigned int cmd)
 468{
 469        struct nvdimm_bus *nvdimm_bus;
 470
 471        if (!nvdimm || cmd != ND_CMD_SET_CONFIG_DATA)
 472                return 0;
 473
 474        nvdimm_bus = walk_to_nvdimm_bus(&nvdimm->dev);
 475        wait_nvdimm_bus_probe_idle(&nvdimm_bus->dev);
 476
 477        if (atomic_read(&nvdimm->busy))
 478                return -EBUSY;
 479        return 0;
 480}
 481
 482static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 483                int read_only, unsigned int ioctl_cmd, unsigned long arg)
 484{
 485        struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
 486        size_t buf_len = 0, in_len = 0, out_len = 0;
 487        static char out_env[ND_CMD_MAX_ENVELOPE];
 488        static char in_env[ND_CMD_MAX_ENVELOPE];
 489        const struct nd_cmd_desc *desc = NULL;
 490        unsigned int cmd = _IOC_NR(ioctl_cmd);
 491        void __user *p = (void __user *) arg;
 492        struct device *dev = &nvdimm_bus->dev;
 493        const char *cmd_name, *dimm_name;
 494        unsigned long dsm_mask;
 495        void *buf;
 496        int rc, i;
 497
 498        if (nvdimm) {
 499                desc = nd_cmd_dimm_desc(cmd);
 500                cmd_name = nvdimm_cmd_name(cmd);
 501                dsm_mask = nvdimm->dsm_mask ? *(nvdimm->dsm_mask) : 0;
 502                dimm_name = dev_name(&nvdimm->dev);
 503        } else {
 504                desc = nd_cmd_bus_desc(cmd);
 505                cmd_name = nvdimm_bus_cmd_name(cmd);
 506                dsm_mask = nd_desc->dsm_mask;
 507                dimm_name = "bus";
 508        }
 509
 510        if (!desc || (desc->out_num + desc->in_num == 0) ||
 511                        !test_bit(cmd, &dsm_mask))
 512                return -ENOTTY;
 513
 514        /* fail write commands (when read-only) */
 515        if (read_only)
 516                switch (ioctl_cmd) {
 517                case ND_IOCTL_VENDOR:
 518                case ND_IOCTL_SET_CONFIG_DATA:
 519                case ND_IOCTL_ARS_START:
 520                        dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
 521                                        nvdimm ? nvdimm_cmd_name(cmd)
 522                                        : nvdimm_bus_cmd_name(cmd));
 523                        return -EPERM;
 524                default:
 525                        break;
 526                }
 527
 528        /* process an input envelope */
 529        for (i = 0; i < desc->in_num; i++) {
 530                u32 in_size, copy;
 531
 532                in_size = nd_cmd_in_size(nvdimm, cmd, desc, i, in_env);
 533                if (in_size == UINT_MAX) {
 534                        dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n",
 535                                        __func__, dimm_name, cmd_name, i);
 536                        return -ENXIO;
 537                }
 538                if (in_len < sizeof(in_env))
 539                        copy = min_t(u32, sizeof(in_env) - in_len, in_size);
 540                else
 541                        copy = 0;
 542                if (copy && copy_from_user(&in_env[in_len], p + in_len, copy))
 543                        return -EFAULT;
 544                in_len += in_size;
 545        }
 546
 547        /* process an output envelope */
 548        for (i = 0; i < desc->out_num; i++) {
 549                u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
 550                                (u32 *) in_env, (u32 *) out_env);
 551                u32 copy;
 552
 553                if (out_size == UINT_MAX) {
 554                        dev_dbg(dev, "%s:%s unknown output size cmd: %s field: %d\n",
 555                                        __func__, dimm_name, cmd_name, i);
 556                        return -EFAULT;
 557                }
 558                if (out_len < sizeof(out_env))
 559                        copy = min_t(u32, sizeof(out_env) - out_len, out_size);
 560                else
 561                        copy = 0;
 562                if (copy && copy_from_user(&out_env[out_len],
 563                                        p + in_len + out_len, copy))
 564                        return -EFAULT;
 565                out_len += out_size;
 566        }
 567
 568        buf_len = out_len + in_len;
 569        if (buf_len > ND_IOCTL_MAX_BUFLEN) {
 570                dev_dbg(dev, "%s:%s cmd: %s buf_len: %zu > %d\n", __func__,
 571                                dimm_name, cmd_name, buf_len,
 572                                ND_IOCTL_MAX_BUFLEN);
 573                return -EINVAL;
 574        }
 575
 576        buf = vmalloc(buf_len);
 577        if (!buf)
 578                return -ENOMEM;
 579
 580        if (copy_from_user(buf, p, buf_len)) {
 581                rc = -EFAULT;
 582                goto out;
 583        }
 584
 585        nvdimm_bus_lock(&nvdimm_bus->dev);
 586        rc = nd_cmd_clear_to_send(nvdimm, cmd);
 587        if (rc)
 588                goto out_unlock;
 589
 590        rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len);
 591        if (rc < 0)
 592                goto out_unlock;
 593        if (copy_to_user(p, buf, buf_len))
 594                rc = -EFAULT;
 595 out_unlock:
 596        nvdimm_bus_unlock(&nvdimm_bus->dev);
 597 out:
 598        vfree(buf);
 599        return rc;
 600}
 601
 602static long nd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 603{
 604        long id = (long) file->private_data;
 605        int rc = -ENXIO, read_only;
 606        struct nvdimm_bus *nvdimm_bus;
 607
 608        read_only = (O_RDWR != (file->f_flags & O_ACCMODE));
 609        mutex_lock(&nvdimm_bus_list_mutex);
 610        list_for_each_entry(nvdimm_bus, &nvdimm_bus_list, list) {
 611                if (nvdimm_bus->id == id) {
 612                        rc = __nd_ioctl(nvdimm_bus, NULL, read_only, cmd, arg);
 613                        break;
 614                }
 615        }
 616        mutex_unlock(&nvdimm_bus_list_mutex);
 617
 618        return rc;
 619}
 620
 621static int match_dimm(struct device *dev, void *data)
 622{
 623        long id = (long) data;
 624
 625        if (is_nvdimm(dev)) {
 626                struct nvdimm *nvdimm = to_nvdimm(dev);
 627
 628                return nvdimm->id == id;
 629        }
 630
 631        return 0;
 632}
 633
 634static long nvdimm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 635{
 636        int rc = -ENXIO, read_only;
 637        struct nvdimm_bus *nvdimm_bus;
 638
 639        read_only = (O_RDWR != (file->f_flags & O_ACCMODE));
 640        mutex_lock(&nvdimm_bus_list_mutex);
 641        list_for_each_entry(nvdimm_bus, &nvdimm_bus_list, list) {
 642                struct device *dev = device_find_child(&nvdimm_bus->dev,
 643                                file->private_data, match_dimm);
 644                struct nvdimm *nvdimm;
 645
 646                if (!dev)
 647                        continue;
 648
 649                nvdimm = to_nvdimm(dev);
 650                rc = __nd_ioctl(nvdimm_bus, nvdimm, read_only, cmd, arg);
 651                put_device(dev);
 652                break;
 653        }
 654        mutex_unlock(&nvdimm_bus_list_mutex);
 655
 656        return rc;
 657}
 658
 659static int nd_open(struct inode *inode, struct file *file)
 660{
 661        long minor = iminor(inode);
 662
 663        file->private_data = (void *) minor;
 664        return 0;
 665}
 666
 667static const struct file_operations nvdimm_bus_fops = {
 668        .owner = THIS_MODULE,
 669        .open = nd_open,
 670        .unlocked_ioctl = nd_ioctl,
 671        .compat_ioctl = nd_ioctl,
 672        .llseek = noop_llseek,
 673};
 674
 675static const struct file_operations nvdimm_fops = {
 676        .owner = THIS_MODULE,
 677        .open = nd_open,
 678        .unlocked_ioctl = nvdimm_ioctl,
 679        .compat_ioctl = nvdimm_ioctl,
 680        .llseek = noop_llseek,
 681};
 682
 683int __init nvdimm_bus_init(void)
 684{
 685        int rc;
 686
 687        rc = bus_register(&nvdimm_bus_type);
 688        if (rc)
 689                return rc;
 690
 691        rc = register_chrdev(0, "ndctl", &nvdimm_bus_fops);
 692        if (rc < 0)
 693                goto err_bus_chrdev;
 694        nvdimm_bus_major = rc;
 695
 696        rc = register_chrdev(0, "dimmctl", &nvdimm_fops);
 697        if (rc < 0)
 698                goto err_dimm_chrdev;
 699        nvdimm_major = rc;
 700
 701        nd_class = class_create(THIS_MODULE, "nd");
 702        if (IS_ERR(nd_class)) {
 703                rc = PTR_ERR(nd_class);
 704                goto err_class;
 705        }
 706
 707        return 0;
 708
 709 err_class:
 710        unregister_chrdev(nvdimm_major, "dimmctl");
 711 err_dimm_chrdev:
 712        unregister_chrdev(nvdimm_bus_major, "ndctl");
 713 err_bus_chrdev:
 714        bus_unregister(&nvdimm_bus_type);
 715
 716        return rc;
 717}
 718
 719void nvdimm_bus_exit(void)
 720{
 721        class_destroy(nd_class);
 722        unregister_chrdev(nvdimm_bus_major, "ndctl");
 723        unregister_chrdev(nvdimm_major, "dimmctl");
 724        bus_unregister(&nvdimm_bus_type);
 725}
 726