linux/drivers/nvdimm/dimm.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#include <linux/vmalloc.h>
  14#include <linux/module.h>
  15#include <linux/device.h>
  16#include <linux/sizes.h>
  17#include <linux/ndctl.h>
  18#include <linux/slab.h>
  19#include <linux/mm.h>
  20#include <linux/nd.h>
  21#include "label.h"
  22#include "nd.h"
  23
  24static int nvdimm_probe(struct device *dev)
  25{
  26        struct nvdimm_drvdata *ndd;
  27        int rc;
  28
  29        ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
  30        if (!ndd)
  31                return -ENOMEM;
  32
  33        dev_set_drvdata(dev, ndd);
  34        ndd->dpa.name = dev_name(dev);
  35        ndd->ns_current = -1;
  36        ndd->ns_next = -1;
  37        ndd->dpa.start = 0;
  38        ndd->dpa.end = -1;
  39        ndd->dev = dev;
  40        get_device(dev);
  41        kref_init(&ndd->kref);
  42
  43        rc = nvdimm_init_nsarea(ndd);
  44        if (rc)
  45                goto err;
  46
  47        rc = nvdimm_init_config_data(ndd);
  48        if (rc)
  49                goto err;
  50
  51        dev_dbg(dev, "config data size: %d\n", ndd->nsarea.config_size);
  52
  53        nvdimm_bus_lock(dev);
  54        ndd->ns_current = nd_label_validate(ndd);
  55        ndd->ns_next = nd_label_next_nsindex(ndd->ns_current);
  56        nd_label_copy(ndd, to_next_namespace_index(ndd),
  57                        to_current_namespace_index(ndd));
  58        rc = nd_label_reserve_dpa(ndd);
  59        nvdimm_bus_unlock(dev);
  60
  61        if (rc)
  62                goto err;
  63
  64        return 0;
  65
  66 err:
  67        put_ndd(ndd);
  68        return rc;
  69}
  70
  71static int nvdimm_remove(struct device *dev)
  72{
  73        struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
  74
  75        nvdimm_bus_lock(dev);
  76        dev_set_drvdata(dev, NULL);
  77        nvdimm_bus_unlock(dev);
  78        put_ndd(ndd);
  79
  80        return 0;
  81}
  82
  83static struct nd_device_driver nvdimm_driver = {
  84        .probe = nvdimm_probe,
  85        .remove = nvdimm_remove,
  86        .drv = {
  87                .name = "nvdimm",
  88        },
  89        .type = ND_DRIVER_DIMM,
  90};
  91
  92int __init nvdimm_init(void)
  93{
  94        return nd_driver_register(&nvdimm_driver);
  95}
  96
  97void nvdimm_exit(void)
  98{
  99        driver_unregister(&nvdimm_driver.drv);
 100}
 101
 102MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DIMM);
 103