[openfabrics-ewg] [PATCH 2 of 2 IB/VNIC] Add VNIC backport patch files for RHEL 4 Update 3

Vladimir Sokolovsky vlad at mellanox.co.il
Tue Jan 9 04:33:21 PST 2007


Applied.

Regards,
Vladimir

On Tue, 2007-01-09 at 17:15 +0530, Ramachandra K wrote:
> Adds two VNIC backport patch files to support VNIC on RHEL4 Update 3
> 
> vnic_sysfs_nested_class_dev.patch - Adds support to VNIC driver to create
> nested class device structure in sysfs for older kernels
> 
> vnic_utsname.patch - Uses old system_utsname for older kernels
> 
> Signed-off-by: Ramachandra K <ramachandra.kuchimanchi at qlogic.com>
> ---
> 
>  .../2.6.9_U3/vnic_sysfs_nested_class_dev.patch     |  281 +++++++++++++++++++++++
>  .../backport/2.6.9_U3/vnic_utsname.patch           |   50 ++++
>  2 files changed, 331 insertions(+), 0 deletions(-)
> 
> diff --git a/kernel_patches/backport/2.6.9_U3/vnic_sysfs_nested_class_dev.patch 
> b/kernel_patches/backport/2.6.9_U3/vnic_sysfs_nested_class_dev.patch
> new file mode 100644
> index 0000000..88cfdd1
> --- /dev/null
> +++ b/kernel_patches/backport/2.6.9_U3/vnic_sysfs_nested_class_dev.patch
> @@ -0,0 +1,281 @@
> +This patch adds support to the VNIC driver to create a nested class_device
> +structure in sysfs for older kernels.(The ability to create nested
> +class_device structure in sysfs was added in 2.6.14)
> +
> +Signed-off-by: Ramachandra K <ramachandra.kuchimanchi at qlogic.com>
> +---
> +
> + drivers/infiniband/ulp/vnic/vnic_main.c    |    3 -
> + drivers/infiniband/ulp/vnic/vnic_netpath.c |    3 -
> + drivers/infiniband/ulp/vnic/vnic_stats.h   |   10 +-
> + drivers/infiniband/ulp/vnic/vnic_sys.c     |  138 +++++++++++++++++++++++++++-
> + drivers/infiniband/ulp/vnic/vnic_sys.h     |   10 ++
> + 5 files changed, 151 insertions(+), 13 deletions(-)
> +
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_main.c b/drivers/infiniband/ulp/vnic/vnic_main.c
> +index 5810bc8..9407f9d 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_main.c
> ++++ b/drivers/infiniband/ulp/vnic/vnic_main.c
> +@@ -681,7 +681,8 @@ static void vnic_handle_free_vnic_evt(st
> +	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
> +			   &vnic_dev_attr_group);
> +	vnic_cleanup_stats_files(vnic);
> +-	class_device_unregister(&vnic->class_dev_info.class_dev);
> ++	vnic_nested_class_device_unregister(&vnic->class_dev_info.class_dev,
> ++					    &interface_cdev.class_dev);
> +	wait_for_completion(&vnic->class_dev_info.released);
> + }
> +
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_netpath.c b/drivers/infiniband/ulp/vnic/vnic_netpath.c
> +index ce54608..29217e9 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_netpath.c
> ++++ b/drivers/infiniband/ulp/vnic/vnic_netpath.c
> +@@ -84,7 +84,8 @@ void netpath_free(struct netpath *netpat
> +	netpath->viport = NULL;
> +	sysfs_remove_group(&netpath->class_dev_info.class_dev.kobj,
> +			   &vnic_path_attr_group);
> +-	class_device_unregister(&netpath->class_dev_info.class_dev);
> ++	vnic_nested_class_device_unregister(&netpath->class_dev_info.class_dev,
> ++				    &netpath->parent->class_dev_info.class_dev);
> +	wait_for_completion(&netpath->class_dev_info.released);
> + }
> +
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_stats.h b/drivers/infiniband/ulp/vnic/vnic_stats.h
> +index 7d1b953..cda43a5 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_stats.h
> ++++ b/drivers/infiniband/ulp/vnic/vnic_stats.h
> +@@ -111,11 +111,11 @@ static inline int vnic_setup_stats_files
> + {
> +	init_completion(&vnic->stat_info.released);
> +	vnic->stat_info.class_dev.class = &vnic_class;
> +-	vnic->stat_info.class_dev.parent = &vnic->class_dev_info.class_dev;
> +	snprintf(vnic->stat_info.class_dev.class_id, BUS_ID_SIZE,
> +		 "stats");
> +
> +-	if (class_device_register(&vnic->stat_info.class_dev)) {
> ++	if (vnic_nested_class_device_register(&vnic->stat_info.class_dev,
> ++				      &vnic->class_dev_info.class_dev)) {
> +		SYS_ERROR("create_vnic: error in registering"
> +			  " stat class dev\n");
> +		goto stats_out;
> +@@ -127,7 +127,8 @@ static inline int vnic_setup_stats_files
> +
> +	return 0;
> + err_stats_file:
> +-	class_device_unregister(&vnic->stat_info.class_dev);
> ++	vnic_nested_class_device_unregister(&vnic->stat_info.class_dev,
> ++					    &vnic->class_dev_info.class_dev);
> +	wait_for_completion(&vnic->stat_info.released);
> + stats_out:
> +	return -1;
> +@@ -137,7 +138,8 @@ static inline void vnic_cleanup_stats_fi
> + {
> +	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
> +			   &vnic_stats_attr_group);
> +-	class_device_unregister(&vnic->stat_info.class_dev);
> ++	vnic_nested_class_device_unregister(&vnic->stat_info.class_dev,
> ++					    &vnic->class_dev_info.class_dev);
> +	wait_for_completion(&vnic->stat_info.released);
> + }
> +
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_sys.c b/drivers/infiniband/ulp/vnic/vnic_sys.c
> +index 034be7c..b07c5d0 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_sys.c
> ++++ b/drivers/infiniband/ulp/vnic/vnic_sys.c
> +@@ -440,11 +440,11 @@ struct vnic *create_vnic(struct path_par
> +	init_completion(&vnic->class_dev_info.released);
> +
> +	vnic->class_dev_info.class_dev.class = &vnic_class;
> +-	vnic->class_dev_info.class_dev.parent = &interface_cdev.class_dev;
> +	snprintf(vnic->class_dev_info.class_dev.class_id, BUS_ID_SIZE,
> +		 vnic_config->name);
> +
> +-	if (class_device_register(&vnic->class_dev_info.class_dev)) {
> ++	if (vnic_nested_class_device_register(&vnic->class_dev_info.class_dev,
> ++					      &interface_cdev.class_dev)) {
> +		SYS_ERROR("create_vnic: error in registering"
> +			  " vnic class dev\n");
> +		goto free_vnic;
> +@@ -466,7 +466,8 @@ err_stats:
> +	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
> +			   &vnic_dev_attr_group);
> + err_attr:
> +-	class_device_unregister(&vnic->class_dev_info.class_dev);
> ++	vnic_nested_class_device_unregister(&vnic->class_dev_info.class_dev,
> ++					    &interface_cdev.class_dev);
> +	wait_for_completion(&vnic->class_dev_info.released);
> + free_vnic:
> +	list_del(&vnic->list_ptrs);
> +@@ -642,12 +643,11 @@ static int setup_path_class_files(struct
> +	init_completion(&path->class_dev_info.released);
> +
> +	path->class_dev_info.class_dev.class = &vnic_class;
> +-	path->class_dev_info.class_dev.parent =
> +-	    &path->parent->class_dev_info.class_dev;
> +	snprintf(path->class_dev_info.class_dev.class_id,
> +		 BUS_ID_SIZE, name);
> +
> +-	if (class_device_register(&path->class_dev_info.class_dev)) {
> ++	if (vnic_nested_class_device_register(&path->class_dev_info.class_dev,
> ++				&path->parent->class_dev_info.class_dev)) {
> +		SYS_ERROR("error in registering path class dev\n");
> +		goto out;
> +	}
> +@@ -661,7 +661,8 @@ static int setup_path_class_files(struct
> +	return 0;
> +
> + err_path:
> +-	class_device_unregister(&path->class_dev_info.class_dev);
> ++	vnic_nested_class_device_unregister(&path->class_dev_info.class_dev,
> ++				     &path->parent->class_dev_info.class_dev);
> +	wait_for_completion(&path->class_dev_info.released);
> + out:
> +	return -1;
> +@@ -784,3 +785,126 @@ free_vnic:
> + out:
> +	return ret;
> + }
> ++
> ++/*
> ++ * The ability to nest class_device structures was added in 2.6.14.
> ++ * Following functions are for providing similar functionality
> ++ * for older kernels
> ++ */
> ++
> ++static int class_device_dev_link(struct class_device * class_dev)
> ++{
> ++	if (class_dev->dev)
> ++		return sysfs_create_link(&class_dev->kobj,
> ++					 &class_dev->dev->kobj, "device");
> ++	return 0;
> ++}
> ++
> ++static int class_device_driver_link(struct class_device * class_dev)
> ++{
> ++	if ((class_dev->dev) && (class_dev->dev->driver))
> ++		return sysfs_create_link(&class_dev->kobj,
> ++				 &class_dev->dev->driver->kobj, "driver");
> ++	return 0;
> ++}
> ++
> ++static int class_device_add_attrs(struct class_device * cd)
> ++{
> ++	int i;
> ++	int error = 0;
> ++	struct class * cls = cd->class;
> ++
> ++	if (cls->class_dev_attrs) {
> ++		for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
> ++			error = class_device_create_file(cd,
> ++						 &cls->class_dev_attrs[i]);
> ++			if (error)
> ++				goto Err;
> ++		}
> ++	}
> ++ Done:
> ++	return error;
> ++ Err:
> ++	while (--i >= 0)
> ++		class_device_remove_file(cd,&cls->class_dev_attrs[i]);
> ++	goto Done;
> ++}
> ++
> ++static int vnic_nested_class_device_add(struct class_device *class_dev,
> ++					struct class_device *parent_dev)
> ++{
> ++	struct class * parent = NULL;
> ++	struct class_interface * class_intf;
> ++	int error;
> ++
> ++	class_dev = class_device_get(class_dev);
> ++	if (!class_dev)
> ++		return -EINVAL;
> ++
> ++	if (!strlen(class_dev->class_id)) {
> ++		error = -EINVAL;
> ++		goto register_done;
> ++	}
> ++
> ++	parent = class_get(class_dev->class);
> ++
> ++	pr_debug("CLASS: registering class device: ID = '%s'\n",
> ++		 class_dev->class_id);
> ++
> ++	/* first, register with generic layer. */
> ++	kobject_set_name(&class_dev->kobj, class_dev->class_id);
> ++
> ++	class_dev->kobj.parent = &parent_dev->kobj;
> ++
> ++	if ((error = kobject_add(&class_dev->kobj)))
> ++		goto register_done;
> ++
> ++	/* now take care of our own registration */
> ++	if (parent) {
> ++		down_write(&parent->subsys.rwsem);
> ++		list_add_tail(&class_dev->node, &parent->children);
> ++		list_for_each_entry(class_intf, &parent->interfaces, node)
> ++			if (class_intf->add)
> ++				class_intf->add(class_dev);
> ++		up_write(&parent->subsys.rwsem);
> ++	}
> ++	class_device_add_attrs(class_dev);
> ++	class_device_dev_link(class_dev);
> ++	class_device_driver_link(class_dev);
> ++
> ++ register_done:
> ++	if (error && parent)
> ++		class_put(parent);
> ++	class_device_put(class_dev);
> ++	return error;
> ++}
> ++
> ++/*
> ++ * vnic_nested_class_device_register()
> ++ * Similar to class_device_register() but sets the parent
> ++ * of the class_device to the specified class_device.
> ++ *
> ++ */
> ++int vnic_nested_class_device_register(struct class_device *class_dev,
> ++				      struct class_device *parent_dev)
> ++{
> ++	int ret;
> ++	parent_dev = class_device_get(parent_dev);
> ++
> ++	if (!parent_dev)
> ++		return -EINVAL;
> ++
> ++	class_device_initialize(class_dev);
> ++
> ++	if((ret = vnic_nested_class_device_add(class_dev, parent_dev)))
> ++		class_device_put(parent_dev);
> ++
> ++	return ret;
> ++}
> ++
> ++void vnic_nested_class_device_unregister(struct class_device *class_dev,
> ++					 struct class_device *parent_dev)
> ++{
> ++	class_device_unregister(class_dev);
> ++	class_device_put(parent_dev);
> ++}
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_sys.h b/drivers/infiniband/ulp/vnic/vnic_sys.h
> +index 5835c4a..d15d18a 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_sys.h
> ++++ b/drivers/infiniband/ulp/vnic/vnic_sys.h
> +@@ -38,6 +38,16 @@ struct class_dev_info {
> +	struct completion	released;
> + };
> +
> ++/*
> ++ * vnic_nested_class_device_register()
> ++ * Similar to class_device_register() but sets the parent
> ++ * of the class_device to the specified class_device.
> ++ *
> ++ */
> ++int vnic_nested_class_device_register(struct class_device *class_dev,
> ++				      struct class_device *parent_dev);
> ++void vnic_nested_class_device_unregister(struct class_device *class_dev,
> ++					 struct class_device *parent_dev);
> + extern struct class vnic_class;
> + extern struct class_dev_info interface_cdev;
> + extern struct attribute_group vnic_dev_attr_group;
> diff --git a/kernel_patches/backport/2.6.9_U3/vnic_utsname.patch 
> b/kernel_patches/backport/2.6.9_U3/vnic_utsname.patch
> new file mode 100644
> index 0000000..dfd98d9
> --- /dev/null
> +++ b/kernel_patches/backport/2.6.9_U3/vnic_utsname.patch
> @@ -0,0 +1,50 @@
> +Use the old system_utsname instead of init_utsname() for older kernels.
> +Also explicit inclusion of linux/types.h required to avoid compilation error
> +from linux/parser.h (seen on 2.6.16).
> +
> +Signed-off-by: Ramachandra K <ramachandra.kuchimanchi at qlogic.com>
> +---
> +
> + drivers/infiniband/ulp/vnic/vnic_config.c |    8 ++++----
> + drivers/infiniband/ulp/vnic/vnic_sys.c    |    1 +
> + 2 files changed, 5 insertions(+), 4 deletions(-)
> +
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_config.c b/drivers/infiniband/ulp/vnic/vnic_config.c
> +index d3b02d4..f482e82 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_config.c
> ++++ b/drivers/infiniband/ulp/vnic/vnic_config.c
> +@@ -105,18 +105,18 @@ static void config_control_defaults(stru
> +	control_config->ib_config.conn_data.path_id = 0;
> +	control_config->ib_config.conn_data.vnic_instance = params->instance;
> +	control_config->ib_config.conn_data.path_num = 0;
> +-	dot = strchr(init_utsname()->nodename, '.');
> ++	dot = strchr(system_utsname.nodename, '.');
> +
> +	if (dot)
> +-		len = dot - init_utsname()->nodename;
> ++		len = dot - system_utsname.nodename;
> +	else
> +-		len = strlen(init_utsname()->nodename);
> ++		len = strlen(system_utsname.nodename);
> +
> +	if (len > VNIC_MAX_NODENAME_LEN)
> +		len = VNIC_MAX_NODENAME_LEN;
> +
> +	memcpy(control_config->ib_config.conn_data.nodename,
> +-	       init_utsname()->nodename, len);
> ++	       system_utsname.nodename, len);
> +
> +	control_config->ib_config.retry_count = RETRY_COUNT;
> +	control_config->ib_config.rnr_retry_count = RETRY_COUNT;
> +diff --git a/drivers/infiniband/ulp/vnic/vnic_sys.c b/drivers/infiniband/ulp/vnic/vnic_sys.c
> +index 034be7c..0be8517 100644
> +--- a/drivers/infiniband/ulp/vnic/vnic_sys.c
> ++++ b/drivers/infiniband/ulp/vnic/vnic_sys.c
> +@@ -30,6 +30,7 @@
> +  * SOFTWARE.
> +  */
> +
> ++#include <linux/types.h>
> + #include <linux/parser.h>
> + #include <linux/netdevice.h>
> + #include <linux/if.h>
> 
> 
> 
> _______________________________________________
> openfabrics-ewg mailing list
> openfabrics-ewg at openib.org
> http://openib.org/mailman/listinfo/openfabrics-ewg




More information about the ewg mailing list