From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT: drivers/infiniband/core/cma_configfs.c

Change-Id: Idb75744ab42c657a5df47d912dc4742334b5ddde
---
 drivers/infiniband/core/cma_configfs.c | 135 +++++++++++++++++++++++--
 1 file changed, 126 insertions(+), 9 deletions(-)

--- a/drivers/infiniband/core/cma_configfs.c
+++ b/drivers/infiniband/core/cma_configfs.c
@@ -38,6 +38,10 @@
 #include "core_priv.h"
 #include "cma_priv.h"
 
+#ifndef CONFIGFS_ATTR
+#define HAVE_OLD_CONFIGFS_API
+#endif
+
 struct cma_device;
 
 struct cma_dev_group;
@@ -55,6 +59,23 @@ struct cma_dev_group {
 	struct cma_dev_port_group	*ports;
 };
 
+#ifdef HAVE_OLD_CONFIGFS_API
+struct cma_configfs_attr {
+	struct configfs_attribute	attr;
+	ssize_t				(*show)(struct config_item *item,
+						char *buf);
+	ssize_t				(*store)(struct config_item *item,
+						 const char *buf, size_t count);
+};
+#define CONFIGFS_ATTR(dummy, _name)				\
+static struct cma_configfs_attr attr_##_name =	\
+	__CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, _name##_show, _name##_store)
+
+#define CONFIGFS_ATTR_ADD(name) &name.attr
+#else
+#define CONFIGFS_ATTR_ADD(name) &name
+#endif /* HAVE_OLD_CONFIGFS_API */
+
 static struct cma_dev_port_group *to_dev_port_group(struct config_item *item)
 {
 	struct config_group *group;
@@ -71,6 +92,34 @@ static bool filter_by_name(struct ib_dev
 	return !strcmp(dev_name(&ib_dev->dev), cookie);
 }
 
+#ifdef HAVE_OLD_CONFIGFS_API
+static ssize_t cma_configfs_attr_show(struct config_item *item,
+				      struct configfs_attribute *attr,
+				      char *buf)
+{
+	struct cma_configfs_attr *ca =
+		container_of(attr, struct cma_configfs_attr, attr);
+
+	if (ca->show)
+		return ca->show(item, buf);
+
+	return -EINVAL;
+}
+
+static ssize_t cma_configfs_attr_store(struct config_item *item,
+				       struct configfs_attribute *attr,
+				       const char *buf, size_t count)
+{
+	struct cma_configfs_attr *ca =
+		container_of(attr, struct cma_configfs_attr, attr);
+
+	if (ca->store)
+		return ca->store(item, buf, count);
+
+	return -EINVAL;
+}
+#endif /* HAVE_OLD_CONFIGFS_API */
+
 static int cma_configfs_params_get(struct config_item *item,
 				   struct cma_device **pcma_dev,
 				   struct cma_dev_port_group **pgroup)
@@ -187,12 +236,23 @@ static ssize_t default_roce_tos_store(st
 CONFIGFS_ATTR(, default_roce_tos);
 
 static struct configfs_attribute *cma_configfs_attributes[] = {
-	&attr_default_roce_mode,
-	&attr_default_roce_tos,
+	CONFIGFS_ATTR_ADD(attr_default_roce_mode),
+	CONFIGFS_ATTR_ADD(attr_default_roce_tos),
 	NULL,
 };
 
-static const struct config_item_type cma_port_group_type = {
+#ifdef HAVE_OLD_CONFIGFS_API
+static struct configfs_item_operations cma_item_ops = {
+	.show_attribute		= cma_configfs_attr_show,
+	.store_attribute	= cma_configfs_attr_store,
+};
+#else /* HAVE_OLD_CONFIGFS_API */
+static struct configfs_item_operations cma_item_ops = {
+};
+#endif
+
+static struct config_item_type cma_port_group_type = {
+	.ct_item_ops	= &cma_item_ops,
 	.ct_attrs	= cma_configfs_attributes,
 	.ct_owner	= THIS_MODULE
 };
@@ -217,6 +277,14 @@ static int make_cma_ports(struct cma_dev
 	if (!ports)
 		return -ENOMEM;
 
+#ifndef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
+	cma_dev_group->ports_group.default_groups = kcalloc((ports_num + 1),
+							    sizeof(struct config_group *),
+							    GFP_KERNEL);
+	if (!cma_dev_group->ports_group.default_groups)
+		return -ENOMEM;
+#endif
+
 	for (i = 0; i < ports_num; i++) {
 		char port_str[10];
 
@@ -226,10 +294,16 @@ static int make_cma_ports(struct cma_dev
 		config_group_init_type_name(&ports[i].group,
 					    port_str,
 					    &cma_port_group_type);
+#ifdef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
 		configfs_add_default_group(&ports[i].group,
 				&cma_dev_group->ports_group);
-
+#else
+		cma_dev_group->ports_group.default_groups[i] = &ports[i].group;
+#endif
 	}
+#ifndef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
+	cma_dev_group->ports_group.default_groups[i] = NULL;
+#endif
 	cma_dev_group->ports = ports;
 	return 0;
 }
@@ -261,7 +335,7 @@ static struct configfs_item_operations c
 	.release = release_cma_ports_group
 };
 
-static const struct config_item_type cma_ports_group_type = {
+static struct config_item_type cma_ports_group_type = {
 	.ct_item_ops	= &cma_ports_item_ops,
 	.ct_owner	= THIS_MODULE
 };
@@ -270,7 +344,7 @@ static struct configfs_item_operations c
 	.release = release_cma_dev
 };
 
-static const struct config_item_type cma_device_group_type = {
+static struct config_item_type cma_device_group_type = {
 	.ct_item_ops	= &cma_device_item_ops,
 	.ct_owner	= THIS_MODULE
 };
@@ -293,6 +367,15 @@ static struct config_group *make_cma_dev
 		goto fail;
 	}
 
+#ifndef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
+	cma_dev_group->device_group.default_groups = kzalloc(sizeof(struct config_group *) * 2,
+							     GFP_KERNEL);
+	if (!cma_dev_group->device_group.default_groups) {
+		err = -ENOMEM;
+		goto fail;
+	}
+#endif
+
 	strlcpy(cma_dev_group->name, name, sizeof(cma_dev_group->name));
 
 	config_group_init_type_name(&cma_dev_group->ports_group, "ports",
@@ -300,16 +383,29 @@ static struct config_group *make_cma_dev
 
 	err = make_cma_ports(cma_dev_group, cma_dev);
 	if (err)
+#ifdef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
 		goto fail;
+#else
+		goto fail_free;
+#endif
 
 	config_group_init_type_name(&cma_dev_group->device_group, name,
 				    &cma_device_group_type);
-	configfs_add_default_group(&cma_dev_group->ports_group,
-			&cma_dev_group->device_group);
+#ifdef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
+       configfs_add_default_group(&cma_dev_group->ports_group,
+       		&cma_dev_group->device_group);
+#else
+	cma_dev_group->device_group.default_groups[0] = &cma_dev_group->ports_group;
+	cma_dev_group->device_group.default_groups[1] = NULL;
+#endif
 
 	cma_dev_put(cma_dev);
 	return &cma_dev_group->device_group;
 
+#ifndef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
+fail_free:
+	kfree(cma_dev_group->device_group.default_groups);
+#endif
 fail:
 	if (cma_dev)
 		cma_dev_put(cma_dev);
@@ -324,8 +420,29 @@ static void drop_cma_dev(struct config_g
 	struct cma_dev_group *cma_dev_group =
 		container_of(group, struct cma_dev_group, device_group);
 
+#ifdef HAVE_CONFIGFS_DEFAULT_GROUPS_LIST
 	configfs_remove_default_groups(&cma_dev_group->ports_group);
 	configfs_remove_default_groups(&cma_dev_group->device_group);
+#else
+        struct config_item *temp_item;
+        int i;
+
+        for (i = 0; cma_dev_group->ports_group.default_groups[i]; i++) {
+                temp_item =
+                        &cma_dev_group->ports_group.default_groups[i]->cg_item;
+                cma_dev_group->ports_group.default_groups[i] = NULL;
+                config_item_put(temp_item);
+        }
+        kfree(cma_dev_group->ports_group.default_groups);
+
+        for (i = 0; cma_dev_group->device_group.default_groups[i]; i++) {
+                temp_item =
+                        &cma_dev_group->device_group.default_groups[i]->cg_item;
+                cma_dev_group->device_group.default_groups[i] = NULL;
+                config_item_put(temp_item);
+        }
+        kfree(cma_dev_group->device_group.default_groups);
+#endif
 	config_item_put(item);
 }
 
@@ -334,7 +451,7 @@ static struct configfs_group_operations
 	.drop_item	= drop_cma_dev,
 };
 
-static const struct config_item_type cma_subsys_type = {
+static struct config_item_type cma_subsys_type = {
 	.ct_group_ops	= &cma_subsys_group_ops,
 	.ct_owner	= THIS_MODULE,
 };
