| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/slab.h>
- #include <linux/nd.h>
- #include "nd.h"
- static void namespace_io_release(struct device *dev)
- {
- struct nd_namespace_io *nsio = to_nd_namespace_io(dev);
- kfree(nsio);
- }
- static struct device_type namespace_io_device_type = {
- .name = "nd_namespace_io",
- .release = namespace_io_release,
- };
- static ssize_t nstype_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct nd_region *nd_region = to_nd_region(dev->parent);
- return sprintf(buf, "%d\n", nd_region_to_nstype(nd_region));
- }
- static DEVICE_ATTR_RO(nstype);
- static struct attribute *nd_namespace_attributes[] = {
- &dev_attr_nstype.attr,
- NULL,
- };
- static struct attribute_group nd_namespace_attribute_group = {
- .attrs = nd_namespace_attributes,
- };
- static const struct attribute_group *nd_namespace_attribute_groups[] = {
- &nd_device_attribute_group,
- &nd_namespace_attribute_group,
- NULL,
- };
- static struct device **create_namespace_io(struct nd_region *nd_region)
- {
- struct nd_namespace_io *nsio;
- struct device *dev, **devs;
- struct resource *res;
- nsio = kzalloc(sizeof(*nsio), GFP_KERNEL);
- if (!nsio)
- return NULL;
- devs = kcalloc(2, sizeof(struct device *), GFP_KERNEL);
- if (!devs) {
- kfree(nsio);
- return NULL;
- }
- dev = &nsio->dev;
- dev->type = &namespace_io_device_type;
- dev->parent = &nd_region->dev;
- res = &nsio->res;
- res->name = dev_name(&nd_region->dev);
- res->flags = IORESOURCE_MEM;
- res->start = nd_region->ndr_start;
- res->end = res->start + nd_region->ndr_size - 1;
- devs[0] = dev;
- return devs;
- }
- int nd_region_register_namespaces(struct nd_region *nd_region, int *err)
- {
- struct device **devs = NULL;
- int i;
- *err = 0;
- switch (nd_region_to_nstype(nd_region)) {
- case ND_DEVICE_NAMESPACE_IO:
- devs = create_namespace_io(nd_region);
- break;
- default:
- break;
- }
- if (!devs)
- return -ENODEV;
- for (i = 0; devs[i]; i++) {
- struct device *dev = devs[i];
- dev_set_name(dev, "namespace%d.%d", nd_region->id, i);
- dev->groups = nd_namespace_attribute_groups;
- nd_device_register(dev);
- }
- kfree(devs);
- return i;
- }
|