#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/nd.h>
+#include "label.h"
#include "nd.h"
-static void free_data(struct nvdimm_drvdata *ndd)
-{
- if (!ndd)
- return;
-
- if (ndd->data && is_vmalloc_addr(ndd->data))
- vfree(ndd->data);
- else
- kfree(ndd->data);
- kfree(ndd);
-}
-
static int nvdimm_probe(struct device *dev)
{
struct nvdimm_drvdata *ndd;
return -ENOMEM;
dev_set_drvdata(dev, ndd);
+ ndd->dpa.name = dev_name(dev);
+ ndd->ns_current = -1;
+ ndd->ns_next = -1;
+ ndd->dpa.start = 0;
+ ndd->dpa.end = -1;
ndd->dev = dev;
+ get_device(dev);
+ kref_init(&ndd->kref);
rc = nvdimm_init_nsarea(ndd);
if (rc)
dev_dbg(dev, "config data size: %d\n", ndd->nsarea.config_size);
+ nvdimm_bus_lock(dev);
+ ndd->ns_current = nd_label_validate(ndd);
+ ndd->ns_next = nd_label_next_nsindex(ndd->ns_current);
+ nd_label_copy(ndd, to_next_namespace_index(ndd),
+ to_current_namespace_index(ndd));
+ rc = nd_label_reserve_dpa(ndd);
+ nvdimm_bus_unlock(dev);
+
+ if (rc)
+ goto err;
+
return 0;
err:
- free_data(ndd);
+ put_ndd(ndd);
return rc;
}
{
struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
- free_data(ndd);
+ nvdimm_bus_lock(dev);
+ dev_set_drvdata(dev, NULL);
+ nvdimm_bus_unlock(dev);
+ put_ndd(ndd);
return 0;
}