[openfabrics-ewg] [PATCH 1 of 2 IB/VNIC] VNIC backport patch files for RHEL 4 Update 4
Vladimir Sokolovsky
vlad at mellanox.co.il
Tue Jan 9 04:33:03 PST 2007
Applied.
Regards,
Vladimir
On Tue, 2007-01-09 at 17:13 +0530, Ramachandra K wrote:
> Adds two VNIC backport patch files to support VNIC on RHEL 4 Update 4
>
> 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_U4/vnic_sysfs_nested_class_dev.patch | 281 +++++++++++++++++++++++
> .../backport/2.6.9_U4/vnic_utsname.patch | 50 ++++
> 2 files changed, 331 insertions(+), 0 deletions(-)
>
> diff --git a/kernel_patches/backport/2.6.9_U4/vnic_sysfs_nested_class_dev.patch
> b/kernel_patches/backport/2.6.9_U4/vnic_sysfs_nested_class_dev.patch
> new file mode 100644
> index 0000000..88cfdd1
> --- /dev/null
> +++ b/kernel_patches/backport/2.6.9_U4/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_U4/vnic_utsname.patch
> b/kernel_patches/backport/2.6.9_U4/vnic_utsname.patch
> new file mode 100644
> index 0000000..dfd98d9
> --- /dev/null
> +++ b/kernel_patches/backport/2.6.9_U4/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