[ewg] [PATCH OFED-1.5] Move RHEL5.1 backports to attic

Jon Mason jon at opengridcomputing.com
Thu Jun 11 13:48:55 PDT 2009


The RHEL5.1 backports are legacy patches from the OFED 1.4 build, and do
not apply cleanly to the 2.6.30 kernel.  Move them to the "attic" so
they can be referenced for their historical value but no longer
interfere with the OFED 1.5 build.

Signed-Off-By: Jon Mason <jon at opengridcomputing.com>
---

diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/2_misc_device_to_2_6_19.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/2_misc_device_to_2_6_19.patch
new file mode 100644
index 0000000..4785803
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/2_misc_device_to_2_6_19.patch
@@ -0,0 +1,56 @@
+>Post a replacement to 2_misc_device_to_2_6_19.patch, we'll test.
+
+I did not test this patch, but you can try replacing the contents of
+the 2_misc_device_to_2_6_19.patch with the changes below.  (It's
+possible that this may lead to some conflict further down in the patch
+chain...)  The function prototype for show_abi_version changed between
+2.6.20 to 2.6.19; this was the missing piece in the original backport
+patch.  I would have expected a build warning for this.
+
+Signed-off-by: Sean Hefty <sean.hefty at intel.com>
+
+---
+---
+ drivers/infiniband/core/ucma.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/ucma.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/ucma.c
++++ ofed_kernel/drivers/infiniband/core/ucma.c
+@@ -1207,13 +1207,11 @@ static struct miscdevice ucma_misc = {
+ 	.fops	= &ucma_fops,
+ };
+ 
+-static ssize_t show_abi_version(struct device *dev,
+-				struct device_attribute *attr,
+-				char *buf)
++static ssize_t show_abi_version(struct class_device *class_dev, char *buf)
+ {
+ 	return sprintf(buf, "%d\n", RDMA_USER_CM_ABI_VERSION);
+ }
+-static DEVICE_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
++static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+ 
+ static int __init ucma_init(void)
+ {
+@@ -1223,7 +1221,8 @@ static int __init ucma_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = device_create_file(ucma_misc.this_device, &dev_attr_abi_version);
++	ret = class_device_create_file(ucma_misc.class,
++				       &class_device_attr_abi_version);
+ 	if (ret) {
+ 		printk(KERN_ERR "rdma_ucm: couldn't create abi_version attr\n");
+ 		goto err;
+@@ -1236,7 +1235,8 @@ err:
+ 
+ static void __exit ucma_cleanup(void)
+ {
+-	device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
++	class_device_remove_file(ucma_misc.class,
++				 &class_device_attr_abi_version);
+ 	misc_deregister(&ucma_misc);
+ 	idr_destroy(&ctx_idr);
+ }
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cma_to_2_6_23.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cma_to_2_6_23.patch
new file mode 100644
index 0000000..82f24b3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cma_to_2_6_23.patch
@@ -0,0 +1,23 @@
+---
+ drivers/infiniband/core/cma.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/cma.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/cma.c
++++ ofed_kernel/drivers/infiniband/core/cma.c
+@@ -2835,13 +2835,10 @@ static int cma_netdev_callback(struct no
+ 	struct rdma_id_private *id_priv;
+ 	int ret = NOTIFY_DONE;
+ 
+-	if (dev_net(ndev) != &init_net)
+-		return NOTIFY_DONE;
+-
+ 	if (event != NETDEV_BONDING_FAILOVER)
+ 		return NOTIFY_DONE;
+ 
+-	if (!(ndev->flags & IFF_MASTER) || !(ndev->priv_flags & IFF_BONDING))
++	if (!(ndev->flags & IFF_MASTER))
+ 		return NOTIFY_DONE;
+ 
+ 	mutex_lock(&lock);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_0_sysfs_to_2_6_25.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_0_sysfs_to_2_6_25.patch
new file mode 100644
index 0000000..504cf73
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_0_sysfs_to_2_6_25.patch
@@ -0,0 +1,81 @@
+---
+ drivers/infiniband/core/cm.c          |    4 ++--
+ drivers/infiniband/core/user_mad.c    |   14 ++++++++------
+ drivers/infiniband/core/uverbs_main.c |   11 +++++------
+ 3 files changed, 15 insertions(+), 14 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/cm.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/cm.c
++++ ofed_kernel/drivers/infiniband/core/cm.c
+@@ -3738,8 +3738,8 @@ static void cm_add_one(struct ib_device 
+ 	cm_dev->ib_device = ib_device;
+ 	cm_get_ack_delay(cm_dev);
+ 
+-	cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
+-					       MKDEV(0, 0), NULL,
++	cm_dev->device = device_create(&cm_class, &ib_device->dev,
++					       MKDEV(0, 0),
+ 					       "%s", ib_device->name);
+ 	if (!cm_dev->device) {
+ 		kfree(cm_dev);
+Index: ofed_kernel/drivers/infiniband/core/user_mad.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/user_mad.c
++++ ofed_kernel/drivers/infiniband/core/user_mad.c
+@@ -1016,9 +1016,8 @@ static int ib_umad_init_port(struct ib_d
+ 	if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
+ 		goto err_cdev;
+ 
+-	port->dev = device_create_drvdata(umad_class, device->dma_device,
+-					  port->cdev->dev, port,
+-					  "umad%d", port->dev_num);
++	port->dev = device_create(umad_class, device->dma_device,
++				  port->cdev->dev, "umad%d", port->dev_num);
+ 	if (IS_ERR(port->dev))
+ 		goto err_cdev;
+ 
+@@ -1036,12 +1035,15 @@ static int ib_umad_init_port(struct ib_d
+ 	if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
+ 		goto err_sm_cdev;
+ 
+-	port->sm_dev = device_create_drvdata(umad_class, device->dma_device,
+-					     port->sm_cdev->dev, port,
+-					     "issm%d", port->dev_num);
++	port->sm_dev = device_create(umad_class, device->dma_device,
++				     port->sm_cdev->dev,
++				     "issm%d", port->dev_num);
+ 	if (IS_ERR(port->sm_dev))
+ 		goto err_sm_cdev;
+ 
++	dev_set_drvdata(port->dev,    port);
++	dev_set_drvdata(port->sm_dev, port);
++
+ 	if (device_create_file(port->sm_dev, &dev_attr_ibdev))
+ 		goto err_sm_dev;
+ 	if (device_create_file(port->sm_dev, &dev_attr_port))
+Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
++++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
+@@ -802,15 +802,14 @@ static void ib_uverbs_add_one(struct ib_
+ 	if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+ 		goto err_cdev;
+ 
+-	uverbs_dev->dev = device_create_drvdata(uverbs_class,
+-						device->dma_device,
+-						uverbs_dev->cdev->dev,
+-						uverbs_dev,
+-						"uverbs%d",
+-						uverbs_dev->devnum);
++	uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
++					uverbs_dev->cdev->dev,
++					"uverbs%d", uverbs_dev->devnum);
+ 	if (IS_ERR(uverbs_dev->dev))
+ 		goto err_cdev;
+ 
++	dev_set_drvdata(uverbs_dev->dev, uverbs_dev);
++
+ 	if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev))
+ 		goto err_class;
+ 	if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_1_kobject_backport.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_1_kobject_backport.patch
new file mode 100644
index 0000000..b96dcf6
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_1_kobject_backport.patch
@@ -0,0 +1,191 @@
+---
+ drivers/infiniband/core/Makefile           |    4 
+ drivers/infiniband/core/kobject_backport.c |  160 +++++++++++++++++++++++++++++
+ 2 files changed, 162 insertions(+), 2 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/Makefile
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/Makefile
++++ ofed_kernel/drivers/infiniband/core/Makefile
+@@ -8,14 +8,14 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) +=	
+ 					$(user_access-y)
+ 
+ ib_core-y :=			packer.o ud_header.o verbs.o sysfs.o \
+-				device.o fmr_pool.o cache.o
++				device.o fmr_pool.o cache.o kobject_backport.o
+ ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
+ 
+ ib_mad-y :=			mad.o smi.o agent.o mad_rmpp.o
+ 
+ ib_sa-y :=			sa_query.o multicast.o notice.o local_sa.o
+ 
+-ib_cm-y :=			cm.o
++ib_cm-y :=			cm.o kobject_backport.o
+ 
+ iw_cm-y :=			iwcm.o
+ 
+Index: ofed_kernel/drivers/infiniband/core/kobject_backport.c
+===================================================================
+--- /dev/null
++++ ofed_kernel/drivers/infiniband/core/kobject_backport.c
+@@ -0,0 +1,160 @@
++#include <linux/slab.h>
++#include <linux/kobject.h>
++
++struct kobj_attribute {
++	struct attribute attr;
++	ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
++			char *buf);
++	ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
++			 const char *buf, size_t count);
++};
++
++/* default kobject attribute operations */
++static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
++			      char *buf)
++{
++	struct kobj_attribute *kattr;
++	ssize_t ret = -EIO;
++
++	kattr = container_of(attr, struct kobj_attribute, attr);
++	if (kattr->show)
++		ret = kattr->show(kobj, kattr, buf);
++	return ret;
++}
++
++static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
++			       const char *buf, size_t count)
++{
++	struct kobj_attribute *kattr;
++	ssize_t ret = -EIO;
++
++	kattr = container_of(attr, struct kobj_attribute, attr);
++	if (kattr->store)
++		ret = kattr->store(kobj, kattr, buf, count);
++	return ret;
++}
++
++static struct sysfs_ops kobj_sysfs_ops = {
++	.show   = kobj_attr_show,
++	.store  = kobj_attr_store,
++};
++
++static void dynamic_kobj_release(struct kobject *kobj)
++{
++	pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__);
++	kfree(kobj);
++}
++
++static struct kobj_type dynamic_kobj_ktype = {
++	.release        = dynamic_kobj_release,
++	.sysfs_ops      = &kobj_sysfs_ops,
++};
++
++/**
++ * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs
++ *
++ * @name: the name for the kset
++ * @parent: the parent kobject of this kobject, if any.
++ *
++ * This function creates a kobject structure dynamically and registers it
++ * with sysfs.  When you are finished with this structure, call
++ * kobject_put() and the structure will be dynamically freed when
++ * it is no longer being used.
++ *
++ * If the kobject was not able to be created, NULL will be returned.
++ */
++struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
++{
++	struct kobject *kobj;
++	int retval;
++
++	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
++	if (!kobj)
++		return NULL;
++
++	kobject_init(kobj);
++	kobj->ktype = &dynamic_kobj_ktype;
++	kobj->parent = parent;
++
++	retval = kobject_set_name(kobj, "%s", name);
++	if (retval) {
++		printk(KERN_WARNING "%s: kobject_set_name error: %d\n",
++			__FUNCTION__, retval);
++		goto err;
++	}
++
++	retval = kobject_add(kobj);
++	if (retval) {
++		printk(KERN_WARNING "%s: kobject_add error: %d\n",
++			__FUNCTION__, retval);
++		goto err;
++	}
++
++	return kobj;
++
++err:
++	kobject_put(kobj);
++	return NULL;
++}
++
++/**
++ * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy
++ * @kobj: pointer to the kobject to initialize
++ * @ktype: pointer to the ktype for this kobject.
++ * @parent: pointer to the parent of this kobject.
++ * @fmt: the name of the kobject.
++ *
++ * This function combines the call to kobject_init() and
++ * kobject_add().  The same type of error handling after a call to
++ * kobject_add() and kobject lifetime rules are the same here.
++ */
++int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
++                         struct kobject *parent, const char *fmt, ...)
++{
++	int retval;
++	int limit;
++	int need;
++	va_list args;
++	char *name;
++
++	/* find out how big a buffer we need */
++	name = kmalloc(1024, GFP_KERNEL);
++	if (!name) {
++		retval = -ENOMEM;
++		goto out;
++	}
++	va_start(args, fmt);
++	need = vsnprintf(name, 1024, fmt, args);
++	va_end(args);
++	kfree(name);
++
++	/* Allocate the new space and copy the string in */
++	limit = need + 1;
++	name = kmalloc(limit, GFP_KERNEL);
++	if (!name) {
++		retval = -ENOMEM;
++		goto out;
++	}
++
++	va_start(args, fmt);
++	need = vsnprintf(name, limit, fmt, args);
++	va_end(args);
++
++	kobject_init(kobj);
++
++	kobj->ktype = ktype;
++	kobj->parent = parent;
++
++	retval = kobject_set_name(kobj, name);
++	kfree(name);
++	if (retval)
++		goto out;
++
++	retval = kobject_add(kobj);
++	if (retval)
++		goto out;
++
++out:
++	return retval;
++}
++
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_2_kobject_unregister_to_2_6_24.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_2_kobject_unregister_to_2_6_24.patch
new file mode 100644
index 0000000..1239f4b
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_2_kobject_unregister_to_2_6_24.patch
@@ -0,0 +1,64 @@
+---
+ drivers/infiniband/core/cm.c    |    8 ++++----
+ drivers/infiniband/core/sysfs.c |    8 +++++---
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/cm.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/cm.c
++++ ofed_kernel/drivers/infiniband/core/cm.c
+@@ -3696,8 +3696,8 @@ static int cm_create_port_fs(struct cm_p
+ 
+ error:
+ 	while (i--)
+-		kobject_put(&port->counter_group[i].obj);
+-	kobject_put(&port->port_obj);
++		kobject_unregister(&port->counter_group[i].obj);
++	kobject_unregister(&port->port_obj);
+ 	return ret;
+ 
+ }
+@@ -3707,9 +3707,9 @@ static void cm_remove_port_fs(struct cm_
+ 	int i;
+ 
+ 	for (i = 0; i < CM_COUNTER_GROUPS; i++)
+-		kobject_put(&port->counter_group[i].obj);
++		kobject_unregister(&port->counter_group[i].obj);
+ 
+-	kobject_put(&port->port_obj);
++	kobject_unregister(&port->port_obj);
+ }
+ 
+ static void cm_add_one(struct ib_device *ib_device)
+Index: ofed_kernel/drivers/infiniband/core/sysfs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/sysfs.c
++++ ofed_kernel/drivers/infiniband/core/sysfs.c
+@@ -838,11 +838,11 @@ err_put:
+ 			sysfs_remove_group(p, &pma_group);
+ 			sysfs_remove_group(p, &port->pkey_group);
+ 			sysfs_remove_group(p, &port->gid_group);
+-			kobject_put(p);
++			kobject_unregister(p);
+ 		}
+ 	}
+ 
+-	kobject_put(&class_dev->kobj);
++	kobject_unregister(&class_dev->kobj);
+ 
+ err_unregister:
+ 	device_unregister(class_dev);
+@@ -862,10 +862,12 @@ void ib_device_unregister_sysfs(struct i
+ 		sysfs_remove_group(p, &pma_group);
+ 		sysfs_remove_group(p, &port->pkey_group);
+ 		sysfs_remove_group(p, &port->gid_group);
+-		kobject_put(p);
++		kobject_unregister(p);
+ 	}
+ 
+ 	kobject_put(device->ports_parent);
++	/* WA for memory leak */
++	kfree(device->ports_parent);
+ 	device_unregister(&device->dev);
+ }
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_2_z010_sysfs_to_2.6.18.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_2_z010_sysfs_to_2.6.18.patch
new file mode 100644
index 0000000..5d1d562
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_2_z010_sysfs_to_2.6.18.patch
@@ -0,0 +1,32 @@
+--- a/drivers/infiniband/core/device.c	2009-02-24 14:00:50.387541000 +0200
++++ b/drivers/infiniband/core/device.c	2009-02-24 14:00:54.891362000 +0200
+@@ -199,7 +199,7 @@ void ib_dealloc_device(struct ib_device 
+ 
+ 	BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
+ 
+-	kobject_put(&device->dev.kobj);
++	ib_device_unregister_sysfs(device);
+ }
+ EXPORT_SYMBOL(ib_dealloc_device);
+ 
+@@ -356,8 +356,6 @@ void ib_unregister_device(struct ib_devi
+ 
+ 	mutex_unlock(&device_mutex);
+ 
+-	ib_device_unregister_sysfs(device);
+-
+ 	spin_lock_irqsave(&device->client_data_lock, flags);
+ 	list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
+ 		kfree(context);
+--- a/drivers/infiniband/core/sysfs.c	2009-02-24 13:58:42.509754000 +0200
++++ b/drivers/infiniband/core/sysfs.c	2009-02-24 14:00:54.894368000 +0200
+@@ -863,9 +863,6 @@ void ib_device_unregister_sysfs(struct i
+ 	struct kobject *p, *t;
+ 	struct ib_port *port;
+ 
+-	/* Hold kobject until ib_dealloc_device() */
+-	kobject_get(&device->dev.kobj);
+-
+ 	list_for_each_entry_safe(p, t, &device->port_list, entry) {
+ 		list_del(&p->entry);
+ 		port = container_of(p, struct ib_port, kobj);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_3_sysfs_to_2_6_18.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_3_sysfs_to_2_6_18.patch
new file mode 100644
index 0000000..c65a40a
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_3_sysfs_to_2_6_18.patch
@@ -0,0 +1,761 @@
+---
+ drivers/infiniband/core/cm.c          |    2 
+ drivers/infiniband/core/sysfs.c       |  172 ++++++++++++++++------------------
+ drivers/infiniband/core/ucm.c         |   62 ++++++------
+ drivers/infiniband/core/user_mad.c    |  109 ++++++++++-----------
+ drivers/infiniband/core/uverbs.h      |    4 
+ drivers/infiniband/core/uverbs_main.c |   51 ++++------
+ include/rdma/ib_verbs.h               |    2 
+ 7 files changed, 199 insertions(+), 203 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/cm.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/cm.c
++++ ofed_kernel/drivers/infiniband/core/cm.c
+@@ -3738,7 +3738,7 @@ static void cm_add_one(struct ib_device 
+ 	cm_dev->ib_device = ib_device;
+ 	cm_get_ack_delay(cm_dev);
+ 
+-	cm_dev->device = device_create(&cm_class, &ib_device->dev,
++	cm_dev->device = device_create(&cm_class, ib_device->class_dev.dev,
+ 					       MKDEV(0, 0),
+ 					       "%s", ib_device->name);
+ 	if (!cm_dev->device) {
+Index: ofed_kernel/drivers/infiniband/core/sysfs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/sysfs.c
++++ ofed_kernel/drivers/infiniband/core/sysfs.c
+@@ -425,25 +425,28 @@ static struct kobj_type port_type = {
+ 	.default_attrs = port_default_attrs
+ };
+ 
+-static void ib_device_release(struct device *device)
++static void ib_device_release(struct class_device *cdev)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 
+ 	kfree(dev);
+ }
+ 
+-static int ib_device_uevent(struct device *device,
+-			    struct kobj_uevent_env *env)
++static int ib_device_uevent(struct class_device *cdev, char **envp,
++			    int num_envp, char *buf, int size)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
++	int i = 0, len = 0;
+ 
+-	if (add_uevent_var(env, "NAME=%s", dev->name))
++	if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
++			   "NAME=%s", dev->name))
+ 		return -ENOMEM;
+ 
+ 	/*
+ 	 * It would be nice to pass the node GUID with the event...
+ 	 */
+ 
++	envp[i] = NULL;
+ 	return 0;
+ }
+ 
+@@ -565,10 +568,9 @@ err_put:
+ 	return ret;
+ }
+ 
+-static ssize_t show_node_type(struct device *device,
+-			      struct device_attribute *attr, char *buf)
++static ssize_t show_node_type(struct class_device *cdev, char *buf)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 
+ 	if (!ibdev_is_alive(dev))
+ 		return -ENODEV;
+@@ -582,10 +584,9 @@ static ssize_t show_node_type(struct dev
+ 	}
+ }
+ 
+-static ssize_t show_sys_image_guid(struct device *device,
+-				   struct device_attribute *dev_attr, char *buf)
++static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 	struct ib_device_attr attr;
+ 	ssize_t ret;
+ 
+@@ -603,10 +604,9 @@ static ssize_t show_sys_image_guid(struc
+ 		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
+ }
+ 
+-static ssize_t show_node_guid(struct device *device,
+-			      struct device_attribute *attr, char *buf)
++static ssize_t show_node_guid(struct class_device *cdev, char *buf)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 
+ 	if (!ibdev_is_alive(dev))
+ 		return -ENODEV;
+@@ -618,19 +618,17 @@ static ssize_t show_node_guid(struct dev
+ 		       be16_to_cpu(((__be16 *) &dev->node_guid)[3]));
+ }
+ 
+-static ssize_t show_node_desc(struct device *device,
+-			      struct device_attribute *attr, char *buf)
++static ssize_t show_node_desc(struct class_device *cdev, char *buf)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 
+ 	return sprintf(buf, "%.64s\n", dev->node_desc);
+ }
+ 
+-static ssize_t set_node_desc(struct device *device,
+-			     struct device_attribute *attr,
+-			     const char *buf, size_t count)
++static ssize_t set_node_desc(struct class_device *cdev, const char *buf,
++			      size_t count)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 	struct ib_device_modify desc = {};
+ 	int ret;
+ 
+@@ -645,30 +643,30 @@ static ssize_t set_node_desc(struct devi
+ 	return count;
+ }
+ 
+-static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
+-static DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
+-static DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
+-static DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc);
+-
+-static struct device_attribute *ib_class_attributes[] = {
+-	&dev_attr_node_type,
+-	&dev_attr_sys_image_guid,
+-	&dev_attr_node_guid,
+-	&dev_attr_node_desc
++static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
++static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
++static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
++static CLASS_DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc);
++
++static struct class_device_attribute *ib_class_attributes[] = {
++	&class_device_attr_node_type,
++	&class_device_attr_sys_image_guid,
++	&class_device_attr_node_guid,
++	&class_device_attr_node_desc
+ };
+ 
+ static struct class ib_class = {
+ 	.name    = "infiniband",
+-	.dev_release = ib_device_release,
+-	.dev_uevent = ib_device_uevent,
++	.release = ib_device_release,
++	.uevent = ib_device_uevent,
+ };
+ 
+ /* Show a given an attribute in the statistics group */
+-static ssize_t show_protocol_stat(const struct device *device,
+-			    struct device_attribute *attr, char *buf,
++static ssize_t show_protocol_stat(struct class_device *cdev,
++			    char *buf,
+ 			    unsigned offset)
+ {
+-	struct ib_device *dev = container_of(device, struct ib_device, dev);
++	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+ 	union rdma_protocol_stats stats;
+ 	ssize_t ret;
+ 
+@@ -682,14 +680,14 @@ static ssize_t show_protocol_stat(const 
+ 
+ /* generate a read-only iwarp statistics attribute */
+ #define IW_STATS_ENTRY(name)						\
+-static ssize_t show_##name(struct device *device,			\
+-			   struct device_attribute *attr, char *buf)	\
++static ssize_t show_##name(struct class_device *cdev,			\
++			   char *buf)					\
+ {									\
+-	return show_protocol_stat(device, attr, buf,			\
++	return show_protocol_stat(cdev, buf,			\
+ 				  offsetof(struct iw_protocol_stats, name) / \
+ 				  sizeof (u64));			\
+ }									\
+-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
++static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+ 
+ IW_STATS_ENTRY(ipInReceives);
+ IW_STATS_ENTRY(ipInHdrErrors);
+@@ -731,44 +729,44 @@ IW_STATS_ENTRY(tcpInErrs);
+ IW_STATS_ENTRY(tcpOutRsts);
+ 
+ static struct attribute *iw_proto_stats_attrs[] = {
+-	&dev_attr_ipInReceives.attr,
+-	&dev_attr_ipInHdrErrors.attr,
+-	&dev_attr_ipInTooBigErrors.attr,
+-	&dev_attr_ipInNoRoutes.attr,
+-	&dev_attr_ipInAddrErrors.attr,
+-	&dev_attr_ipInUnknownProtos.attr,
+-	&dev_attr_ipInTruncatedPkts.attr,
+-	&dev_attr_ipInDiscards.attr,
+-	&dev_attr_ipInDelivers.attr,
+-	&dev_attr_ipOutForwDatagrams.attr,
+-	&dev_attr_ipOutRequests.attr,
+-	&dev_attr_ipOutDiscards.attr,
+-	&dev_attr_ipOutNoRoutes.attr,
+-	&dev_attr_ipReasmTimeout.attr,
+-	&dev_attr_ipReasmReqds.attr,
+-	&dev_attr_ipReasmOKs.attr,
+-	&dev_attr_ipReasmFails.attr,
+-	&dev_attr_ipFragOKs.attr,
+-	&dev_attr_ipFragFails.attr,
+-	&dev_attr_ipFragCreates.attr,
+-	&dev_attr_ipInMcastPkts.attr,
+-	&dev_attr_ipOutMcastPkts.attr,
+-	&dev_attr_ipInBcastPkts.attr,
+-	&dev_attr_ipOutBcastPkts.attr,
+-	&dev_attr_tcpRtoAlgorithm.attr,
+-	&dev_attr_tcpRtoMin.attr,
+-	&dev_attr_tcpRtoMax.attr,
+-	&dev_attr_tcpMaxConn.attr,
+-	&dev_attr_tcpActiveOpens.attr,
+-	&dev_attr_tcpPassiveOpens.attr,
+-	&dev_attr_tcpAttemptFails.attr,
+-	&dev_attr_tcpEstabResets.attr,
+-	&dev_attr_tcpCurrEstab.attr,
+-	&dev_attr_tcpInSegs.attr,
+-	&dev_attr_tcpOutSegs.attr,
+-	&dev_attr_tcpRetransSegs.attr,
+-	&dev_attr_tcpInErrs.attr,
+-	&dev_attr_tcpOutRsts.attr,
++	&class_device_attr_ipInReceives.attr,
++	&class_device_attr_ipInHdrErrors.attr,
++	&class_device_attr_ipInTooBigErrors.attr,
++	&class_device_attr_ipInNoRoutes.attr,
++	&class_device_attr_ipInAddrErrors.attr,
++	&class_device_attr_ipInUnknownProtos.attr,
++	&class_device_attr_ipInTruncatedPkts.attr,
++	&class_device_attr_ipInDiscards.attr,
++	&class_device_attr_ipInDelivers.attr,
++	&class_device_attr_ipOutForwDatagrams.attr,
++	&class_device_attr_ipOutRequests.attr,
++	&class_device_attr_ipOutDiscards.attr,
++	&class_device_attr_ipOutNoRoutes.attr,
++	&class_device_attr_ipReasmTimeout.attr,
++	&class_device_attr_ipReasmReqds.attr,
++	&class_device_attr_ipReasmOKs.attr,
++	&class_device_attr_ipReasmFails.attr,
++	&class_device_attr_ipFragOKs.attr,
++	&class_device_attr_ipFragFails.attr,
++	&class_device_attr_ipFragCreates.attr,
++	&class_device_attr_ipInMcastPkts.attr,
++	&class_device_attr_ipOutMcastPkts.attr,
++	&class_device_attr_ipInBcastPkts.attr,
++	&class_device_attr_ipOutBcastPkts.attr,
++	&class_device_attr_tcpRtoAlgorithm.attr,
++	&class_device_attr_tcpRtoMin.attr,
++	&class_device_attr_tcpRtoMax.attr,
++	&class_device_attr_tcpMaxConn.attr,
++	&class_device_attr_tcpActiveOpens.attr,
++	&class_device_attr_tcpPassiveOpens.attr,
++	&class_device_attr_tcpAttemptFails.attr,
++	&class_device_attr_tcpEstabResets.attr,
++	&class_device_attr_tcpCurrEstab.attr,
++	&class_device_attr_tcpInSegs.attr,
++	&class_device_attr_tcpOutSegs.attr,
++	&class_device_attr_tcpRetransSegs.attr,
++	&class_device_attr_tcpInErrs.attr,
++	&class_device_attr_tcpOutRsts.attr,
+ 	NULL
+ };
+ 
+@@ -779,23 +777,23 @@ static struct attribute_group iw_stats_g
+ 
+ int ib_device_register_sysfs(struct ib_device *device)
+ {
+-	struct device *class_dev = &device->dev;
++	struct class_device *class_dev = &device->class_dev;
+ 	int ret;
+ 	int i;
+ 
+ 	class_dev->class      = &ib_class;
+-	class_dev->driver_data = device;
+-	class_dev->parent     = device->dma_device;
+-	strlcpy(class_dev->bus_id, device->name, BUS_ID_SIZE);
++	class_dev->class_data = device;
++	class_dev->dev	      = device->dma_device;
++	strlcpy(class_dev->class_id, device->name, BUS_ID_SIZE);
+ 
+ 	INIT_LIST_HEAD(&device->port_list);
+ 
+-	ret = device_register(class_dev);
++	ret = class_device_register(class_dev);
+ 	if (ret)
+ 		goto err;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) {
+-		ret = device_create_file(class_dev, ib_class_attributes[i]);
++		ret = class_device_create_file(class_dev, ib_class_attributes[i]);
+ 		if (ret)
+ 			goto err_unregister;
+ 	}
+@@ -845,7 +843,7 @@ err_put:
+ 	kobject_unregister(&class_dev->kobj);
+ 
+ err_unregister:
+-	device_unregister(class_dev);
++	class_device_unregister(class_dev);
+ 
+ err:
+ 	return ret;
+@@ -868,7 +866,7 @@ void ib_device_unregister_sysfs(struct i
+ 	kobject_put(device->ports_parent);
+ 	/* WA for memory leak */
+ 	kfree(device->ports_parent);
+-	device_unregister(&device->dev);
++	class_device_unregister(&device->class_dev);
+ }
+ 
+ int ib_sysfs_setup(void)
+Index: ofed_kernel/drivers/infiniband/core/ucm.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/ucm.c
++++ ofed_kernel/drivers/infiniband/core/ucm.c
+@@ -56,8 +56,8 @@ MODULE_LICENSE("Dual BSD/GPL");
+ 
+ struct ib_ucm_device {
+ 	int			devnum;
+-	struct cdev		cdev;
+-	struct device		dev;
++	struct cdev		dev;
++	struct class_device	class_dev;
+ 	struct ib_device	*ib_dev;
+ };
+ 
+@@ -1177,7 +1177,7 @@ static int ib_ucm_open(struct inode *ino
+ 
+ 	filp->private_data = file;
+ 	file->filp = filp;
+-	file->device = container_of(inode->i_cdev, struct ib_ucm_device, cdev);
++	file->device = container_of(inode->i_cdev, struct ib_ucm_device, dev);
+ 
+ 	return 0;
+ }
+@@ -1208,14 +1208,14 @@ static int ib_ucm_close(struct inode *in
+ 	return 0;
+ }
+ 
+-static void ib_ucm_release_dev(struct device *dev)
++static void ucm_release_class_dev(struct class_device *class_dev)
+ {
+-	struct ib_ucm_device *ucm_dev;
++	struct ib_ucm_device *dev;
+ 
+-	ucm_dev = container_of(dev, struct ib_ucm_device, dev);
+-	cdev_del(&ucm_dev->cdev);
+-	clear_bit(ucm_dev->devnum, dev_map);
+-	kfree(ucm_dev);
++	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
++	cdev_del(&dev->dev);
++	clear_bit(dev->devnum, dev_map);
++	kfree(dev);
+ }
+ 
+ static const struct file_operations ucm_fops = {
+@@ -1226,15 +1226,14 @@ static const struct file_operations ucm_
+ 	.poll    = ib_ucm_poll,
+ };
+ 
+-static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_ucm_device *ucm_dev;
++	struct ib_ucm_device *dev;
+ 
+-	ucm_dev = container_of(dev, struct ib_ucm_device, dev);
+-	return sprintf(buf, "%s\n", ucm_dev->ib_dev->name);
++	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
++	return sprintf(buf, "%s\n", dev->ib_dev->name);
+ }
+-static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
++static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+ 
+ static void ib_ucm_add_one(struct ib_device *device)
+ {
+@@ -1256,31 +1255,32 @@ static void ib_ucm_add_one(struct ib_dev
+ 
+ 	set_bit(ucm_dev->devnum, dev_map);
+ 
+-	cdev_init(&ucm_dev->cdev, &ucm_fops);
+-	ucm_dev->cdev.owner = THIS_MODULE;
+-	kobject_set_name(&ucm_dev->cdev.kobj, "ucm%d", ucm_dev->devnum);
+-	if (cdev_add(&ucm_dev->cdev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
++	cdev_init(&ucm_dev->dev, &ucm_fops);
++	ucm_dev->dev.owner = THIS_MODULE;
++	kobject_set_name(&ucm_dev->dev.kobj, "ucm%d", ucm_dev->devnum);
++	if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
+ 		goto err;
+ 
+-	ucm_dev->dev.class = &cm_class;
+-	ucm_dev->dev.parent = device->dma_device;
+-	ucm_dev->dev.devt = ucm_dev->cdev.dev;
+-	ucm_dev->dev.release = ib_ucm_release_dev;
+-	snprintf(ucm_dev->dev.bus_id, BUS_ID_SIZE, "ucm%d",
++	ucm_dev->class_dev.class = &cm_class;
++	ucm_dev->class_dev.dev = device->dma_device;
++	ucm_dev->class_dev.devt = ucm_dev->dev.dev;
++	ucm_dev->class_dev.release = ucm_release_class_dev;
++	snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
+ 		 ucm_dev->devnum);
+-	if (device_register(&ucm_dev->dev))
++	if (class_device_register(&ucm_dev->class_dev))
+ 		goto err_cdev;
+ 
+-	if (device_create_file(&ucm_dev->dev, &dev_attr_ibdev))
+-		goto err_dev;
++	if (class_device_create_file(&ucm_dev->class_dev,
++				     &class_device_attr_ibdev))
++		goto err_class;
+ 
+ 	ib_set_client_data(device, &ucm_client, ucm_dev);
+ 	return;
+ 
+-err_dev:
+-	device_unregister(&ucm_dev->dev);
++err_class:
++	class_device_unregister(&ucm_dev->class_dev);
+ err_cdev:
+-	cdev_del(&ucm_dev->cdev);
++	cdev_del(&ucm_dev->dev);
+ 	clear_bit(ucm_dev->devnum, dev_map);
+ err:
+ 	kfree(ucm_dev);
+@@ -1294,7 +1294,7 @@ static void ib_ucm_remove_one(struct ib_
+ 	if (!ucm_dev)
+ 		return;
+ 
+-	device_unregister(&ucm_dev->dev);
++	class_device_unregister(&ucm_dev->class_dev);
+ }
+ 
+ static ssize_t show_abi_version(struct class *class, char *buf)
+Index: ofed_kernel/drivers/infiniband/core/user_mad.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/user_mad.c
++++ ofed_kernel/drivers/infiniband/core/user_mad.c
+@@ -86,11 +86,11 @@ enum {
+  */
+ 
+ struct ib_umad_port {
+-	struct cdev           *cdev;
+-	struct device	      *dev;
++	struct cdev           *dev;
++	struct class_device   *class_dev;
+ 
+-	struct cdev           *sm_cdev;
+-	struct device	      *sm_dev;
++	struct cdev           *sm_dev;
++	struct class_device   *sm_class_dev;
+ 	struct semaphore       sm_sem;
+ 
+ 	struct mutex	       file_mutex;
+@@ -959,29 +959,27 @@ static struct ib_client umad_client = {
+ 	.remove = ib_umad_remove_one
+ };
+ 
+-static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_umad_port *port = dev_get_drvdata(dev);
++	struct ib_umad_port *port = class_get_devdata(class_dev);
+ 
+ 	if (!port)
+ 		return -ENODEV;
+ 
+ 	return sprintf(buf, "%s\n", port->ib_dev->name);
+ }
+-static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
++static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+ 
+-static ssize_t show_port(struct device *dev, struct device_attribute *attr,
+-			 char *buf)
++static ssize_t show_port(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_umad_port *port = dev_get_drvdata(dev);
++	struct ib_umad_port *port = class_get_devdata(class_dev);
+ 
+ 	if (!port)
+ 		return -ENODEV;
+ 
+ 	return sprintf(buf, "%d\n", port->port_num);
+ }
+-static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
++static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+ 
+ static ssize_t show_abi_version(struct class *class, char *buf)
+ {
+@@ -1007,47 +1005,48 @@ static int ib_umad_init_port(struct ib_d
+ 	mutex_init(&port->file_mutex);
+ 	INIT_LIST_HEAD(&port->file_list);
+ 
+-	port->cdev = cdev_alloc();
+-	if (!port->cdev)
++	port->dev = cdev_alloc();
++	if (!port->dev)
+ 		return -1;
+-	port->cdev->owner = THIS_MODULE;
+-	port->cdev->ops   = &umad_fops;
+-	kobject_set_name(&port->cdev->kobj, "umad%d", port->dev_num);
+-	if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
++	port->dev->owner = THIS_MODULE;
++	port->dev->ops   = &umad_fops;
++	kobject_set_name(&port->dev->kobj, "umad%d", port->dev_num);
++	if (cdev_add(port->dev, base_dev + port->dev_num, 1))
+ 		goto err_cdev;
+ 
+-	port->dev = device_create(umad_class, device->dma_device,
+-				  port->cdev->dev, "umad%d", port->dev_num);
+-	if (IS_ERR(port->dev))
++	port->class_dev = class_device_create(umad_class, NULL, port->dev->dev,
++					      device->dma_device,
++					      "umad%d", port->dev_num);
++	if (IS_ERR(port->class_dev))
+ 		goto err_cdev;
+ 
+-	if (device_create_file(port->dev, &dev_attr_ibdev))
+-		goto err_dev;
+-	if (device_create_file(port->dev, &dev_attr_port))
+-		goto err_dev;
+-
+-	port->sm_cdev = cdev_alloc();
+-	if (!port->sm_cdev)
+-		goto err_dev;
+-	port->sm_cdev->owner = THIS_MODULE;
+-	port->sm_cdev->ops   = &umad_sm_fops;
+-	kobject_set_name(&port->sm_cdev->kobj, "issm%d", port->dev_num);
+-	if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
++	if (class_device_create_file(port->class_dev, &class_device_attr_ibdev))
++		goto err_class;
++	if (class_device_create_file(port->class_dev, &class_device_attr_port))
++		goto err_class;
++
++	port->sm_dev = cdev_alloc();
++	if (!port->sm_dev)
++		goto err_class;
++	port->sm_dev->owner = THIS_MODULE;
++	port->sm_dev->ops   = &umad_sm_fops;
++	kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
++	if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
+ 		goto err_sm_cdev;
+ 
+-	port->sm_dev = device_create(umad_class, device->dma_device,
+-				     port->sm_cdev->dev,
+-				     "issm%d", port->dev_num);
+-	if (IS_ERR(port->sm_dev))
++	port->sm_class_dev = class_device_create(umad_class, NULL, port->sm_dev->dev,
++						 device->dma_device,
++						 "issm%d", port->dev_num);
++	if (IS_ERR(port->sm_class_dev))
+ 		goto err_sm_cdev;
+ 
+-	dev_set_drvdata(port->dev,    port);
+-	dev_set_drvdata(port->sm_dev, port);
++	class_set_devdata(port->class_dev,    port);
++	class_set_devdata(port->sm_class_dev, port);
+ 
+-	if (device_create_file(port->sm_dev, &dev_attr_ibdev))
+-		goto err_sm_dev;
+-	if (device_create_file(port->sm_dev, &dev_attr_port))
+-		goto err_sm_dev;
++	if (class_device_create_file(port->sm_class_dev, &class_device_attr_ibdev))
++		goto err_sm_class;
++	if (class_device_create_file(port->sm_class_dev, &class_device_attr_port))
++		goto err_sm_class;
+ 
+ 	spin_lock(&port_lock);
+ 	umad_port[port->dev_num] = port;
+@@ -1055,17 +1054,17 @@ static int ib_umad_init_port(struct ib_d
+ 
+ 	return 0;
+ 
+-err_sm_dev:
+-	device_destroy(umad_class, port->sm_cdev->dev);
++err_sm_class:
++	class_device_destroy(umad_class, port->sm_dev->dev);
+ 
+ err_sm_cdev:
+-	cdev_del(port->sm_cdev);
++	cdev_del(port->sm_dev);
+ 
+-err_dev:
+-	device_destroy(umad_class, port->cdev->dev);
++err_class:
++	class_device_destroy(umad_class, port->dev->dev);
+ 
+ err_cdev:
+-	cdev_del(port->cdev);
++	cdev_del(port->dev);
+ 	clear_bit(port->dev_num, dev_map);
+ 
+ 	return -1;
+@@ -1077,14 +1076,14 @@ static void ib_umad_kill_port(struct ib_
+ 	int already_dead;
+ 	int id;
+ 
+-	dev_set_drvdata(port->dev,    NULL);
+-	dev_set_drvdata(port->sm_dev, NULL);
++	class_set_devdata(port->class_dev,    NULL);
++	class_set_devdata(port->sm_class_dev, NULL);
+ 
+-	device_destroy(umad_class, port->cdev->dev);
+-	device_destroy(umad_class, port->sm_cdev->dev);
++	class_device_destroy(umad_class, port->dev->dev);
++	class_device_destroy(umad_class, port->sm_dev->dev);
+ 
+-	cdev_del(port->cdev);
+-	cdev_del(port->sm_cdev);
++	cdev_del(port->dev);
++	cdev_del(port->sm_dev);
+ 
+ 	spin_lock(&port_lock);
+ 	umad_port[port->dev_num] = NULL;
+Index: ofed_kernel/drivers/infiniband/core/uverbs.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/uverbs.h
++++ ofed_kernel/drivers/infiniband/core/uverbs.h
+@@ -71,8 +71,8 @@ struct ib_uverbs_device {
+ 	struct kref				ref;
+ 	struct completion			comp;
+ 	int					devnum;
+-	struct cdev			       *cdev;
+-	struct device			       *dev;
++	struct cdev			       *dev;
++	struct class_device		       *class_dev;
+ 	struct ib_device		       *ib_dev;
+ 	int					num_comp_vectors;
+ };
+Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
++++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
+@@ -737,29 +737,27 @@ static struct ib_client uverbs_client = 
+ 	.remove = ib_uverbs_remove_one
+ };
+ 
+-static ssize_t show_ibdev(struct device *device, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_uverbs_device *dev = dev_get_drvdata(device);
++	struct ib_uverbs_device *dev = class_get_devdata(class_dev);
+ 
+ 	if (!dev)
+ 		return -ENODEV;
+ 
+ 	return sprintf(buf, "%s\n", dev->ib_dev->name);
+ }
+-static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
++static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+ 
+-static ssize_t show_dev_abi_version(struct device *device,
+-				    struct device_attribute *attr, char *buf)
++static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf)
+ {
+-	struct ib_uverbs_device *dev = dev_get_drvdata(device);
++	struct ib_uverbs_device *dev = class_get_devdata(class_dev);
+ 
+ 	if (!dev)
+ 		return -ENODEV;
+ 
+ 	return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver);
+ }
+-static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
++static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
+ 
+ static ssize_t show_abi_version(struct class *class, char *buf)
+ {
+@@ -793,26 +791,27 @@ static void ib_uverbs_add_one(struct ib_
+ 	uverbs_dev->ib_dev           = device;
+ 	uverbs_dev->num_comp_vectors = device->num_comp_vectors;
+ 
+-	uverbs_dev->cdev = cdev_alloc();
+-	if (!uverbs_dev->cdev)
++	uverbs_dev->dev = cdev_alloc();
++	if (!uverbs_dev->dev)
+ 		goto err;
+-	uverbs_dev->cdev->owner = THIS_MODULE;
+-	uverbs_dev->cdev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
+-	kobject_set_name(&uverbs_dev->cdev->kobj, "uverbs%d", uverbs_dev->devnum);
+-	if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
++	uverbs_dev->dev->owner = THIS_MODULE;
++	uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
++	kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum);
++	if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+ 		goto err_cdev;
+ 
+-	uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
+-					uverbs_dev->cdev->dev,
+-					"uverbs%d", uverbs_dev->devnum);
+-	if (IS_ERR(uverbs_dev->dev))
++	uverbs_dev->class_dev = class_device_create(uverbs_class, NULL,
++						    uverbs_dev->dev->dev,
++						    device->dma_device,
++						    "uverbs%d", uverbs_dev->devnum);
++	if (IS_ERR(uverbs_dev->class_dev))
+ 		goto err_cdev;
+ 
+-	dev_set_drvdata(uverbs_dev->dev, uverbs_dev);
++	class_set_devdata(uverbs_dev->class_dev, uverbs_dev);
+ 
+-	if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev))
++	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev))
+ 		goto err_class;
+-	if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
++	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version))
+ 		goto err_class;
+ 
+ 	spin_lock(&map_lock);
+@@ -824,10 +823,10 @@ static void ib_uverbs_add_one(struct ib_
+ 	return;
+ 
+ err_class:
+-	device_destroy(uverbs_class, uverbs_dev->cdev->dev);
++	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
+ 
+ err_cdev:
+-	cdev_del(uverbs_dev->cdev);
++	cdev_del(uverbs_dev->dev);
+ 	clear_bit(uverbs_dev->devnum, dev_map);
+ 
+ err:
+@@ -844,9 +843,9 @@ static void ib_uverbs_remove_one(struct 
+ 	if (!uverbs_dev)
+ 		return;
+ 
+-	dev_set_drvdata(uverbs_dev->dev, NULL);
+-	device_destroy(uverbs_class, uverbs_dev->cdev->dev);
+-	cdev_del(uverbs_dev->cdev);
++	class_set_devdata(uverbs_dev->class_dev, NULL);
++	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
++	cdev_del(uverbs_dev->dev);
+ 
+ 	spin_lock(&map_lock);
+ 	dev_table[uverbs_dev->devnum] = NULL;
+Index: ofed_kernel/include/rdma/ib_verbs.h
+===================================================================
+--- ofed_kernel.orig/include/rdma/ib_verbs.h
++++ ofed_kernel/include/rdma/ib_verbs.h
+@@ -1196,7 +1196,7 @@ struct ib_device {
+ 	struct ib_dma_mapping_ops   *dma_ops;
+ 
+ 	struct module               *owner;
+-	struct device                dev;
++	struct class_device          class_dev;
+ 	struct kobject               *ports_parent;
+ 	struct list_head             port_list;
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_undo_weak_ordering.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_undo_weak_ordering.patch
new file mode 100644
index 0000000..7277c55
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_undo_weak_ordering.patch
@@ -0,0 +1,83 @@
+From 91f5e350089e023d485e42e6f30a7fcf28ea394c Mon Sep 17 00:00:00 2001
+From: Eli Cohen <eli at mellanox.co.il>
+Date: Tue, 28 Oct 2008 10:19:24 +0200
+Subject: [PATCH] Revert "ib_core: Use weak ordering for data registered memory"
+
+This reverts commit 4beb8b521a750990346adf47f549c7db5fd50893.
+
+Doing this for backports since the original patch requires API
+available in kernel 2.6.27 and newer.
+
+Signed-off-by: Eli Cohen <eli at mellanox.co.il>
+---
+ drivers/infiniband/core/umem.c |   12 ++----------
+ include/rdma/ib_umem.h         |    2 --
+ 2 files changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
+index da5e247..6f7c096 100644
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -40,10 +40,6 @@
+ 
+ #include "uverbs.h"
+ 
+-static int allow_weak_ordering;
+-module_param(allow_weak_ordering, bool, 0444);
+-MODULE_PARM_DESC(allow_weak_ordering,  "Allow weak ordering for data registered memory");
+-
+ #define IB_UMEM_MAX_PAGE_CHUNK						\
+ 	((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) /	\
+ 	 ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] -	\
+@@ -55,8 +51,8 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
+ 	int i;
+ 
+ 	list_for_each_entry_safe(chunk, tmp, &umem->chunk_list, list) {
+-		ib_dma_unmap_sg_attrs(dev, chunk->page_list,
+-				      chunk->nents, DMA_BIDIRECTIONAL, &chunk->attrs);
++		ib_dma_unmap_sg(dev, chunk->page_list,
++				chunk->nents, DMA_BIDIRECTIONAL);
+ 		for (i = 0; i < chunk->nents; ++i) {
+ 			struct page *page = sg_page(&chunk->page_list[i]);
+ 
+@@ -95,9 +91,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ 
+ 	if (dmasync)
+ 		dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
+-	else if (allow_weak_ordering)
+-		dma_set_attr(DMA_ATTR_WEAK_ORDERING, &attrs);
+-
+ 
+ 	if (!can_do_mlock())
+ 		return ERR_PTR(-EPERM);
+@@ -176,7 +169,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ 				goto out;
+ 			}
+ 
+-			chunk->attrs = attrs;
+ 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+ 			sg_init_table(chunk->page_list, chunk->nents);
+ 			for (i = 0; i < chunk->nents; ++i) {
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index 90f3712..9ee0d2e 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -36,7 +36,6 @@
+ #include <linux/list.h>
+ #include <linux/scatterlist.h>
+ #include <linux/workqueue.h>
+-#include <linux/dma-attrs.h>
+ 
+ struct ib_ucontext;
+ 
+@@ -57,7 +56,6 @@ struct ib_umem_chunk {
+ 	struct list_head	list;
+ 	int                     nents;
+ 	int                     nmap;
+-	struct dma_attrs	attrs;
+ 	struct scatterlist      page_list[0];
+ };
+ 
+-- 
+1.6.0.2
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/core_z0010_sysfs_race.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/core_z0010_sysfs_race.patch
new file mode 100644
index 0000000..73367e5
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/core_z0010_sysfs_race.patch
@@ -0,0 +1,496 @@
+ib_core: avoid race condition between sysfs access and low-level module unload. (V2)
+
+In newer kernels, although a low-level module will not be unloaded (code)
+while its sysfs interface is being accessed, it is possible for the module to
+free all its resources (data) during such access.  This almost always causes
+a kernel Oops.
+
+To avoid this, we protect the device reg_state with a mutex, and perform
+all sysfs operations (show, store) atomically within this mutex.
+
+V2: fix thinko bug in sysfs_state_show changes(found by Ralph Campbell).
+
+Signed-off-by: Jack Morgenstein <jackm at dev.mellanox.co.il>
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+Index: ofed_kernel/drivers/infiniband/core/device.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/device.c	2009-02-22 15:36:34.531430000 +0200
++++ ofed_kernel/drivers/infiniband/core/device.c	2009-02-22 15:38:28.650322000 +0200
+@@ -178,9 +178,14 @@ static int end_port(struct ib_device *de
+  */
+ struct ib_device *ib_alloc_device(size_t size)
+ {
++	struct ib_device *ibdev;
++
+ 	BUG_ON(size < sizeof (struct ib_device));
+ 
+-	return kzalloc(size, GFP_KERNEL);
++	ibdev = kzalloc(size, GFP_KERNEL);
++	if (ibdev)
++		mutex_init(&ibdev->sysfs_mutex);
++	return ibdev;
+ }
+ EXPORT_SYMBOL(ib_alloc_device);
+ 
+@@ -313,9 +318,10 @@ int ib_register_device(struct ib_device 
+ 		goto out;
+ 	}
+ 
++	mutex_lock(&device->sysfs_mutex);
+ 	list_add_tail(&device->core_list, &device_list);
+-
+ 	device->reg_state = IB_DEV_REGISTERED;
++	mutex_unlock(&device->sysfs_mutex);
+ 
+ 	{
+ 		struct ib_client *client;
+@@ -361,7 +367,9 @@ void ib_unregister_device(struct ib_devi
+ 		kfree(context);
+ 	spin_unlock_irqrestore(&device->client_data_lock, flags);
+ 
++	mutex_lock(&device->sysfs_mutex);
+ 	device->reg_state = IB_DEV_UNREGISTERED;
++	mutex_unlock(&device->sysfs_mutex);
+ }
+ EXPORT_SYMBOL(ib_unregister_device);
+ 
+Index: ofed_kernel/drivers/infiniband/core/sysfs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/sysfs.c	2009-02-22 15:36:35.914354000 +0200
++++ ofed_kernel/drivers/infiniband/core/sysfs.c	2009-02-22 16:12:37.485629000 +0200
+@@ -94,7 +94,7 @@ static ssize_t state_show(struct ib_port
+ 			  char *buf)
+ {
+ 	struct ib_port_attr attr;
+-	ssize_t ret;
++	ssize_t ret = -ENODEV;
+ 
+ 	static const char *state_name[] = {
+ 		[IB_PORT_NOP]		= "NOP",
+@@ -105,26 +105,33 @@ static ssize_t state_show(struct ib_port
+ 		[IB_PORT_ACTIVE_DEFER]	= "ACTIVE_DEFER"
+ 	};
+ 
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
+-
+-	return sprintf(buf, "%d: %s\n", attr.state,
+-		       attr.state >= 0 && attr.state < ARRAY_SIZE(state_name) ?
+-		       state_name[attr.state] : "UNKNOWN");
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret)
++			ret = sprintf(buf, "%d: %s\n", attr.state,
++				      attr.state >= 0 &&
++				      attr.state < ARRAY_SIZE(state_name) ?
++				      state_name[attr.state] : "UNKNOWN");
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t lid_show(struct ib_port *p, struct port_attribute *unused,
+ 			char *buf)
+ {
+ 	struct ib_port_attr attr;
+-	ssize_t ret;
++	ssize_t ret = -ENODEV;
+ 
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
+-
+-	return sprintf(buf, "0x%x\n", attr.lid);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret)
++			ret = sprintf(buf, "0x%x\n", attr.lid);
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t lid_mask_count_show(struct ib_port *p,
+@@ -132,52 +139,64 @@ static ssize_t lid_mask_count_show(struc
+ 				   char *buf)
+ {
+ 	struct ib_port_attr attr;
+-	ssize_t ret;
+-
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
++	ssize_t ret = -ENODEV;
+ 
+-	return sprintf(buf, "%d\n", attr.lmc);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret)
++			ret = sprintf(buf, "%d\n", attr.lmc);
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t sm_lid_show(struct ib_port *p, struct port_attribute *unused,
+ 			   char *buf)
+ {
+ 	struct ib_port_attr attr;
+-	ssize_t ret;
+-
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
++	ssize_t ret = -ENODEV;
+ 
+-	return sprintf(buf, "0x%x\n", attr.sm_lid);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret)
++			ret = sprintf(buf, "0x%x\n", attr.sm_lid);
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t sm_sl_show(struct ib_port *p, struct port_attribute *unused,
+ 			  char *buf)
+ {
+ 	struct ib_port_attr attr;
+-	ssize_t ret;
+-
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
++	ssize_t ret = -ENODEV;
+ 
+-	return sprintf(buf, "%d\n", attr.sm_sl);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret)
++			ret = sprintf(buf, "%d\n", attr.sm_sl);
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t cap_mask_show(struct ib_port *p, struct port_attribute *unused,
+ 			     char *buf)
+ {
+ 	struct ib_port_attr attr;
+-	ssize_t ret;
+-
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
++	ssize_t ret = -ENODEV;
+ 
+-	return sprintf(buf, "0x%08x\n", attr.port_cap_flags);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret)
++			ret = sprintf(buf, "0x%08x\n", attr.port_cap_flags);
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
+@@ -186,24 +205,33 @@ static ssize_t rate_show(struct ib_port 
+ 	struct ib_port_attr attr;
+ 	char *speed = "";
+ 	int rate;
+-	ssize_t ret;
++	ssize_t ret = -ENODEV;
+ 
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
+-
+-	switch (attr.active_speed) {
+-	case 2: speed = " DDR"; break;
+-	case 4: speed = " QDR"; break;
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret) {
++			switch (attr.active_speed) {
++			case 2: speed = " DDR"; break;
++			case 4: speed = " QDR"; break;
++			}
++
++			rate = 25 * ib_width_enum_to_int(attr.active_width) *
++				attr.active_speed;
++			if (rate < 0) {
++				ret = -EINVAL;
++				goto out;
++			}
++
++			ret = sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
++				      rate / 10, rate % 10 ? ".5" : "",
++				      ib_width_enum_to_int(attr.active_width),
++				      speed);
++		}
+ 	}
+-
+-	rate = 25 * ib_width_enum_to_int(attr.active_width) * attr.active_speed;
+-	if (rate < 0)
+-		return -EINVAL;
+-
+-	return sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
+-		       rate / 10, rate % 10 ? ".5" : "",
+-		       ib_width_enum_to_int(attr.active_width), speed);
++out:
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
+@@ -211,22 +239,42 @@ static ssize_t phys_state_show(struct ib
+ {
+ 	struct ib_port_attr attr;
+ 
+-	ssize_t ret;
+-
+-	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+-	if (ret)
+-		return ret;
++	ssize_t ret = -ENODEV;
+ 
+-	switch (attr.phys_state) {
+-	case 1:  return sprintf(buf, "1: Sleep\n");
+-	case 2:  return sprintf(buf, "2: Polling\n");
+-	case 3:  return sprintf(buf, "3: Disabled\n");
+-	case 4:  return sprintf(buf, "4: PortConfigurationTraining\n");
+-	case 5:  return sprintf(buf, "5: LinkUp\n");
+-	case 6:  return sprintf(buf, "6: LinkErrorRecovery\n");
+-	case 7:  return sprintf(buf, "7: Phy Test\n");
+-	default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_port(p->ibdev, p->port_num, &attr);
++		if (!ret) {
++			switch (attr.phys_state) {
++			case 1:
++				ret = sprintf(buf, "1: Sleep\n");
++				break;
++			case 2:
++				ret = sprintf(buf, "2: Polling\n");
++				break;
++			case 3:
++				ret = sprintf(buf, "3: Disabled\n");
++				break;
++			case 4:
++				ret = sprintf(buf, "4: PortConfigurationTraining\n");
++				break;
++			case 5:
++				ret = sprintf(buf, "5: LinkUp\n");
++				break;
++			case 6:
++				ret = sprintf(buf, "6: LinkErrorRecovery\n");
++				break;
++			case 7:
++				ret = sprintf(buf, "7: Phy Test\n");
++				break;
++			default:
++				ret = sprintf(buf, "%d: <unknown>\n", attr.phys_state);
++				break;
++			}
++		}
+ 	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static PORT_ATTR_RO(state);
+@@ -256,21 +304,24 @@ static ssize_t show_port_gid(struct ib_p
+ 	struct port_table_attribute *tab_attr =
+ 		container_of(attr, struct port_table_attribute, attr);
+ 	union ib_gid gid;
+-	ssize_t ret;
++	ssize_t ret = -ENODEV;
+ 
+-	ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid);
+-	if (ret)
+-		return ret;
+-
+-	return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+-		       be16_to_cpu(((__be16 *) gid.raw)[0]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[1]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[2]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[3]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[4]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[5]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[6]),
+-		       be16_to_cpu(((__be16 *) gid.raw)[7]));
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid);
++		if (!ret)
++			ret = sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
++				      be16_to_cpu(((__be16 *) gid.raw)[0]),
++				      be16_to_cpu(((__be16 *) gid.raw)[1]),
++				      be16_to_cpu(((__be16 *) gid.raw)[2]),
++				      be16_to_cpu(((__be16 *) gid.raw)[3]),
++				      be16_to_cpu(((__be16 *) gid.raw)[4]),
++				      be16_to_cpu(((__be16 *) gid.raw)[5]),
++				      be16_to_cpu(((__be16 *) gid.raw)[6]),
++				      be16_to_cpu(((__be16 *) gid.raw)[7]));
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
+@@ -279,13 +330,16 @@ static ssize_t show_port_pkey(struct ib_
+ 	struct port_table_attribute *tab_attr =
+ 		container_of(attr, struct port_table_attribute, attr);
+ 	u16 pkey;
+-	ssize_t ret;
+-
+-	ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
+-	if (ret)
+-		return ret;
++	ssize_t ret = -ENODEV;
+ 
+-	return sprintf(buf, "0x%04x\n", pkey);
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (ibdev_is_alive(p->ibdev)) {
++		ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
++		if (!ret)
++			ret = sprintf(buf, "0x%04x\n", pkey);
++	}
++	mutex_unlock(&p->ibdev->sysfs_mutex);
++	return ret;
+ }
+ 
+ #define PORT_PMA_ATTR(_name, _counter, _width, _offset)			\
+@@ -308,6 +346,12 @@ static ssize_t show_pma_counter(struct i
+ 	if (!p->ibdev->process_mad)
+ 		return sprintf(buf, "N/A (no PMA)\n");
+ 
++	mutex_lock(&p->ibdev->sysfs_mutex);
++	if (!ibdev_is_alive(p->ibdev)) {
++		ret = -ENODEV;
++		goto out;
++	}
++
+ 	in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
+ 	out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+ 	if (!in_mad || !out_mad) {
+@@ -354,7 +414,7 @@ static ssize_t show_pma_counter(struct i
+ out:
+ 	kfree(in_mad);
+ 	kfree(out_mad);
+-
++	mutex_unlock(&p->ibdev->sysfs_mutex);
+ 	return ret;
+ }
+ 
+@@ -594,20 +654,20 @@ static ssize_t show_sys_image_guid(struc
+ {
+ 	struct ib_device *dev = container_of(device, struct ib_device, dev);
+ 	struct ib_device_attr attr;
+-	ssize_t ret;
+-
+-	if (!ibdev_is_alive(dev))
+-		return -ENODEV;
++	ssize_t ret = -ENODEV;
+ 
+-	ret = ib_query_device(dev, &attr);
+-	if (ret)
+-		return ret;
+-
+-	return sprintf(buf, "%04x:%04x:%04x:%04x\n",
+-		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
+-		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
+-		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
+-		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
++	mutex_lock(&dev->sysfs_mutex);
++	if (ibdev_is_alive(dev)) {
++		ret = ib_query_device(dev, &attr);
++		if (!ret)
++			ret = sprintf(buf, "%04x:%04x:%04x:%04x\n",
++				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
++				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
++				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
++				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
++	}
++	mutex_unlock(&dev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static ssize_t show_node_guid(struct device *device,
+@@ -639,17 +699,20 @@ static ssize_t set_node_desc(struct devi
+ {
+ 	struct ib_device *dev = container_of(device, struct ib_device, dev);
+ 	struct ib_device_modify desc = {};
+-	int ret;
++	int ret = -ENODEV;
+ 
+ 	if (!dev->modify_device)
+ 		return -EIO;
+ 
+ 	memcpy(desc.node_desc, buf, min_t(int, count, 64));
+-	ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
+-	if (ret)
+-		return ret;
+-
+-	return count;
++	mutex_lock(&dev->sysfs_mutex);
++	if (ibdev_is_alive(dev)) {
++		ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
++		if (!ret)
++			ret = count;
++	}
++	mutex_unlock(&dev->sysfs_mutex);
++	return ret;
+ }
+ 
+ static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
+@@ -677,14 +740,18 @@ static ssize_t show_protocol_stat(const 
+ {
+ 	struct ib_device *dev = container_of(device, struct ib_device, dev);
+ 	union rdma_protocol_stats stats;
+-	ssize_t ret;
++	ssize_t ret = -ENODEV;
+ 
+-	ret = dev->get_protocol_stats(dev, &stats);
+-	if (ret)
+-		return ret;
+-
+-	return sprintf(buf, "%llu\n",
+-		       (unsigned long long) ((u64 *) &stats)[offset]);
++	mutex_lock(&dev->sysfs_mutex);
++	if (ibdev_is_alive(dev)) {
++		ret = dev->get_protocol_stats(dev, &stats);
++		if (!ret)
++			ret = sprintf(buf, "%llu\n",
++				      (unsigned long long)
++				      ((u64 *) &stats)[offset]);
++	}
++	mutex_unlock(&dev->sysfs_mutex);
++	return ret;
+ }
+ 
+ /* generate a read-only iwarp statistics attribute */
+Index: ofed_kernel/include/rdma/ib_verbs.h
+===================================================================
+--- ofed_kernel.orig/include/rdma/ib_verbs.h	2009-02-22 15:36:40.252210000 +0200
++++ ofed_kernel/include/rdma/ib_verbs.h	2009-02-22 15:38:28.678322000 +0200
+@@ -1205,6 +1205,7 @@ struct ib_device {
+ 		IB_DEV_REGISTERED,
+ 		IB_DEV_UNREGISTERED
+ 	}                            reg_state;
++	struct mutex		     sysfs_mutex;
+ 
+ 	u64			     uverbs_cmd_mask;
+ 	int			     uverbs_abi_ver;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0002_undo_250.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0002_undo_250.patch
new file mode 100644
index 0000000..9605fb7
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0002_undo_250.patch
@@ -0,0 +1,158 @@
+diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
+index d5e9bf7..dc2c79d 100644
+--- a/drivers/net/cxgb3/common.h
++++ b/drivers/net/cxgb3/common.h
+@@ -726,7 +726,6 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index);
+ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai);
+ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
+ 		    int reset);
+-int t3_replay_prep_adapter(struct adapter *adapter);
+ void t3_led_ready(struct adapter *adapter);
+ void t3_fatal_err(struct adapter *adapter);
+ void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
+diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
+index 8de820e..48fbda6 100644
+--- a/drivers/net/cxgb3/cxgb3_main.c
++++ b/drivers/net/cxgb3/cxgb3_main.c
+@@ -2485,6 +2485,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
+ 	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
+ 		offload_close(&adapter->tdev);
+ 
++	/* Free sge resources */
++	t3_free_sge_resources(adapter);
++
+ 	adapter->flags &= ~FULL_INIT_DONE;
+ 
+ 	pci_disable_device(pdev);
+@@ -2509,12 +2512,8 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
+ 		goto err;
+ 	}
+ 	pci_set_master(pdev);
+-	pci_restore_state(pdev);
+-
+-	/* Free sge resources */
+-	t3_free_sge_resources(adapter);
+ 
+-	if (t3_replay_prep_adapter(adapter))
++	if (t3_prep_adapter(adapter, adapter->params.info, 1))
+ 		goto err;
+ 
+ 	return PCI_ERS_RESULT_RECOVERED;
+@@ -2666,7 +2665,6 @@ static int __devinit init_one(struct pci_dev *pdev,
+ 	}
+ 
+ 	pci_set_master(pdev);
+-	pci_save_state(pdev);
+ 
+ 	mmio_start = pci_resource_start(pdev, 0);
+ 	mmio_len = pci_resource_len(pdev, 0);
+diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
+index a035d5c..086cd02 100644
+--- a/drivers/net/cxgb3/regs.h
++++ b/drivers/net/cxgb3/regs.h
+@@ -444,14 +444,6 @@
+ 
+ #define A_PCIE_CFG 0x88
+ 
+-#define S_ENABLELINKDWNDRST    21
+-#define V_ENABLELINKDWNDRST(x) ((x) << S_ENABLELINKDWNDRST)
+-#define F_ENABLELINKDWNDRST    V_ENABLELINKDWNDRST(1U)
+-
+-#define S_ENABLELINKDOWNRST    20
+-#define V_ENABLELINKDOWNRST(x) ((x) << S_ENABLELINKDOWNRST)
+-#define F_ENABLELINKDOWNRST    V_ENABLELINKDOWNRST(1U)
+-
+ #define S_PCIE_CLIDECEN    16
+ #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN)
+ #define F_PCIE_CLIDECEN    V_PCIE_CLIDECEN(1U)
+diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
+index 1b0861d..912f816 100644
+--- a/drivers/net/cxgb3/sge.c
++++ b/drivers/net/cxgb3/sge.c
+@@ -563,33 +563,6 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
+ }
+ 
+ /**
+- *	t3_reset_qset - reset a sge qset
+- *	@q: the queue set
+- *
+- *	Reset the qset structure.
+- *	the NAPI structure is preserved in the event of
+- *	the qset's reincarnation, for example during EEH recovery.
+- */
+-static void t3_reset_qset(struct sge_qset *q)
+-{
+-	if (q->adap &&
+-	    !(q->adap->flags & NAPI_INIT)) {
+-		memset(q, 0, sizeof(*q));
+-		return;
+-	}
+-
+-	q->adap = NULL;
+-	memset(&q->rspq, 0, sizeof(q->rspq));
+-	memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
+-	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
+-	q->txq_stopped = 0;
+-	memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
+-	kfree(q->lro_frag_tbl);
+-	q->lro_nfrags = q->lro_frag_len = 0;
+-}
+-
+-
+-/**
+  *	free_qset - free the resources of an SGE queue set
+  *	@adapter: the adapter owning the queue set
+  *	@q: the queue set
+@@ -645,7 +618,7 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
+ 				  q->rspq.desc, q->rspq.phys_addr);
+ 	}
+ 
+-	t3_reset_qset(q);
++	memset(q, 0, sizeof(*q));
+ }
+ 
+ /**
+diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
+index bf5c076..533fc74 100644
+--- a/drivers/net/cxgb3/t3_hw.c
++++ b/drivers/net/cxgb3/t3_hw.c
+@@ -3303,7 +3303,6 @@ static void config_pcie(struct adapter *adap)
+ 
+ 	t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
+ 	t3_set_reg_field(adap, A_PCIE_CFG, 0,
+-			 F_ENABLELINKDWNDRST | F_ENABLELINKDOWNRST |
+ 			 F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
+ }
+ 
+@@ -3706,31 +3705,3 @@ void t3_led_ready(struct adapter *adapter)
+ 			 F_GPIO0_OUT_VAL);
+ }
+ 
+-int t3_replay_prep_adapter(struct adapter *adapter)
+-{
+-	const struct adapter_info *ai = adapter->params.info;
+-	unsigned int i, j = -1;
+-	int ret;
+-
+-	early_hw_init(adapter, ai);
+-	ret = init_parity(adapter);
+-	if (ret)
+-		return ret;
+-
+-	for_each_port(adapter, i) {
+-		const struct port_type_info *pti;
+-		struct port_info *p = adap2pinfo(adapter, i);
+-
+-		while (!adapter->params.vpd.port_type[++j])
+-			;
+-
+-		pti = &port_types[adapter->params.vpd.port_type[j]];
+-		ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
+-		if (ret)
+-			return ret;
+-		p->phy.ops->power_down(&p->phy, 1);
+-	}
+-
+-return 0;
+-}
+-
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0004_undo_240.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0004_undo_240.patch
new file mode 100644
index 0000000..62df290
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0004_undo_240.patch
@@ -0,0 +1,120 @@
+commit 48c4b6dbb7e246957e13302668acf7c77e4f8b3a
+Author: Divy Le Ray <divy at chelsio.com>
+Date:   Tue May 6 19:25:56 2008 -0700
+
+    cxgb3 - fix port up/down error path
+    
+    Fix faiures path when ports are stopped and restarted
+    in EEH recovery.
+    
+    Signed-off-by: Divy Le Ray <divy at chelsio.com>
+    Signed-off-by: Jeff Garzik <jgarzik at redhat.com>
+
+---
+ drivers/net/cxgb3/adapter.h    |    1 -
+ drivers/net/cxgb3/cxgb3_main.c |   32 +++++++++++++++-----------------
+ 2 files changed, 15 insertions(+), 18 deletions(-)
+
+Index: ofed_kernel/drivers/net/cxgb3/adapter.h
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/adapter.h
++++ ofed_kernel/drivers/net/cxgb3/adapter.h
+@@ -72,7 +72,6 @@ enum {				/* adapter flags */
+ 	USING_MSIX = (1 << 2),
+ 	QUEUES_BOUND = (1 << 3),
+ 	TP_PARITY_INIT = (1 << 4),
+-	NAPI_INIT = (1 << 5),
+ };
+ 
+ struct fl_pg_chunk {
+Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
++++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+@@ -421,13 +421,6 @@ static void init_napi(struct adapter *ad
+ 			netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
+ 				       64);
+ 	}
+-
+-	/*
+-	 * netif_napi_add() can be called only once per napi_struct because it
+-	 * adds each new napi_struct to a list.  Be careful not to call it a
+-	 * second time, e.g., during EEH recovery, by making a note of it.
+-	 */
+-	adap->flags |= NAPI_INIT;
+ }
+ 
+ /*
+@@ -903,8 +896,7 @@ static int cxgb_up(struct adapter *adap)
+ 			goto out;
+ 
+ 		setup_rss(adap);
+-		if (!(adap->flags & NAPI_INIT))
+-			init_napi(adap);
++		init_napi(adap);
+ 		adap->flags |= FULL_INIT_DONE;
+ 	}
+ 
+@@ -1007,7 +999,7 @@ static int offload_open(struct net_devic
+ 		return 0;
+ 
+ 	if (!adap_up && (err = cxgb_up(adapter)) < 0)
+-		goto out;
++		return err;
+ 
+ 	t3_tp_set_offload_mode(adapter, 1);
+ 	tdev->lldev = adapter->port[0];
+@@ -1069,8 +1061,10 @@ static int cxgb_open(struct net_device *
+ 	int other_ports = adapter->open_device_map & PORT_MASK;
+ 	int err;
+ 
+-	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
++	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
++		quiesce_rx(adapter);
+ 		return err;
++	}
+ 
+ 	set_bit(pi->port_id, &adapter->open_device_map);
+ 	if (is_offload(adapter) && !ofld_disable) {
+@@ -2456,7 +2450,7 @@ static pci_ers_result_t t3_io_error_dete
+ 
+ 	pci_disable_device(pdev);
+ 
+-	/* Request a slot reset. */
++	/* Request a slot slot reset. */
+ 	return PCI_ERS_RESULT_NEED_RESET;
+ }
+ 
+@@ -2473,16 +2467,13 @@ static pci_ers_result_t t3_io_slot_reset
+ 	if (pci_enable_device(pdev)) {
+ 		dev_err(&pdev->dev,
+ 			"Cannot re-enable PCI device after reset.\n");
+-		goto err;
++		return PCI_ERS_RESULT_DISCONNECT;
+ 	}
+ 	pci_set_master(pdev);
+ 
+-	if (t3_prep_adapter(adapter, adapter->params.info, 1))
+-		goto err;
++	t3_prep_adapter(adapter, adapter->params.info, 1);
+ 
+ 	return PCI_ERS_RESULT_RECOVERED;
+-err:
+-	return PCI_ERS_RESULT_DISCONNECT;
+ }
+ 
+ /**
+@@ -2511,6 +2502,13 @@ static void t3_io_resume(struct pci_dev 
+ 			netif_device_attach(netdev);
+ 		}
+ 	}
++
++	if (is_offload(adapter)) {
++		__set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
++		if (offload_open(adapter->port[0]))
++			printk(KERN_WARNING
++			       "Could not bring back offload capabilities\n");
++	}
+ }
+ 
+ static struct pci_error_handlers t3_err_handler = {
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0008_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0008_pci_dma_mapping_error_to_2_6_26.patch
new file mode 100644
index 0000000..bcf69aa
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0008_pci_dma_mapping_error_to_2_6_26.patch
@@ -0,0 +1,17 @@
+---
+ drivers/net/cxgb3/sge.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: ofed_kernel/drivers/net/cxgb3/sge.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/sge.c
++++ ofed_kernel/drivers/net/cxgb3/sge.c
+@@ -386,7 +386,7 @@ static inline int add_one_rx_buf(void *v
+ 	dma_addr_t mapping;
+ 
+ 	mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE);
+-	if (unlikely(pci_dma_mapping_error(pdev, mapping)))
++	if (unlikely(pci_dma_mapping_error(mapping)))
+ 		return -ENOMEM;
+ 
+ 	pci_unmap_addr_set(sd, dma_addr, mapping);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0010_napi.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0010_napi.patch
new file mode 100644
index 0000000..df3eaed
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0010_napi.patch
@@ -0,0 +1,610 @@
+diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
+index 3b33ecb..21dad82 100644
+--- a/drivers/net/cxgb3/adapter.h
++++ b/drivers/net/cxgb3/adapter.h
+@@ -48,12 +48,10 @@
+ 
+ struct vlan_group;
+ struct adapter;
+-struct sge_qset;
+ 
+ struct port_info {
+ 	struct adapter *adapter;
+ 	struct vlan_group *vlan_grp;
+-	struct sge_qset *qs;
+ 	u8 port_id;
+ 	u8 rx_csum_offload;
+ 	u8 nqsets;
+@@ -183,8 +181,6 @@ enum {				/* per port SGE statistics */
+ #define T3_MAX_LRO_MAX_PKTS 64
+ 
+ struct sge_qset {		/* an SGE queue set */
+-	struct adapter *adap;
+-	struct napi_struct napi;
+ 	struct sge_rspq rspq;
+ 	struct sge_fl fl[SGE_RXQ_PER_SET];
+ 	struct sge_txq txq[SGE_TXQ_PER_SET];
+@@ -195,7 +191,7 @@ struct sge_qset {		/* an SGE queue set */
+ 	int lro_enabled;
+ 	int lro_frag_len;
+ 	void *lro_va;
+-	struct net_device *netdev;
++	struct net_device *netdev;	/* associated net device */
+ 	unsigned long txq_stopped;	/* which Tx queues are stopped */
+ 	struct timer_list tx_reclaim_timer;	/* reclaims TX buffers */
+ 	unsigned long port_stats[SGE_PSTAT_MAX];
+@@ -240,6 +236,12 @@ struct adapter {
+ 	struct delayed_work adap_check_task;
+ 	struct work_struct ext_intr_handler_task;
+ 
++	/*
++	 * Dummy netdevices are needed when using multiple receive queues with
++	 * NAPI as each netdevice can service only one queue.
++	 */
++	struct net_device *dummy_netdev[SGE_QSETS - 1];
++
+ 	struct dentry *debugfs_root;
+ 
+ 	struct mutex mdio_lock;
+@@ -266,6 +268,12 @@ static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
+ 	return netdev_priv(adap->port[idx]);
+ }
+ 
++/*
++ * We use the spare atalk_ptr to map a net device to its SGE queue set.
++ * This is a macro so it can be used as l-value.
++ */
++#define dev2qset(netdev) ((netdev)->atalk_ptr)
++
+ #define OFFLOAD_DEVMAP_BIT 15
+ 
+ #define tdev2adap(d) container_of(d, struct adapter, tdev)
+@@ -292,7 +300,7 @@ int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
+ void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p);
+ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
+ 		      int irq_vec_idx, const struct qset_params *p,
+-		      int ntxq, struct net_device *dev);
++		      int ntxq, struct net_device *netdev);
+ int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
+ 		unsigned char *data);
+ irqreturn_t t3_sge_intr_msix(int irq, void *cookie);
+diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
+index 0f4c694..342d441 100644
+--- a/drivers/net/cxgb3/cxgb3_main.c
++++ b/drivers/net/cxgb3/cxgb3_main.c
+@@ -435,17 +435,49 @@ static void setup_rss(struct adapter *adap)
+ 		      V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map);
+ }
+ 
+-static void init_napi(struct adapter *adap)
++/*
++ * If we have multiple receive queues per port serviced by NAPI we need one
++ * netdevice per queue as NAPI operates on netdevices.  We already have one
++ * netdevice, namely the one associated with the interface, so we use dummy
++ * ones for any additional queues.  Note that these netdevices exist purely
++ * so that NAPI has something to work with, they do not represent network
++ * ports and are not registered.
++ */
++static int init_dummy_netdevs(struct adapter *adap)
+ {
+-	int i;
++	int i, j, dummy_idx = 0;
++	struct net_device *nd;
++
++	for_each_port(adap, i) {
++		struct net_device *dev = adap->port[i];
++		const struct port_info *pi = netdev_priv(dev);
++
++		for (j = 0; j < pi->nqsets - 1; j++) {
++			if (!adap->dummy_netdev[dummy_idx]) {
++				struct port_info *p;
++
++				nd = alloc_netdev(sizeof(*p), "", ether_setup);
++				if (!nd)
++					goto free_all;
+ 
+-	for (i = 0; i < SGE_QSETS; i++) {
+-		struct sge_qset *qs = &adap->sge.qs[i];
++				p = netdev_priv(nd);
++				p->adapter = adap;
++				nd->weight = 64;
++				set_bit(__LINK_STATE_START, &nd->state);
++				adap->dummy_netdev[dummy_idx] = nd;
++			}
++			strcpy(adap->dummy_netdev[dummy_idx]->name, dev->name);
++			dummy_idx++;
++		}
++	}
++	return 0;
+ 
+-		if (qs->adap)
+-			netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
+-				       64);
++free_all:
++	while (--dummy_idx >= 0) {
++		free_netdev(adap->dummy_netdev[dummy_idx]);
++		adap->dummy_netdev[dummy_idx] = NULL;
+ 	}
++	return -ENOMEM;
+ }
+ 
+ /*
+@@ -456,18 +488,20 @@ static void init_napi(struct adapter *adap)
+ static void quiesce_rx(struct adapter *adap)
+ {
+ 	int i;
++	struct net_device *dev;
+ 
+-	for (i = 0; i < SGE_QSETS; i++)
+-		if (adap->sge.qs[i].adap)
+-			napi_disable(&adap->sge.qs[i].napi);
+-}
++	for_each_port(adap, i) {
++		dev = adap->port[i];
++		while (test_bit(__LINK_STATE_RX_SCHED, &dev->state))
++			msleep(1);
++	}
+ 
+-static void enable_all_napi(struct adapter *adap)
+-{
+-	int i;
+-	for (i = 0; i < SGE_QSETS; i++)
+-		if (adap->sge.qs[i].adap)
+-			napi_enable(&adap->sge.qs[i].napi);
++	for (i = 0; i < ARRAY_SIZE(adap->dummy_netdev); i++) {
++		dev = adap->dummy_netdev[i];
++		if (dev)
++			while (test_bit(__LINK_STATE_RX_SCHED, &dev->state))
++				msleep(1);
++	}
+ }
+ 
+ /**
+@@ -480,7 +514,7 @@ static void enable_all_napi(struct adapter *adap)
+  */
+ static int setup_sge_qsets(struct adapter *adap)
+ {
+-	int i, j, err, irq_idx = 0, qset_idx = 0;
++	int i, j, err, irq_idx = 0, qset_idx = 0, dummy_dev_idx = 0;
+ 	unsigned int ntxq = SGE_TXQ_PER_SET;
+ 
+ 	if (adap->params.rev > 0 && !(adap->flags & USING_MSI))
+@@ -488,14 +522,15 @@ static int setup_sge_qsets(struct adapter *adap)
+ 
+ 	for_each_port(adap, i) {
+ 		struct net_device *dev = adap->port[i];
+-		struct port_info *pi = netdev_priv(dev);
++		const struct port_info *pi = netdev_priv(dev);
+ 
+-		pi->qs = &adap->sge.qs[pi->first_qset];
+ 		for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
+ 			err = t3_sge_alloc_qset(adap, qset_idx, 1,
+ 				(adap->flags & USING_MSIX) ? qset_idx + 1 :
+ 							     irq_idx,
+-				&adap->params.sge.qset[qset_idx], ntxq, dev);
++				&adap->params.sge.qset[qset_idx], ntxq,
++				j == 0 ? dev :
++					 adap-> dummy_netdev[dummy_dev_idx++]);
+ 			if (err) {
+ 				t3_free_sge_resources(adap);
+ 				return err;
+@@ -909,6 +944,10 @@ static int cxgb_up(struct adapter *adap)
+ 				goto out;
+ 		}
+ 
++ 		err = init_dummy_netdevs(adap);
++ 		if (err)
++ 			goto out;
++
+ 		err = t3_init_hw(adap, 0);
+ 		if (err)
+ 			goto out;
+@@ -921,7 +960,6 @@ static int cxgb_up(struct adapter *adap)
+ 			goto out;
+ 
+ 		setup_rss(adap);
+-		init_napi(adap);
+ 		adap->flags |= FULL_INIT_DONE;
+ 	}
+ 
+@@ -949,7 +987,6 @@ static int cxgb_up(struct adapter *adap)
+ 				      adap->name, adap)))
+ 		goto irq_err;
+ 
+-	enable_all_napi(adap);
+ 	t3_sge_start(adap);
+ 	t3_intr_enable(adap);
+ 
+@@ -1086,10 +1123,8 @@ static int cxgb_open(struct net_device *dev)
+ 	int other_ports = adapter->open_device_map & PORT_MASK;
+ 	int err;
+ 
+-	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
+-		quiesce_rx(adapter);
++	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
+ 		return err;
+-	}
+ 
+ 	set_bit(pi->port_id, &adapter->open_device_map);
+ 	if (is_offload(adapter) && !ofld_disable) {
+@@ -2736,6 +2771,7 @@ static int __devinit init_one(struct pci_dev *pdev,
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ 		netdev->poll_controller = cxgb_netpoll;
+ #endif
++		netdev->weight = 64;
+ 
+ 		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+ 	}
+@@ -2836,6 +2872,12 @@ static void __devexit remove_one(struct pci_dev *pdev)
+ 		t3_free_sge_resources(adapter);
+ 		cxgb_disable_msi(adapter);
+ 
++		for (i = 0; i < ARRAY_SIZE(adapter->dummy_netdev); i++)
++			if (adapter->dummy_netdev[i]) {
++				free_netdev(adapter->dummy_netdev[i]);
++				adapter->dummy_netdev[i] = NULL;
++			}
++
+ 		for_each_port(adapter, i)
+ 			if (adapter->port[i])
+ 				free_netdev(adapter->port[i]);
+diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
+index f6bc6fe..3bbf626 100644
+--- a/drivers/net/cxgb3/sge.c
++++ b/drivers/net/cxgb3/sge.c
+@@ -618,6 +618,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
+ 				  q->rspq.desc, q->rspq.phys_addr);
+ 	}
+ 
++	if (q->netdev)
++		q->netdev->atalk_ptr = NULL;
++
+ 	memset(q, 0, sizeof(*q));
+ }
+ 
+@@ -1116,7 +1119,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	unsigned int ndesc, pidx, credits, gen, compl;
+ 	const struct port_info *pi = netdev_priv(dev);
+ 	struct adapter *adap = pi->adapter;
+-	struct sge_qset *qs = pi->qs;
++	struct sge_qset *qs = dev2qset(dev);
+ 	struct sge_txq *q = &qs->txq[TXQ_ETH];
+ 
+ 	/*
+@@ -1365,12 +1368,13 @@ static void restart_ctrlq(unsigned long data)
+ 	struct sk_buff *skb;
+ 	struct sge_qset *qs = (struct sge_qset *)data;
+ 	struct sge_txq *q = &qs->txq[TXQ_CTRL];
++	const struct port_info *pi = netdev_priv(qs->netdev);
++	struct adapter *adap = pi->adapter;
+ 
+ 	spin_lock(&q->lock);
+       again:reclaim_completed_tx_imm(q);
+ 
+-	while (q->in_use < q->size &&
+-	       (skb = __skb_dequeue(&q->sendq)) != NULL) {
++	while (q->in_use < q->size && (skb = __skb_dequeue(&q->sendq)) != NULL) {
+ 
+ 		write_imm(&q->desc[q->pidx], skb, skb->len, q->gen);
+ 
+@@ -1393,7 +1397,7 @@ static void restart_ctrlq(unsigned long data)
+ 
+ 	spin_unlock(&q->lock);
+ 	wmb();
+-	t3_write_reg(qs->adap, A_SG_KDOORBELL,
++	t3_write_reg(adap, A_SG_KDOORBELL,
+ 		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+ }
+ 
+@@ -1683,7 +1687,8 @@ static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb)
+ 	else {
+ 		struct sge_qset *qs = rspq_to_qset(q);
+ 
+-		napi_schedule(&qs->napi);
++		if (__netif_rx_schedule_prep(qs->netdev))
++			__netif_rx_schedule(qs->netdev);
+ 		q->rx_head = skb;
+ 	}
+ 	q->rx_tail = skb;
+@@ -1719,30 +1724,34 @@ static inline void deliver_partial_bundle(struct t3cdev *tdev,
+  *	receive handler.  Batches need to be of modest size as we do prefetches
+  *	on the packets in each.
+  */
+-static int ofld_poll(struct napi_struct *napi, int budget)
++static int ofld_poll(struct net_device *dev, int *budget)
+ {
+-	struct sge_qset *qs = container_of(napi, struct sge_qset, napi);
++	const struct port_info *pi = netdev_priv(dev);
++	struct adapter *adapter = pi->adapter;
++	struct sge_qset *qs = dev2qset(dev);
+ 	struct sge_rspq *q = &qs->rspq;
+-	struct adapter *adapter = qs->adap;
+-	int work_done = 0;
++	int work_done, limit = min(*budget, dev->quota), avail = limit;
+ 
+-	while (work_done < budget) {
++	while (avail) {
+ 		struct sk_buff *head, *tail, *skbs[RX_BUNDLE_SIZE];
+ 		int ngathered;
+ 
+ 		spin_lock_irq(&q->lock);
+ 		head = q->rx_head;
+ 		if (!head) {
+-			napi_complete(napi);
++			work_done = limit - avail;
++			*budget -= work_done;
++			dev->quota -= work_done;
++			__netif_rx_complete(dev);
+ 			spin_unlock_irq(&q->lock);
+-			return work_done;
++			return 0;
+ 		}
+ 
+ 		tail = q->rx_tail;
+ 		q->rx_head = q->rx_tail = NULL;
+ 		spin_unlock_irq(&q->lock);
+ 
+-		for (ngathered = 0; work_done < budget && head; work_done++) {
++		for (ngathered = 0; avail && head; avail--) {
+ 			prefetch(head->data);
+ 			skbs[ngathered] = head;
+ 			head = head->next;
+@@ -1764,8 +1773,10 @@ static int ofld_poll(struct napi_struct *napi, int budget)
+ 		}
+ 		deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered);
+ 	}
+-
+-	return work_done;
++	work_done = limit - avail;
++	*budget -= work_done;
++	dev->quota -= work_done;
++	return 1;
+ }
+ 
+ /**
+@@ -2325,47 +2336,50 @@ static inline int is_pure_response(const struct rsp_desc *r)
+ 
+ /**
+  *	napi_rx_handler - the NAPI handler for Rx processing
+- *	@napi: the napi instance
++ *	@dev: the net device
+  *	@budget: how many packets we can process in this round
+  *
+  *	Handler for new data events when using NAPI.
+  */
+-static int napi_rx_handler(struct napi_struct *napi, int budget)
++static int napi_rx_handler(struct net_device *dev, int *budget)
+ {
+-	struct sge_qset *qs = container_of(napi, struct sge_qset, napi);
+-	struct adapter *adap = qs->adap;
+-	int work_done = process_responses(adap, qs, budget);
++	const struct port_info *pi = netdev_priv(dev);
++	struct adapter *adap = pi->adapter;
++	struct sge_qset *qs = dev2qset(dev);
++	int effective_budget = min(*budget, dev->quota);
+ 
+-	if (likely(work_done < budget)) {
+-		napi_complete(napi);
++	int work_done = process_responses(adap, qs, effective_budget);
++	*budget -= work_done;
++	dev->quota -= work_done;
+ 
+-		/*
+-		 * Because we don't atomically flush the following
+-		 * write it is possible that in very rare cases it can
+-		 * reach the device in a way that races with a new
+-		 * response being written plus an error interrupt
+-		 * causing the NAPI interrupt handler below to return
+-		 * unhandled status to the OS.  To protect against
+-		 * this would require flushing the write and doing
+-		 * both the write and the flush with interrupts off.
+-		 * Way too expensive and unjustifiable given the
+-		 * rarity of the race.
+-		 *
+-		 * The race cannot happen at all with MSI-X.
+-		 */
+-		t3_write_reg(adap, A_SG_GTS, V_RSPQ(qs->rspq.cntxt_id) |
+-			     V_NEWTIMER(qs->rspq.next_holdoff) |
+-			     V_NEWINDEX(qs->rspq.cidx));
+-	}
+-	return work_done;
++	if (work_done >= effective_budget)
++		return 1;
++
++	netif_rx_complete(dev);
++
++	/*
++	 * Because we don't atomically flush the following write it is
++	 * possible that in very rare cases it can reach the device in a way
++	 * that races with a new response being written plus an error interrupt
++	 * causing the NAPI interrupt handler below to return unhandled status
++	 * to the OS.  To protect against this would require flushing the write
++	 * and doing both the write and the flush with interrupts off.  Way too
++	 * expensive and unjustifiable given the rarity of the race.
++	 *
++	 * The race cannot happen at all with MSI-X.
++	 */
++	t3_write_reg(adap, A_SG_GTS, V_RSPQ(qs->rspq.cntxt_id) |
++		     V_NEWTIMER(qs->rspq.next_holdoff) |
++		     V_NEWINDEX(qs->rspq.cidx));
++	return 0;
+ }
+ 
+ /*
+  * Returns true if the device is already scheduled for polling.
+  */
+-static inline int napi_is_scheduled(struct napi_struct *napi)
++static inline int napi_is_scheduled(struct net_device *dev)
+ {
+-	return test_bit(NAPI_STATE_SCHED, &napi->state);
++	return test_bit(__LINK_STATE_RX_SCHED, &dev->state);
+ }
+ 
+ /**
+@@ -2448,7 +2462,8 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
+ 			     V_NEWTIMER(q->holdoff_tmr) | V_NEWINDEX(q->cidx));
+ 		return 0;
+ 	}
+-	napi_schedule(&qs->napi);
++	if (likely(__netif_rx_schedule_prep(qs->netdev)))
++		__netif_rx_schedule(qs->netdev);
+ 	return 1;
+ }
+ 
+@@ -2459,7 +2474,8 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
+ irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
+ {
+ 	struct sge_qset *qs = cookie;
+-	struct adapter *adap = qs->adap;
++	const struct port_info *pi = netdev_priv(qs->netdev);
++	struct adapter *adap = pi->adapter;
+ 	struct sge_rspq *q = &qs->rspq;
+ 
+ 	spin_lock(&q->lock);
+@@ -2478,11 +2494,13 @@ irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
+ static irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
+ {
+ 	struct sge_qset *qs = cookie;
++	const struct port_info *pi = netdev_priv(qs->netdev);
++	struct adapter *adap = pi->adapter;
+ 	struct sge_rspq *q = &qs->rspq;
+ 
+ 	spin_lock(&q->lock);
+ 
+-	if (handle_responses(qs->adap, q) < 0)
++	if (handle_responses(adap, q) < 0)
+ 		q->unhandled_irqs++;
+ 	spin_unlock(&q->lock);
+ 	return IRQ_HANDLED;
+@@ -2525,13 +2543,11 @@ static irqreturn_t t3_intr_msi(int irq, void *cookie)
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int rspq_check_napi(struct sge_qset *qs)
++static int rspq_check_napi(struct net_device *dev, struct sge_rspq *q)
+ {
+-	struct sge_rspq *q = &qs->rspq;
+-
+-	if (!napi_is_scheduled(&qs->napi) &&
+-	    is_new_response(&q->desc[q->cidx], q)) {
+-		napi_schedule(&qs->napi);
++	if (!napi_is_scheduled(dev) && is_new_response(&q->desc[q->cidx], q)) {
++		if (likely(__netif_rx_schedule_prep(dev)))
++			__netif_rx_schedule(dev);
+ 		return 1;
+ 	}
+ 	return 0;
+@@ -2552,9 +2568,10 @@ static irqreturn_t t3_intr_msi_napi(int irq, void *cookie)
+ 
+ 	spin_lock(&q->lock);
+ 
+-	new_packets = rspq_check_napi(&adap->sge.qs[0]);
++	new_packets = rspq_check_napi(adap->sge.qs[0].netdev, q);
+ 	if (adap->params.nports == 2)
+-		new_packets += rspq_check_napi(&adap->sge.qs[1]);
++		new_packets += rspq_check_napi(adap->sge.qs[1].netdev,
++					       &adap->sge.qs[1].rspq);
+ 	if (!new_packets && t3_slow_intr_handler(adap) == 0)
+ 		q->unhandled_irqs++;
+ 
+@@ -2657,9 +2674,9 @@ static irqreturn_t t3b_intr(int irq, void *cookie)
+ static irqreturn_t t3b_intr_napi(int irq, void *cookie)
+ {
+ 	u32 map;
++	struct net_device *dev;
+ 	struct adapter *adap = cookie;
+-	struct sge_qset *qs0 = &adap->sge.qs[0];
+-	struct sge_rspq *q0 = &qs0->rspq;
++	struct sge_rspq *q0 = &adap->sge.qs[0].rspq;
+ 
+ 	t3_write_reg(adap, A_PL_CLI, 0);
+ 	map = t3_read_reg(adap, A_SG_DATA_INTR);
+@@ -2672,11 +2689,18 @@ static irqreturn_t t3b_intr_napi(int irq, void *cookie)
+ 	if (unlikely(map & F_ERRINTR))
+ 		t3_slow_intr_handler(adap);
+ 
+-	if (likely(map & 1))
+-		napi_schedule(&qs0->napi);
++	if (likely(map & 1)) {
++		dev = adap->sge.qs[0].netdev;
+ 
+-	if (map & 2)
+-		napi_schedule(&adap->sge.qs[1].napi);
++		if (likely(__netif_rx_schedule_prep(dev)))
++			__netif_rx_schedule(dev);
++	}
++	if (map & 2) {
++		dev = adap->sge.qs[1].netdev;
++
++		if (likely(__netif_rx_schedule_prep(dev)))
++			__netif_rx_schedule(dev);
++	}
+ 
+ 	spin_unlock(&q0->lock);
+ 	return IRQ_HANDLED;
+@@ -2775,7 +2799,8 @@ static void sge_timer_cb(unsigned long data)
+ {
+ 	spinlock_t *lock;
+ 	struct sge_qset *qs = (struct sge_qset *)data;
+-	struct adapter *adap = qs->adap;
++	const struct port_info *pi = netdev_priv(qs->netdev);
++	struct adapter *adap = pi->adapter;
+ 
+ 	if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
+ 		reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
+@@ -2786,9 +2811,9 @@ static void sge_timer_cb(unsigned long data)
+ 		spin_unlock(&qs->txq[TXQ_OFLD].lock);
+ 	}
+ 	lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock :
+-					    &adap->sge.qs[0].rspq.lock;
++	    &adap->sge.qs[0].rspq.lock;
+ 	if (spin_trylock_irq(lock)) {
+-		if (!napi_is_scheduled(&qs->napi)) {
++		if (!napi_is_scheduled(qs->netdev)) {
+ 			u32 status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
+ 
+ 			if (qs->fl[0].credits < qs->fl[0].size)
+@@ -2822,9 +2847,12 @@ static void sge_timer_cb(unsigned long data)
+  */
+ void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p)
+ {
++	if (!qs->netdev)
++		return;
++
+ 	qs->rspq.holdoff_tmr = max(p->coalesce_usecs * 10, 1U);/* can't be 0 */
+ 	qs->rspq.polling = p->polling;
+-	qs->napi.poll = p->polling ? napi_rx_handler : ofld_poll;
++	qs->netdev->poll = p->polling ? napi_rx_handler : ofld_poll;
+ }
+ 
+ /**
+@@ -2844,7 +2872,7 @@ void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p)
+  */
+ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
+ 		      int irq_vec_idx, const struct qset_params *p,
+-		      int ntxq, struct net_device *dev)
++		      int ntxq, struct net_device *netdev)
+ {
+ 	int i, avail, ret = -ENOMEM;
+ 	struct sge_qset *q = &adapter->sge.qs[id];
+@@ -2978,11 +3006,17 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
+ 	}
+ 
+ 	spin_unlock_irq(&adapter->sge.reg_lock);
+-
+-	q->adap = adapter;
+-	q->netdev = dev;
++	q->netdev = netdev;
+ 	t3_update_qset_coalesce(q, p);
+ 
++ 	/*
++ 	 * We use atalk_ptr as a backpointer to a qset.  In case a device is
++ 	 * associated with multiple queue sets only the first one sets
++ 	 * atalk_ptr.
++ 	 */
++ 	if (netdev->atalk_ptr == NULL)
++ 		netdev->atalk_ptr = q;
++
+ 	init_lro_mgr(q, lro_mgr);
+ 
+ 	avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0020_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0020_sysfs.patch
new file mode 100644
index 0000000..d5ddedb
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0020_sysfs.patch
@@ -0,0 +1,202 @@
+---
+ drivers/net/cxgb3/cxgb3_main.c |   78 +++++++++++++++++++----------------------
+ 1 file changed, 38 insertions(+), 40 deletions(-)
+
+Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
++++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+@@ -76,6 +76,8 @@ enum {
+ 
+ #define EEPROM_MAGIC 0x38E2F10C
+ 
++#define to_net_dev(class) container_of(class, struct net_device, class_dev)
++
+ #define CH_DEVICE(devid, idx) \
+ 	{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, idx }
+ 
+@@ -516,7 +518,7 @@ static int setup_sge_qsets(struct adapte
+ 	return 0;
+ }
+ 
+-static ssize_t attr_show(struct device *d, char *buf,
++static ssize_t attr_show(struct class_device *d, char *buf,
+ 			 ssize_t(*format) (struct net_device *, char *))
+ {
+ 	ssize_t len;
+@@ -528,7 +530,7 @@ static ssize_t attr_show(struct device *
+ 	return len;
+ }
+ 
+-static ssize_t attr_store(struct device *d,
++static ssize_t attr_store(struct class_device *d,
+ 			  const char *buf, size_t len,
+ 			  ssize_t(*set) (struct net_device *, unsigned int),
+ 			  unsigned int min_val, unsigned int max_val)
+@@ -559,10 +561,9 @@ static ssize_t format_##name(struct net_
+ 	struct adapter *adap = pi->adapter; \
+ 	return sprintf(buf, "%u\n", val_expr); \
+ } \
+-static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
+-			   char *buf) \
++static ssize_t show_##name(struct class_device *cd, char *buf) \
+ { \
+-	return attr_show(d, buf, format_##name); \
++	return attr_show(cd, buf, format_##name); \
+ }
+ 
+ static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
+@@ -582,10 +583,10 @@ static ssize_t set_nfilters(struct net_d
+ 	return 0;
+ }
+ 
+-static ssize_t store_nfilters(struct device *d, struct device_attribute *attr,
+-			      const char *buf, size_t len)
++static ssize_t store_nfilters(struct class_device *cd, const char *buf,
++			      size_t len)
+ {
+-	return attr_store(d, buf, len, set_nfilters, 0, ~0);
++	return attr_store(cd, buf, len, set_nfilters, 0, ~0);
+ }
+ 
+ static ssize_t set_nservers(struct net_device *dev, unsigned int val)
+@@ -602,35 +603,34 @@ static ssize_t set_nservers(struct net_d
+ 	return 0;
+ }
+ 
+-static ssize_t store_nservers(struct device *d, struct device_attribute *attr,
+-			      const char *buf, size_t len)
++static ssize_t store_nservers(struct class_device *cd, const char *buf,
++			      size_t len)
+ {
+-	return attr_store(d, buf, len, set_nservers, 0, ~0);
++	return attr_store(cd, buf, len, set_nservers, 0, ~0);
+ }
+ 
+ #define CXGB3_ATTR_R(name, val_expr) \
+ CXGB3_SHOW(name, val_expr) \
+-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
++static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+ 
+ #define CXGB3_ATTR_RW(name, val_expr, store_method) \
+ CXGB3_SHOW(name, val_expr) \
+-static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method)
++static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method)
+ 
+ CXGB3_ATTR_R(cam_size, t3_mc5_size(&adap->mc5));
+ CXGB3_ATTR_RW(nfilters, adap->params.mc5.nfilters, store_nfilters);
+ CXGB3_ATTR_RW(nservers, adap->params.mc5.nservers, store_nservers);
+ 
+ static struct attribute *cxgb3_attrs[] = {
+-	&dev_attr_cam_size.attr,
+-	&dev_attr_nfilters.attr,
+-	&dev_attr_nservers.attr,
++	&class_device_attr_cam_size.attr,
++	&class_device_attr_nfilters.attr,
++	&class_device_attr_nservers.attr,
+ 	NULL
+ };
+ 
+ static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs };
+ 
+-static ssize_t tm_attr_show(struct device *d,
+-			    char *buf, int sched)
++static ssize_t tm_attr_show(struct class_device *d, char *buf, int sched)
+ {
+ 	struct port_info *pi = netdev_priv(to_net_dev(d));
+ 	struct adapter *adap = pi->adapter;
+@@ -655,8 +655,8 @@ static ssize_t tm_attr_show(struct devic
+ 	return len;
+ }
+ 
+-static ssize_t tm_attr_store(struct device *d,
+-			     const char *buf, size_t len, int sched)
++static ssize_t tm_attr_store(struct class_device *d, const char *buf,
++			     size_t len, int sched)
+ {
+ 	struct port_info *pi = netdev_priv(to_net_dev(d));
+ 	struct adapter *adap = pi->adapter;
+@@ -680,17 +680,15 @@ static ssize_t tm_attr_store(struct devi
+ }
+ 
+ #define TM_ATTR(name, sched) \
+-static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
+-			   char *buf) \
++static ssize_t show_##name(struct class_device *cd, char *buf) \
+ { \
+-	return tm_attr_show(d, buf, sched); \
++	return tm_attr_show(cd, buf, sched); \
+ } \
+-static ssize_t store_##name(struct device *d, struct device_attribute *attr, \
+-			    const char *buf, size_t len) \
++static ssize_t store_##name(struct class_device *cd, const char *buf, size_t len) \
+ { \
+-	return tm_attr_store(d, buf, len, sched); \
++	return tm_attr_store(cd, buf, len, sched); \
+ } \
+-static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
++static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
+ 
+ TM_ATTR(sched0, 0);
+ TM_ATTR(sched1, 1);
+@@ -702,14 +700,14 @@ TM_ATTR(sched6, 6);
+ TM_ATTR(sched7, 7);
+ 
+ static struct attribute *offload_attrs[] = {
+-	&dev_attr_sched0.attr,
+-	&dev_attr_sched1.attr,
+-	&dev_attr_sched2.attr,
+-	&dev_attr_sched3.attr,
+-	&dev_attr_sched4.attr,
+-	&dev_attr_sched5.attr,
+-	&dev_attr_sched6.attr,
+-	&dev_attr_sched7.attr,
++	&class_device_attr_sched0.attr,
++	&class_device_attr_sched1.attr,
++	&class_device_attr_sched2.attr,
++	&class_device_attr_sched3.attr,
++	&class_device_attr_sched4.attr,
++	&class_device_attr_sched5.attr,
++	&class_device_attr_sched6.attr,
++	&class_device_attr_sched7.attr,
+ 	NULL
+ };
+ 
+@@ -1051,8 +1049,8 @@ static int offload_open(struct net_devic
+ 		     adapter->port[0]->mtu : 0xffff);
+ 	init_smt(adapter);
+ 
+-	if (sysfs_create_group(&tdev->lldev->dev.kobj, &offload_attr_group))
+-		dev_dbg(&dev->dev, "cannot create sysfs group\n");
++ 	if (sysfs_create_group(&tdev->lldev->class_dev.kobj, &offload_attr_group))
++		dev_dbg(&adapter->pdev->dev, "cannot create sysfs group\n");
+ 
+ 	/* Call back all registered clients */
+ 	cxgb3_add_clients(tdev);
+@@ -1077,7 +1075,7 @@ static int offload_close(struct t3cdev *
+ 	/* Call back all registered clients */
+ 	cxgb3_remove_clients(tdev);
+ 
+-	sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
++	sysfs_remove_group(&tdev->lldev->class_dev.kobj, &offload_attr_group);
+ 
+ 	tdev->lldev = NULL;
+ 	cxgb3_set_dummy_ops(tdev);
+@@ -2788,7 +2786,7 @@ static int __devinit init_one(struct pci
+ 	else if (msi > 0 && pci_enable_msi(pdev) == 0)
+ 		adapter->flags |= USING_MSI;
+ 
+-	err = sysfs_create_group(&adapter->port[0]->dev.kobj,
++	err = sysfs_create_group(&adapter->port[0]->class_dev.kobj,
+ 				 &cxgb3_attr_group);
+ 
+ 	print_port_info(adapter, ai);
+@@ -2819,7 +2817,7 @@ static void __devexit remove_one(struct 
+ 		int i;
+ 
+ 		t3_sge_stop(adapter);
+-		sysfs_remove_group(&adapter->port[0]->dev.kobj,
++		sysfs_remove_group(&adapter->port[0]->class_dev.kobj,
+ 				   &cxgb3_attr_group);
+ 
+ 		if (is_offload(adapter)) {
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0030_sset.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0030_sset.patch
new file mode 100644
index 0000000..3f1b40e
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0030_sset.patch
@@ -0,0 +1,34 @@
+---
+ drivers/net/cxgb3/cxgb3_main.c |   11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
++++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+@@ -1249,14 +1249,9 @@ static char stats_strings[][ETH_GSTRING_
+ 
+ };
+ 
+-static int get_sset_count(struct net_device *dev, int sset)
++static int get_stats_count(struct net_device *dev)
+ {
+-	switch (sset) {
+-	case ETH_SS_STATS:
+-		return ARRAY_SIZE(stats_strings);
+-	default:
+-		return -EOPNOTSUPP;
+-	}
++	return ARRAY_SIZE(stats_strings);
+ }
+ 
+ #define T3_REGMAP_SIZE (3 * 1024)
+@@ -1774,7 +1769,7 @@ static const struct ethtool_ops cxgb_eth
+ 	.get_strings = get_strings,
+ 	.phys_id = cxgb3_phys_id,
+ 	.nway_reset = restart_autoneg,
+-	.get_sset_count = get_sset_count,
++	.get_stats_count = get_stats_count,
+ 	.get_ethtool_stats = get_stats,
+ 	.get_regs_len = get_regs_len,
+ 	.get_regs = get_regs,
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0100_remove_lro.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0100_remove_lro.patch
new file mode 100644
index 0000000..6cd1123
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0100_remove_lro.patch
@@ -0,0 +1,491 @@
+---
+ drivers/net/cxgb3/adapter.h     |   14 --
+ drivers/net/cxgb3/common.h      |    1 
+ drivers/net/cxgb3/cxgb3_ioctl.h |    1 
+ drivers/net/cxgb3/cxgb3_main.c  |   19 ---
+ drivers/net/cxgb3/sge.c         |  230 ++--------------------------------------
+ drivers/net/cxgb3/t3_cpl.h      |   11 -
+ 6 files changed, 12 insertions(+), 264 deletions(-)
+
+Index: ofed_kernel/drivers/net/cxgb3/adapter.h
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/adapter.h
++++ ofed_kernel/drivers/net/cxgb3/adapter.h
+@@ -42,7 +42,6 @@
+ #include <linux/cache.h>
+ #include <linux/mutex.h>
+ #include <linux/bitops.h>
+-#include <linux/inet_lro.h>
+ #include "t3cdev.h"
+ #include <asm/io.h>
+ 
+@@ -171,27 +170,14 @@ enum {				/* per port SGE statistics */
+ 	SGE_PSTAT_TX_CSUM,	/* # of TX checksum offloads */
+ 	SGE_PSTAT_VLANEX,	/* # of VLAN tag extractions */
+ 	SGE_PSTAT_VLANINS,	/* # of VLAN tag insertions */
+-	SGE_PSTAT_LRO_AGGR,	/* # of page chunks added to LRO sessions */
+-	SGE_PSTAT_LRO_FLUSHED,	/* # of flushed LRO sessions */
+-	SGE_PSTAT_LRO_NO_DESC,	/* # of overflown LRO sessions */
+ 
+ 	SGE_PSTAT_MAX		/* must be last */
+ };
+ 
+-#define T3_MAX_LRO_SES 8
+-#define T3_MAX_LRO_MAX_PKTS 64
+-
+ struct sge_qset {		/* an SGE queue set */
+ 	struct sge_rspq rspq;
+ 	struct sge_fl fl[SGE_RXQ_PER_SET];
+ 	struct sge_txq txq[SGE_TXQ_PER_SET];
+-	struct net_lro_mgr lro_mgr;
+-	struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
+-	struct skb_frag_struct *lro_frag_tbl;
+-	int lro_nfrags;
+-	int lro_enabled;
+-	int lro_frag_len;
+-	void *lro_va;
+ 	struct net_device *netdev;	/* associated net device */
+ 	unsigned long txq_stopped;	/* which Tx queues are stopped */
+ 	struct timer_list tx_reclaim_timer;	/* reclaims TX buffers */
+Index: ofed_kernel/drivers/net/cxgb3/common.h
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/common.h
++++ ofed_kernel/drivers/net/cxgb3/common.h
+@@ -351,7 +351,6 @@ struct tp_params {
+ 
+ struct qset_params {		/* SGE queue set parameters */
+ 	unsigned int polling;	/* polling/interrupt service for rspq */
+-	unsigned int lro;	/* large receive offload */
+ 	unsigned int coalesce_usecs;	/* irq coalescing timer */
+ 	unsigned int rspq_size;	/* # of entries in response queue */
+ 	unsigned int fl_size;	/* # of entries in regular free list */
+Index: ofed_kernel/drivers/net/cxgb3/cxgb3_ioctl.h
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_ioctl.h
++++ ofed_kernel/drivers/net/cxgb3/cxgb3_ioctl.h
+@@ -90,7 +90,6 @@ struct ch_qset_params {
+ 	int32_t fl_size[2];
+ 	int32_t intr_lat;
+ 	int32_t polling;
+-	int32_t lro;
+ 	int32_t cong_thres;
+ };
+ 
+Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
++++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
+@@ -1239,9 +1239,6 @@ static char stats_strings[][ETH_GSTRING_
+ 	"VLANinsertions     ",
+ 	"TxCsumOffload      ",
+ 	"RxCsumGood         ",
+-	"LroAggregated      ",
+-	"LroFlushed         ",
+-	"LroNoDesc          ",
+ 	"RxDrops            ",
+ 
+ 	"CheckTXEnToggled   ",
+@@ -1365,9 +1362,6 @@ static void get_stats(struct net_device 
+ 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
+ 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
+ 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
+-	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
+-	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
+-	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
+ 	*data++ = s->rx_cong_drops;
+ 
+ 	*data++ = s->num_toggled;
+@@ -1586,13 +1580,6 @@ static int set_rx_csum(struct net_device
+ 	struct port_info *p = netdev_priv(dev);
+ 
+ 	p->rx_csum_offload = data;
+-	if (!data) {
+-		struct adapter *adap = p->adapter;
+-		int i;
+-
+-		for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
+-			adap->sge.qs[i].lro_enabled = 0;
+-	}
+ 	return 0;
+ }
+ 
+@@ -1865,11 +1852,6 @@ static int cxgb_extension_ioctl(struct n
+ 				}
+ 			}
+ 		}
+-		if (t.lro >= 0) {
+-			struct sge_qset *qs = &adapter->sge.qs[t.qset_idx];
+-			q->lro = t.lro;
+-			qs->lro_enabled = t.lro;
+-		}
+ 		break;
+ 	}
+ 	case CHELSIO_GET_QSET_PARAMS:{
+@@ -1889,7 +1871,6 @@ static int cxgb_extension_ioctl(struct n
+ 		t.fl_size[0] = q->fl_size;
+ 		t.fl_size[1] = q->jumbo_size;
+ 		t.polling = q->polling;
+-		t.lro = q->lro;
+ 		t.intr_lat = q->coalesce_usecs;
+ 		t.cong_thres = q->cong_thres;
+ 
+Index: ofed_kernel/drivers/net/cxgb3/sge.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/sge.c
++++ ofed_kernel/drivers/net/cxgb3/sge.c
+@@ -774,7 +774,7 @@ recycle:
+ 		goto recycle;
+ 
+ 	if (!skb)
+-		newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
++		newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
+ 	if (unlikely(!newskb)) {
+ 		if (!drop_thres)
+ 			return NULL;
+@@ -1854,10 +1854,9 @@ static void restart_tx(struct sge_qset *
+  *	if it was immediate data in a response.
+  */
+ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
+-		   struct sk_buff *skb, int pad, int lro)
++		   struct sk_buff *skb, int pad)
+ {
+ 	struct cpl_rx_pkt *p = (struct cpl_rx_pkt *)(skb->data + pad);
+-	struct sge_qset *qs = rspq_to_qset(rq);
+ 	struct port_info *pi;
+ 
+ 	skb_pull(skb, sizeof(*p) + pad);
+@@ -1874,202 +1873,18 @@ static void rx_eth(struct adapter *adap,
+ 	if (unlikely(p->vlan_valid)) {
+ 		struct vlan_group *grp = pi->vlan_grp;
+ 
+-		qs->port_stats[SGE_PSTAT_VLANEX]++;
++		rspq_to_qset(rq)->port_stats[SGE_PSTAT_VLANEX]++;
+ 		if (likely(grp))
+-			if (lro)
+-				lro_vlan_hwaccel_receive_skb(&qs->lro_mgr, skb,
+-							     grp,
+-							     ntohs(p->vlan),
+-							     p);
+-			else
+-				__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
+-					  	  rq->polling);
++			__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
++					  rq->polling);
+ 		else
+ 			dev_kfree_skb_any(skb);
+-	} else if (rq->polling) {
+-		if (lro)
+-			lro_receive_skb(&qs->lro_mgr, skb, p);
+-		else
+-			netif_receive_skb(skb);
+-	} else
++	} else if (rq->polling)
++		netif_receive_skb(skb);
++	else
+ 		netif_rx(skb);
+ }
+ 
+-static inline int is_eth_tcp(u32 rss)
+-{
+-	return G_HASHTYPE(ntohl(rss)) == RSS_HASH_4_TUPLE;
+-}
+-
+-/**
+- *	lro_frame_ok - check if an ingress packet is eligible for LRO
+- *	@p: the CPL header of the packet
+- *
+- *	Returns true if a received packet is eligible for LRO.
+- *	The following conditions must be true:
+- *	- packet is TCP/IP Ethernet II (checked elsewhere)
+- *	- not an IP fragment
+- *	- no IP options
+- *	- TCP/IP checksums are correct
+- *	- the packet is for this host
+- */
+-static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
+-{
+-	const struct ethhdr *eh = (struct ethhdr *)(p + 1);
+-	const struct iphdr *ih = (struct iphdr *)(eh + 1);
+-
+-	return (*((u8 *)p + 1) & 0x90) == 0x10 && p->csum == htons(0xffff) &&
+-		eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
+-}
+-
+-#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
+-                       TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
+-		                       TCP_FLAG_SYN | TCP_FLAG_FIN)
+-#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
+-                     (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
+-
+-/**
+- *	lro_segment_ok - check if a TCP segment is eligible for LRO
+- *	@tcph: the TCP header of the packet
+- *
+- *	Returns true if a TCP packet is eligible for LRO.  This requires that
+- *	the packet have only the ACK flag set and no TCP options besides
+- *	time stamps.
+- */
+-static inline int lro_segment_ok(const struct tcphdr *tcph)
+-{
+-	int optlen;
+-
+-	if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
+-		return 0;
+-
+-	optlen = (tcph->doff << 2) - sizeof(*tcph);
+-	if (optlen) {
+-		const u32 *opt = (const u32 *)(tcph + 1);
+-
+-		if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
+-		    *opt != htonl(TSTAMP_WORD) || !opt[2])
+-			return 0;
+-	}
+-	return 1;
+-}
+-
+-static int t3_get_lro_header(void **eh,  void **iph, void **tcph,
+-			     u64 *hdr_flags, void *priv)
+-{
+-	const struct cpl_rx_pkt *cpl = priv;
+-
+-	if (!lro_frame_ok(cpl))
+-		return -1;
+-
+-	*eh = (struct ethhdr *)(cpl + 1);
+-	*iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
+-	*tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
+-
+-	 if (!lro_segment_ok(*tcph))
+-		return -1;
+-
+-	*hdr_flags = LRO_IPV4 | LRO_TCP;
+-	return 0;
+-}
+-
+-static int t3_get_skb_header(struct sk_buff *skb,
+-			      void **iph, void **tcph, u64 *hdr_flags,
+-			      void *priv)
+-{
+-	void *eh;
+-
+-	return t3_get_lro_header(&eh, iph, tcph, hdr_flags, priv);
+-}
+-
+-static int t3_get_frag_header(struct skb_frag_struct *frag, void **eh,
+-			      void **iph, void **tcph, u64 *hdr_flags,
+-			      void *priv)
+-{
+-	return t3_get_lro_header(eh, iph, tcph, hdr_flags, priv);
+-}
+-
+-/**
+- *	lro_add_page - add a page chunk to an LRO session
+- *	@adap: the adapter
+- *	@qs: the associated queue set
+- *	@fl: the free list containing the page chunk to add
+- *	@len: packet length
+- *	@complete: Indicates the last fragment of a frame
+- *
+- *	Add a received packet contained in a page chunk to an existing LRO
+- *	session.
+- */
+-static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
+-			 struct sge_fl *fl, int len, int complete)
+-{
+-	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+-	struct cpl_rx_pkt *cpl;
+-	struct skb_frag_struct *rx_frag = qs->lro_frag_tbl;
+-	int nr_frags = qs->lro_nfrags, frag_len = qs->lro_frag_len;
+-	int offset = 0;
+-
+-	if (!nr_frags) {
+-		offset = 2 + sizeof(struct cpl_rx_pkt);
+-		qs->lro_va = cpl = sd->pg_chunk.va + 2;
+-	}
+-
+-	fl->credits--;
+-
+-	len -= offset;
+-	pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
+-			 fl->buf_size, PCI_DMA_FROMDEVICE);
+-
+-	rx_frag += nr_frags;
+-	rx_frag->page = sd->pg_chunk.page;
+-	rx_frag->page_offset = sd->pg_chunk.offset + offset;
+-	rx_frag->size = len;
+-	frag_len += len;
+-	qs->lro_nfrags++;
+-	qs->lro_frag_len = frag_len;
+-
+-	if (!complete)
+-		return;
+-
+-	qs->lro_nfrags = qs->lro_frag_len = 0;
+-	cpl = qs->lro_va;
+-
+-	if (unlikely(cpl->vlan_valid)) {
+-		struct net_device *dev = qs->netdev;
+-		struct port_info *pi = netdev_priv(dev);
+-		struct vlan_group *grp = pi->vlan_grp;
+-
+-		if (likely(grp != NULL)) {
+-			lro_vlan_hwaccel_receive_frags(&qs->lro_mgr,
+-						       qs->lro_frag_tbl,
+-						       frag_len, frag_len,
+-						       grp, ntohs(cpl->vlan),
+-						       cpl, 0);
+-			return;
+-		}
+-	}
+-	lro_receive_frags(&qs->lro_mgr, qs->lro_frag_tbl,
+-			  frag_len, frag_len, cpl, 0);
+-}
+-
+-/**
+- *	init_lro_mgr - initialize a LRO manager object
+- *	@lro_mgr: the LRO manager object
+- */
+-static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
+-{
+-	lro_mgr->dev = qs->netdev;
+-	lro_mgr->features = LRO_F_NAPI;
+-	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
+-	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
+-	lro_mgr->max_desc = T3_MAX_LRO_SES;
+-	lro_mgr->lro_arr = qs->lro_desc;
+-	lro_mgr->get_frag_header = t3_get_frag_header;
+-	lro_mgr->get_skb_header = t3_get_skb_header;
+-	lro_mgr->max_aggr = T3_MAX_LRO_MAX_PKTS;
+-	if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
+-		lro_mgr->max_aggr = MAX_SKB_FRAGS;
+-}
+-
+ /**
+  *	handle_rsp_cntrl_info - handles control information in a response
+  *	@qs: the queue set corresponding to the response
+@@ -2198,7 +2013,7 @@ static int process_responses(struct adap
+ 	q->next_holdoff = q->holdoff_tmr;
+ 
+ 	while (likely(budget_left && is_new_response(r, q))) {
+-		int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
++		int packet_complete, eth, ethpad = 2;
+ 		struct sk_buff *skb = NULL;
+ 		u32 len, flags = ntohl(r->flags);
+ 		__be32 rss_hi = *(const __be32 *)r,
+@@ -2230,9 +2045,6 @@ no_mem:
+ 		} else if ((len = ntohl(r->len_cq)) != 0) {
+ 			struct sge_fl *fl;
+ 
+-			if (eth)
+-				lro = qs->lro_enabled && is_eth_tcp(rss_hi);
+-
+ 			fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
+ 			if (fl->use_pages) {
+ 				void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
+@@ -2242,12 +2054,6 @@ no_mem:
+ 				prefetch(addr + L1_CACHE_BYTES);
+ #endif
+ 				__refill_fl(adap, fl);
+-				if (lro > 0) {
+-					lro_add_page(adap, qs, fl,
+-						     G_RSPD_LEN(len),
+-						     flags & F_RSPD_EOP);
+-					 goto next_fl;
+-				}
+ 
+ 				skb = get_packet_pg(adap, fl, q,
+ 						    G_RSPD_LEN(len),
+@@ -2263,7 +2069,7 @@ no_mem:
+ 				q->rx_drops++;
+ 			} else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT))
+ 				__skb_pull(skb, 2);
+-next_fl:
++
+ 			if (++fl->cidx == fl->size)
+ 				fl->cidx = 0;
+ 		} else
+@@ -2293,7 +2099,7 @@ next_fl:
+ 
+ 		if (skb != NULL && packet_complete) {
+ 			if (eth)
+-				rx_eth(adap, q, skb, ethpad, lro);
++				rx_eth(adap, q, skb, ethpad);
+ 			else {
+ 				q->offload_pkts++;
+ 				/* Preserve the RSS info in csum & priority */
+@@ -2305,17 +2111,12 @@ next_fl:
+ 			}
+ 
+ 			if (flags & F_RSPD_EOP)
+-				clear_rspq_bufstate(q);
++				clear_rspq_bufstate(q);
+ 		}
+ 		--budget_left;
+ 	}
+ 
+ 	deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);
+-	lro_flush_all(&qs->lro_mgr);
+-	qs->port_stats[SGE_PSTAT_LRO_AGGR] = qs->lro_mgr.stats.aggregated;
+-	qs->port_stats[SGE_PSTAT_LRO_FLUSHED] = qs->lro_mgr.stats.flushed;
+-	qs->port_stats[SGE_PSTAT_LRO_NO_DESC] = qs->lro_mgr.stats.no_desc;
+-
+ 	if (sleeping)
+ 		check_ring_db(adap, qs, sleeping);
+ 
+@@ -2876,7 +2677,6 @@ int t3_sge_alloc_qset(struct adapter *ad
+ {
+ 	int i, avail, ret = -ENOMEM;
+ 	struct sge_qset *q = &adapter->sge.qs[id];
+-	struct net_lro_mgr *lro_mgr = &q->lro_mgr;
+ 
+ 	init_qset_cntxt(q, id);
+ 	init_timer(&q->tx_reclaim_timer);
+@@ -2957,10 +2757,6 @@ int t3_sge_alloc_qset(struct adapter *ad
+ 	q->fl[0].order = FL0_PG_ORDER;
+ 	q->fl[1].order = FL1_PG_ORDER;
+ 
+-	q->lro_frag_tbl = kcalloc(MAX_FRAME_SIZE / FL1_PG_CHUNK_SIZE + 1,
+-				  sizeof(struct skb_frag_struct),
+-				  GFP_KERNEL);
+-	q->lro_nfrags = q->lro_frag_len = 0;
+ 	spin_lock_irq(&adapter->sge.reg_lock);
+ 
+ 	/* FL threshold comparison uses < */
+@@ -3017,8 +2813,6 @@ int t3_sge_alloc_qset(struct adapter *ad
+  	if (netdev->atalk_ptr == NULL)
+  		netdev->atalk_ptr = q;
+ 
+-	init_lro_mgr(q, lro_mgr);
+-
+ 	avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
+ 			  GFP_KERNEL | __GFP_COMP);
+ 	if (!avail) {
+Index: ofed_kernel/drivers/net/cxgb3/t3_cpl.h
+===================================================================
+--- ofed_kernel.orig/drivers/net/cxgb3/t3_cpl.h
++++ ofed_kernel/drivers/net/cxgb3/t3_cpl.h
+@@ -174,13 +174,6 @@ enum {				/* TCP congestion control algo
+ 	CONG_ALG_HIGHSPEED
+ };
+ 
+-enum {			/* RSS hash type */
+-	RSS_HASH_NONE = 0,
+-	RSS_HASH_2_TUPLE = 1,
+-	RSS_HASH_4_TUPLE = 2,
+-	RSS_HASH_TCPV6 = 3
+-};
+-
+ union opcode_tid {
+ 	__be32 opcode_tid;
+ 	__u8 opcode;
+@@ -194,10 +187,6 @@ union opcode_tid {
+ #define S_QNUM 0
+ #define G_QNUM(x) (((x) >> S_QNUM) & 0xFFFF)
+ 
+-#define S_HASHTYPE 22
+-#define M_HASHTYPE 0x3
+-#define G_HASHTYPE(x) (((x) >> S_HASHTYPE) & M_HASHTYPE)
+-
+ /* tid is assumed to be 24-bits */
+ #define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid))
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0110_provider_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0110_provider_sysfs.patch
new file mode 100644
index 0000000..cafd90e
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/cxgb3_0110_provider_sysfs.patch
@@ -0,0 +1,120 @@
+---
+ drivers/infiniband/hw/cxgb3/iwch_provider.c |   63 +++++++++++++---------------
+ 1 file changed, 30 insertions(+), 33 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_provider.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/cxgb3/iwch_provider.c
++++ ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_provider.c
+@@ -1178,46 +1178,43 @@ static int iwch_query_port(struct ib_dev
+ 	return 0;
+ }
+ 
+-static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_rev(struct class_device *cdev, char *buf)
+ {
+-	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
+-						 ibdev.dev);
+-	PDBG("%s dev 0x%p\n", __func__, dev);
++	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
++						 ibdev.class_dev);
++	PDBG("%s dev 0x%p\n", __func__, cdev);
+ 	return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type);
+ }
+ 
+-static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
+ {
+-	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
+-						 ibdev.dev);
++	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
++						 ibdev.class_dev);
+ 	struct ethtool_drvinfo info;
+ 	struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
+ 
+-	PDBG("%s dev 0x%p\n", __func__, dev);
++	PDBG("%s dev 0x%p\n", __func__, cdev);
+ 	lldev->ethtool_ops->get_drvinfo(lldev, &info);
+ 	return sprintf(buf, "%s\n", info.fw_version);
+ }
+ 
+-static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_hca(struct class_device *cdev, char *buf)
+ {
+-	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
+-						 ibdev.dev);
++	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
++						 ibdev.class_dev);
+ 	struct ethtool_drvinfo info;
+ 	struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
+ 
+-	PDBG("%s dev 0x%p\n", __func__, dev);
++	PDBG("%s dev 0x%p\n", __func__, cdev);
+ 	lldev->ethtool_ops->get_drvinfo(lldev, &info);
+ 	return sprintf(buf, "%s\n", info.driver);
+ }
+ 
+-static ssize_t show_board(struct device *dev, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_board(struct class_device *cdev, char *buf)
+ {
+-	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
+-						 ibdev.dev);
+-	PDBG("%s dev 0x%p\n", __func__, dev);
++	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
++						 ibdev.class_dev);
++	PDBG("%s dev 0x%p\n", __func__, cdev);
+ 	return sprintf(buf, "%x.%x\n", iwch_dev->rdev.rnic_info.pdev->vendor,
+ 		       iwch_dev->rdev.rnic_info.pdev->device);
+ }
+@@ -1281,16 +1278,16 @@ static int iwch_get_mib(struct ib_device
+ 	return 0;
+ }
+ 
+-static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
+-static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
+-static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
+-static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
+-
+-static struct device_attribute *iwch_class_attributes[] = {
+-	&dev_attr_hw_rev,
+-	&dev_attr_fw_ver,
+-	&dev_attr_hca_type,
+-	&dev_attr_board_id,
++static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
++static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
++static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
++static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
++
++static struct class_device_attribute *iwch_class_attributes[] = {
++	&class_device_attr_hw_rev,
++	&class_device_attr_fw_ver,
++	&class_device_attr_hca_type,
++	&class_device_attr_board_id,
+ };
+ 
+ int iwch_register_device(struct iwch_dev *dev)
+@@ -1389,8 +1386,8 @@ int iwch_register_device(struct iwch_dev
+ 		goto bail1;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(iwch_class_attributes); ++i) {
+-		ret = device_create_file(&dev->ibdev.dev,
+-					 iwch_class_attributes[i]);
++		ret = class_device_create_file(&dev->ibdev.class_dev,
++						iwch_class_attributes[i]);
+ 		if (ret) {
+ 			goto bail2;
+ 		}
+@@ -1408,8 +1405,8 @@ void iwch_unregister_device(struct iwch_
+ 
+ 	PDBG("%s iwch_dev %p\n", __func__, dev);
+ 	for (i = 0; i < ARRAY_SIZE(iwch_class_attributes); ++i)
+-		device_remove_file(&dev->ibdev.dev,
+-				   iwch_class_attributes[i]);
++		class_device_remove_file(&dev->ibdev.class_dev,
++					iwch_class_attributes[i]);
+ 	ib_unregister_device(&dev->ibdev);
+ 	return;
+ }
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/dma_mapping_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/dma_mapping_to_2_6_26.patch
new file mode 100644
index 0000000..3159b92
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/dma_mapping_to_2_6_26.patch
@@ -0,0 +1,17 @@
+---
+ include/rdma/ib_verbs.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: ofed_kernel/include/rdma/ib_verbs.h
+===================================================================
+--- ofed_kernel.orig/include/rdma/ib_verbs.h
++++ ofed_kernel/include/rdma/ib_verbs.h
+@@ -1682,7 +1682,7 @@ static inline int ib_dma_mapping_error(s
+ {
+ 	if (dev->dma_ops)
+ 		return dev->dma_ops->mapping_error(dev, dma_addr);
+-	return dma_mapping_error(dev->dma_device, dma_addr);
++	return dma_mapping_error(dma_addr);
+ }
+ 
+ /**
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ehca-00-revert_inhibit_dmem.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ehca-00-revert_inhibit_dmem.patch
new file mode 100644
index 0000000..3b153ec
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ehca-00-revert_inhibit_dmem.patch
@@ -0,0 +1,112 @@
+From 8e110a2fff1f110a9211f240acc12b8310e5cbd3 Mon Sep 17 00:00:00 2001
+From: Stefan Roscher <ossrosch at linux.vnet.ibm.com>
+Date: Wed, 22 Oct 2008 15:54:38 -0700
+Subject: [PATCH] IB/ehca: Reject dynamic memory add/remove when ehca adapter is present
+
+Since the ehca device driver does not support dynamic memory add and
+remove operations, the driver must explicitly reject such requests in
+order to prevent unpredictable behaviors related to existing memory
+regions that cover all of memory being used by InfiniBand protocols in
+the kernel.
+
+The solution (for now at least) is to add a memory notifier to the
+ehca device driver and if a request for dynamic memory add or remove
+comes in, ehca will always reject it.  The user can add or remove
+memory by hot-removing the ehca adapter, performing the memory
+operation, and then hot-adding the ehca adapter back.
+
+Signed-off-by: Stefan Roscher <stefan.roscher at de.ibm.com>
+Signed-off-by: Roland Dreier <rolandd at cisco.com>
+---
+ drivers/infiniband/hw/ehca/ehca_main.c |   47 --------------------------------
+ 1 files changed, 0 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
+index bec7e02..086959a 100644
+--- a/drivers/infiniband/hw/ehca/ehca_main.c
++++ b/drivers/infiniband/hw/ehca/ehca_main.c
+@@ -44,8 +44,6 @@
+ #include <linux/slab.h>
+ #endif
+ 
+-#include <linux/notifier.h>
+-#include <linux/memory.h>
+ #include "ehca_classes.h"
+ #include "ehca_iverbs.h"
+ #include "ehca_mrmw.h"
+@@ -971,40 +969,6 @@ void ehca_poll_eqs(unsigned long data)
+ 	spin_unlock(&shca_list_lock);
+ }
+ 
+-static int ehca_mem_notifier(struct notifier_block *nb,
+-			     unsigned long action, void *data)
+-{
+-	static unsigned long ehca_dmem_warn_time;
+-
+-	switch (action) {
+-	case MEM_CANCEL_OFFLINE:
+-	case MEM_CANCEL_ONLINE:
+-	case MEM_ONLINE:
+-	case MEM_OFFLINE:
+-		return NOTIFY_OK;
+-	case MEM_GOING_ONLINE:
+-	case MEM_GOING_OFFLINE:
+-		/* only ok if no hca is attached to the lpar */
+-		spin_lock(&shca_list_lock);
+-		if (list_empty(&shca_list)) {
+-			spin_unlock(&shca_list_lock);
+-			return NOTIFY_OK;
+-		} else {
+-			spin_unlock(&shca_list_lock);
+-			if (printk_timed_ratelimit(&ehca_dmem_warn_time,
+-						   30 * 1000))
+-				ehca_gen_err("DMEM operations are not allowed"
+-					     "in conjunction with eHCA");
+-			return NOTIFY_BAD;
+-		}
+-	}
+-	return NOTIFY_OK;
+-}
+-
+-static struct notifier_block ehca_mem_nb = {
+-	.notifier_call = ehca_mem_notifier,
+-};
+-
+ static int __init ehca_module_init(void)
+ {
+ 	int ret;
+@@ -1032,12 +996,6 @@ static int __init ehca_module_init(void)
+ 		goto module_init2;
+ 	}
+ 
+-	ret = register_memory_notifier(&ehca_mem_nb);
+-	if (ret) {
+-		ehca_gen_err("Failed registering memory add/remove notifier");
+-		goto module_init3;
+-	}
+-
+ 	if (ehca_poll_all_eqs != 1) {
+ 		ehca_gen_err("WARNING!!!");
+ 		ehca_gen_err("It is possible to lose interrupts.");
+@@ -1050,9 +1008,6 @@ static int __init ehca_module_init(void)
+ 
+ 	return 0;
+ 
+-module_init3:
+-	ibmebus_unregister_driver(&ehca_driver);
+-
+ module_init2:
+ 	ehca_destroy_slab_caches();
+ 
+@@ -1068,8 +1023,6 @@ static void __exit ehca_module_exit(void)
+ 
+ 	ibmebus_unregister_driver(&ehca_driver);
+ 
+-	unregister_memory_notifier(&ehca_mem_nb);
+-
+ 	ehca_destroy_slab_caches();
+ 
+ 	ehca_destroy_comp_pool();
+-- 
+1.5.5
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ehca-01-ibmebus_loc_code.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ehca-01-ibmebus_loc_code.patch
new file mode 100644
index 0000000..c486733
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ehca-01-ibmebus_loc_code.patch
@@ -0,0 +1,191 @@
+---
+ drivers/infiniband/hw/ehca/ehca_classes.h |    2 -
+ drivers/infiniband/hw/ehca/ehca_eq.c      |    6 +--
+ drivers/infiniband/hw/ehca/ehca_main.c    |   49 ++++++++++++++----------------
+ 3 files changed, 27 insertions(+), 30 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_classes.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_classes.h
++++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_classes.h
+@@ -112,7 +112,7 @@ struct ehca_sport {
+ 
+ struct ehca_shca {
+ 	struct ib_device ib_device;
+-	struct of_device *ofdev;
++	struct ibmebus_dev *ibmebus_dev;
+ 	u8 num_ports;
+ 	int hw_level;
+ 	struct list_head shca_list;
+Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_eq.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_eq.c
++++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_eq.c
+@@ -122,7 +122,7 @@ int ehca_create_eq(struct ehca_shca *shc
+ 
+ 	/* register interrupt handlers and initialize work queues */
+ 	if (type == EHCA_EQ) {
+-		ret = ibmebus_request_irq(eq->ist, ehca_interrupt_eq,
++		ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq,
+ 					  IRQF_DISABLED, "ehca_eq",
+ 					  (void *)shca);
+ 		if (ret < 0)
+@@ -130,7 +130,7 @@ int ehca_create_eq(struct ehca_shca *shc
+ 
+ 		tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
+ 	} else if (type == EHCA_NEQ) {
+-		ret = ibmebus_request_irq(eq->ist, ehca_interrupt_neq,
++		ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq,
+ 					  IRQF_DISABLED, "ehca_neq",
+ 					  (void *)shca);
+ 		if (ret < 0)
+@@ -170,7 +170,7 @@ int ehca_destroy_eq(struct ehca_shca *sh
+ 	u64 h_ret;
+ 
+ 	spin_lock_irqsave(&eq->spinlock, flags);
+-	ibmebus_free_irq(eq->ist, (void *)shca);
++	ibmebus_free_irq(NULL, eq->ist, (void *)shca);
+ 
+ 	h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
+ 
+Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_main.c
++++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_main.c
+@@ -289,8 +289,8 @@ static int ehca_sense_attributes(struct 
+ 	};
+ 
+ 	ehca_gen_dbg("Probing adapter %s...",
+-		     shca->ofdev->node->full_name);
+-	loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL);
++		     shca->ibmebus_dev->ofdev.node->full_name);
++	loc_code = of_get_property(shca->ibmebus_dev->ofdev.node, "ibm,loc-code", NULL);
+ 	if (loc_code)
+ 		ehca_gen_dbg(" ... location lode=%s", loc_code);
+ 
+@@ -458,7 +458,7 @@ static int ehca_init_device(struct ehca_
+ 	shca->ib_device.node_type           = RDMA_NODE_IB_CA;
+ 	shca->ib_device.phys_port_cnt       = shca->num_ports;
+ 	shca->ib_device.num_comp_vectors    = 1;
+-	shca->ib_device.dma_device          = &shca->ofdev->dev;
++	shca->ib_device.dma_device          = &shca->ibmebus_dev->ofdev.dev;
+ 	shca->ib_device.query_device        = ehca_query_device;
+ 	shca->ib_device.query_port          = ehca_query_port;
+ 	shca->ib_device.query_gid           = ehca_query_gid;
+@@ -619,11 +619,6 @@ static struct attribute_group ehca_drv_a
+ 	.attrs = ehca_drv_attrs
+ };
+ 
+-static struct attribute_group *ehca_drv_attr_groups[] = {
+-	&ehca_drv_attr_grp,
+-	NULL,
+-};
+-
+ #define EHCA_RESOURCE_ATTR(name)                                           \
+ static ssize_t  ehca_show_##name(struct device *dev,                       \
+ 				 struct device_attribute *attr,            \
+@@ -707,7 +702,7 @@ static struct attribute_group ehca_dev_a
+ 	.attrs = ehca_dev_attrs
+ };
+ 
+-static int __devinit ehca_probe(struct of_device *dev,
++static int __devinit ehca_probe(struct ibmebus_dev *dev,
+ 				const struct of_device_id *id)
+ {
+ 	struct ehca_shca *shca;
+@@ -715,16 +710,16 @@ static int __devinit ehca_probe(struct o
+ 	struct ib_pd *ibpd;
+ 	int ret, i, eq_size;
+ 
+-	handle = of_get_property(dev->node, "ibm,hca-handle", NULL);
++	handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
+ 	if (!handle) {
+ 		ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
+-			     dev->node->full_name);
++			     dev->ofdev.node->full_name);
+ 		return -ENODEV;
+ 	}
+ 
+ 	if (!(*handle)) {
+ 		ehca_gen_err("Wrong eHCA handle for adapter: %s.",
+-			     dev->node->full_name);
++			     dev->ofdev.node->full_name);
+ 		return -ENODEV;
+ 	}
+ 
+@@ -739,9 +734,9 @@ static int __devinit ehca_probe(struct o
+ 	for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
+ 		spin_lock_init(&shca->sport[i].mod_sqp_lock);
+ 
+-	shca->ofdev = dev;
++	shca->ibmebus_dev = dev;
+ 	shca->ipz_hca_handle.handle = *handle;
+-	dev->dev.driver_data = shca;
++	dev->ofdev.dev.driver_data = shca;
+ 
+ 	ret = ehca_sense_attributes(shca);
+ 	if (ret < 0) {
+@@ -818,7 +813,7 @@ static int __devinit ehca_probe(struct o
+ 		}
+ 	}
+ 
+-	ret = sysfs_create_group(&dev->dev.kobj, &ehca_dev_attr_grp);
++	ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
+ 	if (ret) /* only complain; we can live without attributes */
+ 		ehca_err(&shca->ib_device,
+ 			 "Cannot create device attributes  ret=%d", ret);
+@@ -868,12 +863,12 @@ probe1:
+ 	return -EINVAL;
+ }
+ 
+-static int __devexit ehca_remove(struct of_device *dev)
++static int __devexit ehca_remove(struct ibmebus_dev *dev)
+ {
+-	struct ehca_shca *shca = dev->dev.driver_data;
++	struct ehca_shca *shca = dev->ofdev.dev.driver_data;
+ 	int ret;
+ 
+-	sysfs_remove_group(&dev->dev.kobj, &ehca_dev_attr_grp);
++	sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
+ 
+ 	if (ehca_open_aqp1 == 1) {
+ 		int i;
+@@ -925,14 +920,11 @@ static struct of_device_id ehca_device_t
+ };
+ MODULE_DEVICE_TABLE(of, ehca_device_table);
+ 
+-static struct of_platform_driver ehca_driver = {
+-	.name        = "ehca",
+-	.match_table = ehca_device_table,
+-	.probe       = ehca_probe,
+-	.remove      = ehca_remove,
+-	.driver	     = {
+-		.groups = ehca_drv_attr_groups,
+-	},
++static struct ibmebus_driver ehca_driver = {
++	.name     = "ehca",
++	.id_table = ehca_device_table,
++	.probe    = ehca_probe,
++	.remove   = ehca_remove,
+ };
+ 
+ void ehca_poll_eqs(unsigned long data)
+@@ -991,6 +983,10 @@ static int __init ehca_module_init(void)
+ 		goto module_init2;
+ 	}
+ 
++	ret = sysfs_create_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp);
++	if (ret) /* only complain; we can live without attributes */
++		ehca_gen_err("Cannot create driver attributes  ret=%d", ret);
++
+ 	if (ehca_poll_all_eqs != 1) {
+ 		ehca_gen_err("WARNING!!!");
+ 		ehca_gen_err("It is possible to lose interrupts.");
+@@ -1016,6 +1012,7 @@ static void __exit ehca_module_exit(void
+ 	if (ehca_poll_all_eqs == 1)
+ 		del_timer_sync(&poll_eqs_timer);
+ 
++	sysfs_remove_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp);
+ 	ibmebus_unregister_driver(&ehca_driver);
+ 
+ 	ehca_destroy_slab_caches();
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ehca_02_revert_interface_change.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ehca_02_revert_interface_change.patch
new file mode 100644
index 0000000..5cbbabd
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ehca_02_revert_interface_change.patch
@@ -0,0 +1,25 @@
+From 7ef1f7881a8f660654e7d1567213638b37adbbb5 Mon Sep 17 00:00:00 2001
+From: Stefan Roscher <stefan.roscher at de.ibm.com>
+Date: Wed, 6 Aug 2008 16:27:25 +0200
+Subject: [PATCH] Revert "infiniband: use performance variant for_each_cpu_mask_nr"
+
+This reverts commit 5d7bfd0c4d463d288422032c9903d0452dee141d.
+---
+ drivers/infiniband/hw/ehca/ehca_irq.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_irq.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_irq.c
++++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_irq.c
+@@ -650,8 +650,8 @@ static inline int find_next_online_cpu(s
+ 		ehca_dmp(&cpu_online_map, sizeof(cpumask_t), "");
+ 
+ 	spin_lock_irqsave(&pool->last_cpu_lock, flags);
+-	cpu = next_cpu_nr(pool->last_cpu, cpu_online_map);
+-	if (cpu >= nr_cpu_ids)
++	cpu = next_cpu(pool->last_cpu, cpu_online_map);
++	if (cpu == NR_CPUS)
+ 		cpu = first_cpu(cpu_online_map);
+ 	pool->last_cpu = cpu;
+ 	spin_unlock_irqrestore(&pool->last_cpu_lock, flags);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0005_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0005_pci_dma_mapping_error_to_2_6_26.patch
new file mode 100644
index 0000000..9d336a7
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0005_pci_dma_mapping_error_to_2_6_26.patch
@@ -0,0 +1,58 @@
+---
+ drivers/infiniband/hw/ipath/ipath_sdma.c      |    2 +-
+ drivers/infiniband/hw/ipath/ipath_user_sdma.c |    6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+Index: ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_sdma.c
+===================================================================
+--- ofa_kernel-1.4.orig/drivers/infiniband/hw/ipath/ipath_sdma.c	2009-01-25 21:37:35.000000000 -0800
++++ ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_sdma.c	2009-01-25 21:41:22.000000000 -0800
+@@ -698,7 +698,7 @@ retry:
+ 
+ 	addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr,
+ 			      tx->map_len, DMA_TO_DEVICE);
+-	if (dma_mapping_error(&dd->pcidev->dev, addr))
++	if (dma_mapping_error(addr))
+ 		goto ioerr;
+ 
+ 	dwoffset = tx->map_len >> 2;
+@@ -739,7 +739,7 @@ retry:
+ 		dw = (len + 3) >> 2;
+ 		addr = dma_map_single(&dd->pcidev->dev, sge->vaddr, dw << 2,
+ 				      DMA_TO_DEVICE);
+-		if (dma_mapping_error(&dd->pcidev->dev, addr))
++		if (dma_mapping_error(addr))
+ 			goto unmap;
+ 		make_sdma_desc(dd, sdmadesc, (u64) addr, dw, dwoffset);
+ 		/* SDmaUseLargeBuf has to be set in every descriptor */
+Index: ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_user_sdma.c
+===================================================================
+--- ofa_kernel-1.4.orig/drivers/infiniband/hw/ipath/ipath_user_sdma.c	2009-01-25 21:37:18.000000000 -0800
++++ ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_user_sdma.c	2009-01-25 21:37:54.000000000 -0800
+@@ -206,7 +206,7 @@ static int ipath_user_sdma_coalesce(cons
+ 
+ 	dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len,
+ 				DMA_TO_DEVICE);
+-	if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) {
++	if (dma_mapping_error(dma_addr)) {
+ 		ret = -ENOMEM;
+ 		goto free_unmap;
+ 	}
+@@ -301,7 +301,7 @@ static int ipath_user_sdma_pin_pages(con
+ 				     pages[j], 0, flen, DMA_TO_DEVICE);
+ 		unsigned long fofs = addr & ~PAGE_MASK;
+ 
+-		if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) {
++		if (dma_mapping_error(dma_addr)) {
+ 			ret = -ENOMEM;
+ 			goto done;
+ 		}
+@@ -508,7 +508,7 @@ static int ipath_user_sdma_queue_pkts(co
+ 		if (page) {
+ 			dma_addr = dma_map_page(&dd->pcidev->dev,
+ 						page, 0, len, DMA_TO_DEVICE);
+-			if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) {
++			if (dma_mapping_error(dma_addr)) {
+ 				ret = -ENOMEM;
+ 				goto free_pbc;
+ 			}
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0010_revert_pid.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0010_revert_pid.patch
new file mode 100644
index 0000000..58d1019
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0010_revert_pid.patch
@@ -0,0 +1,141 @@
+Signed-off-by: Dave Olson <dave.olson at qlogic.com>
+---
+
+diff -upr ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_driver.c ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_driver.c
+--- ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_driver.c	2008-10-28 12:27:04.000000000 -0700
++++ ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_driver.c	2008-10-28 12:31:40.000000000 -0700
+@@ -2622,7 +2622,7 @@ int ipath_reset_device(int unit)
+ 				ipath_dbg("unit %u port %d is in use "
+ 					  "(PID %u cmd %s), can't reset\n",
+ 					  unit, i,
+-					  pid_nr(dd->ipath_pd[i]->port_pid),
++					  dd->ipath_pd[i]->port_pid,
+ 					  dd->ipath_pd[i]->port_comm);
+ 				ret = -EBUSY;
+ 				goto bail;
+@@ -2661,7 +2661,7 @@ bail:
+ static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
+ {
+ 	int i, sub, any = 0;
+-	struct pid *pid;
++	pid_t pid;
+ 	unsigned long flags;
+ 	
+ 	if (!dd->ipath_pd)
+@@ -2669,7 +2669,8 @@ static int ipath_signal_procs(struct ipa
+ 
+ 	spin_lock_irqsave(&dd->ipath_uctxt_lock, flags);
+ 	for (i = 1; i < dd->ipath_cfgports; i++) {
+-		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt)
++		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt ||
++		    !dd->ipath_pd[i]->port_pid)
+ 			continue;
+ 		pid = dd->ipath_pd[i]->port_pid;
+ 		if (!pid)
+@@ -2677,8 +2678,8 @@ static int ipath_signal_procs(struct ipa
+ 
+ 		dev_info(&dd->pcidev->dev, "context %d in use "
+ 			  "(PID %u), sending signal %d\n",
+-			  i, pid_nr(pid), sig);
+-		kill_pid(pid, sig, 1);
++			  i, pid, sig);
++		kill_proc(pid, sig, 1);
+ 		any++;
+ 		for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) {
+ 			pid = dd->ipath_pd[i]->port_subpid[sub];
+@@ -2686,8 +2687,8 @@ static int ipath_signal_procs(struct ipa
+ 				continue;
+ 			dev_info(&dd->pcidev->dev, "sub-context "
+ 				"%d:%d in use (PID %u), sending "
+-				"signal %d\n", i, sub, pid_nr(pid), sig);
+-			kill_pid(pid, sig, 1);
++				"signal %d\n", i, sub, pid, sig);
++			kill_proc(pid, sig, 1);
+ 			any++;
+ 		}
+ 	}
+diff -upr ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_file_ops.c ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_file_ops.c
+--- ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_file_ops.c	2008-10-28 12:27:04.000000000 -0700
++++ ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_file_ops.c	2008-10-28 12:46:09.000000000 -0700
+@@ -556,7 +556,7 @@ static int ipath_tid_free(struct ipath_p
+ 			p = dd->ipath_pageshadow[porttid + tid];
+ 			dd->ipath_pageshadow[porttid + tid] = NULL;
+ 			ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
+-				   pid_nr(pd->port_pid), tid);
++				   pd->port_pid, tid);
+ 			dd->ipath_f_put_tid(dd, &tidbase[tid],
+ 					    RCVHQ_RCV_TYPE_EXPECTED,
+ 					    dd->ipath_tidinvalid);
+@@ -1610,7 +1610,7 @@ static int try_alloc_port(struct ipath_d
+ 			   port);
+ 		pd->port_cnt = 1;
+ 		port_fp(fp) = pd;
+-		pd->port_pid = get_pid(task_pid(current));
++		pd->port_pid = current->pid;
+ 		strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
+ 		ipath_stats.sps_ports++;
+ 		ret = 0;
+@@ -1794,15 +1794,14 @@ static int find_shared_port(struct file 
+ 			}
+ 			port_fp(fp) = pd;
+ 			subport_fp(fp) = pd->port_cnt++;
+-			pd->port_subpid[subport_fp(fp)] =
+-				get_pid(task_pid(current));
++			pd->port_subpid[subport_fp(fp)] = current->pid;
+ 			tidcursor_fp(fp) = 0;
+ 			pd->active_slaves |= 1 << subport_fp(fp);
+ 			ipath_cdbg(PROC,
+ 				   "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
+ 				   current->comm, current->pid,
+ 				   subport_fp(fp),
+-				   pd->port_comm, pid_nr(pd->port_pid),
++				   pd->port_comm, pd->port_pid,
+ 				   dd->ipath_unit, pd->port_port);
+ 			ret = 1;
+ 			goto done;
+@@ -2043,7 +2042,7 @@ static int ipath_close(struct inode *in,
+ 	struct ipath_devdata *dd;
+ 	unsigned long flags;
+ 	unsigned port;
+-	struct pid *pid;
++	pid_t pid;
+ 
+ 	ipath_cdbg(VERBOSE, "close on dev %lx, private data %p\n",
+ 		   (long)in->i_rdev, fp->private_data);
+@@ -2071,8 +2070,7 @@ static int ipath_close(struct inode *in,
+ 		 * the slave(s) don't wait for receive data forever.
+ 		 */
+ 		pd->active_slaves &= ~(1 << fd->subport);
+-		put_pid(pd->port_subpid[fd->subport]);
+-		pd->port_subpid[fd->subport] = NULL;
++		pd->port_subpid[fd->subport] = 0;
+ 		mutex_unlock(&ipath_mutex);
+ 		goto bail;
+ 	}
+@@ -2139,11 +2137,10 @@ static int ipath_close(struct inode *in,
+ 			unlock_expected_tids(pd);
+ 		ipath_stats.sps_ports--;
+ 		ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
+-			   pd->port_comm, pid_nr(pid),
++			   pd->port_comm, pid,
+ 			   dd->ipath_unit, port);
+ 	}
+ 
+-	put_pid(pid);
+ 	mutex_unlock(&ipath_mutex);
+ 	ipath_free_pddata(dd, pd); /* after releasing the mutex */
+ 
+diff -upr ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_kernel.h ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_kernel.h
+--- ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_kernel.h	2008-10-28 12:27:04.000000000 -0700
++++ ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_kernel.h	2008-10-28 12:29:17.000000000 -0700
+@@ -159,8 +159,8 @@ struct ipath_portdata {
+ 	/* saved total number of polled urgent packets for poll edge trigger */
+ 	u32 port_urgent_poll;
+ 	/* pid of process using this port */
+-	struct pid *port_pid;
+-	struct pid *port_subpid[INFINIPATH_MAX_SUBPORT];
++	pid_t port_pid;
++	pid_t port_subpid[INFINIPATH_MAX_SUBPORT];
+ 	/* same size as task_struct .comm[] */
+ 	char port_comm[16];
+ 	/* pkeys set by this use of this port */
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0020_class_dev_to_device.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0020_class_dev_to_device.patch
new file mode 100644
index 0000000..bc9d4a1
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0020_class_dev_to_device.patch
@@ -0,0 +1,207 @@
+BACKPORT - revert struct class_dev to device
+
+This patch reverts commit f4e91eb4a81559da87a3843758a641b5cc590b65 in 2.6.26.
+
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+---
+ drivers/infiniband/hw/ipath/ipath_diag.c     |   10 +++---
+ drivers/infiniband/hw/ipath/ipath_file_ops.c |   44 +++++++++++++--------------
+ drivers/infiniband/hw/ipath/ipath_kernel.h   |    8 ++--
+ 3 files changed, 31 insertions(+), 31 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_diag.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_diag.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_diag.c
+@@ -79,7 +79,7 @@ static const struct file_operations diag
+ 
+ static atomic_t diagpkt_count = ATOMIC_INIT(0);
+ static struct cdev *diagpkt_cdev;
+-static struct device *diagpkt_dev;
++static struct class_device *diagpkt_class_dev;
+ 
+ int ipath_diag_add(struct ipath_devdata *dd)
+ {
+@@ -89,7 +89,7 @@ int ipath_diag_add(struct ipath_devdata 
+ 	if (atomic_inc_return(&diagpkt_count) == 1) {
+ 		ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR,
+ 				      "ipath_diagpkt", &diagpkt_file_ops,
+-				      &diagpkt_cdev, &diagpkt_dev);
++				      &diagpkt_cdev, &diagpkt_class_dev);
+ 
+ 		if (ret) {
+ 			ipath_dev_err(dd, "Couldn't create ipath_diagpkt "
+@@ -102,7 +102,7 @@ int ipath_diag_add(struct ipath_devdata 
+ 
+ 	ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
+ 			      &diag_file_ops, &dd->diag_cdev,
+-			      &dd->diag_dev);
++			      &dd->diag_class_dev);
+ 	if (ret)
+ 		ipath_dev_err(dd, "Couldn't create %s device: %d",
+ 			      name, ret);
+@@ -114,9 +114,9 @@ done:
+ void ipath_diag_remove(struct ipath_devdata *dd)
+ {
+ 	if (atomic_dec_and_test(&diagpkt_count))
+-		ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_dev);
++		ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
+ 
+-	ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_dev);
++	ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev);
+ }
+ 
+ /**
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+@@ -2424,11 +2424,11 @@ static ssize_t ipath_writev(struct kiocb
+ static struct class *ipath_class;
+ 
+ static int init_cdev(int minor, char *name, const struct file_operations *fops,
+-		     struct cdev **cdevp, struct device **devp)
++		     struct cdev **cdevp, struct class_device **class_devp)
+ {
+ 	const dev_t dev = MKDEV(IPATH_MAJOR, minor);
+ 	struct cdev *cdev = NULL;
+-	struct device *device = NULL;
++	struct class_device *class_dev = NULL;
+ 	int ret;
+ 
+ 	cdev = cdev_alloc();
+@@ -2452,12 +2452,12 @@ static int init_cdev(int minor, char *na
+ 		goto err_cdev;
+ 	}
+ 
+-	device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
++	class_dev = class_device_create(ipath_class, NULL, dev, NULL, name);
+ 
+-	if (IS_ERR(device)) {
+-		ret = PTR_ERR(device);
++	if (IS_ERR(class_dev)) {
++		ret = PTR_ERR(class_dev);
+ 		printk(KERN_ERR IPATH_DRV_NAME ": Could not create "
+-		       "device for minor %d, %s (err %d)\n",
++		       "class_dev for minor %d, %s (err %d)\n",
+ 		       minor, name, -ret);
+ 		goto err_cdev;
+ 	}
+@@ -2471,29 +2471,29 @@ err_cdev:
+ done:
+ 	if (ret >= 0) {
+ 		*cdevp = cdev;
+-		*devp = device;
++		*class_devp = class_dev;
+ 	} else {
+ 		*cdevp = NULL;
+-		*devp = NULL;
++		*class_devp = NULL;
+ 	}
+ 
+ 	return ret;
+ }
+ 
+ int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
+-		    struct cdev **cdevp, struct device **devp)
++		    struct cdev **cdevp, struct class_device **class_devp)
+ {
+-	return init_cdev(minor, name, fops, cdevp, devp);
++	return init_cdev(minor, name, fops, cdevp, class_devp);
+ }
+ 
+ static void cleanup_cdev(struct cdev **cdevp,
+-			 struct device **devp)
++			 struct class_device **class_devp)
+ {
+-	struct device *dev = *devp;
++	struct class_device *class_dev = *class_devp;
+ 
+-	if (dev) {
+-		device_unregister(dev);
+-		*devp = NULL;
++	if (class_dev) {
++		class_device_unregister(class_dev);
++		*class_devp = NULL;
+ 	}
+ 
+ 	if (*cdevp) {
+@@ -2503,13 +2503,13 @@ static void cleanup_cdev(struct cdev **c
+ }
+ 
+ void ipath_cdev_cleanup(struct cdev **cdevp,
+-			struct device **devp)
++			struct class_device **class_devp)
+ {
+-	cleanup_cdev(cdevp, devp);
++	cleanup_cdev(cdevp, class_devp);
+ }
+ 
+ static struct cdev *wildcard_cdev;
+-static struct device *wildcard_dev;
++static struct class_device *wildcard_class_dev;
+ 
+ static const dev_t dev = MKDEV(IPATH_MAJOR, 0);
+ 
+@@ -2566,7 +2566,7 @@ int ipath_user_add(struct ipath_devdata 
+ 			goto bail;
+ 		}
+ 		ret = init_cdev(0, "ipath", &ipath_file_ops, &wildcard_cdev,
+-				&wildcard_dev);
++				&wildcard_class_dev);
+ 		if (ret < 0) {
+ 			ipath_dev_err(dd, "Could not create wildcard "
+ 				      "minor: error %d\n", -ret);
+@@ -2579,7 +2579,7 @@ int ipath_user_add(struct ipath_devdata 
+ 	snprintf(name, sizeof(name), "ipath%d", dd->ipath_unit);
+ 
+ 	ret = init_cdev(dd->ipath_unit + 1, name, &ipath_file_ops,
+-			&dd->user_cdev, &dd->user_dev);
++			&dd->user_cdev, &dd->user_class_dev);
+ 	if (ret < 0)
+ 		ipath_dev_err(dd, "Could not create user minor %d, %s\n",
+ 			      dd->ipath_unit + 1, name);
+@@ -2594,13 +2594,13 @@ bail:
+ 
+ void ipath_user_remove(struct ipath_devdata *dd)
+ {
+-	cleanup_cdev(&dd->user_cdev, &dd->user_dev);
++	cleanup_cdev(&dd->user_cdev, &dd->user_class_dev);
+ 
+ 	if (atomic_dec_return(&user_count) == 0) {
+ 		if (atomic_read(&user_setup) == 0)
+ 			goto bail;
+ 
+-		cleanup_cdev(&wildcard_cdev, &wildcard_dev);
++		cleanup_cdev(&wildcard_cdev, &wildcard_class_dev);
+ 		user_cleanup();
+ 
+ 		atomic_set(&user_setup, 0);
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_kernel.h
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
+@@ -477,8 +477,8 @@ struct ipath_devdata {
+ 	struct pci_dev *pcidev;
+ 	struct cdev *user_cdev;
+ 	struct cdev *diag_cdev;
+-	struct device *user_dev;
+-	struct device *diag_dev;
++	struct class_device *user_class_dev;
++	struct class_device *diag_class_dev;
+ 	/* timer used to prevent stats overflow, error throttling, etc. */
+ 	struct timer_list ipath_stats_timer;
+ 	/* timer to verify interrupts work, and fallback if possible */
+@@ -865,9 +865,9 @@ void ipath_clear_freeze(struct ipath_dev
+ 
+ struct file_operations;
+ int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
+-		    struct cdev **cdevp, struct device **devp);
++		    struct cdev **cdevp, struct class_device **class_devp);
+ void ipath_cdev_cleanup(struct cdev **cdevp,
+-			struct device **devp);
++			struct class_device **class_devp);
+ 
+ int ipath_diag_add(struct ipath_devdata *);
+ void ipath_diag_remove(struct ipath_devdata *);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0030_revert_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0030_revert_sysfs.patch
new file mode 100644
index 0000000..f369f4d
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0030_revert_sysfs.patch
@@ -0,0 +1,113 @@
+BACKPORT - revert to older code for creating sysfs driver groups
+
+This reverts commit 23b9c1ab5baf368a32b7242bf110ef1f48700d04 in 2.6.25
+    
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+---
+ drivers/infiniband/hw/ipath/ipath_driver.c |   17 +++++++++++++----
+ drivers/infiniband/hw/ipath/ipath_kernel.h |    3 ++-
+ drivers/infiniband/hw/ipath/ipath_sysfs.c  |   19 ++++++++++++++-----
+ 3 files changed, 29 insertions(+), 10 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_driver.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
+@@ -151,9 +151,6 @@ static struct pci_driver ipath_driver = 
+ 	.probe = ipath_init_one,
+ 	.remove = __devexit_p(ipath_remove_one),
+ 	.id_table = ipath_pci_tbl,
+-	.driver = {
+-		.groups = ipath_driver_attr_groups,
+-	},
+ };
+ 
+ static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev,
+@@ -2544,15 +2541,25 @@ static int __init infinipath_init(void)
+ 		goto bail_unit;
+ 	}
+ 
++	ret = ipath_driver_create_group(&ipath_driver.driver);
++	if (ret < 0) {
++		printk(KERN_ERR IPATH_DRV_NAME ": Unable to create driver "
++		       "sysfs entries: error %d\n", -ret);
++		goto bail_pci;
++	}
++
+ 	ret = ipath_init_ipathfs();
+ 	if (ret < 0) {
+ 		printk(KERN_ERR IPATH_DRV_NAME ": Unable to create "
+ 		       "ipathfs: error %d\n", -ret);
+-		goto bail_pci;
++		goto bail_group;
+ 	}
+ 
+ 	goto bail;
+ 
++bail_group:
++	ipath_driver_remove_group(&ipath_driver.driver);
++
+ bail_pci:
+ 	pci_unregister_driver(&ipath_driver);
+ 
+@@ -2567,6 +2574,8 @@ static void __exit infinipath_cleanup(vo
+ {
+ 	ipath_exit_ipathfs();
+ 
++	ipath_driver_remove_group(&ipath_driver.driver);
++
+ 	ipath_cdbg(VERBOSE, "Unregistering pci driver\n");
+ 	pci_unregister_driver(&ipath_driver);
+ 
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_kernel.h
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
+@@ -1271,7 +1271,8 @@ struct device_driver;
+ 
+ extern const char ib_ipath_version[];
+ 
+-extern struct attribute_group *ipath_driver_attr_groups[];
++int ipath_driver_create_group(struct device_driver *);
++void ipath_driver_remove_group(struct device_driver *);
+ 
+ int ipath_device_create_group(struct device *, struct ipath_devdata *);
+ void ipath_device_remove_group(struct device *, struct ipath_devdata *);
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_sysfs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_sysfs.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_sysfs.c
+@@ -1069,11 +1069,6 @@ static ssize_t show_tempsense(struct dev
+ 	return ret;
+ }
+ 
+-struct attribute_group *ipath_driver_attr_groups[] = {
+-	&driver_attr_group,
+-	NULL,
+-};
+-
+ static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid);
+ static DEVICE_ATTR(lmc, S_IWUSR | S_IRUGO, show_lmc, store_lmc);
+ static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid);
+@@ -1181,6 +1176,20 @@ int ipath_expose_reset(struct device *de
+ 	return ret;
+ }
+ 
++int ipath_driver_create_group(struct device_driver *drv)
++{
++	int ret;
++
++	ret = sysfs_create_group(&drv->kobj, &driver_attr_group);
++
++	return ret;
++}
++
++void ipath_driver_remove_group(struct device_driver *drv)
++{
++	sysfs_remove_group(&drv->kobj, &driver_attr_group);
++}
++
+ int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd)
+ {
+ 	int ret;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0040_nopage_to_fault.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0040_nopage_to_fault.patch
new file mode 100644
index 0000000..a8557d0
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0040_nopage_to_fault.patch
@@ -0,0 +1,81 @@
+IB/ipath - revert struct vm_operations_struct nopage to fault rename
+
+This patch reverts commit 3c8450860ba9d6279dbc969633eacf99161860d9 in 2.6.25
+
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+---
+ drivers/infiniband/hw/ipath/ipath_debug.h    |    4 +--
+ drivers/infiniband/hw/ipath/ipath_file_ops.c |   29 +++++++++++++++++----------
+ 2 files changed, 21 insertions(+), 12 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_debug.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_debug.h
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_debug.h
+@@ -55,7 +55,7 @@
+ #define __IPATH_PKTDBG      0x80	/* print packet data */
+ /* print process startup (init)/exit messages */
+ #define __IPATH_PROCDBG     0x100
+-/* print mmap/fault stuff, not using VDBG any more */
++/* print mmap/nopage stuff, not using VDBG any more */
+ #define __IPATH_MMDBG       0x200
+ #define __IPATH_ERRPKTDBG   0x400
+ #define __IPATH_USER_SEND   0x1000	/* use user mode send */
+@@ -82,7 +82,7 @@
+ #define __IPATH_VERBDBG   0x0	/* very verbose debug */
+ #define __IPATH_PKTDBG    0x0	/* print packet data */
+ #define __IPATH_PROCDBG   0x0	/* process startup (init)/exit messages */
+-/* print mmap/fault stuff, not using VDBG any more */
++/* print mmap/nopage stuff, not using VDBG any more */
+ #define __IPATH_MMDBG     0x0
+ #define __IPATH_EPKTDBG   0x0	/* print ethernet packet data */
+ #define __IPATH_IPATHDBG  0x0	/* Ethernet (IPATH) table dump on */
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+@@ -1130,24 +1130,33 @@ bail:
+ }
+ 
+ /*
+- * ipath_file_vma_fault - handle a VMA page fault.
++ * ipath_file_vma_nopage - handle a VMA page fault.
+  */
+-static int ipath_file_vma_fault(struct vm_area_struct *vma,
+-					struct vm_fault *vmf)
++static struct page *ipath_file_vma_nopage(struct vm_area_struct *vma,
++					  unsigned long address, int *type)
+ {
+-	struct page *page;
++	unsigned long offset = address - vma->vm_start;
++	struct page *page = NOPAGE_SIGBUS;
++	void *pageptr;
+ 
+-	page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT));
++	/*
++	 * Convert the vmalloc address into a struct page.
++	 */
++	pageptr = (void *)(offset + (vma->vm_pgoff << PAGE_SHIFT));
++	page = vmalloc_to_page(pageptr);
+ 	if (!page)
+-		return VM_FAULT_SIGBUS;
+-	get_page(page);
+-	vmf->page = page;
++		goto out;
+ 
+-	return 0;
++	/* Increment the reference count. */
++	get_page(page);
++	if (type)
++		*type = VM_FAULT_MINOR;
++out:
++	return page;
+ }
+ 
+ static struct vm_operations_struct ipath_file_vm_ops = {
+-	.fault = ipath_file_vma_fault,
++	.nopage = ipath_file_vma_nopage,
+ };
+ 
+ static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0050_aio_write.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0050_aio_write.patch
new file mode 100644
index 0000000..3a0b5e3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0050_aio_write.patch
@@ -0,0 +1,44 @@
+BACKPORT - Use writev instead of aio_write in 2.6.18 and older kernels
+
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+---
+ drivers/infiniband/hw/ipath/ipath_file_ops.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+@@ -50,15 +50,15 @@ static int ipath_open(struct inode *, st
+ static int ipath_close(struct inode *, struct file *);
+ static ssize_t ipath_write(struct file *, const char __user *, size_t,
+ 			   loff_t *);
+-static ssize_t ipath_writev(struct kiocb *, const struct iovec *,
+-			    unsigned long , loff_t);
++static ssize_t ipath_writev(struct file *, const struct iovec *,
++			    unsigned long , loff_t *);
+ static unsigned int ipath_poll(struct file *, struct poll_table_struct *);
+ static int ipath_mmap(struct file *, struct vm_area_struct *);
+ 
+ static const struct file_operations ipath_file_ops = {
+ 	.owner = THIS_MODULE,
+ 	.write = ipath_write,
+-	.aio_write = ipath_writev,
++	.writev = ipath_writev,
+ 	.open = ipath_open,
+ 	.release = ipath_close,
+ 	.poll = ipath_poll,
+@@ -2416,10 +2416,9 @@ bail:
+ 	return ret;
+ }
+ 
+-static ssize_t ipath_writev(struct kiocb *iocb, const struct iovec *iov,
+-			    unsigned long dim, loff_t off)
++static ssize_t ipath_writev(struct file *filp, const struct iovec *iov,
++			    unsigned long dim, loff_t *off)
+ {
+-	struct file *filp = iocb->ki_filp;
+ 	struct ipath_filedata *fp = filp->private_data;
+ 	struct ipath_portdata *pd = port_fp(filp);
+ 	struct ipath_user_sdma_queue *pq = fp->pq;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0060_htirq.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0060_htirq.patch
new file mode 100644
index 0000000..e2fa5a3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0060_htirq.patch
@@ -0,0 +1,164 @@
+BACKPORT - use old HT IRQ infrastructure on 2.6.18 and earlier
+
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+---
+ drivers/infiniband/hw/ipath/Makefile        |    2 
+ drivers/infiniband/hw/ipath/ipath_driver.c  |    2 
+ drivers/infiniband/hw/ipath/ipath_iba6110.c |   82 ++++++++++++++++++----------
+ 3 files changed, 57 insertions(+), 29 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ipath/Makefile
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/Makefile
++++ ofed_kernel/drivers/infiniband/hw/ipath/Makefile
+@@ -34,7 +34,7 @@ ib_ipath-y := \
+ 	ipath_sd7220.o \
+ 	ipath_sd7220_img.o
+ 
+-ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
++ib_ipath-y += ipath_iba6110.o
+ ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
+ 
+ ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_driver.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
+@@ -42,6 +42,8 @@
+ #include "ipath_kernel.h"
+ #include "ipath_verbs.h"
+ 
++#define CONFIG_HT_IRQ
++
+ static void ipath_update_pio_bufs(struct ipath_devdata *);
+ 
+ const char *ipath_get_unit_name(int unit)
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_iba6110.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_iba6110.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_iba6110.c
+@@ -39,7 +39,6 @@
+ #include <linux/vmalloc.h>
+ #include <linux/pci.h>
+ #include <linux/delay.h>
+-#include <linux/htirq.h>
+ #include <rdma/ib_verbs.h>
+ 
+ #include "ipath_kernel.h"
+@@ -986,23 +985,50 @@ static int ipath_ht_intconfig(struct ipa
+ 	return ret;
+ }
+ 
+-static void ipath_ht_irq_update(struct pci_dev *dev, int irq,
+-				struct ht_irq_msg *msg)
++static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev,
++			    int pos)
+ {
+-	struct ipath_devdata *dd = pci_get_drvdata(dev);
+-	u64 prev_intconfig = dd->ipath_intconfig;
++	u32 int_handler_addr_lower;
++	u32 int_handler_addr_upper;
++	u64 ihandler;
++	u32 intvec;
++
++	/* use indirection register to get the intr handler */
++	pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10);
++	pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower);
++	pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11);
++	pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper);
++
++	ihandler = (u64) int_handler_addr_lower |
++		((u64) int_handler_addr_upper << 32);
++
++	/*
++	 * kernels with CONFIG_PCI_MSI set the vector in the irq field of
++	 * struct pci_device, so we use that to program the internal
++	 * interrupt register (not config space) with that value. The BIOS
++	 * must still have done the basic MSI setup.
++	 */
++	intvec = pdev->irq;
++	/*
++	 * clear any vector bits there; normally not set but we'll overload
++	 * this for some debug purposes (setting the HTC debug register
++	 * value from software, rather than GPIOs), so it might be set on a
++	 * driver reload.
++	 */
++	ihandler &= ~0xff0000;
++	/* x86 vector goes in intrinfo[23:16] */
++	ihandler |= intvec << 16;
++	ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, "
++		   "interruptconfig %llx\n", int_handler_addr_lower,
++		   int_handler_addr_upper, intvec,
++		   (unsigned long long) ihandler);
++
++	/* can't program yet, so save for interrupt setup */
++	dd->ipath_intconfig = ihandler;
++	dd->ipath_irq = intvec;
++	/* keep going, so we find link control stuff also */
+ 
+-	dd->ipath_intconfig = msg->address_lo;
+-	dd->ipath_intconfig |= ((u64) msg->address_hi) << 32;
+-
+-	/*
+-	 * If the previous value of dd->ipath_intconfig is zero, we're
+-	 * getting configured for the first time, and must not program the
+-	 * intconfig register here (it will be programmed later, when the
+-	 * hardware is ready).  Otherwise, we should.
+-	 */
+-	if (prev_intconfig)
+-		ipath_ht_intconfig(dd);
++	return ihandler != 0;
+ }
+ 
+ /**
+@@ -1018,19 +1044,12 @@ static void ipath_ht_irq_update(struct p
+ static int ipath_setup_ht_config(struct ipath_devdata *dd,
+ 				 struct pci_dev *pdev)
+ {
+-	int pos, ret;
+-
+-	ret = __ht_create_irq(pdev, 0, ipath_ht_irq_update);
+-	if (ret < 0) {
+-		ipath_dev_err(dd, "Couldn't create interrupt handler: "
+-			      "err %d\n", ret);
+-		goto bail;
+-	}
+-	dd->ipath_irq = ret;
+-	ret = 0;
++	int pos, ret = 0;
++	int ihandler = 0;
+ 
+ 	/*
+-	 * Handle clearing CRC errors in linkctrl register if necessary.  We
++	 * Read the capability info to find the interrupt info, and also
++	 * handle clearing CRC errors in linkctrl register if necessary.  We
+ 	 * do this early, before we ever enable errors or hardware errors,
+ 	 * mostly to avoid causing the chip to enter freeze mode.
+ 	 */
+@@ -1055,9 +1074,17 @@ static int ipath_setup_ht_config(struct 
+ 		}
+ 		if (!(cap_type & 0xE0))
+ 			slave_or_pri_blk(dd, pdev, pos, cap_type);
++		else if (cap_type == HT_INTR_DISC_CONFIG)
++			ihandler = set_int_handler(dd, pdev, pos);
+ 	} while ((pos = pci_find_next_capability(pdev, pos,
+ 						 PCI_CAP_ID_HT)));
+ 
++	if (!ihandler) {
++		ipath_dev_err(dd, "Couldn't find interrupt handler in "
++			      "config space\n");
++		ret = -ENODEV;
++	}
++
+ 	dd->ipath_flags |= IPATH_SWAP_PIOBUFS;
+ 
+ bail:
+@@ -1690,7 +1717,6 @@ static int ipath_ht_get_base_info(struct
+ static void ipath_ht_free_irq(struct ipath_devdata *dd)
+ {
+ 	free_irq(dd->ipath_irq, dd);
+-	ht_destroy_irq(dd->ipath_irq);
+ 	dd->ipath_irq = 0;
+ 	dd->ipath_intconfig = 0;
+ }
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0070_vmalloc_user-2.6.18.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0070_vmalloc_user-2.6.18.patch
new file mode 100644
index 0000000..4e0f1f3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0070_vmalloc_user-2.6.18.patch
@@ -0,0 +1,143 @@
+BACKPORT - avoid using vmalloc_user() in 2.6.18 due to bugs.
+
+Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
+
+diff -up a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
+--- a/drivers/infiniband/hw/ipath/ipath_cq.c	2008-10-24 10:40:30.000000000 -0700
++++ b/drivers/infiniband/hw/ipath/ipath_cq.c	2008-10-24 10:45:56.000000000 -0700
+@@ -230,11 +230,12 @@ struct ib_cq *ipath_create_cq(struct ib_
+ 		sz += sizeof(struct ib_uverbs_wc) * (entries + 1);
+ 	else
+ 		sz += sizeof(struct ib_wc) * (entries + 1);
+-	wc = vmalloc_user(sz);
++	wc = vmalloc(sz);
+ 	if (!wc) {
+ 		ret = ERR_PTR(-ENOMEM);
+ 		goto bail_cq;
+ 	}
++	memset(wc, 0, sz);
+ 
+ 	/*
+ 	 * Return the address of the WC as the offset to mmap.
+@@ -389,11 +390,12 @@ int ipath_resize_cq(struct ib_cq *ibcq, 
+ 		sz += sizeof(struct ib_uverbs_wc) * (cqe + 1);
+ 	else
+ 		sz += sizeof(struct ib_wc) * (cqe + 1);
+-	wc = vmalloc_user(sz);
++	wc = vmalloc(sz);
+ 	if (!wc) {
+ 		ret = -ENOMEM;
+ 		goto bail;
+ 	}
++	memset(wc, 0, sz);
+ 
+ 	/* Check that we can write the offset to mmap. */
+ 	if (udata && udata->outlen >= sizeof(__u64)) {
+diff -up a/drivers/infiniband/hw/ipath/ipath_mmap.c b/drivers/infiniband/hw/ipath/ipath_mmap.c
+--- a/drivers/infiniband/hw/ipath/ipath_mmap.c	2008-10-24 10:40:30.000000000 -0700
++++ b/drivers/infiniband/hw/ipath/ipath_mmap.c	2008-10-24 10:45:56.000000000 -0700
+@@ -74,9 +74,40 @@ static void ipath_vma_close(struct vm_ar
+ 	kref_put(&ip->ref, ipath_release_mmap_info);
+ }
+ 
++/*
++ * ipath_vma_nopage - handle a VMA page fault.
++ */
++static struct page *ipath_vma_nopage(struct vm_area_struct *vma,
++				     unsigned long address, int *type)
++{
++	struct ipath_mmap_info *ip = vma->vm_private_data;
++	unsigned long offset = address - vma->vm_start;
++	struct page *page = NOPAGE_SIGBUS;
++	void *pageptr;
++
++	if (offset >= ip->size)
++		goto out; /* out of range */
++
++	/*
++	 * Convert the vmalloc address into a struct page.
++	 */
++	pageptr = (void *)(offset + ip->obj);
++	page = vmalloc_to_page(pageptr);
++	if (!page)
++		goto out;
++
++	/* Increment the reference count. */
++	get_page(page);
++	if (type)
++		*type = VM_FAULT_MINOR;
++out:
++	return page;
++}
++
+ static struct vm_operations_struct ipath_vm_ops = {
+ 	.open =     ipath_vma_open,
+ 	.close =    ipath_vma_close,
++	.nopage =   ipath_vma_nopage,
+ };
+ 
+ /**
+@@ -111,10 +142,10 @@ int ipath_mmap(struct ib_ucontext *conte
+ 		list_del_init(&ip->pending_mmaps);
+ 		spin_unlock_irq(&dev->pending_lock);
+ 
+-		ret = remap_vmalloc_range(vma, ip->obj, 0);
+-		if (ret)
+-			goto done;
++		ret = 0;
++
+ 		vma->vm_ops = &ipath_vm_ops;
++		vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ 		vma->vm_private_data = ip;
+ 		ipath_vma_open(vma);
+ 		goto done;
+diff -up a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
+--- a/drivers/infiniband/hw/ipath/ipath_qp.c	2008-10-24 10:40:33.000000000 -0700
++++ b/drivers/infiniband/hw/ipath/ipath_qp.c	2008-10-24 10:47:56.000000000 -0700
+@@ -827,12 +827,14 @@ struct ib_qp *ipath_create_qp(struct ib_
+ 			qp->r_rq.max_sge = init_attr->cap.max_recv_sge;
+ 			sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +
+ 				sizeof(struct ipath_rwqe);
+-			qp->r_rq.wq = vmalloc_user(sizeof(struct ipath_rwq) +
++			qp->r_rq.wq = vmalloc(sizeof(struct ipath_rwq) +
+ 					      qp->r_rq.size * sz);
+ 			if (!qp->r_rq.wq) {
+ 				ret = ERR_PTR(-ENOMEM);
+ 				goto bail_sg_list;
+ 			}
++			memset(qp->r_rq.wq, 0,
++			       sizeof(struct ipath_rwq) + qp->r_rq.size * sz);
+ 		}
+ 
+ 		/*
+diff -up a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
+--- a/drivers/infiniband/hw/ipath/ipath_srq.c	2008-10-24 10:40:30.000000000 -0700
++++ b/drivers/infiniband/hw/ipath/ipath_srq.c	2008-10-24 10:45:56.000000000 -0700
+@@ -130,11 +130,12 @@ struct ib_srq *ipath_create_srq(struct i
+ 	srq->rq.max_sge = srq_init_attr->attr.max_sge;
+ 	sz = sizeof(struct ib_sge) * srq->rq.max_sge +
+ 		sizeof(struct ipath_rwqe);
+-	srq->rq.wq = vmalloc_user(sizeof(struct ipath_rwq) + srq->rq.size * sz);
++	srq->rq.wq = vmalloc(sizeof(struct ipath_rwq) + srq->rq.size * sz);
+ 	if (!srq->rq.wq) {
+ 		ret = ERR_PTR(-ENOMEM);
+ 		goto bail_srq;
+ 	}
++	memset(srq->rq.wq, 0, sizeof(struct ipath_rwq) + srq->rq.size * sz);
+ 
+ 	/*
+ 	 * Return the address of the RWQ as the offset to mmap.
+@@ -230,11 +231,12 @@ int ipath_modify_srq(struct ib_srq *ibsr
+ 		sz = sizeof(struct ipath_rwqe) +
+ 			srq->rq.max_sge * sizeof(struct ib_sge);
+ 		size = attr->max_wr + 1;
+-		wq = vmalloc_user(sizeof(struct ipath_rwq) + size * sz);
++		wq = vmalloc(sizeof(struct ipath_rwq) + size * sz);
+ 		if (!wq) {
+ 			ret = -ENOMEM;
+ 			goto bail;
+ 		}
++		memset(wq, 0, sizeof(struct ipath_rwq) + size * sz);
+ 
+ 		/* Check that we can write the offset to mmap. */
+ 		if (udata && udata->inlen >= sizeof(__u64)) {
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0080_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0080_sysfs.patch
new file mode 100644
index 0000000..2703595
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0080_sysfs.patch
@@ -0,0 +1,85 @@
+---
+ drivers/infiniband/hw/ipath/ipath_verbs.c |   39 +++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 21 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_verbs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_verbs.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_verbs.c
+@@ -2235,20 +2235,18 @@ void ipath_unregister_ib_device(struct i
+ 	ib_dealloc_device(ibdev);
+ }
+ 
+-static ssize_t show_rev(struct device *device, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_rev(struct class_device *cdev, char *buf)
+ {
+ 	struct ipath_ibdev *dev =
+-		container_of(device, struct ipath_ibdev, ibdev.dev);
++		container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
+ 
+ 	return sprintf(buf, "%x\n", dev->dd->ipath_pcirev);
+ }
+ 
+-static ssize_t show_hca(struct device *device, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_hca(struct class_device *cdev, char *buf)
+ {
+ 	struct ipath_ibdev *dev =
+-		container_of(device, struct ipath_ibdev, ibdev.dev);
++		container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
+ 	int ret;
+ 
+ 	ret = dev->dd->ipath_f_get_boardname(dev->dd, buf, 128);
+@@ -2261,11 +2259,10 @@ bail:
+ 	return ret;
+ }
+ 
+-static ssize_t show_stats(struct device *device, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_stats(struct class_device *cdev, char *buf)
+ {
+ 	struct ipath_ibdev *dev =
+-		container_of(device, struct ipath_ibdev, ibdev.dev);
++		container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
+ 	int i;
+ 	int len;
+ 
+@@ -2300,16 +2297,16 @@ static ssize_t show_stats(struct device 
+ 	return len;
+ }
+ 
+-static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
+-static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
+-static DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL);
+-static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
+-
+-static struct device_attribute *ipath_class_attributes[] = {
+-	&dev_attr_hw_rev,
+-	&dev_attr_hca_type,
+-	&dev_attr_board_id,
+-	&dev_attr_stats
++static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
++static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
++static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL);
++static CLASS_DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
++
++static struct class_device_attribute *ipath_class_attributes[] = {
++	&class_device_attr_hw_rev,
++	&class_device_attr_hca_type,
++	&class_device_attr_board_id,
++	&class_device_attr_stats
+ };
+ 
+ static int ipath_verbs_register_sysfs(struct ib_device *dev)
+@@ -2318,8 +2315,8 @@ static int ipath_verbs_register_sysfs(st
+ 	int ret;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i)
+-		if (device_create_file(&dev->dev,
+-				       ipath_class_attributes[i])) {
++		if (class_device_create_file(&dev->class_dev,
++					       ipath_class_attributes[i])) {
+ 			ret = 1;
+ 			goto bail;
+ 		}
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0095_pat.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0095_pat.patch
new file mode 100644
index 0000000..ceb9a9f
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipath_0095_pat.patch
@@ -0,0 +1,77 @@
+--- a/drivers/infiniband/hw/ipath/ipath_wc_pat.c.orig	2008-11-04 13:46:56.557658000 -0800
++++ b/drivers/infiniband/hw/ipath/ipath_wc_pat.c	2008-11-04 13:47:50.521639000 -0800
+@@ -182,7 +182,7 @@
+ 	preempt_disable();
+ 	rd_old_pat(&ret);
+ 	if (!ret)
+-		smp_call_function(rd_old_pat, &ret, 1);
++		smp_call_function(rd_old_pat, &ret, 1, 1);
+ 	if (ret)
+ 		goto out;
+ 
+@@ -193,7 +193,7 @@
+ 	if (ret)
+ 		goto out;
+ 
+-	smp_call_function(wr_new_pat, &ret, 1);
++	smp_call_function(wr_new_pat, &ret, 1, 1);
+ 	BUG_ON(ret); /* have inconsistent PAT state */
+ out:
+ 	preempt_enable();
+@@ -207,7 +207,7 @@
+ 	preempt_disable();
+ 	wr_old_pat(&ret);
+ 	if (!ret) {
+-		smp_call_function(wr_old_pat, &ret, 1);
++		smp_call_function(wr_old_pat, &ret, 1, 1);
+ 		BUG_ON(ret); /* have inconsistent PAT state */
+ 	}
+ 
+diff --git a/drivers/infiniband/hw/ipath/ipath_wc_pat.c b/drivers/infiniband/hw/ipath/ipath_wc_pat.c
+index 8edf2fb..5233eac 100644
+--- a/drivers/infiniband/hw/ipath/ipath_wc_pat.c
++++ b/drivers/infiniband/hw/ipath/ipath_wc_pat.c
+@@ -217,7 +217,7 @@
+ 
+ int ipath_enable_wc_pat(void)
+ {
+-	struct cpuinfo_x86 *c = &cpu_data(0);
++	struct cpuinfo_x86 *c = &(cpu_data)[0];
+ 	int ret;
+ 
+ 	if (wc_enabled)
+@@ -257,6 +257,11 @@ pgprot_t pgprot_wc(pgprot_t _prot)
+ 		pgprot_noncached(_prot);
+ }
+ 
++void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size)
++{
++	return __ioremap(phys_addr, size, IPATH_WC_FLAGS);
++}
++
+ int ipath_wc_pat_enabled(void)
+ {
+ 	return wc_enabled;
+@@ -272,6 +277,11 @@ pgprot_t pgprot_wc(pgprot_t _prot)
+ 	return pgprot_noncached(_prot);
+ }
+ 
++void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size)
++{
++	return ioremap_nocache(phys_addr, size);
++}
++
+ int ipath_wc_pat_enabled(void)
+ {
+ 	return 0;
+diff --git a/drivers/infiniband/hw/ipath/ipath_wc_pat.h b/drivers/infiniband/hw/ipath/ipath_wc_pat.h
+index 28ba52f..1b17661 100644
+--- a/drivers/infiniband/hw/ipath/ipath_wc_pat.h
++++ b/drivers/infiniband/hw/ipath/ipath_wc_pat.h
+@@ -42,5 +42,6 @@ int ipath_enable_wc_pat(void);
+ void ipath_disable_wc_pat(void);
+ int ipath_wc_pat_enabled(void);
+ pgprot_t pgprot_wc(pgprot_t _prot);
++void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size);
+ 
+ #endif
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0100_to_2.6.21.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0100_to_2.6.21.patch
new file mode 100644
index 0000000..ee2706f
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0100_to_2.6.21.patch
@@ -0,0 +1,458 @@
+Backport IPOIB to kernel 2.6.23
+
+Signed-off-by: Eli Cohen <eli at mellanox.co.il>
+
+---
+
+---
+ drivers/infiniband/ulp/ipoib/ipoib.h           |    6 +-
+ drivers/infiniband/ulp/ipoib/ipoib_cm.c        |   20 ++++-----
+ drivers/infiniband/ulp/ipoib/ipoib_ib.c        |   55 +++++++++++++------------
+ drivers/infiniband/ulp/ipoib/ipoib_main.c      |   34 +++++----------
+ drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   10 ++--
+ 5 files changed, 61 insertions(+), 64 deletions(-)
+
+Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib.h
+===================================================================
+--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2009-04-16 23:35:04.000000000 +0300
++++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib.h	2009-04-16 23:46:20.000000000 +0300
+@@ -277,8 +277,6 @@ struct ipoib_dev_priv {
+ 
+ 	struct net_device *dev;
+ 
+-	struct napi_struct napi;
+-
+ 	unsigned long flags;
+ 
+ 	struct mutex vlan_mutex;
+@@ -336,6 +334,8 @@ struct ipoib_dev_priv {
+ 
+ 	struct ib_event_handler event_handler;
+ 
++	struct net_device_stats stats;
++
+ 	struct net_device *parent;
+ 	struct list_head child_intfs;
+ 	struct list_head list;
+@@ -423,7 +423,7 @@ extern struct workqueue_struct *ipoib_wo
+ 
+ /* functions */
+ 
+-int ipoib_poll(struct napi_struct *napi, int budget);
++int ipoib_poll(struct net_device *dev, int *budget);
+ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
+ void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr);
+ 
+Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+===================================================================
+--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2009-04-16 23:35:04.000000000 +0300
++++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2009-04-16 23:46:20.000000000 +0300
+@@ -593,7 +593,7 @@ void ipoib_cm_handle_rx_wc(struct net_de
+ 		ipoib_dbg(priv, "cm recv error "
+ 			   "(status=%d, wrid=%d vend_err %x)\n",
+ 			   wc->status, wr_id, wc->vendor_err);
+-		++dev->stats.rx_dropped;
++		++priv->stats.rx_dropped;
+ 		if (has_srq)
+ 			goto repost;
+ 		else {
+@@ -646,7 +646,7 @@ void ipoib_cm_handle_rx_wc(struct net_de
+ 		 * this packet and reuse the old buffer.
+ 		 */
+ 		ipoib_dbg(priv, "failed to allocate receive buffer %d\n", wr_id);
+-		++dev->stats.rx_dropped;
++		++priv->stats.rx_dropped;
+ 		goto repost;
+ 	}
+ 
+@@ -664,8 +664,8 @@ copied:
+ 	skb_pull(skb, IPOIB_ENCAP_LEN);
+ 
+ 	dev->last_rx = jiffies;
+-	++dev->stats.rx_packets;
+-	dev->stats.rx_bytes += skb->len;
++	++priv->stats.rx_packets;
++	priv->stats.rx_bytes += skb->len;
+ 
+ 	skb->dev = dev;
+ 	/* XXX get correct PACKET_ type here */
+@@ -714,8 +714,8 @@ void ipoib_cm_send(struct net_device *de
+ 	if (unlikely(skb->len > tx->mtu)) {
+ 		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
+ 			   skb->len, tx->mtu);
+-		++dev->stats.tx_dropped;
+-		++dev->stats.tx_errors;
++		++priv->stats.tx_dropped;
++		++priv->stats.tx_errors;
+ 		ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN);
+ 		return;
+ 	}
+@@ -734,7 +734,7 @@ void ipoib_cm_send(struct net_device *de
+ 	tx_req->skb = skb;
+ 	addr = ib_dma_map_single(priv->ca, skb->data, skb->len, DMA_TO_DEVICE);
+ 	if (unlikely(ib_dma_mapping_error(priv->ca, addr))) {
+-		++dev->stats.tx_errors;
++		++priv->stats.tx_errors;
+ 		dev_kfree_skb_any(skb);
+ 		return;
+ 	}
+@@ -744,7 +744,7 @@ void ipoib_cm_send(struct net_device *de
+ 	if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
+ 			       addr, skb->len))) {
+ 		ipoib_warn(priv, "post_send failed\n");
+-		++dev->stats.tx_errors;
++		++priv->stats.tx_errors;
+ 		ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE);
+ 		dev_kfree_skb_any(skb);
+ 	} else {
+@@ -781,8 +781,8 @@ void ipoib_cm_handle_tx_wc(struct net_de
+ 	ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE);
+ 
+ 	/* FIXME: is this right? Shouldn't we only increment on success? */
+-	++dev->stats.tx_packets;
+-	dev->stats.tx_bytes += tx_req->skb->len;
++	++priv->stats.tx_packets;
++	priv->stats.tx_bytes += tx_req->skb->len;
+ 
+ 	dev_kfree_skb_any(tx_req->skb);
+ 
+Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+===================================================================
+--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-04-16 23:43:16.000000000 +0300
++++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-04-16 23:49:04.000000000 +0300
+@@ -261,7 +261,7 @@ static void ipoib_ib_handle_rx_wc(struct
+ 	 * this packet and reuse the old buffer.
+ 	 */
+ 	if (unlikely(!ipoib_alloc_rx_skb(dev, wr_id))) {
+-		++dev->stats.rx_dropped;
++		++priv->stats.rx_dropped;
+ 		goto repost;
+ 	}
+ 
+@@ -278,8 +278,8 @@ static void ipoib_ib_handle_rx_wc(struct
+ 	skb_pull(skb, IPOIB_ENCAP_LEN);
+ 
+ 	dev->last_rx = jiffies;
+-	++dev->stats.rx_packets;
+-	dev->stats.rx_bytes += skb->len;
++	++priv->stats.rx_packets;
++	priv->stats.rx_bytes += skb->len;
+ 
+ 	skb->dev = dev;
+ 	/* XXX get correct PACKET_ type here */
+@@ -379,8 +379,8 @@ static void ipoib_ib_handle_tx_wc(struct
+ 
+ 	ipoib_dma_unmap_tx(priv->ca, tx_req);
+ 
+-	++dev->stats.tx_packets;
+-	dev->stats.tx_bytes += tx_req->skb->len;
++	++priv->stats.tx_packets;
++	priv->stats.tx_bytes += tx_req->skb->len;
+ 
+ 	dev_kfree_skb_any(tx_req->skb);
+ 
+@@ -408,19 +408,19 @@ static int poll_tx(struct ipoib_dev_priv
+ 	return n == MAX_SEND_CQE;
+ }
+ 
+-int ipoib_poll(struct napi_struct *napi, int budget)
++int ipoib_poll(struct net_device *dev, int *budget)
+ {
+-	struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi);
+-	struct net_device *dev = priv->dev;
++	struct ipoib_dev_priv *priv = netdev_priv(dev);
++	int max = min(*budget, dev->quota);
+ 	int done;
+ 	int t;
+ 	int n, i;
++	int ret;
+ 
+ 	done  = 0;
+ 
+ poll_more:
+-	while (done < budget) {
+-		int max = (budget - done);
++	while (max) {
+ 
+ 		t = min(IPOIB_NUM_WC, max);
+ 		n = ib_poll_cq(priv->recv_cq, t, priv->ibwc);
+@@ -430,6 +430,7 @@ poll_more:
+ 
+ 			if (wc->wr_id & IPOIB_OP_RECV) {
+ 				++done;
++				--max;
+ 				if (wc->wr_id & IPOIB_OP_CM)
+ 					ipoib_cm_handle_rx_wc(dev, wc);
+ 				else
+@@ -442,27 +443,29 @@ poll_more:
+ 			break;
+ 	}
+ 
+-	if (done < budget) {
++	if (max) {
+ 		if (dev->features & NETIF_F_LRO)
+ 			lro_flush_all(&priv->lro.lro_mgr);
+ 
+-		netif_rx_complete(dev, napi);
++		netif_rx_complete(dev);
+ 		if (unlikely(ib_req_notify_cq(priv->recv_cq,
+ 					      IB_CQ_NEXT_COMP |
+ 					      IB_CQ_REPORT_MISSED_EVENTS)) &&
+-		    netif_rx_reschedule(dev, napi))
++					      netif_rx_reschedule(dev, 0))
+ 			goto poll_more;
+-	}
++		ret = 0;
++	} else
++		ret = 1;
++
++	dev->quota -= done;
++	*budget    -= done;
+ 
+-	return done;
++	return ret;
+ }
+ 
+ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
+ {
+-	struct net_device *dev = dev_ptr;
+-	struct ipoib_dev_priv *priv = netdev_priv(dev);
+-
+-	netif_rx_schedule(dev, &priv->napi);
++	netif_rx_schedule(dev_ptr);
+ }
+ 
+ static void drain_tx_cq(struct net_device *dev)
+@@ -539,8 +542,8 @@ void ipoib_send(struct net_device *dev, 
+ 		phead = skb->data;
+ 		if (unlikely(!skb_pull(skb, hlen))) {
+ 			ipoib_warn(priv, "linear data too small\n");
+-			++dev->stats.tx_dropped;
+-			++dev->stats.tx_errors;
++			++priv->stats.tx_dropped;
++			++priv->stats.tx_errors;
+ 			dev_kfree_skb_any(skb);
+ 			return;
+ 		}
+@@ -548,8 +551,8 @@ void ipoib_send(struct net_device *dev, 
+ 		if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {
+ 			ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
+ 				   skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);
+-			++dev->stats.tx_dropped;
+-			++dev->stats.tx_errors;
++			++priv->stats.tx_dropped;
++			++priv->stats.tx_errors;
+ 			ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);
+ 			return;
+ 		}
+@@ -570,7 +573,7 @@ void ipoib_send(struct net_device *dev, 
+ 	tx_req = &priv->tx_ring[priv->tx_head & (ipoib_sendq_size - 1)];
+ 	tx_req->skb = skb;
+ 	if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req))) {
+-		++dev->stats.tx_errors;
++		++priv->stats.tx_errors;
+ 		dev_kfree_skb_any(skb);
+ 		return;
+ 	}
+@@ -590,7 +593,7 @@ void ipoib_send(struct net_device *dev, 
+ 	if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
+ 			       address->ah, qpn, tx_req, phead, hlen))) {
+ 		ipoib_warn(priv, "post_send failed\n");
+-		++dev->stats.tx_errors;
++		++priv->stats.tx_errors;
+ 		--priv->tx_outstanding;
+ 		ipoib_dma_unmap_tx(priv->ca, tx_req);
+ 		dev_kfree_skb_any(skb);
+@@ -708,8 +711,7 @@ int ipoib_ib_dev_open(struct net_device 
+ 	priv->poll_timer.function = ipoib_ib_tx_timer_func;
+ 	priv->poll_timer.data = (unsigned long)dev;
+ 
+-	if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+-		napi_enable(&priv->napi);
++	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+ 
+ 	return 0;
+ }
+@@ -828,8 +830,8 @@ int ipoib_ib_dev_stop(struct net_device 
+ 	struct ipoib_tx_buf *tx_req;
+ 	int i;
+ 
+-	if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+-		napi_disable(&priv->napi);
++	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
++	netif_poll_disable(dev);
+ 
+ 	ipoib_cm_dev_stop(dev);
+ 
+@@ -903,6 +905,7 @@ timeout:
+ 
+ 	ipoib_ah_dev_cleanup(dev);
+ 
++	netif_poll_enable(dev);
+ 	ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP);
+ 
+ 	return 0;
+Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_main.c
+===================================================================
+--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-04-16 23:44:02.000000000 +0300
++++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-04-16 23:46:20.000000000 +0300
+@@ -585,7 +585,7 @@ static void neigh_add_path(struct sk_buf
+ 
+ 	neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
+ 	if (!neigh) {
+-		++dev->stats.tx_dropped;
++		++priv->stats.tx_dropped;
+ 		dev_kfree_skb_any(skb);
+ 		return;
+ 	}
+@@ -646,7 +646,7 @@ err_list:
+ err_path:
+ 	ipoib_neigh_free(dev, neigh);
+ err_drop:
+-	++dev->stats.tx_dropped;
++	++priv->stats.tx_dropped;
+ 	dev_kfree_skb_any(skb);
+ 
+ 	spin_unlock_irqrestore(&priv->lock, flags);
+@@ -697,7 +697,7 @@ static void unicast_arp_send(struct sk_b
+ 			} else
+ 				__path_add(dev, path);
+ 		} else {
+-			++dev->stats.tx_dropped;
++			++priv->stats.tx_dropped;
+ 			dev_kfree_skb_any(skb);
+ 		}
+ 
+@@ -716,7 +716,7 @@ static void unicast_arp_send(struct sk_b
+ 		skb_push(skb, sizeof *phdr);
+ 		__skb_queue_tail(&path->queue, skb);
+ 	} else {
+-		++dev->stats.tx_dropped;
++		++priv->stats.tx_dropped;
+ 		dev_kfree_skb_any(skb);
+ 	}
+ 
+@@ -773,7 +773,7 @@ static int ipoib_start_xmit(struct sk_bu
+ 			__skb_queue_tail(&neigh->queue, skb);
+ 			spin_unlock_irqrestore(&priv->lock, flags);
+ 		} else {
+-			++dev->stats.tx_dropped;
++			++priv->stats.tx_dropped;
+ 			dev_kfree_skb_any(skb);
+ 		}
+ 	} else {
+@@ -799,7 +799,7 @@ static int ipoib_start_xmit(struct sk_bu
+ 					   IPOIB_QPN(phdr->hwaddr),
+ 					   IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
+ 				dev_kfree_skb_any(skb);
+-				++dev->stats.tx_dropped;
++				++priv->stats.tx_dropped;
+ 				return NETDEV_TX_OK;
+ 			}
+ 
+@@ -825,7 +825,7 @@ static void ipoib_timeout(struct net_dev
+ static int ipoib_hard_header(struct sk_buff *skb,
+ 			     struct net_device *dev,
+ 			     unsigned short type,
+-			     const void *daddr, const void *saddr, unsigned len)
++			     void *daddr, void *saddr, unsigned len)
+ {
+ 	struct ipoib_header *header;
+ 
+@@ -914,9 +914,10 @@ struct ipoib_neigh *ipoib_neigh_alloc(st
+ void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
+ {
+ 	struct sk_buff *skb;
++	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	*to_ipoib_neigh(neigh->neighbour) = NULL;
+ 	while ((skb = __skb_dequeue(&neigh->queue))) {
+-		++dev->stats.tx_dropped;
++		++priv->stats.tx_dropped;
+ 		dev_kfree_skb_any(skb);
+ 	}
+ 	if (ipoib_cm_get(neigh))
+@@ -991,10 +992,6 @@ void ipoib_dev_cleanup(struct net_device
+ 	priv->tx_ring = NULL;
+ }
+ 
+-static const struct header_ops ipoib_header_ops = {
+-	.create	= ipoib_hard_header,
+-};
+-
+ static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
+ 		       void **tcph, u64 *hdr_flags, void *priv)
+ {
+@@ -1052,13 +1049,13 @@ static void ipoib_setup(struct net_devic
+ 	dev->change_mtu		 = ipoib_change_mtu;
+ 	dev->hard_start_xmit	 = ipoib_start_xmit;
+ 	dev->tx_timeout		 = ipoib_timeout;
+-	dev->header_ops		 = &ipoib_header_ops;
++	dev->hard_header         = ipoib_hard_header;
+ 	dev->set_multicast_list	 = ipoib_set_mcast_list;
+ 	dev->neigh_setup	 = ipoib_neigh_setup_dev;
+-
+ 	ipoib_set_ethtool_ops(dev);
++	dev->poll                = ipoib_poll;
++	dev->weight              = 100;
+ 
+-	netif_napi_add(dev, &priv->napi, ipoib_poll, 100);
+ 
+ 	dev->watchdog_timeo	 = HZ;
+ 
+Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+===================================================================
+--- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2009-04-16 23:35:04.000000000 +0300
++++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2009-04-16 23:46:20.000000000 +0300
+@@ -100,7 +100,7 @@ static void ipoib_mcast_free(struct ipoi
+ 	}
+ 
+ 	netif_tx_lock_bh(dev);
+-	dev->stats.tx_dropped += tx_dropped;
++	priv->stats.tx_dropped += tx_dropped;
+ 	netif_tx_unlock_bh(dev);
+ 
+ 	kfree(mcast);
+@@ -285,6 +285,7 @@ ipoib_mcast_sendonly_join_complete(int s
+ {
+ 	struct ipoib_mcast *mcast = multicast->context;
+ 	struct net_device *dev = mcast->dev;
++	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 
+ 	/* We trap for port events ourselves. */
+ 	if (status == -ENETRESET)
+@@ -302,7 +303,7 @@ ipoib_mcast_sendonly_join_complete(int s
+ 		/* Flush out any queued packets */
+ 		netif_tx_lock_bh(dev);
+ 		while (!skb_queue_empty(&mcast->pkt_queue)) {
+-			++dev->stats.tx_dropped;
++			++priv->stats.tx_dropped;
+ 			dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
+ 		}
+ 		netif_tx_unlock_bh(dev);
+@@ -677,7 +678,7 @@ void ipoib_mcast_send(struct net_device 
+ 	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)		||
+ 	    !priv->broadcast					||
+ 	    !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
+-		++dev->stats.tx_dropped;
++		++priv->stats.tx_dropped;
+ 		dev_kfree_skb_any(skb);
+ 		goto unlock;
+ 	}
+@@ -692,7 +693,7 @@ void ipoib_mcast_send(struct net_device 
+ 		if (!mcast) {
+ 			ipoib_warn(priv, "unable to allocate memory for "
+ 				   "multicast structure\n");
+-			++dev->stats.tx_dropped;
++			++priv->stats.tx_dropped;
+ 			dev_kfree_skb_any(skb);
+ 			goto out;
+ 		}
+@@ -707,7 +708,7 @@ void ipoib_mcast_send(struct net_device 
+ 		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
+ 			skb_queue_tail(&mcast->pkt_queue, skb);
+ 		else {
+-			++dev->stats.tx_dropped;
++			++priv->stats.tx_dropped;
+ 			dev_kfree_skb_any(skb);
+ 		}
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0110_restore_get_stats.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0110_restore_get_stats.patch
new file mode 100644
index 0000000..1b9bae4
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0110_restore_get_stats.patch
@@ -0,0 +1,30 @@
+---
+ drivers/infiniband/ulp/ipoib/ipoib_main.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -813,6 +813,13 @@ out:
+ 	return NETDEV_TX_OK;
+ }
+ 
++static struct net_device_stats *ipoib_get_stats(struct net_device *dev)
++{
++	struct ipoib_dev_priv *priv = netdev_priv(dev);
++
++	return &priv->stats;
++}
++
+ static void ipoib_timeout(struct net_device *dev)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+@@ -1051,6 +1058,7 @@ static void ipoib_setup(struct net_devic
+ 	dev->stop		 = ipoib_stop;
+ 	dev->change_mtu		 = ipoib_change_mtu;
+ 	dev->hard_start_xmit	 = ipoib_start_xmit;
++	dev->get_stats 		 = ipoib_get_stats;
+ 	dev->tx_timeout		 = ipoib_timeout;
+ 	dev->hard_header         = ipoib_hard_header;
+ 	dev->set_multicast_list	 = ipoib_set_mcast_list;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0500_warnings_ipoib_fs_to_2_6_19.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0500_warnings_ipoib_fs_to_2_6_19.patch
new file mode 100644
index 0000000..7f45167
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0500_warnings_ipoib_fs_to_2_6_19.patch
@@ -0,0 +1,26 @@
+---
+ drivers/infiniband/ulp/ipoib/ipoib_fs.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: ofa_kernel-1.4/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+===================================================================
+--- ofa_kernel-1.4.orig/drivers/infiniband/ulp/ipoib/ipoib_fs.c
++++ ofa_kernel-1.4/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+@@ -134,7 +134,7 @@ static int ipoib_mcg_open(struct inode *
+ 	struct seq_file *seq;
+ 	int ret;
+ 
+-	ret = seq_open(file, &ipoib_mcg_seq_ops);
++	ret = seq_open(file, (struct seq_operations *) &ipoib_mcg_seq_ops);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -240,7 +240,7 @@ static int ipoib_path_open(struct inode 
+ 	struct seq_file *seq;
+ 	int ret;
+ 
+-	ret = seq_open(file, &ipoib_path_seq_ops);
++	ret = seq_open(file, (struct seq_operations *) &ipoib_path_seq_ops);
+ 	if (ret)
+ 		return ret;
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0900_netif_lock_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0900_netif_lock_to_2_6_26.patch
new file mode 100644
index 0000000..c2fdd18
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_0900_netif_lock_to_2_6_26.patch
@@ -0,0 +1,26 @@
+---
+ drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -777,7 +777,7 @@ void ipoib_mcast_restart_task(struct wor
+ 	ipoib_mcast_stop_thread(dev, 0);
+ 
+ 	local_irq_save(flags);
+-	netif_addr_lock(dev);
++	netif_tx_lock(dev);
+ 	spin_lock(&priv->lock);
+ 
+ 	/*
+@@ -854,7 +854,7 @@ void ipoib_mcast_restart_task(struct wor
+ 	}
+ 
+ 	spin_unlock(&priv->lock);
+-	netif_addr_unlock(dev);
++	netif_tx_unlock(dev);
+ 	local_irq_restore(flags);
+ 
+ 	/* We have to cancel outside of the spinlock */
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20.patch
new file mode 100644
index 0000000..f7cb26d
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20.patch
@@ -0,0 +1,186 @@
+Revert the following patch:
+
+commit 43cb76d91ee85f579a69d42bc8efc08bac560278
+Author: Greg Kroah-Hartman <gregkh at suse.de>
+Date:   Tue Apr 9 12:14:34 2002 -0700
+
+    Network: convert network devices to use struct device instead of class_device
+
+    This lets the network core have the ability to handle suspend/resume
+    issues, if it wants to.
+
+    Thanks to Frederik Deweerdt <frederik.deweerdt at gmail.com> for the arm
+    driver fixes.
+
+    Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+---
+ drivers/infiniband/ulp/ipoib/ipoib_cm.c   |   13 ++++++-------
+ drivers/infiniband/ulp/ipoib/ipoib_main.c |   26 ++++++++++++++------------
+ drivers/infiniband/ulp/ipoib/ipoib_vlan.c |   10 ++++++----
+ 3 files changed, 26 insertions(+), 23 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+@@ -47,6 +47,8 @@ MODULE_PARM_DESC(max_nonsrq_conn_qp,
+ 		 "Max number of connected-mode QPs per interface "
+ 		 "(applied only if shared receive queue is not available)");
+ 
++#define to_net_dev(class) container_of(class, struct net_device, class_dev)
++
+ #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA
+ static int data_debug_level;
+ 
+@@ -1433,9 +1435,7 @@ static void ipoib_cm_stale_task(struct w
+ 	spin_unlock_irq(&priv->lock);
+ }
+ 
+-
+-static ssize_t show_mode(struct device *d, struct device_attribute *attr,
+-			 char *buf)
++static ssize_t show_mode(struct class_device *d, char *buf)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(d));
+ 
+@@ -1445,8 +1445,7 @@ static ssize_t show_mode(struct device *
+ 		return sprintf(buf, "datagram\n");
+ }
+ 
+-static ssize_t set_mode(struct device *d, struct device_attribute *attr,
+-			const char *buf, size_t count)
++static ssize_t set_mode(struct class_device *d, const char *buf, size_t count)
+ {
+ 	struct net_device *dev = to_net_dev(d);
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+@@ -1490,11 +1489,11 @@ static ssize_t set_mode(struct device *d
+ 	return -EINVAL;
+ }
+ 
+-static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
++static CLASS_DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
+ 
+ int ipoib_cm_add_mode_attr(struct net_device *dev)
+ {
+-	return device_create_file(&dev->dev, &dev_attr_mode);
++	return class_device_create_file(&dev->class_dev, &class_device_attr_mode);
+ }
+ 
+ static void ipoib_cm_create_srq(struct net_device *dev, int max_sge)
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -100,6 +100,8 @@ static struct ib_client ipoib_client = {
+ 	.remove = ipoib_remove_one
+ };
+ 
++#define to_net_dev(class) container_of(class, struct net_device, class_dev)
++
+ int ipoib_open(struct net_device *dev)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+@@ -1123,14 +1125,13 @@ struct ipoib_dev_priv *ipoib_intf_alloc(
+ 	return netdev_priv(dev);
+ }
+ 
+-static ssize_t show_pkey(struct device *dev,
+-			 struct device_attribute *attr, char *buf)
++static ssize_t show_pkey(struct class_device *dev, char *buf)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+ 
+ 	return sprintf(buf, "0x%04x\n", priv->pkey);
+ }
+-static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
++static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
+ 
+ static ssize_t show_umcast(struct device *dev,
+ 			   struct device_attribute *attr, char *buf)
+@@ -1163,8 +1164,7 @@ int ipoib_add_umcast_attr(struct net_dev
+ 	return device_create_file(&dev->dev, &dev_attr_umcast);
+ }
+ 
+-static ssize_t create_child(struct device *dev,
+-			    struct device_attribute *attr,
++static ssize_t create_child(struct class_device *dev,
+ 			    const char *buf, size_t count)
+ {
+ 	int pkey;
+@@ -1186,10 +1186,9 @@ static ssize_t create_child(struct devic
+ 
+ 	return ret ? ret : count;
+ }
+-static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
++static CLASS_DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
+ 
+-static ssize_t delete_child(struct device *dev,
+-			    struct device_attribute *attr,
++static ssize_t delete_child(struct class_device *dev,
+ 			    const char *buf, size_t count)
+ {
+ 	int pkey;
+@@ -1206,11 +1205,12 @@ static ssize_t delete_child(struct devic
+ 	return ret ? ret : count;
+ 
+ }
+-static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
++static CLASS_DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
+ 
+ int ipoib_add_pkey_attr(struct net_device *dev)
+ {
+-	return device_create_file(&dev->dev, &dev_attr_pkey);
++	return class_device_create_file(&dev->class_dev,
++					&class_device_attr_pkey);
+ }
+ 
+ static struct net_device *ipoib_add_port(const char *format,
+@@ -1324,9 +1324,11 @@ static struct net_device *ipoib_add_port
+ 		goto sysfs_failed;
+ 	if (ipoib_add_umcast_attr(priv->dev))
+ 		goto sysfs_failed;
+-	if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
++	if (class_device_create_file(&priv->dev->class_dev,
++				     &class_device_attr_create_child))
+ 		goto sysfs_failed;
+-	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
++	if (class_device_create_file(&priv->dev->class_dev,
++				     &class_device_attr_delete_child))
+ 		goto sysfs_failed;
+ 
+ 	return priv->dev;
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+@@ -40,15 +40,16 @@
+ 
+ #include "ipoib.h"
+ 
+-static ssize_t show_parent(struct device *d, struct device_attribute *attr,
+-			   char *buf)
++#define to_net_dev(class) container_of(class, struct net_device, class_dev)
++
++static ssize_t show_parent(struct class_device *d, char *buf)
+ {
+ 	struct net_device *dev = to_net_dev(d);
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 
+ 	return sprintf(buf, "%s\n", priv->parent->name);
+ }
+-static DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
++static CLASS_DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
+ 
+ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
+ {
+@@ -124,7 +125,8 @@ int ipoib_vlan_add(struct net_device *pd
+ 	if (ipoib_add_umcast_attr(priv->dev))
+ 		goto sysfs_failed;
+ 
+-	if (device_create_file(&priv->dev->dev, &dev_attr_parent))
++	if (class_device_create_file(&priv->dev->class_dev,
++				     &class_device_attr_parent))
+ 		goto sysfs_failed;
+ 
+ 	list_add_tail(&priv->list, &ppriv->child_intfs);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20_umcast.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20_umcast.patch
new file mode 100644
index 0000000..45b6ec3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20_umcast.patch
@@ -0,0 +1,54 @@
+This patch is the buddy of ipoib_class_device_to_2_6_20.patch, namely it handles
+the same issue in the same method for the /sys/class/net/$dev/umcast sysfs entry
+
+Hence it  needs to go to all the directories under kernel_patches/backport that 
+contain the ipoib_class_device_to_2_6_20.patch
+
+---
+
+backport kernel_patches/fixes/zzz_ipoib_allow_umcast.patch to older kernels
+
+Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>
+
+---
+ drivers/infiniband/ulp/ipoib/ipoib_main.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -1133,16 +1133,14 @@ static ssize_t show_pkey(struct class_de
+ }
+ static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
+ 
+-static ssize_t show_umcast(struct device *dev,
+-			   struct device_attribute *attr, char *buf)
++static ssize_t show_umcast(struct class_device *dev, char *buf)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+ 
+ 	return sprintf(buf, "%d\n", test_bit(IPOIB_FLAG_UMCAST, &priv->flags));
+ }
+ 
+-static ssize_t set_umcast(struct device *dev,
+-			  struct device_attribute *attr,
++static ssize_t set_umcast(struct class_device *dev,
+ 			  const char *buf, size_t count)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+@@ -1157,11 +1155,12 @@ static ssize_t set_umcast(struct device 
+ 
+ 	return count;
+ }
+-static DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
++static CLASS_DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
+ 
+ int ipoib_add_umcast_attr(struct net_device *dev)
+ {
+-	return device_create_file(&dev->dev, &dev_attr_umcast);
++	return class_device_create_file(&dev->class_dev,
++					&class_device_attr_umcast);
+ }
+ 
+ static ssize_t create_child(struct class_device *dev,
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_lro_to_2.6.23.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_lro_to_2.6.23.patch
new file mode 100644
index 0000000..4e349d2
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_lro_to_2.6.23.patch
@@ -0,0 +1,659 @@
+---
+ drivers/infiniband/ulp/ipoib/Makefile        |    3 
+ drivers/infiniband/ulp/ipoib/inet_lro.c      |  601 +++++++++++++++++++++++++++
+ drivers/infiniband/ulp/ipoib/ipoib_ethtool.c |   13 
+ 3 files changed, 606 insertions(+), 11 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/Makefile
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/Makefile
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/Makefile
+@@ -5,7 +5,8 @@ ib_ipoib-y					:= ipoib_main.o \
+ 						   ipoib_multicast.o \
+ 						   ipoib_verbs.o \
+ 						   ipoib_vlan.o \
+-						   ipoib_ethtool.o
++						   ipoib_ethtool.o \
++						   inet_lro.o
+ ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_CM)		+= ipoib_cm.o
+ ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_DEBUG)	+= ipoib_fs.o
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/inet_lro.c
+===================================================================
+--- /dev/null
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/inet_lro.c
+@@ -0,0 +1,601 @@
++/*
++ *  linux/net/ipv4/inet_lro.c
++ *
++ *  Large Receive Offload (ipv4 / tcp)
++ *
++ *  (C) Copyright IBM Corp. 2007
++ *
++ *  Authors:
++ *       Jan-Bernd Themann <themann at de.ibm.com>
++ *       Christoph Raisch <raisch at de.ibm.com>
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++
++#include <linux/module.h>
++#include <linux/if_vlan.h>
++#include <linux/inet_lro.h>
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Jan-Bernd Themann <themann at de.ibm.com>");
++MODULE_DESCRIPTION("Large Receive Offload (ipv4 / tcp)");
++
++#define TCP_HDR_LEN(tcph) (tcph->doff << 2)
++#define IP_HDR_LEN(iph) (iph->ihl << 2)
++#define TCP_PAYLOAD_LENGTH(iph, tcph) \
++	(ntohs(iph->tot_len) - IP_HDR_LEN(iph) - TCP_HDR_LEN(tcph))
++
++#define IPH_LEN_WO_OPTIONS 5
++#define TCPH_LEN_WO_OPTIONS 5
++#define TCPH_LEN_W_TIMESTAMP 8
++
++#define LRO_MAX_PG_HLEN 64
++
++#define LRO_INC_STATS(lro_mgr, attr) { lro_mgr->stats.attr++; }
++
++/*
++ * Basic tcp checks whether packet is suitable for LRO
++ */
++
++static int lro_tcp_ip_check(struct iphdr *iph, struct tcphdr *tcph,
++			    int len, struct net_lro_desc *lro_desc)
++{
++        /* check ip header: don't aggregate padded frames */
++	if (ntohs(iph->tot_len) != len)
++		return -1;
++
++	if (TCP_PAYLOAD_LENGTH(iph, tcph) == 0)
++		return -1;
++
++	if (iph->ihl != IPH_LEN_WO_OPTIONS)
++		return -1;
++
++	if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack
++	    || tcph->rst || tcph->syn || tcph->fin)
++		return -1;
++
++	if (INET_ECN_is_ce(ipv4_get_dsfield(iph)))
++		return -1;
++
++	if (tcph->doff != TCPH_LEN_WO_OPTIONS
++	    && tcph->doff != TCPH_LEN_W_TIMESTAMP)
++		return -1;
++
++	/* check tcp options (only timestamp allowed) */
++	if (tcph->doff == TCPH_LEN_W_TIMESTAMP) {
++		__be32 *topt = (__be32 *)(tcph + 1);
++
++		if (*topt != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
++				   | (TCPOPT_TIMESTAMP << 8)
++				   | TCPOLEN_TIMESTAMP))
++			return -1;
++
++		/* timestamp should be in right order */
++		topt++;
++		if (lro_desc && after(ntohl(lro_desc->tcp_rcv_tsval),
++				      ntohl(*topt)))
++			return -1;
++
++		/* timestamp reply should not be zero */
++		topt++;
++		if (*topt == 0)
++			return -1;
++	}
++
++	return 0;
++}
++
++static void lro_update_tcp_ip_header(struct net_lro_desc *lro_desc)
++{
++	struct iphdr *iph = lro_desc->iph;
++	struct tcphdr *tcph = lro_desc->tcph;
++	__be32 *p;
++	__wsum tcp_hdr_csum;
++
++	tcph->ack_seq = lro_desc->tcp_ack;
++	tcph->window = lro_desc->tcp_window;
++
++	if (lro_desc->tcp_saw_tstamp) {
++		p = (__be32 *)(tcph + 1);
++		*(p+2) = lro_desc->tcp_rcv_tsecr;
++	}
++
++	iph->tot_len = htons(lro_desc->ip_tot_len);
++
++	iph->check = 0;
++	iph->check = ip_fast_csum((u8 *)lro_desc->iph, iph->ihl);
++
++	tcph->check = 0;
++	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), 0);
++	lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum);
++	tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
++					lro_desc->ip_tot_len -
++					IP_HDR_LEN(iph), IPPROTO_TCP,
++					lro_desc->data_csum);
++}
++
++static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
++{
++	__wsum tcp_csum;
++	__wsum tcp_hdr_csum;
++	__wsum tcp_ps_hdr_csum;
++
++	tcp_csum = ~csum_unfold(tcph->check);
++	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), tcp_csum);
++
++	tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
++					     len + TCP_HDR_LEN(tcph),
++					     IPPROTO_TCP, 0);
++
++	return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum),
++			tcp_ps_hdr_csum);
++}
++
++static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb,
++			  struct iphdr *iph, struct tcphdr *tcph,
++			  u16 vlan_tag, struct vlan_group *vgrp)
++{
++	int nr_frags;
++	__be32 *ptr;
++	u32 tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
++
++	nr_frags = skb_shinfo(skb)->nr_frags;
++	lro_desc->parent = skb;
++	lro_desc->next_frag = &(skb_shinfo(skb)->frags[nr_frags]);
++	lro_desc->iph = iph;
++	lro_desc->tcph = tcph;
++	lro_desc->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len;
++	lro_desc->tcp_ack = tcph->ack_seq;
++	lro_desc->tcp_window = tcph->window;
++
++	lro_desc->pkt_aggr_cnt = 1;
++	lro_desc->ip_tot_len = ntohs(iph->tot_len);
++
++	if (tcph->doff == 8) {
++		ptr = (__be32 *)(tcph+1);
++		lro_desc->tcp_saw_tstamp = 1;
++		lro_desc->tcp_rcv_tsval = *(ptr+1);
++		lro_desc->tcp_rcv_tsecr = *(ptr+2);
++	}
++
++	lro_desc->mss = tcp_data_len;
++	lro_desc->vgrp = vgrp;
++	lro_desc->vlan_tag = vlan_tag;
++	lro_desc->active = 1;
++
++	lro_desc->data_csum = lro_tcp_data_csum(iph, tcph,
++						tcp_data_len);
++}
++
++static inline void lro_clear_desc(struct net_lro_desc *lro_desc)
++{
++	memset(lro_desc, 0, sizeof(struct net_lro_desc));
++}
++
++static void lro_add_common(struct net_lro_desc *lro_desc, struct iphdr *iph,
++			   struct tcphdr *tcph, int tcp_data_len)
++{
++	struct sk_buff *parent = lro_desc->parent;
++	__be32 *topt;
++
++	lro_desc->pkt_aggr_cnt++;
++	lro_desc->ip_tot_len += tcp_data_len;
++	lro_desc->tcp_next_seq += tcp_data_len;
++	lro_desc->tcp_window = tcph->window;
++	lro_desc->tcp_ack = tcph->ack_seq;
++
++	/* don't update tcp_rcv_tsval, would not work with PAWS */
++	if (lro_desc->tcp_saw_tstamp) {
++		topt = (__be32 *) (tcph + 1);
++		lro_desc->tcp_rcv_tsecr = *(topt + 2);
++	}
++
++	lro_desc->data_csum = csum_block_add(lro_desc->data_csum,
++					     lro_tcp_data_csum(iph, tcph,
++							       tcp_data_len),
++					     parent->len);
++
++	parent->len += tcp_data_len;
++	parent->data_len += tcp_data_len;
++	if (tcp_data_len > lro_desc->mss)
++		lro_desc->mss = tcp_data_len;
++}
++
++static void lro_add_packet(struct net_lro_desc *lro_desc, struct sk_buff *skb,
++			   struct iphdr *iph, struct tcphdr *tcph)
++{
++	struct sk_buff *parent = lro_desc->parent;
++	int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
++
++	lro_add_common(lro_desc, iph, tcph, tcp_data_len);
++
++	skb_pull(skb, (skb->len - tcp_data_len));
++	parent->truesize += skb->truesize;
++
++	if (lro_desc->last_skb)
++		lro_desc->last_skb->next = skb;
++	else
++		skb_shinfo(parent)->frag_list = skb;
++
++	lro_desc->last_skb = skb;
++}
++
++static void lro_add_frags(struct net_lro_desc *lro_desc,
++			  int len, int hlen, int truesize,
++			  struct skb_frag_struct *skb_frags,
++			  struct iphdr *iph, struct tcphdr *tcph)
++{
++	struct sk_buff *skb = lro_desc->parent;
++	int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
++
++	lro_add_common(lro_desc, iph, tcph, tcp_data_len);
++
++	skb->truesize += truesize;
++
++	skb_frags[0].page_offset += hlen;
++	skb_frags[0].size -= hlen;
++
++	while (tcp_data_len > 0) {
++		*(lro_desc->next_frag) = *skb_frags;
++		tcp_data_len -= skb_frags->size;
++		lro_desc->next_frag++;
++		skb_frags++;
++		skb_shinfo(skb)->nr_frags++;
++	}
++}
++
++static int lro_check_tcp_conn(struct net_lro_desc *lro_desc,
++			      struct iphdr *iph,
++			      struct tcphdr *tcph)
++{
++	if ((lro_desc->iph->saddr != iph->saddr)
++	    || (lro_desc->iph->daddr != iph->daddr)
++	    || (lro_desc->tcph->source != tcph->source)
++	    || (lro_desc->tcph->dest != tcph->dest))
++		return -1;
++	return 0;
++}
++
++static struct net_lro_desc *lro_get_desc(struct net_lro_mgr *lro_mgr,
++					 struct net_lro_desc *lro_arr,
++					 struct iphdr *iph,
++					 struct tcphdr *tcph)
++{
++	struct net_lro_desc *lro_desc = NULL;
++	struct net_lro_desc *tmp;
++	int max_desc = lro_mgr->max_desc;
++	int i;
++
++	for (i = 0; i < max_desc; i++) {
++		tmp = &lro_arr[i];
++		if (tmp->active)
++			if (!lro_check_tcp_conn(tmp, iph, tcph)) {
++				lro_desc = tmp;
++				goto out;
++			}
++	}
++
++	for (i = 0; i < max_desc; i++) {
++		if (!lro_arr[i].active) {
++			lro_desc = &lro_arr[i];
++			goto out;
++		}
++	}
++
++	LRO_INC_STATS(lro_mgr, no_desc);
++out:
++	return lro_desc;
++}
++
++static void lro_flush(struct net_lro_mgr *lro_mgr,
++		      struct net_lro_desc *lro_desc)
++{
++	if (lro_desc->pkt_aggr_cnt > 1)
++		lro_update_tcp_ip_header(lro_desc);
++
++	skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss;
++
++	if (lro_desc->vgrp) {
++		if (lro_mgr->features & LRO_F_NAPI)
++			vlan_hwaccel_receive_skb(lro_desc->parent,
++						 lro_desc->vgrp,
++						 lro_desc->vlan_tag);
++		else
++			vlan_hwaccel_rx(lro_desc->parent,
++					lro_desc->vgrp,
++					lro_desc->vlan_tag);
++
++	} else {
++		if (lro_mgr->features & LRO_F_NAPI)
++			netif_receive_skb(lro_desc->parent);
++		else
++			netif_rx(lro_desc->parent);
++	}
++
++	LRO_INC_STATS(lro_mgr, flushed);
++	lro_clear_desc(lro_desc);
++}
++
++static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
++			  struct vlan_group *vgrp, u16 vlan_tag, void *priv)
++{
++	struct net_lro_desc *lro_desc;
++	struct iphdr *iph;
++	struct tcphdr *tcph;
++	u64 flags;
++	int vlan_hdr_len = 0;
++
++	if (!lro_mgr->get_skb_header
++	    || lro_mgr->get_skb_header(skb, (void *)&iph, (void *)&tcph,
++				       &flags, priv))
++		goto out;
++
++	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))
++		goto out;
++
++	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
++	if (!lro_desc)
++		goto out;
++
++	if ((skb->protocol == htons(ETH_P_8021Q))
++	    && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID))
++		vlan_hdr_len = VLAN_HLEN;
++
++	if (!lro_desc->active) { /* start new lro session */
++		if (lro_tcp_ip_check(iph, tcph, skb->len - vlan_hdr_len, NULL))
++			goto out;
++
++		skb->ip_summed = lro_mgr->ip_summed_aggr;
++		lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp);
++		LRO_INC_STATS(lro_mgr, aggregated);
++		return 0;
++	}
++
++	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))
++		goto out2;
++
++	if (lro_tcp_ip_check(iph, tcph, skb->len, lro_desc))
++		goto out2;
++
++	lro_add_packet(lro_desc, skb, iph, tcph);
++	LRO_INC_STATS(lro_mgr, aggregated);
++
++	if ((lro_desc->pkt_aggr_cnt >= lro_mgr->max_aggr) ||
++	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
++		lro_flush(lro_mgr, lro_desc);
++
++	return 0;
++
++out2: /* send aggregated SKBs to stack */
++	lro_flush(lro_mgr, lro_desc);
++
++out:  /* Original SKB has to be posted to stack */
++	skb->ip_summed = lro_mgr->ip_summed;
++	return 1;
++}
++
++
++static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,
++				   struct skb_frag_struct *frags,
++				   int len, int true_size,
++				   void *mac_hdr,
++				   int hlen, __wsum sum,
++				   u32 ip_summed)
++{
++	struct sk_buff *skb;
++	struct skb_frag_struct *skb_frags;
++	int data_len = len;
++	int hdr_len = min(len, hlen);
++
++	skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad);
++	if (!skb)
++		return NULL;
++
++	skb_reserve(skb, lro_mgr->frag_align_pad);
++	skb->len = len;
++	skb->data_len = len - hdr_len;
++	skb->truesize += true_size;
++	skb->tail += hdr_len;
++
++	memcpy(skb->data, mac_hdr, hdr_len);
++
++	skb_frags = skb_shinfo(skb)->frags;
++	while (data_len > 0) {
++		*skb_frags = *frags;
++		data_len -= frags->size;
++		skb_frags++;
++		frags++;
++		skb_shinfo(skb)->nr_frags++;
++	}
++
++	skb_shinfo(skb)->frags[0].page_offset += hdr_len;
++	skb_shinfo(skb)->frags[0].size -= hdr_len;
++
++	skb->ip_summed = ip_summed;
++	skb->csum = sum;
++	skb->protocol = eth_type_trans(skb, lro_mgr->dev);
++	return skb;
++}
++
++static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
++					  struct skb_frag_struct *frags,
++					  int len, int true_size,
++					  struct vlan_group *vgrp,
++					  u16 vlan_tag, void *priv, __wsum sum)
++{
++	struct net_lro_desc *lro_desc;
++	struct iphdr *iph;
++	struct tcphdr *tcph;
++	struct sk_buff *skb;
++	u64 flags;
++	void *mac_hdr;
++	int mac_hdr_len;
++	int hdr_len = LRO_MAX_PG_HLEN;
++	int vlan_hdr_len = 0;
++
++	if (!lro_mgr->get_frag_header
++	    || lro_mgr->get_frag_header(frags, (void *)&mac_hdr, (void *)&iph,
++					(void *)&tcph, &flags, priv)) {
++		mac_hdr = page_address(frags->page) + frags->page_offset;
++		goto out1;
++	}
++
++	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))
++		goto out1;
++
++	hdr_len = (int)((void *)(tcph) + TCP_HDR_LEN(tcph) - mac_hdr);
++	mac_hdr_len = (int)((void *)(iph) - mac_hdr);
++
++	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
++	if (!lro_desc)
++		goto out1;
++
++	if (!lro_desc->active) { /* start new lro session */
++		if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, NULL))
++			goto out1;
++
++		skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
++				  hdr_len, 0, lro_mgr->ip_summed_aggr);
++		if (!skb)
++			goto out;
++
++		if ((skb->protocol == htons(ETH_P_8021Q))
++		    && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID))
++			vlan_hdr_len = VLAN_HLEN;
++
++		iph = (void *)(skb->data + vlan_hdr_len);
++		tcph = (void *)((u8 *)skb->data + vlan_hdr_len
++				+ IP_HDR_LEN(iph));
++
++		lro_init_desc(lro_desc, skb, iph, tcph, 0, NULL);
++		LRO_INC_STATS(lro_mgr, aggregated);
++		return NULL;
++	}
++
++	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))
++		goto out2;
++
++	if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, lro_desc))
++		goto out2;
++
++	lro_add_frags(lro_desc, len, hdr_len, true_size, frags, iph, tcph);
++	LRO_INC_STATS(lro_mgr, aggregated);
++
++	if ((skb_shinfo(lro_desc->parent)->nr_frags >= lro_mgr->max_aggr) ||
++	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
++		lro_flush(lro_mgr, lro_desc);
++
++	return NULL;
++
++out2: /* send aggregated packets to the stack */
++	lro_flush(lro_mgr, lro_desc);
++
++out1:  /* Original packet has to be posted to the stack */
++	skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
++			  hdr_len, sum, lro_mgr->ip_summed);
++out:
++	return skb;
++}
++
++void lro_receive_skb(struct net_lro_mgr *lro_mgr,
++		     struct sk_buff *skb,
++		     void *priv)
++{
++	if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) {
++		if (lro_mgr->features & LRO_F_NAPI)
++			netif_receive_skb(skb);
++		else
++			netif_rx(skb);
++	}
++}
++EXPORT_SYMBOL(lro_receive_skb);
++
++void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
++				  struct sk_buff *skb,
++				  struct vlan_group *vgrp,
++				  u16 vlan_tag,
++				  void *priv)
++{
++	if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) {
++		if (lro_mgr->features & LRO_F_NAPI)
++			vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
++		else
++			vlan_hwaccel_rx(skb, vgrp, vlan_tag);
++	}
++}
++EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb);
++
++void lro_receive_frags(struct net_lro_mgr *lro_mgr,
++		       struct skb_frag_struct *frags,
++		       int len, int true_size, void *priv, __wsum sum)
++{
++	struct sk_buff *skb;
++
++	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0,
++				 priv, sum);
++	if (!skb)
++		return;
++
++	if (lro_mgr->features & LRO_F_NAPI)
++		netif_receive_skb(skb);
++	else
++		netif_rx(skb);
++}
++EXPORT_SYMBOL(lro_receive_frags);
++
++void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
++				    struct skb_frag_struct *frags,
++				    int len, int true_size,
++				    struct vlan_group *vgrp,
++				    u16 vlan_tag, void *priv, __wsum sum)
++{
++	struct sk_buff *skb;
++
++	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp,
++				 vlan_tag, priv, sum);
++	if (!skb)
++		return;
++
++	if (lro_mgr->features & LRO_F_NAPI)
++		vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
++	else
++		vlan_hwaccel_rx(skb, vgrp, vlan_tag);
++}
++EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags);
++
++void lro_flush_all(struct net_lro_mgr *lro_mgr)
++{
++	int i;
++	struct net_lro_desc *lro_desc = lro_mgr->lro_arr;
++
++	for (i = 0; i < lro_mgr->max_desc; i++) {
++		if (lro_desc[i].active)
++			lro_flush(lro_mgr, &lro_desc[i]);
++	}
++}
++EXPORT_SYMBOL(lro_flush_all);
++
++void lro_flush_pkt(struct net_lro_mgr *lro_mgr,
++		  struct iphdr *iph, struct tcphdr *tcph)
++{
++	struct net_lro_desc *lro_desc;
++
++	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
++	if (lro_desc->active)
++		lro_flush(lro_mgr, lro_desc);
++}
++EXPORT_SYMBOL(lro_flush_pkt);
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+@@ -100,14 +100,9 @@ static void ipoib_get_strings(struct net
+ 	}
+ }
+ 
+-static int ipoib_get_sset_count(struct net_device *dev, int sset)
++static int ipoib_get_stats_count(struct net_device *dev)
+ {
+-	switch (sset) {
+-	case ETH_SS_STATS:
+-		return ARRAY_SIZE(ipoib_stats_keys);
+-	default:
+-		return -EOPNOTSUPP;
+-	}
++	return ARRAY_SIZE(ipoib_stats_keys);
+ }
+ 
+ static void ipoib_get_ethtool_stats(struct net_device *dev,
+@@ -132,10 +127,8 @@ static const struct ethtool_ops ipoib_et
+ 	.get_tso		= ethtool_op_get_tso,
+ 	.get_coalesce		= ipoib_get_coalesce,
+ 	.set_coalesce		= ipoib_set_coalesce,
+-	.get_flags		= ethtool_op_get_flags,
+-	.set_flags		= ethtool_op_set_flags,
+ 	.get_strings		= ipoib_get_strings,
+-	.get_sset_count		= ipoib_get_sset_count,
++	.get_stats_count 	= ipoib_get_stats_count,
+ 	.get_ethtool_stats	= ipoib_get_ethtool_stats,
+ };
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_mcast_set_pkey_to_2_6_24.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_mcast_set_pkey_to_2_6_24.patch
new file mode 100644
index 0000000..9c466cd
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_mcast_set_pkey_to_2_6_24.patch
@@ -0,0 +1,19 @@
+---
+ drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -796,6 +796,10 @@ void ipoib_mcast_restart_task(struct wor
+ 
+ 		memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
+ 
++		/* Add in the P_Key */
++		mgid.raw[4] = (priv->pkey >> 8) & 0xff;
++		mgid.raw[5] = priv->pkey & 0xff;
++
+ 		mcast = __ipoib_mcast_find(dev, &mgid);
+ 		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
+ 			struct ipoib_mcast *nmcast;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_skb_to_2_6_20.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_skb_to_2_6_20.patch
new file mode 100644
index 0000000..d56793d
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_skb_to_2_6_20.patch
@@ -0,0 +1,16 @@
+---
+ drivers/infiniband/ulp/ipoib/ipoib_ib.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c
++++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+@@ -35,6 +35,7 @@
+ 
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
++#include <linux/skbuff.h>
+ 
+ #include <rdma/ib_cache.h>
+ #include <linux/ip.h>
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_x_neigh_cleanup.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_x_neigh_cleanup.patch
new file mode 100644
index 0000000..820fd8c
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/ipoib_x_neigh_cleanup.patch
@@ -0,0 +1,182 @@
+IB/ipoib: Fix neigh destructor oops
+
+For kernels 2.6.20 and older, it may happen that the pointer to
+ipoib_neigh_cleanup() is called after IPoIB has been unloades,
+causing a kernel oops. This problem has been fixed for 2.6.21 with
+the following commit: ecbb416939da77c0d107409976499724baddce7b
+
+The idea with this patch is to have a helper module which remains
+always loaded, and this modules provides the destructor for
+neighbours which calls IPoIB's destructor through a function poiner.
+When IPoIB is unloaded, the function pointer is cleared so subsequent
+calls to a neighbour destructor will be made to valid addresses but
+IPoIB's destructor won't get called.
+
+Signed-off-by: Eli Cohen <eli at mellanox.co.il>
+---
+
+Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
+===================================================================
+--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2008-05-14 12:49:11.000000000 +0300
++++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c	2008-05-14 12:49:32.000000000 +0300
+@@ -49,6 +49,7 @@
+ 
+ #include <net/dst.h>
+ #include <linux/vmalloc.h>
++#include <linux/delay.h>
+ 
+ MODULE_AUTHOR("Roland Dreier");
+ MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
+@@ -916,7 +917,7 @@ void ipoib_neigh_free(struct net_device 
+ 
+ static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
+ {
+-	parms->neigh_cleanup = ipoib_neigh_cleanup;
++	parms->neigh_cleanup = ipoib_neigh_cleanup_container;
+ 
+ 	return 0;
+ }
+@@ -1383,9 +1384,13 @@ static int __init ipoib_init_module(void
+ 	ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
+ #endif
+ 
++
++	ipoib_set_cleanup_function(ipoib_neigh_cleanup);
+ 	ret = ipoib_register_debugfs();
+-	if (ret)
++	if (ret) {
++		ipoib_set_cleanup_function(NULL);
+ 		return ret;
++	}
+ 
+ 	/*
+ 	 * We create our own workqueue mainly because we want to be
+@@ -1397,6 +1402,7 @@ static int __init ipoib_init_module(void
+ 	 */
+ 	ipoib_workqueue = create_singlethread_workqueue("ipoib");
+ 	if (!ipoib_workqueue) {
++		ipoib_set_cleanup_function(NULL);
+ 		ret = -ENOMEM;
+ 		goto err_fs;
+ 	}
+@@ -1404,8 +1410,10 @@ static int __init ipoib_init_module(void
+ 	ib_sa_register_client(&ipoib_sa_client);
+ 
+ 	ret = ib_register_client(&ipoib_client);
+-	if (ret)
++	if (ret) {
++		ipoib_set_cleanup_function(NULL);
+ 		goto err_sa;
++	}
+ 
+ 	return 0;
+ 
+@@ -1421,7 +1429,16 @@ err_fs:
+ 
+ static void __exit ipoib_cleanup_module(void)
+ {
++	int ret;
++
+ 	ib_unregister_client(&ipoib_client);
++
++	do {
++		ret = ipoib_set_cleanup_function(NULL);
++		if (ret)
++			msleep(10);
++	} while(ret);
++
+ 	ib_sa_unregister_client(&ipoib_sa_client);
+ 	ipoib_unregister_debugfs();
+ 	destroy_workqueue(ipoib_workqueue);
+Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/Makefile
+===================================================================
+--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/Makefile	2008-05-14 12:49:11.000000000 +0300
++++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/Makefile	2008-05-14 12:49:32.000000000 +0300
+@@ -1,4 +1,4 @@
+-obj-$(CONFIG_INFINIBAND_IPOIB)			+= ib_ipoib.o
++obj-$(CONFIG_INFINIBAND_IPOIB)			+= ib_ipoib.o ipoib_helper.o
+ 
+ ib_ipoib-y					:= ipoib_main.o \
+ 						   ipoib_ib.o \
+Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h
+===================================================================
+--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2008-05-14 12:49:11.000000000 +0300
++++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h	2008-05-14 12:49:32.000000000 +0300
+@@ -554,6 +554,9 @@ int ipoib_mcast_stop_thread(struct net_d
+ void ipoib_mcast_dev_down(struct net_device *dev);
+ void ipoib_mcast_dev_flush(struct net_device *dev);
+ 
++int ipoib_set_cleanup_function(void (*func)(struct neighbour *n));
++void ipoib_neigh_cleanup_container(struct neighbour *n);
++
+ #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
+ int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
+Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_helper.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_helper.c	2008-05-14 12:49:32.000000000 +0300
+@@ -0,0 +1,63 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <net/neighbour.h>
++
++MODULE_AUTHOR("Eli Cohen");
++MODULE_DESCRIPTION("container for ipoib neighbour destructor");
++MODULE_LICENSE("Dual BSD/GPL");
++
++DEFINE_SPINLOCK(spl);
++static int busy;
++
++static void (*cleanup_func)(struct neighbour *n);
++
++static int ipoib_set_cleanup_function(void (*func)(struct neighbour *n))
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&spl, flags);
++	if (busy) {
++		spin_unlock_irqrestore(&spl, flags);
++		return -EBUSY;
++	}
++	cleanup_func = func;
++	spin_unlock_irqrestore(&spl, flags);
++
++	return 0;
++}
++
++static void ipoib_neigh_cleanup_container(struct neighbour *n)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&spl, flags);
++	busy = 1;
++	spin_unlock_irqrestore(&spl, flags);
++	if (cleanup_func)
++		cleanup_func(n);
++
++	spin_lock_irqsave(&spl, flags);
++	busy = 0;
++	spin_unlock_irqrestore(&spl, flags);
++}
++
++
++EXPORT_SYMBOL(ipoib_set_cleanup_function);
++EXPORT_SYMBOL(ipoib_neigh_cleanup_container);
++
++
++static int __init ipoib_helper_init(void)
++{
++	if (!try_module_get(THIS_MODULE))
++		return -1;
++
++	return 0;
++}
++
++
++static void __exit ipoib_helper_cleanup(void)
++{
++}
++
++module_init(ipoib_helper_init);
++module_exit(ipoib_helper_cleanup);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_01_sync_kernel_code_with_release_2.0-869.2.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_01_sync_kernel_code_with_release_2.0-869.2.patch
new file mode 100644
index 0000000..ca3c430
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_01_sync_kernel_code_with_release_2.0-869.2.patch
@@ -0,0 +1,4742 @@
+From 89ac09ec66db75fbda1bd77918066fb2ddebac38 Mon Sep 17 00:00:00 2001
+From: Doron Shoham <dorons at voltaire.com>
+Date: Mon, 25 Aug 2008 16:16:26 +0300
+Subject: [PATCH] iscsi_01_sync_kernel_code_with_release_2.0-869.2
+
+Signed-off-by: Doron Shoham <dorons at voltaire.com>
+---
+ drivers/scsi/iscsi_tcp.c            |  529 ++++++-------
+ drivers/scsi/iscsi_tcp.h            |    7 
+ drivers/scsi/libiscsi.c             | 1455 +++++++++++++++---------------------
+ drivers/scsi/scsi_transport_iscsi.c |  500 +++---------
+ include/scsi/libiscsi.h             |  108 +-
+ include/scsi/scsi_transport_iscsi.h |   93 +-
+ 6 files changed, 1119 insertions(+), 1573 deletions(-)
+
+Index: ofed_kernel/drivers/scsi/iscsi_tcp.c
+===================================================================
+--- ofed_kernel.orig/drivers/scsi/iscsi_tcp.c
++++ ofed_kernel/drivers/scsi/iscsi_tcp.c
+@@ -64,10 +64,6 @@ MODULE_LICENSE("GPL");
+ #define BUG_ON(expr)
+ #endif
+ 
+-static struct scsi_transport_template *iscsi_tcp_scsi_transport;
+-static struct scsi_host_template iscsi_sht;
+-static struct iscsi_transport iscsi_tcp_transport;
+-
+ static unsigned int iscsi_max_lun = 512;
+ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
+ 
+@@ -498,63 +494,58 @@ iscsi_tcp_data_recv_prep(struct iscsi_tc
+  * must be called with session lock
+  */
+ static void
+-iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
++iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_tcp_task *tcp_task = task->dd_data;
++	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 	struct iscsi_r2t_info *r2t;
+ 
+-	/* nothing to do for mgmt tasks */
+-	if (!task->sc)
+-		return;
+-
+-	/* flush task's r2t queues */
+-	while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
+-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
++	/* flush ctask's r2t queues */
++	while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
++		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+ 			    sizeof(void*));
+-		debug_scsi("iscsi_tcp_cleanup_task pending r2t dropped\n");
++		debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n");
+ 	}
+ 
+-	r2t = tcp_task->r2t;
++	r2t = tcp_ctask->r2t;
+ 	if (r2t != NULL) {
+-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
++		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+ 			    sizeof(void*));
+-		tcp_task->r2t = NULL;
++		tcp_ctask->r2t = NULL;
+ 	}
+ }
+ 
+ /**
+  * iscsi_data_rsp - SCSI Data-In Response processing
+  * @conn: iscsi connection
+- * @task: scsi command task
++ * @ctask: scsi command task
+  **/
+ static int
+-iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
++iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ {
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+-	struct iscsi_tcp_task *tcp_task = task->dd_data;
++	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 	struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
+ 	struct iscsi_session *session = conn->session;
+-	struct scsi_cmnd *sc = task->sc;
++	struct scsi_cmnd *sc = ctask->sc;
+ 	int datasn = be32_to_cpu(rhdr->datasn);
+-	unsigned total_in_length = scsi_in(sc)->length;
+ 
+ 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ 	if (tcp_conn->in.datalen == 0)
+ 		return 0;
+ 
+-	if (tcp_task->exp_datasn != datasn) {
+-		debug_tcp("%s: task->exp_datasn(%d) != rhdr->datasn(%d)\n",
+-		          __func__, tcp_task->exp_datasn, datasn);
++	if (tcp_ctask->exp_datasn != datasn) {
++		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
++		          __FUNCTION__, tcp_ctask->exp_datasn, datasn);
+ 		return ISCSI_ERR_DATASN;
+ 	}
+ 
+-	tcp_task->exp_datasn++;
++	tcp_ctask->exp_datasn++;
+ 
+-	tcp_task->data_offset = be32_to_cpu(rhdr->offset);
+-	if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) {
++	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
++	if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) {
+ 		debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
+-		          __func__, tcp_task->data_offset,
+-		          tcp_conn->in.datalen, total_in_length);
++		          __FUNCTION__, tcp_ctask->data_offset,
++		          tcp_conn->in.datalen, scsi_bufflen(sc));
+ 		return ISCSI_ERR_DATA_OFFSET;
+ 	}
+ 
+@@ -567,8 +558,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, 
+ 
+ 			if (res_count > 0 &&
+ 			    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
+-			     res_count <= total_in_length))
+-				scsi_in(sc)->resid = res_count;
++			     res_count <= scsi_bufflen(sc)))
++				scsi_set_resid(sc, res_count);
+ 			else
+ 				sc->result = (DID_BAD_TARGET << 16) |
+ 					rhdr->cmd_status;
+@@ -582,7 +573,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, 
+ /**
+  * iscsi_solicit_data_init - initialize first Data-Out
+  * @conn: iscsi connection
+- * @task: scsi command task
++ * @ctask: scsi command task
+  * @r2t: R2T info
+  *
+  * Notes:
+@@ -592,7 +583,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, 
+  *	This function is called with connection lock taken.
+  **/
+ static void
+-iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_task *task,
++iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ 			struct iscsi_r2t_info *r2t)
+ {
+ 	struct iscsi_data *hdr;
+@@ -603,8 +594,8 @@ iscsi_solicit_data_init(struct iscsi_con
+ 	hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
+ 	r2t->solicit_datasn++;
+ 	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+-	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
+-	hdr->itt = task->hdr->itt;
++	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
++	hdr->itt = ctask->hdr->itt;
+ 	hdr->exp_statsn = r2t->exp_statsn;
+ 	hdr->offset = cpu_to_be32(r2t->data_offset);
+ 	if (r2t->data_length > conn->max_xmit_dlength) {
+@@ -624,14 +615,14 @@ iscsi_solicit_data_init(struct iscsi_con
+ /**
+  * iscsi_r2t_rsp - iSCSI R2T Response processing
+  * @conn: iscsi connection
+- * @task: scsi command task
++ * @ctask: scsi command task
+  **/
+ static int
+-iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
++iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ {
+ 	struct iscsi_r2t_info *r2t;
+ 	struct iscsi_session *session = conn->session;
+-	struct iscsi_tcp_task *tcp_task = task->dd_data;
++	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ 	struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
+ 	int r2tsn = be32_to_cpu(rhdr->r2tsn);
+@@ -644,23 +635,23 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
+ 		return ISCSI_ERR_DATALEN;
+ 	}
+ 
+-	if (tcp_task->exp_datasn != r2tsn){
+-		debug_tcp("%s: task->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
+-		          __func__, tcp_task->exp_datasn, r2tsn);
++	if (tcp_ctask->exp_datasn != r2tsn){
++		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
++		          __FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
+ 		return ISCSI_ERR_R2TSN;
+ 	}
+ 
+ 	/* fill-in new R2T associated with the task */
+ 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ 
+-	if (!task->sc || session->state != ISCSI_STATE_LOGGED_IN) {
++	if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) {
+ 		iscsi_conn_printk(KERN_INFO, conn,
+ 				  "dropping R2T itt %d in recovery.\n",
+-				  task->itt);
++				  ctask->itt);
+ 		return 0;
+ 	}
+ 
+-	rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
++	rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
+ 	BUG_ON(!rc);
+ 
+ 	r2t->exp_statsn = rhdr->statsn;
+@@ -668,7 +659,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
+ 	if (r2t->data_length == 0) {
+ 		iscsi_conn_printk(KERN_ERR, conn,
+ 				  "invalid R2T with zero data len\n");
+-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
++		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+ 			    sizeof(void*));
+ 		return ISCSI_ERR_DATALEN;
+ 	}
+@@ -679,12 +670,12 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
+ 			    r2t->data_length, session->max_burst);
+ 
+ 	r2t->data_offset = be32_to_cpu(rhdr->data_offset);
+-	if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) {
++	if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) {
+ 		iscsi_conn_printk(KERN_ERR, conn,
+ 				  "invalid R2T with data len %u at offset %u "
+ 				  "and total length %d\n", r2t->data_length,
+-				  r2t->data_offset, scsi_out(task->sc)->length);
+-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
++				  r2t->data_offset, scsi_bufflen(ctask->sc));
++		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+ 			    sizeof(void*));
+ 		return ISCSI_ERR_DATALEN;
+ 	}
+@@ -692,13 +683,13 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
+ 	r2t->ttt = rhdr->ttt; /* no flip */
+ 	r2t->solicit_datasn = 0;
+ 
+-	iscsi_solicit_data_init(conn, task, r2t);
++	iscsi_solicit_data_init(conn, ctask, r2t);
+ 
+-	tcp_task->exp_datasn = r2tsn + 1;
+-	__kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
++	tcp_ctask->exp_datasn = r2tsn + 1;
++	__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
+ 	conn->r2t_pdus_cnt++;
+ 
+-	iscsi_requeue_task(task);
++	iscsi_requeue_ctask(ctask);
+ 	return 0;
+ }
+ 
+@@ -741,8 +732,10 @@ static int
+ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
+ {
+ 	int rc = 0, opcode, ahslen;
++	struct iscsi_session *session = conn->session;
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+-	struct iscsi_task *task;
++	struct iscsi_cmd_task *ctask;
++	uint32_t itt;
+ 
+ 	/* verify PDU length */
+ 	tcp_conn->in.datalen = ntoh24(hdr->dlength);
+@@ -760,7 +753,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
+ 
+ 	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
+ 	/* verify itt (itt encoding: age+cid+itt) */
+-	rc = iscsi_verify_itt(conn, hdr->itt);
++	rc = iscsi_verify_itt(conn, hdr, &itt);
+ 	if (rc)
+ 		return rc;
+ 
+@@ -769,21 +762,15 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
+ 
+ 	switch(opcode) {
+ 	case ISCSI_OP_SCSI_DATA_IN:
++		ctask = session->cmds[itt];
+ 		spin_lock(&conn->session->lock);
+-		task = iscsi_itt_to_ctask(conn, hdr->itt);
+-		if (!task)
+-			rc = ISCSI_ERR_BAD_ITT;
+-		else
+-			rc = iscsi_data_rsp(conn, task);
+-		if (rc) {
+-			spin_unlock(&conn->session->lock);
+-			break;
+-		}
+-
++		rc = iscsi_data_rsp(conn, ctask);
++		spin_unlock(&conn->session->lock);
++		if (rc)
++			return rc;
+ 		if (tcp_conn->in.datalen) {
+-			struct iscsi_tcp_task *tcp_task = task->dd_data;
++			struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 			struct hash_desc *rx_hash = NULL;
+-			struct scsi_data_buffer *sdb = scsi_in(task->sc);
+ 
+ 			/*
+ 			 * Setup copy of Data-In into the Scsi_Cmnd
+@@ -798,21 +785,17 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
+ 
+ 			debug_tcp("iscsi_tcp_begin_data_in(%p, offset=%d, "
+ 				  "datalen=%d)\n", tcp_conn,
+-				  tcp_task->data_offset,
++				  tcp_ctask->data_offset,
+ 				  tcp_conn->in.datalen);
+-			rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
+-						   sdb->table.sgl,
+-						   sdb->table.nents,
+-						   tcp_task->data_offset,
+-						   tcp_conn->in.datalen,
+-						   iscsi_tcp_process_data_in,
+-						   rx_hash);
+-			spin_unlock(&conn->session->lock);
+-			return rc;
++			return iscsi_segment_seek_sg(&tcp_conn->in.segment,
++						     scsi_sglist(ctask->sc),
++						     scsi_sg_count(ctask->sc),
++						     tcp_ctask->data_offset,
++						     tcp_conn->in.datalen,
++						     iscsi_tcp_process_data_in,
++						     rx_hash);
+ 		}
+-		rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
+-		spin_unlock(&conn->session->lock);
+-		break;
++		/* fall through */
+ 	case ISCSI_OP_SCSI_CMD_RSP:
+ 		if (tcp_conn->in.datalen) {
+ 			iscsi_tcp_data_recv_prep(tcp_conn);
+@@ -821,17 +804,15 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
+ 		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
+ 		break;
+ 	case ISCSI_OP_R2T:
+-		spin_lock(&conn->session->lock);
+-		task = iscsi_itt_to_ctask(conn, hdr->itt);
+-		if (!task)
+-			rc = ISCSI_ERR_BAD_ITT;
+-		else if (ahslen)
++		ctask = session->cmds[itt];
++		if (ahslen)
+ 			rc = ISCSI_ERR_AHSLEN;
+-		else if (task->sc->sc_data_direction == DMA_TO_DEVICE)
+-			rc = iscsi_r2t_rsp(conn, task);
+-		else
++		else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
++			spin_lock(&session->lock);
++			rc = iscsi_r2t_rsp(conn, ctask);
++			spin_unlock(&session->lock);
++		} else
+ 			rc = ISCSI_ERR_PROTO;
+-		spin_unlock(&conn->session->lock);
+ 		break;
+ 	case ISCSI_OP_LOGIN_RSP:
+ 	case ISCSI_OP_TEXT_RSP:
+@@ -1193,7 +1174,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_con
+ {
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ 
+-	debug_tcp("%s(%p%s)\n", __func__, tcp_conn,
++	debug_tcp("%s(%p%s)\n", __FUNCTION__, tcp_conn,
+ 			conn->hdrdgst_en? ", digest enabled" : "");
+ 
+ 	/* Clear the data segment - needs to be filled in by the
+@@ -1202,7 +1183,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_con
+ 
+ 	/* If header digest is enabled, compute the CRC and
+ 	 * place the digest into the same buffer. We make
+-	 * sure that both iscsi_tcp_task and mtask have
++	 * sure that both iscsi_tcp_ctask and mtask have
+ 	 * sufficient room.
+ 	 */
+ 	if (conn->hdrdgst_en) {
+@@ -1234,7 +1215,7 @@ iscsi_tcp_send_data_prep(struct iscsi_co
+ 	struct hash_desc *tx_hash = NULL;
+ 	unsigned int hdr_spec_len;
+ 
+-	debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __func__,
++	debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __FUNCTION__,
+ 			tcp_conn, offset, len,
+ 			conn->datadgst_en? ", digest enabled" : "");
+ 
+@@ -1259,7 +1240,7 @@ iscsi_tcp_send_linear_data_prepare(struc
+ 	struct hash_desc *tx_hash = NULL;
+ 	unsigned int hdr_spec_len;
+ 
+-	debug_tcp("%s(%p, datalen=%d%s)\n", __func__, tcp_conn, len,
++	debug_tcp("%s(%p, datalen=%d%s)\n", __FUNCTION__, tcp_conn, len,
+ 		  conn->datadgst_en? ", digest enabled" : "");
+ 
+ 	/* Make sure the datalen matches what the caller
+@@ -1277,7 +1258,7 @@ iscsi_tcp_send_linear_data_prepare(struc
+ /**
+  * iscsi_solicit_data_cont - initialize next Data-Out
+  * @conn: iscsi connection
+- * @task: scsi command task
++ * @ctask: scsi command task
+  * @r2t: R2T info
+  * @left: bytes left to transfer
+  *
+@@ -1288,7 +1269,7 @@ iscsi_tcp_send_linear_data_prepare(struc
+  *	Called under connection lock.
+  **/
+ static int
+-iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_task *task,
++iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ 			struct iscsi_r2t_info *r2t)
+ {
+ 	struct iscsi_data *hdr;
+@@ -1305,8 +1286,8 @@ iscsi_solicit_data_cont(struct iscsi_con
+ 	hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
+ 	r2t->solicit_datasn++;
+ 	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+-	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
+-	hdr->itt = task->hdr->itt;
++	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
++	hdr->itt = ctask->hdr->itt;
+ 	hdr->exp_statsn = r2t->exp_statsn;
+ 	new_offset = r2t->data_offset + r2t->sent;
+ 	hdr->offset = cpu_to_be32(new_offset);
+@@ -1324,76 +1305,87 @@ iscsi_solicit_data_cont(struct iscsi_con
+ }
+ 
+ /**
+- * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
++ * iscsi_tcp_ctask - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
+  * @conn: iscsi connection
+- * @task: scsi command task
++ * @ctask: scsi command task
+  * @sc: scsi command
+  **/
+ static int
+-iscsi_tcp_task_init(struct iscsi_task *task)
++iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_tcp_task *tcp_task = task->dd_data;
+-	struct iscsi_conn *conn = task->conn;
+-	struct scsi_cmnd *sc = task->sc;
++	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
++	struct iscsi_conn *conn = ctask->conn;
++	struct scsi_cmnd *sc = ctask->sc;
+ 	int err;
+ 
+-	if (!sc) {
+-		/*
+-		 * mgmt tasks do not have a scatterlist since they come
+-		 * in from the iscsi interface.
+-		 */
+-		debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id,
+-			   task->itt);
+-
+-		/* Prepare PDU, optionally w/ immediate data */
+-		iscsi_tcp_send_hdr_prep(conn, task->hdr, sizeof(*task->hdr));
+-
+-		/* If we have immediate data, attach a payload */
+-		if (task->data_count)
+-			iscsi_tcp_send_linear_data_prepare(conn, task->data,
+-							   task->data_count);
+-		return 0;
+-	}
+-
+-	BUG_ON(__kfifo_len(tcp_task->r2tqueue));
+-	tcp_task->sent = 0;
+-	tcp_task->exp_datasn = 0;
++	BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
++	tcp_ctask->sent = 0;
++	tcp_ctask->exp_datasn = 0;
+ 
+ 	/* Prepare PDU, optionally w/ immediate data */
+-	debug_scsi("task deq [cid %d itt 0x%x imm %d unsol %d]\n",
+-		    conn->id, task->itt, task->imm_count,
+-		    task->unsol_count);
+-	iscsi_tcp_send_hdr_prep(conn, task->hdr, task->hdr_len);
++	debug_scsi("ctask deq [cid %d itt 0x%x imm %d unsol %d]\n",
++		    conn->id, ctask->itt, ctask->imm_count,
++		    ctask->unsol_count);
++	iscsi_tcp_send_hdr_prep(conn, ctask->hdr, ctask->hdr_len);
+ 
+-	if (!task->imm_count)
++	if (!ctask->imm_count)
+ 		return 0;
+ 
+ 	/* If we have immediate data, attach a payload */
+-	err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl,
+-				       scsi_out(sc)->table.nents,
+-				       0, task->imm_count);
++	err = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), scsi_sg_count(sc),
++				       0, ctask->imm_count);
+ 	if (err)
+ 		return err;
+-	tcp_task->sent += task->imm_count;
+-	task->imm_count = 0;
++	tcp_ctask->sent += ctask->imm_count;
++	ctask->imm_count = 0;
++	return 0;
++}
++
++/**
++ * iscsi_tcp_mtask_xmit - xmit management(immediate) task
++ * @conn: iscsi connection
++ * @mtask: task management task
++ *
++ * Notes:
++ *	The function can return -EAGAIN in which case caller must
++ *	call it again later, or recover. '0' return code means successful
++ *	xmit.
++ **/
++static int
++iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
++{
++	int rc;
++
++	/* Flush any pending data first. */
++	rc = iscsi_tcp_flush(conn);
++	if (rc < 0)
++		return rc;
++
++	if (mtask->hdr->itt == RESERVED_ITT) {
++		struct iscsi_session *session = conn->session;
++
++		spin_lock_bh(&session->lock);
++		iscsi_free_mgmt_task(conn, mtask);
++		spin_unlock_bh(&session->lock);
++	}
++
+ 	return 0;
+ }
+ 
+ /*
+- * iscsi_tcp_task_xmit - xmit normal PDU task
+- * @task: iscsi command task
++ * iscsi_tcp_ctask_xmit - xmit normal PDU task
++ * @conn: iscsi connection
++ * @ctask: iscsi command task
+  *
+  * We're expected to return 0 when everything was transmitted succesfully,
+  * -EAGAIN if there's still data in the queue, or != 0 for any other kind
+  * of error.
+  */
+ static int
+-iscsi_tcp_task_xmit(struct iscsi_task *task)
++iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_conn *conn = task->conn;
+-	struct iscsi_tcp_task *tcp_task = task->dd_data;
+-	struct scsi_cmnd *sc = task->sc;
+-	struct scsi_data_buffer *sdb;
++	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
++	struct scsi_cmnd *sc = ctask->sc;
+ 	int rc = 0;
+ 
+ flush:
+@@ -1402,39 +1394,32 @@ flush:
+ 	if (rc < 0)
+ 		return rc;
+ 
+-	/* mgmt command */
+-	if (!sc) {
+-		if (task->hdr->itt == RESERVED_ITT)
+-			iscsi_put_task(task);
+-		return 0;
+-	}
+-
+ 	/* Are we done already? */
+ 	if (sc->sc_data_direction != DMA_TO_DEVICE)
+ 		return 0;
+ 
+-	sdb = scsi_out(sc);
+-	if (task->unsol_count != 0) {
+-		struct iscsi_data *hdr = &tcp_task->unsol_dtask.hdr;
++	if (ctask->unsol_count != 0) {
++		struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr;
+ 
+ 		/* Prepare a header for the unsolicited PDU.
+ 		 * The amount of data we want to send will be
+-		 * in task->data_count.
++		 * in ctask->data_count.
+ 		 * FIXME: return the data count instead.
+ 		 */
+-		iscsi_prep_unsolicit_data_pdu(task, hdr);
++		iscsi_prep_unsolicit_data_pdu(ctask, hdr);
+ 
+ 		debug_tcp("unsol dout [itt 0x%x doff %d dlen %d]\n",
+-				task->itt, tcp_task->sent, task->data_count);
++				ctask->itt, tcp_ctask->sent, ctask->data_count);
+ 
+ 		iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr));
+-		rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
+-					      sdb->table.nents, tcp_task->sent,
+-					      task->data_count);
++		rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
++					      scsi_sg_count(sc),
++					      tcp_ctask->sent,
++					      ctask->data_count);
+ 		if (rc)
+ 			goto fail;
+-		tcp_task->sent += task->data_count;
+-		task->unsol_count -= task->data_count;
++		tcp_ctask->sent += ctask->data_count;
++		ctask->unsol_count -= ctask->data_count;
+ 		goto flush;
+ 	} else {
+ 		struct iscsi_session *session = conn->session;
+@@ -1443,22 +1428,22 @@ flush:
+ 		/* All unsolicited PDUs sent. Check for solicited PDUs.
+ 		 */
+ 		spin_lock_bh(&session->lock);
+-		r2t = tcp_task->r2t;
++		r2t = tcp_ctask->r2t;
+ 		if (r2t != NULL) {
+ 			/* Continue with this R2T? */
+-			if (!iscsi_solicit_data_cont(conn, task, r2t)) {
++			if (!iscsi_solicit_data_cont(conn, ctask, r2t)) {
+ 				debug_scsi("  done with r2t %p\n", r2t);
+ 
+-				__kfifo_put(tcp_task->r2tpool.queue,
++				__kfifo_put(tcp_ctask->r2tpool.queue,
+ 					    (void*)&r2t, sizeof(void*));
+-				tcp_task->r2t = r2t = NULL;
++				tcp_ctask->r2t = r2t = NULL;
+ 			}
+ 		}
+ 
+ 		if (r2t == NULL) {
+-			__kfifo_get(tcp_task->r2tqueue, (void*)&tcp_task->r2t,
++			__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
+ 				    sizeof(void*));
+-			r2t = tcp_task->r2t;
++			r2t = tcp_ctask->r2t;
+ 		}
+ 		spin_unlock_bh(&session->lock);
+ 
+@@ -1469,19 +1454,19 @@ flush:
+ 		}
+ 
+ 		debug_scsi("sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n",
+-			r2t, r2t->solicit_datasn - 1, task->itt,
++			r2t, r2t->solicit_datasn - 1, ctask->itt,
+ 			r2t->data_offset + r2t->sent, r2t->data_count);
+ 
+ 		iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr,
+ 					sizeof(struct iscsi_hdr));
+ 
+-		rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
+-					      sdb->table.nents,
++		rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
++					      scsi_sg_count(sc),
+ 					      r2t->data_offset + r2t->sent,
+ 					      r2t->data_count);
+ 		if (rc)
+ 			goto fail;
+-		tcp_task->sent += r2t->data_count;
++		tcp_ctask->sent += r2t->data_count;
+ 		r2t->sent += r2t->data_count;
+ 		goto flush;
+ 	}
+@@ -1498,7 +1483,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
+ 	struct iscsi_cls_conn *cls_conn;
+ 	struct iscsi_tcp_conn *tcp_conn;
+ 
+-	cls_conn = iscsi_conn_setup(cls_session, sizeof(*tcp_conn), conn_idx);
++	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
+ 	if (!cls_conn)
+ 		return NULL;
+ 	conn = cls_conn->dd_data;
+@@ -1508,14 +1493,18 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
+ 	 */
+ 	conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
+ 
+-	tcp_conn = conn->dd_data;
++	tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL);
++	if (!tcp_conn)
++		goto tcp_conn_alloc_fail;
++
++	conn->dd_data = tcp_conn;
+ 	tcp_conn->iscsi_conn = conn;
+ 
+ 	tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
+ 						  CRYPTO_ALG_ASYNC);
+ 	tcp_conn->tx_hash.flags = 0;
+ 	if (IS_ERR(tcp_conn->tx_hash.tfm))
+-		goto free_conn;
++		goto free_tcp_conn;
+ 
+ 	tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
+ 						  CRYPTO_ALG_ASYNC);
+@@ -1527,12 +1516,14 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
+ 
+ free_tx_tfm:
+ 	crypto_free_hash(tcp_conn->tx_hash.tfm);
+-free_conn:
++free_tcp_conn:
+ 	iscsi_conn_printk(KERN_ERR, conn,
+ 			  "Could not create connection due to crc32c "
+ 			  "loading error. Make sure the crc32c "
+ 			  "module is built as a module or into the "
+ 			  "kernel\n");
++	kfree(tcp_conn);
++tcp_conn_alloc_fail:
+ 	iscsi_conn_teardown(cls_conn);
+ 	return NULL;
+ }
+@@ -1553,6 +1544,7 @@ iscsi_tcp_release_conn(struct iscsi_conn
+ 
+ 	spin_lock_bh(&session->lock);
+ 	tcp_conn->sock = NULL;
++	conn->recv_lock = NULL;
+ 	spin_unlock_bh(&session->lock);
+ 	sockfd_put(sock);
+ }
+@@ -1564,32 +1556,20 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ 
+ 	iscsi_tcp_release_conn(conn);
++	iscsi_conn_teardown(cls_conn);
+ 
+ 	if (tcp_conn->tx_hash.tfm)
+ 		crypto_free_hash(tcp_conn->tx_hash.tfm);
+ 	if (tcp_conn->rx_hash.tfm)
+ 		crypto_free_hash(tcp_conn->rx_hash.tfm);
+ 
+-	iscsi_conn_teardown(cls_conn);
++	kfree(tcp_conn);
+ }
+ 
+ static void
+ iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
+ {
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+-	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+-
+-	/* userspace may have goofed up and not bound us */
+-	if (!tcp_conn->sock)
+-		return;
+-	/*
+-	 * Make sure our recv side is stopped.
+-	 * Older tools called conn stop before ep_disconnect
+-	 * so IO could still be coming in.
+-	 */
+-	write_lock_bh(&tcp_conn->sock->sk->sk_callback_lock);
+-	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
+-	write_unlock_bh(&tcp_conn->sock->sk->sk_callback_lock);
+ 
+ 	iscsi_conn_stop(cls_conn, flag);
+ 	iscsi_tcp_release_conn(conn);
+@@ -1640,8 +1620,6 @@ iscsi_tcp_conn_bind(struct iscsi_cls_ses
+ 		    struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
+ 		    int is_leading)
+ {
+-	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+-	struct iscsi_host *ihost = shost_priv(shost);
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ 	struct sock *sk;
+@@ -1665,8 +1643,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_ses
+ 	if (err)
+ 		goto free_socket;
+ 
+-	err = iscsi_tcp_get_addr(conn, sock, ihost->local_address,
+-				&ihost->local_port, kernel_getsockname);
++	err = iscsi_tcp_get_addr(conn, sock, conn->local_address,
++				&conn->local_port, kernel_getsockname);
+ 	if (err)
+ 		goto free_socket;
+ 
+@@ -1683,6 +1661,13 @@ iscsi_tcp_conn_bind(struct iscsi_cls_ses
+ 	sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
+ 	sk->sk_allocation = GFP_ATOMIC;
+ 
++	/* FIXME: disable Nagle's algorithm */
++
++	/*
++	 * Intercept TCP callbacks for sendfile like receive
++	 * processing.
++	 */
++	conn->recv_lock = &sk->sk_callback_lock;
+ 	iscsi_conn_set_callbacks(conn);
+ 	tcp_conn->sendpage = tcp_conn->sock->ops->sendpage;
+ 	/*
+@@ -1696,6 +1681,21 @@ free_socket:
+ 	return err;
+ }
+ 
++/* called with host lock */
++static void
++iscsi_tcp_mtask_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
++{
++	debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
++
++	/* Prepare PDU, optionally w/ immediate data */
++	iscsi_tcp_send_hdr_prep(conn, mtask->hdr, sizeof(*mtask->hdr));
++
++	/* If we have immediate data, attach a payload */
++	if (mtask->data_count)
++		iscsi_tcp_send_linear_data_prepare(conn, mtask->data,
++						   mtask->data_count);
++}
++
+ static int
+ iscsi_r2tpool_alloc(struct iscsi_session *session)
+ {
+@@ -1706,8 +1706,8 @@ iscsi_r2tpool_alloc(struct iscsi_session
+ 	 * initialize per-task: R2T pool and xmit queue
+ 	 */
+ 	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
+-	        struct iscsi_task *task = session->cmds[cmd_i];
+-		struct iscsi_tcp_task *tcp_task = task->dd_data;
++	        struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
++		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 
+ 		/*
+ 		 * pre-allocated x4 as much r2ts to handle race when
+@@ -1716,16 +1716,16 @@ iscsi_r2tpool_alloc(struct iscsi_session
+ 		 */
+ 
+ 		/* R2T pool */
+-		if (iscsi_pool_init(&tcp_task->r2tpool, session->max_r2t * 4, NULL,
++		if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, NULL,
+ 				    sizeof(struct iscsi_r2t_info))) {
+ 			goto r2t_alloc_fail;
+ 		}
+ 
+ 		/* R2T xmit queue */
+-		tcp_task->r2tqueue = kfifo_alloc(
++		tcp_ctask->r2tqueue = kfifo_alloc(
+ 		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
+-		if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) {
+-			iscsi_pool_free(&tcp_task->r2tpool);
++		if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
++			iscsi_pool_free(&tcp_ctask->r2tpool);
+ 			goto r2t_alloc_fail;
+ 		}
+ 	}
+@@ -1734,11 +1734,11 @@ iscsi_r2tpool_alloc(struct iscsi_session
+ 
+ r2t_alloc_fail:
+ 	for (i = 0; i < cmd_i; i++) {
+-		struct iscsi_task *task = session->cmds[i];
+-		struct iscsi_tcp_task *tcp_task = task->dd_data;
++		struct iscsi_cmd_task *ctask = session->cmds[i];
++		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 
+-		kfifo_free(tcp_task->r2tqueue);
+-		iscsi_pool_free(&tcp_task->r2tpool);
++		kfifo_free(tcp_ctask->r2tqueue);
++		iscsi_pool_free(&tcp_ctask->r2tpool);
+ 	}
+ 	return -ENOMEM;
+ }
+@@ -1749,11 +1749,11 @@ iscsi_r2tpool_free(struct iscsi_session 
+ 	int i;
+ 
+ 	for (i = 0; i < session->cmds_max; i++) {
+-		struct iscsi_task *task = session->cmds[i];
+-		struct iscsi_tcp_task *tcp_task = task->dd_data;
++		struct iscsi_cmd_task *ctask = session->cmds[i];
++		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ 
+-		kfifo_free(tcp_task->r2tqueue);
+-		iscsi_pool_free(&tcp_task->r2tpool);
++		kfifo_free(tcp_ctask->r2tqueue);
++		iscsi_pool_free(&tcp_ctask->r2tpool);
+ 	}
+ }
+ 
+@@ -1818,6 +1818,29 @@ iscsi_tcp_conn_get_param(struct iscsi_cl
+ 	return len;
+ }
+ 
++static int
++iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
++			 char *buf)
++{
++        struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
++	int len;
++
++	switch (param) {
++	case ISCSI_HOST_PARAM_IPADDRESS:
++		spin_lock_bh(&session->lock);
++		if (!session->leadconn)
++			len = -ENODEV;
++		else
++			len = sprintf(buf, "%s\n",
++				     session->leadconn->local_address);
++		spin_unlock_bh(&session->lock);
++		break;
++	default:
++		return iscsi_host_get_param(shost, param, buf);
++	}
++	return len;
++}
++
+ static void
+ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
+ {
+@@ -1843,70 +1866,54 @@ iscsi_conn_get_stats(struct iscsi_cls_co
+ }
+ 
+ static struct iscsi_cls_session *
+-iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
+-			 uint16_t qdepth, uint32_t initial_cmdsn,
+-			 uint32_t *hostno)
++iscsi_tcp_session_create(struct iscsi_transport *iscsit,
++			 struct scsi_transport_template *scsit,
++			 uint16_t cmds_max, uint16_t qdepth,
++			 uint32_t initial_cmdsn, uint32_t *hostno)
+ {
+ 	struct iscsi_cls_session *cls_session;
+ 	struct iscsi_session *session;
+-	struct Scsi_Host *shost;
++	uint32_t hn;
+ 	int cmd_i;
+ 
+-	if (ep) {
+-		printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep);
+-		return NULL;
+-	}
+-
+-	shost = iscsi_host_alloc(&iscsi_sht, 0, qdepth);
+-	if (!shost)
+-		return NULL;
+-	shost->transportt = iscsi_tcp_scsi_transport;
+-	shost->max_lun = iscsi_max_lun;
+-	shost->max_id = 0;
+-	shost->max_channel = 0;
+-	shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE;
+-
+-	if (iscsi_host_add(shost, NULL))
+-		goto free_host;
+-	*hostno = shost->host_no;
+-
+-	cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max,
+-					  sizeof(struct iscsi_tcp_task),
+-					  initial_cmdsn, 0);
++	cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
++					 sizeof(struct iscsi_tcp_cmd_task),
++					 sizeof(struct iscsi_tcp_mgmt_task),
++					 initial_cmdsn, &hn);
+ 	if (!cls_session)
+-		goto remove_host;
+-	session = cls_session->dd_data;
++		return NULL;
++	*hostno = hn;
+ 
+-	shost->can_queue = session->scsi_cmds_max;
++	session = class_to_transport_session(cls_session);
+ 	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
+-		struct iscsi_task *task = session->cmds[cmd_i];
+-		struct iscsi_tcp_task *tcp_task = task->dd_data;
++		struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
++		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
++
++		ctask->hdr = &tcp_ctask->hdr.cmd_hdr;
++		ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE;
++	}
++
++	for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
++		struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
++		struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
+ 
+-		task->hdr = &tcp_task->hdr.cmd_hdr;
+-		task->hdr_max = sizeof(tcp_task->hdr) - ISCSI_DIGEST_SIZE;
++		mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr;
+ 	}
+ 
+-	if (iscsi_r2tpool_alloc(session))
+-		goto remove_session;
++	if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session)))
++		goto r2tpool_alloc_fail;
++
+ 	return cls_session;
+ 
+-remove_session:
++r2tpool_alloc_fail:
+ 	iscsi_session_teardown(cls_session);
+-remove_host:
+-	iscsi_host_remove(shost);
+-free_host:
+-	iscsi_host_free(shost);
+ 	return NULL;
+ }
+ 
+ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
+ {
+-	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+-
+-	iscsi_r2tpool_free(cls_session->dd_data);
+-
+-	iscsi_host_remove(shost);
+-	iscsi_host_free(shost);
++	iscsi_r2tpool_free(class_to_transport_session(cls_session));
++	iscsi_session_teardown(cls_session);
+ }
+ 
+ static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
+@@ -1961,11 +1968,14 @@ static struct iscsi_transport iscsi_tcp_
+ 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
+ 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+ 				  ISCSI_LU_RESET_TMO |
+-				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
+-				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
++				  ISCSI_PING_TMO | ISCSI_RECV_TMO,
+ 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
+ 				  ISCSI_HOST_INITIATOR_NAME |
+ 				  ISCSI_HOST_NETDEV_NAME,
++	.host_template		= &iscsi_sht,
++	.conndata_size		= sizeof(struct iscsi_conn),
++	.max_conn		= 1,
++	.max_cmd_len		= 16,
+ 	/* session management */
+ 	.create_session		= iscsi_tcp_session_create,
+ 	.destroy_session	= iscsi_tcp_session_destroy,
+@@ -1979,14 +1989,16 @@ static struct iscsi_transport iscsi_tcp_
+ 	.start_conn		= iscsi_conn_start,
+ 	.stop_conn		= iscsi_tcp_conn_stop,
+ 	/* iscsi host params */
+-	.get_host_param		= iscsi_host_get_param,
++	.get_host_param		= iscsi_tcp_host_get_param,
+ 	.set_host_param		= iscsi_host_set_param,
+ 	/* IO */
+ 	.send_pdu		= iscsi_conn_send_pdu,
+ 	.get_stats		= iscsi_conn_get_stats,
+-	.init_task		= iscsi_tcp_task_init,
+-	.xmit_task		= iscsi_tcp_task_xmit,
+-	.cleanup_task		= iscsi_tcp_cleanup_task,
++	.init_cmd_task		= iscsi_tcp_ctask_init,
++	.init_mgmt_task		= iscsi_tcp_mtask_init,
++	.xmit_cmd_task		= iscsi_tcp_ctask_xmit,
++	.xmit_mgmt_task		= iscsi_tcp_mtask_xmit,
++	.cleanup_cmd_task	= iscsi_tcp_cleanup_ctask,
+ 	/* recovery */
+ 	.session_recovery_timedout = iscsi_session_recovery_timedout,
+ };
+@@ -1999,10 +2011,9 @@ iscsi_tcp_init(void)
+ 		       iscsi_max_lun);
+ 		return -EINVAL;
+ 	}
++	iscsi_tcp_transport.max_lun = iscsi_max_lun;
+ 
+-	iscsi_tcp_scsi_transport = iscsi_register_transport(
+-							&iscsi_tcp_transport);
+-	if (!iscsi_tcp_scsi_transport)
++	if (!iscsi_register_transport(&iscsi_tcp_transport))
+ 		return -ENODEV;
+ 
+ 	return 0;
+Index: ofed_kernel/drivers/scsi/iscsi_tcp.h
+===================================================================
+--- ofed_kernel.orig/drivers/scsi/iscsi_tcp.h
++++ ofed_kernel/drivers/scsi/iscsi_tcp.h
+@@ -103,6 +103,11 @@ struct iscsi_data_task {
+ 	char			hdrext[ISCSI_DIGEST_SIZE];/* Header-Digest */
+ };
+ 
++struct iscsi_tcp_mgmt_task {
++	struct iscsi_hdr	hdr;
++	char			hdrext[ISCSI_DIGEST_SIZE]; /* Header-Digest */
++};
++
+ struct iscsi_r2t_info {
+ 	__be32			ttt;		/* copied from R2T */
+ 	__be32			exp_statsn;	/* copied from R2T */
+@@ -114,7 +119,7 @@ struct iscsi_r2t_info {
+ 	struct iscsi_data_task	dtask;		/* Data-Out header buf */
+ };
+ 
+-struct iscsi_tcp_task {
++struct iscsi_tcp_cmd_task {
+ 	struct iscsi_hdr_buff {
+ 		struct iscsi_cmd	cmd_hdr;
+ 		char			hdrextbuf[ISCSI_MAX_AHS_SIZE +
+Index: ofed_kernel/drivers/scsi/libiscsi.c
+===================================================================
+--- ofed_kernel.orig/drivers/scsi/libiscsi.c
++++ ofed_kernel/drivers/scsi/libiscsi.c
+@@ -38,6 +38,14 @@
+ #include <scsi/scsi_transport_iscsi.h>
+ #include <scsi/libiscsi.h>
+ 
++struct iscsi_session *
++class_to_transport_session(struct iscsi_cls_session *cls_session)
++{
++	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
++	return iscsi_hostdata(shost->hostdata);
++}
++EXPORT_SYMBOL_GPL(class_to_transport_session);
++
+ /* Serial Number Arithmetic, 32 bits, less than, RFC1982 */
+ #define SNA32_CHECK 2147483648UL
+ 
+@@ -79,170 +87,91 @@ iscsi_update_cmdsn(struct iscsi_session 
+ 		 * xmit thread
+ 		 */
+ 		if (!list_empty(&session->leadconn->xmitqueue) ||
+-		    !list_empty(&session->leadconn->mgmtqueue)) {
+-			if (!(session->tt->caps & CAP_DATA_PATH_OFFLOAD))
+-				scsi_queue_work(session->host,
+-						&session->leadconn->xmitwork);
+-		}
++		    !list_empty(&session->leadconn->mgmtqueue))
++			scsi_queue_work(session->host,
++					&session->leadconn->xmitwork);
+ 	}
+ }
+ EXPORT_SYMBOL_GPL(iscsi_update_cmdsn);
+ 
+-void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *task,
++void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
+ 				   struct iscsi_data *hdr)
+ {
+-	struct iscsi_conn *conn = task->conn;
++	struct iscsi_conn *conn = ctask->conn;
+ 
+ 	memset(hdr, 0, sizeof(struct iscsi_data));
+ 	hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
+-	hdr->datasn = cpu_to_be32(task->unsol_datasn);
+-	task->unsol_datasn++;
++	hdr->datasn = cpu_to_be32(ctask->unsol_datasn);
++	ctask->unsol_datasn++;
+ 	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+-	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
++	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
+ 
+-	hdr->itt = task->hdr->itt;
++	hdr->itt = ctask->hdr->itt;
+ 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
+-	hdr->offset = cpu_to_be32(task->unsol_offset);
++	hdr->offset = cpu_to_be32(ctask->unsol_offset);
+ 
+-	if (task->unsol_count > conn->max_xmit_dlength) {
++	if (ctask->unsol_count > conn->max_xmit_dlength) {
+ 		hton24(hdr->dlength, conn->max_xmit_dlength);
+-		task->data_count = conn->max_xmit_dlength;
+-		task->unsol_offset += task->data_count;
++		ctask->data_count = conn->max_xmit_dlength;
++		ctask->unsol_offset += ctask->data_count;
+ 		hdr->flags = 0;
+ 	} else {
+-		hton24(hdr->dlength, task->unsol_count);
+-		task->data_count = task->unsol_count;
++		hton24(hdr->dlength, ctask->unsol_count);
++		ctask->data_count = ctask->unsol_count;
+ 		hdr->flags = ISCSI_FLAG_CMD_FINAL;
+ 	}
+ }
+ EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu);
+ 
+-static int iscsi_add_hdr(struct iscsi_task *task, unsigned len)
++static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len)
+ {
+-	unsigned exp_len = task->hdr_len + len;
++	unsigned exp_len = ctask->hdr_len + len;
+ 
+-	if (exp_len > task->hdr_max) {
++	if (exp_len > ctask->hdr_max) {
+ 		WARN_ON(1);
+ 		return -EINVAL;
+ 	}
+ 
+ 	WARN_ON(len & (ISCSI_PAD_LEN - 1)); /* caller must pad the AHS */
+-	task->hdr_len = exp_len;
+-	return 0;
+-}
+-
+-/*
+- * make an extended cdb AHS
+- */
+-static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
+-{
+-	struct scsi_cmnd *cmd = task->sc;
+-	unsigned rlen, pad_len;
+-	unsigned short ahslength;
+-	struct iscsi_ecdb_ahdr *ecdb_ahdr;
+-	int rc;
+-
+-	ecdb_ahdr = iscsi_next_hdr(task);
+-	rlen = cmd->cmd_len - ISCSI_CDB_SIZE;
+-
+-	BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb));
+-	ahslength = rlen + sizeof(ecdb_ahdr->reserved);
+-
+-	pad_len = iscsi_padding(rlen);
+-
+-	rc = iscsi_add_hdr(task, sizeof(ecdb_ahdr->ahslength) +
+-	                   sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len);
+-	if (rc)
+-		return rc;
+-
+-	if (pad_len)
+-		memset(&ecdb_ahdr->ecdb[rlen], 0, pad_len);
+-
+-	ecdb_ahdr->ahslength = cpu_to_be16(ahslength);
+-	ecdb_ahdr->ahstype = ISCSI_AHSTYPE_CDB;
+-	ecdb_ahdr->reserved = 0;
+-	memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen);
+-
+-	debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d "
+-		   "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n",
+-		   cmd->cmd_len, rlen, pad_len, ahslength, task->hdr_len);
+-
+-	return 0;
+-}
+-
+-static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
+-{
+-	struct scsi_cmnd *sc = task->sc;
+-	struct iscsi_rlength_ahdr *rlen_ahdr;
+-	int rc;
+-
+-	rlen_ahdr = iscsi_next_hdr(task);
+-	rc = iscsi_add_hdr(task, sizeof(*rlen_ahdr));
+-	if (rc)
+-		return rc;
+-
+-	rlen_ahdr->ahslength =
+-		cpu_to_be16(sizeof(rlen_ahdr->read_length) +
+-						  sizeof(rlen_ahdr->reserved));
+-	rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
+-	rlen_ahdr->reserved = 0;
+-	rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
+-
+-	debug_scsi("bidi-in rlen_ahdr->read_length(%d) "
+-		   "rlen_ahdr->ahslength(%d)\n",
+-		   be32_to_cpu(rlen_ahdr->read_length),
+-		   be16_to_cpu(rlen_ahdr->ahslength));
++	ctask->hdr_len = exp_len;
+ 	return 0;
+ }
+ 
+ /**
+  * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
+- * @task: iscsi task
++ * @ctask: iscsi cmd task
+  *
+  * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set
+  * fields like dlength or final based on how much data it sends
+  */
+-static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
++static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_conn *conn = task->conn;
++	struct iscsi_conn *conn = ctask->conn;
+ 	struct iscsi_session *session = conn->session;
+-	struct iscsi_cmd *hdr = task->hdr;
+-	struct scsi_cmnd *sc = task->sc;
+-	unsigned hdrlength, cmd_len;
++	struct iscsi_cmd *hdr = ctask->hdr;
++	struct scsi_cmnd *sc = ctask->sc;
++	unsigned hdrlength;
+ 	int rc;
+ 
+-	task->hdr_len = 0;
+-	rc = iscsi_add_hdr(task, sizeof(*hdr));
++	ctask->hdr_len = 0;
++	rc = iscsi_add_hdr(ctask, sizeof(*hdr));
+ 	if (rc)
+ 		return rc;
+ 	hdr->opcode = ISCSI_OP_SCSI_CMD;
+ 	hdr->flags = ISCSI_ATTR_SIMPLE;
+ 	int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
+-	hdr->itt = build_itt(task->itt, session->age);
++	hdr->itt = build_itt(ctask->itt, session->age);
++	hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
+ 	hdr->cmdsn = cpu_to_be32(session->cmdsn);
+ 	session->cmdsn++;
+ 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
+-	cmd_len = sc->cmd_len;
+-	if (cmd_len < ISCSI_CDB_SIZE)
+-		memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len);
+-	else if (cmd_len > ISCSI_CDB_SIZE) {
+-		rc = iscsi_prep_ecdb_ahs(task);
+-		if (rc)
+-			return rc;
+-		cmd_len = ISCSI_CDB_SIZE;
+-	}
+-	memcpy(hdr->cdb, sc->cmnd, cmd_len);
++	memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
++	if (sc->cmd_len < MAX_COMMAND_SIZE)
++		memset(&hdr->cdb[sc->cmd_len], 0,
++			MAX_COMMAND_SIZE - sc->cmd_len);
+ 
+-	task->imm_count = 0;
+-	if (scsi_bidi_cmnd(sc)) {
+-		hdr->flags |= ISCSI_FLAG_CMD_READ;
+-		rc = iscsi_prep_bidi_ahs(task);
+-		if (rc)
+-			return rc;
+-	}
++	ctask->imm_count = 0;
+ 	if (sc->sc_data_direction == DMA_TO_DEVICE) {
+-		unsigned out_len = scsi_out(sc)->length;
+-		hdr->data_length = cpu_to_be32(out_len);
+ 		hdr->flags |= ISCSI_FLAG_CMD_WRITE;
+ 		/*
+ 		 * Write counters:
+@@ -258,41 +187,40 @@ static int iscsi_prep_scsi_cmd_pdu(struc
+ 		 *
+ 		 *      pad_count       bytes to be sent as zero-padding
+ 		 */
+-		task->unsol_count = 0;
+-		task->unsol_offset = 0;
+-		task->unsol_datasn = 0;
++		ctask->unsol_count = 0;
++		ctask->unsol_offset = 0;
++		ctask->unsol_datasn = 0;
+ 
+ 		if (session->imm_data_en) {
+-			if (out_len >= session->first_burst)
+-				task->imm_count = min(session->first_burst,
++			if (scsi_bufflen(sc) >= session->first_burst)
++				ctask->imm_count = min(session->first_burst,
+ 							conn->max_xmit_dlength);
+ 			else
+-				task->imm_count = min(out_len,
++				ctask->imm_count = min(scsi_bufflen(sc),
+ 							conn->max_xmit_dlength);
+-			hton24(hdr->dlength, task->imm_count);
++			hton24(hdr->dlength, ctask->imm_count);
+ 		} else
+ 			zero_data(hdr->dlength);
+ 
+ 		if (!session->initial_r2t_en) {
+-			task->unsol_count = min(session->first_burst, out_len)
+-							     - task->imm_count;
+-			task->unsol_offset = task->imm_count;
++			ctask->unsol_count = min((session->first_burst),
++				(scsi_bufflen(sc))) - ctask->imm_count;
++			ctask->unsol_offset = ctask->imm_count;
+ 		}
+ 
+-		if (!task->unsol_count)
++		if (!ctask->unsol_count)
+ 			/* No unsolicit Data-Out's */
+ 			hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+ 	} else {
+ 		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+ 		zero_data(hdr->dlength);
+-		hdr->data_length = cpu_to_be32(scsi_in(sc)->length);
+ 
+ 		if (sc->sc_data_direction == DMA_FROM_DEVICE)
+ 			hdr->flags |= ISCSI_FLAG_CMD_READ;
+ 	}
+ 
+ 	/* calculate size of additional header segments (AHSs) */
+-	hdrlength = task->hdr_len - sizeof(*hdr);
++	hdrlength = ctask->hdr_len - sizeof(*hdr);
+ 
+ 	WARN_ON(hdrlength & (ISCSI_PAD_LEN-1));
+ 	hdrlength /= ISCSI_PAD_LEN;
+@@ -300,180 +228,110 @@ static int iscsi_prep_scsi_cmd_pdu(struc
+ 	WARN_ON(hdrlength >= 256);
+ 	hdr->hlength = hdrlength & 0xFF;
+ 
+-	if (conn->session->tt->init_task &&
+-	    conn->session->tt->init_task(task))
+-		return -EIO;
+-
+-	task->state = ISCSI_TASK_RUNNING;
+-	list_move_tail(&task->running, &conn->run_list);
++	if (conn->session->tt->init_cmd_task(conn->ctask))
++		return EIO;
+ 
+ 	conn->scsicmd_pdus_cnt++;
+ 	debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d "
+-		   "bidi_len %d cmdsn %d win %d]\n", scsi_bidi_cmnd(sc) ?
+-		   "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ?
+-		   "write" : "read", conn->id, sc, sc->cmnd[0], task->itt,
+-		   scsi_bufflen(sc),
+-		   scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
+-		   session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
++		"cmdsn %d win %d]\n",
++		sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
++		conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc),
++		session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
+ 	return 0;
+ }
+ 
+ /**
+- * iscsi_complete_command - finish a task
+- * @task: iscsi cmd task
++ * iscsi_complete_command - return command back to scsi-ml
++ * @ctask: iscsi cmd task
+  *
+  * Must be called with session lock.
+- * This function returns the scsi command to scsi-ml or cleans
+- * up mgmt tasks then returns the task to the pool.
++ * This function returns the scsi command to scsi-ml and returns
++ * the cmd task to the pool of available cmd tasks.
+  */
+-static void iscsi_complete_command(struct iscsi_task *task)
++static void iscsi_complete_command(struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_conn *conn = task->conn;
++	struct iscsi_conn *conn = ctask->conn;
+ 	struct iscsi_session *session = conn->session;
+-	struct scsi_cmnd *sc = task->sc;
+-
+-	list_del_init(&task->running);
+-	task->state = ISCSI_TASK_COMPLETED;
+-	task->sc = NULL;
+-
+-	if (conn->task == task)
+-		conn->task = NULL;
+-	/*
+-	 * login task is preallocated so do not free
+-	 */
+-	if (conn->login_task == task)
+-		return;
+-
+-	__kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*));
+-
+-	if (conn->ping_task == task)
+-		conn->ping_task = NULL;
++	struct scsi_cmnd *sc = ctask->sc;
+ 
+-	if (sc) {
+-		task->sc = NULL;
+-		/* SCSI eh reuses commands to verify us */
+-		sc->SCp.ptr = NULL;
+-		/*
+-		 * queue command may call this to free the task, but
+-		 * not have setup the sc callback
+-		 */
+-		if (sc->scsi_done)
+-			sc->scsi_done(sc);
+-	}
++	ctask->state = ISCSI_TASK_COMPLETED;
++	ctask->sc = NULL;
++	/* SCSI eh reuses commands to verify us */
++	sc->SCp.ptr = NULL;
++	if (conn->ctask == ctask)
++		conn->ctask = NULL;
++	list_del_init(&ctask->running);
++	__kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
++	sc->scsi_done(sc);
+ }
+ 
+-void __iscsi_get_task(struct iscsi_task *task)
++static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask)
+ {
+-	atomic_inc(&task->refcount);
++	atomic_inc(&ctask->refcount);
+ }
+-EXPORT_SYMBOL_GPL(__iscsi_get_task);
+ 
+-static void __iscsi_put_task(struct iscsi_task *task)
++static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask)
+ {
+-	if (atomic_dec_and_test(&task->refcount))
+-		iscsi_complete_command(task);
++	if (atomic_dec_and_test(&ctask->refcount))
++		iscsi_complete_command(ctask);
+ }
+ 
+-void iscsi_put_task(struct iscsi_task *task)
+-{
+-	struct iscsi_session *session = task->conn->session;
+-
+-	spin_lock_bh(&session->lock);
+-	__iscsi_put_task(task);
+-	spin_unlock_bh(&session->lock);
+-}
+-EXPORT_SYMBOL_GPL(iscsi_put_task);
+-
+ /*
+  * session lock must be held
+  */
+-static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task,
++static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ 			 int err)
+ {
+ 	struct scsi_cmnd *sc;
+ 
+-	sc = task->sc;
++	sc = ctask->sc;
+ 	if (!sc)
+ 		return;
+ 
+-	if (task->state == ISCSI_TASK_PENDING)
++	if (ctask->state == ISCSI_TASK_PENDING)
+ 		/*
+ 		 * cmd never made it to the xmit thread, so we should not count
+ 		 * the cmd in the sequencing
+ 		 */
+ 		conn->session->queued_cmdsn--;
+ 	else
+-		conn->session->tt->cleanup_task(conn, task);
+-	/*
+-	 * Check if cleanup_task dropped the lock and the command completed,
+-	 */
+-	if (!task->sc)
+-		return;
++		conn->session->tt->cleanup_cmd_task(conn, ctask);
+ 
+ 	sc->result = err;
+-	if (!scsi_bidi_cmnd(sc))
+-		scsi_set_resid(sc, scsi_bufflen(sc));
+-	else {
+-		scsi_out(sc)->resid = scsi_out(sc)->length;
+-		scsi_in(sc)->resid = scsi_in(sc)->length;
+-	}
+-
+-	if (conn->task == task)
+-		conn->task = NULL;
++	scsi_set_resid(sc, scsi_bufflen(sc));
++	if (conn->ctask == ctask)
++		conn->ctask = NULL;
+ 	/* release ref from queuecommand */
+-	__iscsi_put_task(task);
++	__iscsi_put_ctask(ctask);
+ }
+ 
+-static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
+-				struct iscsi_task *task)
++/**
++ * iscsi_free_mgmt_task - return mgmt task back to pool
++ * @conn: iscsi connection
++ * @mtask: mtask
++ *
++ * Must be called with session lock.
++ */
++void iscsi_free_mgmt_task(struct iscsi_conn *conn,
++			  struct iscsi_mgmt_task *mtask)
+ {
+-	struct iscsi_session *session = conn->session;
+-	struct iscsi_hdr *hdr = (struct iscsi_hdr *)task->hdr;
+-	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
+-
+-	if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
+-		return -ENOTCONN;
+-
+-	if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) &&
+-	    hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+-		nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
+-	/*
+-	 * pre-format CmdSN for outgoing PDU.
+-	 */
+-	nop->cmdsn = cpu_to_be32(session->cmdsn);
+-	if (hdr->itt != RESERVED_ITT) {
+-		hdr->itt = build_itt(task->itt, session->age);
+-		/*
+-		 * TODO: We always use immediate, so we never hit this.
+-		 * If we start to send tmfs or nops as non-immediate then
+-		 * we should start checking the cmdsn numbers for mgmt tasks.
+-		 */
+-		if (conn->c_stage == ISCSI_CONN_STARTED &&
+-		    !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+-			session->queued_cmdsn++;
+-			session->cmdsn++;
+-		}
+-	}
+-
+-	if (session->tt->init_task)
+-		session->tt->init_task(task);
+-
+-	if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
+-		session->state = ISCSI_STATE_LOGGING_OUT;
++	list_del_init(&mtask->running);
++	if (conn->login_mtask == mtask)
++		return;
+ 
+-	list_move_tail(&task->running, &conn->mgmt_run_list);
+-	debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
+-		   hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt,
+-		   task->data_count);
+-	return 0;
++	if (conn->ping_mtask == mtask)
++		conn->ping_mtask = NULL;
++	__kfifo_put(conn->session->mgmtpool.queue,
++		    (void*)&mtask, sizeof(void*));
+ }
++EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task);
+ 
+-static struct iscsi_task *
++static struct iscsi_mgmt_task *
+ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ 		      char *data, uint32_t data_size)
+ {
+ 	struct iscsi_session *session = conn->session;
+-	struct iscsi_task *task;
++	struct iscsi_mgmt_task *mtask;
+ 
+ 	if (session->state == ISCSI_STATE_TERMINATE)
+ 		return NULL;
+@@ -483,56 +341,29 @@ __iscsi_conn_send_pdu(struct iscsi_conn 
+ 		/*
+ 		 * Login and Text are sent serially, in
+ 		 * request-followed-by-response sequence.
+-		 * Same task can be used. Same ITT must be used.
+-		 * Note that login_task is preallocated at conn_create().
++		 * Same mtask can be used. Same ITT must be used.
++		 * Note that login_mtask is preallocated at conn_create().
+ 		 */
+-		task = conn->login_task;
++		mtask = conn->login_mtask;
+ 	else {
+ 		BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
+ 		BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
+ 
+-		if (!__kfifo_get(session->cmdpool.queue,
+-				 (void*)&task, sizeof(void*)))
++		if (!__kfifo_get(session->mgmtpool.queue,
++				 (void*)&mtask, sizeof(void*)))
+ 			return NULL;
+-
+-		if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) &&
+-		     hdr->ttt == RESERVED_ITT) {
+-			conn->ping_task = task;
+-			conn->last_ping = jiffies;
+-		}
+ 	}
+-	/*
+-	 * released in complete pdu for task we expect a response for, and
+-	 * released by the lld when it has transmitted the task for
+-	 * pdus we do not expect a response for.
+-	 */
+-	atomic_set(&task->refcount, 1);
+-	task->conn = conn;
+-	task->sc = NULL;
+ 
+ 	if (data_size) {
+-		memcpy(task->data, data, data_size);
+-		task->data_count = data_size;
++		memcpy(mtask->data, data, data_size);
++		mtask->data_count = data_size;
+ 	} else
+-		task->data_count = 0;
+-
+-	memcpy(task->hdr, hdr, sizeof(struct iscsi_hdr));
+-	INIT_LIST_HEAD(&task->running);
+-	list_add_tail(&task->running, &conn->mgmtqueue);
+-
+-	if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) {
+-		if (iscsi_prep_mgmt_task(conn, task)) {
+-			__iscsi_put_task(task);
+-			return NULL;
+-		}
+-
+-		if (session->tt->xmit_task(task))
+-			task = NULL;
++		mtask->data_count = 0;
+ 
+-	} else
+-		scsi_queue_work(conn->session->host, &conn->xmitwork);
+-
+-	return task;
++	memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr));
++	INIT_LIST_HEAD(&mtask->running);
++	list_add_tail(&mtask->running, &conn->mgmtqueue);
++	return mtask;
+ }
+ 
+ int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
+@@ -546,6 +377,7 @@ int iscsi_conn_send_pdu(struct iscsi_cls
+ 	if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
+ 		err = -EPERM;
+ 	spin_unlock_bh(&session->lock);
++	scsi_queue_work(session->host, &conn->xmitwork);
+ 	return err;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
+@@ -554,7 +386,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
+  * iscsi_cmd_rsp - SCSI Command Response processing
+  * @conn: iscsi connection
+  * @hdr: iscsi header
+- * @task: scsi command task
++ * @ctask: scsi command task
+  * @data: cmd data buffer
+  * @datalen: len of buffer
+  *
+@@ -562,12 +394,12 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
+  * then completes the command and task.
+  **/
+ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+-			       struct iscsi_task *task, char *data,
++			       struct iscsi_cmd_task *ctask, char *data,
+ 			       int datalen)
+ {
+ 	struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)hdr;
+ 	struct iscsi_session *session = conn->session;
+-	struct scsi_cmnd *sc = task->sc;
++	struct scsi_cmnd *sc = ctask->sc;
+ 
+ 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ 	conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
+@@ -591,7 +423,7 @@ invalid_datalen:
+ 			goto out;
+ 		}
+ 
+-		senselen = get_unaligned_be16(data);
++		senselen = be16_to_cpu(get_unaligned((__be16 *) data));
+ 		if (datalen < senselen)
+ 			goto invalid_datalen;
+ 
+@@ -601,18 +433,6 @@ invalid_datalen:
+ 			   min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
+ 	}
+ 
+-	if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
+-			   ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
+-		int res_count = be32_to_cpu(rhdr->bi_residual_count);
+-
+-		if (scsi_bidi_cmnd(sc) && res_count > 0 &&
+-				(rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
+-				 res_count <= scsi_in(sc)->length))
+-			scsi_in(sc)->resid = res_count;
+-		else
+-			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+-	}
+-
+ 	if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
+ 	                   ISCSI_FLAG_CMD_OVERFLOW)) {
+ 		int res_count = be32_to_cpu(rhdr->residual_count);
+@@ -620,17 +440,19 @@ invalid_datalen:
+ 		if (res_count > 0 &&
+ 		    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
+ 		     res_count <= scsi_bufflen(sc)))
+-			/* write side for bidi or uni-io set_resid */
+ 			scsi_set_resid(sc, res_count);
+ 		else
+ 			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+-	}
++	} else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
++	                          ISCSI_FLAG_CMD_BIDI_OVERFLOW))
++		sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
++
+ out:
+ 	debug_scsi("done [sc %lx res %d itt 0x%x]\n",
+-		   (long)sc, sc->result, task->itt);
++		   (long)sc, sc->result, ctask->itt);
+ 	conn->scsirsp_pdus_cnt++;
+ 
+-	__iscsi_put_task(task);
++	__iscsi_put_ctask(ctask);
+ }
+ 
+ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
+@@ -655,9 +477,9 @@ static void iscsi_tmf_rsp(struct iscsi_c
+ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
+ {
+         struct iscsi_nopout hdr;
+-	struct iscsi_task *task;
++	struct iscsi_mgmt_task *mtask;
+ 
+-	if (!rhdr && conn->ping_task)
++	if (!rhdr && conn->ping_mtask)
+ 		return;
+ 
+ 	memset(&hdr, 0, sizeof(struct iscsi_nopout));
+@@ -671,9 +493,18 @@ static void iscsi_send_nopout(struct isc
+ 	} else
+ 		hdr.ttt = RESERVED_ITT;
+ 
+-	task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
+-	if (!task)
++	mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
++	if (!mtask) {
+ 		iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
++		return;
++	}
++
++	/* only track our nops */
++	if (!rhdr) {
++		conn->ping_mtask = mtask;
++		conn->last_ping = jiffies;
++	}
++	scsi_queue_work(conn->session->host, &conn->xmitwork);
+ }
+ 
+ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+@@ -702,31 +533,6 @@ static int iscsi_handle_reject(struct is
+ }
+ 
+ /**
+- * iscsi_itt_to_task - look up task by itt
+- * @conn: iscsi connection
+- * @itt: itt
+- *
+- * This should be used for mgmt tasks like login and nops, or if
+- * the LDD's itt space does not include the session age.
+- *
+- * The session lock must be held.
+- */
+-static struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt)
+-{
+-	struct iscsi_session *session = conn->session;
+-	uint32_t i;
+-
+-	if (itt == RESERVED_ITT)
+-		return NULL;
+-
+-	i = get_itt(itt);
+-	if (i >= session->cmds_max)
+-		return NULL;
+-
+-	return session->cmds[i];
+-}
+-
+-/**
+  * __iscsi_complete_pdu - complete pdu
+  * @conn: iscsi conn
+  * @hdr: iscsi header
+@@ -737,28 +543,108 @@ static struct iscsi_task *iscsi_itt_to_t
+  * queuecommand or send generic. session lock must be held and verify
+  * itt must have been called.
+  */
+-int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+-			 char *data, int datalen)
++static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
++				char *data, int datalen)
+ {
+ 	struct iscsi_session *session = conn->session;
+ 	int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0;
+-	struct iscsi_task *task;
++	struct iscsi_cmd_task *ctask;
++	struct iscsi_mgmt_task *mtask;
+ 	uint32_t itt;
+ 
+ 	conn->last_recv = jiffies;
+-	rc = iscsi_verify_itt(conn, hdr->itt);
+-	if (rc)
+-		return rc;
+-
+ 	if (hdr->itt != RESERVED_ITT)
+ 		itt = get_itt(hdr->itt);
+ 	else
+ 		itt = ~0U;
+ 
+-	debug_scsi("[op 0x%x cid %d itt 0x%x len %d]\n",
+-		   opcode, conn->id, itt, datalen);
++	if (itt < session->cmds_max) {
++		ctask = session->cmds[itt];
++
++		debug_scsi("cmdrsp [op 0x%x cid %d itt 0x%x len %d]\n",
++			   opcode, conn->id, ctask->itt, datalen);
++
++		switch(opcode) {
++		case ISCSI_OP_SCSI_CMD_RSP:
++			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
++			iscsi_scsi_cmd_rsp(conn, hdr, ctask, data,
++					   datalen);
++			break;
++		case ISCSI_OP_SCSI_DATA_IN:
++			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
++			if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
++				conn->scsirsp_pdus_cnt++;
++				__iscsi_put_ctask(ctask);
++			}
++			break;
++		case ISCSI_OP_R2T:
++			/* LLD handles this for now */
++			break;
++		default:
++			rc = ISCSI_ERR_BAD_OPCODE;
++			break;
++		}
++	} else if (itt >= ISCSI_MGMT_ITT_OFFSET &&
++		   itt < ISCSI_MGMT_ITT_OFFSET + session->mgmtpool_max) {
++		mtask = session->mgmt_cmds[itt - ISCSI_MGMT_ITT_OFFSET];
++
++		debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
++			   opcode, conn->id, mtask->itt, datalen);
++
++		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
++		switch(opcode) {
++		case ISCSI_OP_LOGOUT_RSP:
++			if (datalen) {
++				rc = ISCSI_ERR_PROTO;
++				break;
++			}
++			conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
++			/* fall through */
++		case ISCSI_OP_LOGIN_RSP:
++		case ISCSI_OP_TEXT_RSP:
++			/*
++			 * login related PDU's exp_statsn is handled in
++			 * userspace
++			 */
++			if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
++				rc = ISCSI_ERR_CONN_FAILED;
++			iscsi_free_mgmt_task(conn, mtask);
++			break;
++		case ISCSI_OP_SCSI_TMFUNC_RSP:
++			if (datalen) {
++				rc = ISCSI_ERR_PROTO;
++				break;
++			}
++
++			iscsi_tmf_rsp(conn, hdr);
++			iscsi_free_mgmt_task(conn, mtask);
++			break;
++		case ISCSI_OP_NOOP_IN:
++			if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) ||
++			    datalen) {
++				rc = ISCSI_ERR_PROTO;
++				break;
++			}
++			conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
+ 
+-	if (itt == ~0U) {
++			if (conn->ping_mtask != mtask) {
++				/*
++				 * If this is not in response to one of our
++				 * nops then it must be from userspace.
++				 */
++				if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
++						   datalen))
++					rc = ISCSI_ERR_CONN_FAILED;
++			} else
++				mod_timer(&conn->transport_timer,
++					  jiffies + conn->recv_timeout);
++			iscsi_free_mgmt_task(conn, mtask);
++			break;
++		default:
++			rc = ISCSI_ERR_BAD_OPCODE;
++			break;
++		}
++	} else if (itt == ~0U) {
+ 		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
+ 
+ 		switch(opcode) {
+@@ -785,104 +671,11 @@ int __iscsi_complete_pdu(struct iscsi_co
+ 			rc = ISCSI_ERR_BAD_OPCODE;
+ 			break;
+ 		}
+-		goto out;
+-	}
+-
+-	switch(opcode) {
+-	case ISCSI_OP_SCSI_CMD_RSP:
+-	case ISCSI_OP_SCSI_DATA_IN:
+-		task = iscsi_itt_to_ctask(conn, hdr->itt);
+-		if (!task)
+-			return ISCSI_ERR_BAD_ITT;
+-		break;
+-	case ISCSI_OP_R2T:
+-		/*
+-		 * LLD handles R2Ts if they need to.
+-		 */
+-		return 0;
+-	case ISCSI_OP_LOGOUT_RSP:
+-	case ISCSI_OP_LOGIN_RSP:
+-	case ISCSI_OP_TEXT_RSP:
+-	case ISCSI_OP_SCSI_TMFUNC_RSP:
+-	case ISCSI_OP_NOOP_IN:
+-		task = iscsi_itt_to_task(conn, hdr->itt);
+-		if (!task)
+-			return ISCSI_ERR_BAD_ITT;
+-		break;
+-	default:
+-		return ISCSI_ERR_BAD_OPCODE;
+-	}
+-
+-	switch(opcode) {
+-	case ISCSI_OP_SCSI_CMD_RSP:
+-		iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen);
+-		break;
+-	case ISCSI_OP_SCSI_DATA_IN:
+-		if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
+-			conn->scsirsp_pdus_cnt++;
+-			iscsi_update_cmdsn(session,
+-					   (struct iscsi_nopin*) hdr);
+-			__iscsi_put_task(task);
+-		}
+-		break;
+-	case ISCSI_OP_LOGOUT_RSP:
+-		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
+-		if (datalen) {
+-			rc = ISCSI_ERR_PROTO;
+-			break;
+-		}
+-		conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
+-		goto recv_pdu;
+-	case ISCSI_OP_LOGIN_RSP:
+-	case ISCSI_OP_TEXT_RSP:
+-		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
+-		/*
+-		 * login related PDU's exp_statsn is handled in
+-		 * userspace
+-		 */
+-		goto recv_pdu;
+-	case ISCSI_OP_SCSI_TMFUNC_RSP:
+-		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
+-		if (datalen) {
+-			rc = ISCSI_ERR_PROTO;
+-			break;
+-		}
+-
+-		iscsi_tmf_rsp(conn, hdr);
+-		__iscsi_put_task(task);
+-		break;
+-	case ISCSI_OP_NOOP_IN:
+-		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
+-		if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) {
+-			rc = ISCSI_ERR_PROTO;
+-			break;
+-		}
+-		conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
+-
+-		if (conn->ping_task != task)
+-			/*
+-			 * If this is not in response to one of our
+-			 * nops then it must be from userspace.
+-			 */
+-			goto recv_pdu;
+-
+-		mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout);
+-		__iscsi_put_task(task);
+-		break;
+-	default:
+-		rc = ISCSI_ERR_BAD_OPCODE;
+-		break;
+-	}
++	} else
++		rc = ISCSI_ERR_BAD_ITT;
+ 
+-out:
+-	return rc;
+-recv_pdu:
+-	if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
+-		rc = ISCSI_ERR_CONN_FAILED;
+-	__iscsi_put_task(task);
+ 	return rc;
+ }
+-EXPORT_SYMBOL_GPL(__iscsi_complete_pdu);
+ 
+ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ 		       char *data, int datalen)
+@@ -896,63 +689,51 @@ int iscsi_complete_pdu(struct iscsi_conn
+ }
+ EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
+ 
+-int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
++/* verify itt (itt encoding: age+cid+itt) */
++int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
++		     uint32_t *ret_itt)
+ {
+ 	struct iscsi_session *session = conn->session;
+-	uint32_t i;
+-
+-	if (itt == RESERVED_ITT)
+-		return 0;
+-
+-	if (((__force u32)itt & ISCSI_AGE_MASK) !=
+-	    (session->age << ISCSI_AGE_SHIFT)) {
+-		iscsi_conn_printk(KERN_ERR, conn,
+-				  "received itt %x expected session age (%x)\n",
+-				  (__force u32)itt, session->age);
+-		return ISCSI_ERR_BAD_ITT;
+-	}
++	struct iscsi_cmd_task *ctask;
++	uint32_t itt;
+ 
+-	i = get_itt(itt);
+-	if (i >= session->cmds_max) {
+-		iscsi_conn_printk(KERN_ERR, conn,
+-				  "received invalid itt index %u (max cmds "
+-				   "%u.\n", i, session->cmds_max);
+-		return ISCSI_ERR_BAD_ITT;
+-	}
+-	return 0;
+-}
+-EXPORT_SYMBOL_GPL(iscsi_verify_itt);
++	if (hdr->itt != RESERVED_ITT) {
++		if (((__force u32)hdr->itt & ISCSI_AGE_MASK) !=
++		    (session->age << ISCSI_AGE_SHIFT)) {
++			iscsi_conn_printk(KERN_ERR, conn,
++					  "received itt %x expected session "
++					  "age (%x)\n", (__force u32)hdr->itt,
++					  session->age & ISCSI_AGE_MASK);
++			return ISCSI_ERR_BAD_ITT;
++		}
+ 
+-/**
+- * iscsi_itt_to_ctask - look up ctask by itt
+- * @conn: iscsi connection
+- * @itt: itt
+- *
+- * This should be used for cmd tasks.
+- *
+- * The session lock must be held.
+- */
+-struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
+-{
+-	struct iscsi_task *task;
++		itt = get_itt(hdr->itt);
++	} else
++		itt = ~0U;
+ 
+-	if (iscsi_verify_itt(conn, itt))
+-		return NULL;
++	if (itt < session->cmds_max) {
++		ctask = session->cmds[itt];
+ 
+-	task = iscsi_itt_to_task(conn, itt);
+-	if (!task || !task->sc)
+-		return NULL;
++		if (!ctask->sc) {
++			iscsi_conn_printk(KERN_INFO, conn, "dropping ctask "
++					  "with itt 0x%x\n", ctask->itt);
++			/* force drop */
++			return ISCSI_ERR_NO_SCSI_CMD;
++		}
+ 
+-	if (task->sc->SCp.phase != conn->session->age) {
+-		iscsi_session_printk(KERN_ERR, conn->session,
+-				  "task's session age %d, expected %d\n",
+-				  task->sc->SCp.phase, conn->session->age);
+-		return NULL;
++		if (ctask->sc->SCp.phase != session->age) {
++			iscsi_conn_printk(KERN_ERR, conn,
++					  "iscsi: ctask's session age %d, "
++					  "expected %d\n", ctask->sc->SCp.phase,
++					  session->age);
++			return ISCSI_ERR_SESSION_FAILED;
++		}
+ 	}
+ 
+-	return task;
++	*ret_itt = itt;
++	return 0;
+ }
+-EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
++EXPORT_SYMBOL_GPL(iscsi_verify_itt);
+ 
+ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
+ {
+@@ -974,6 +755,61 @@ void iscsi_conn_failure(struct iscsi_con
+ }
+ EXPORT_SYMBOL_GPL(iscsi_conn_failure);
+ 
++static void iscsi_prep_mtask(struct iscsi_conn *conn,
++			     struct iscsi_mgmt_task *mtask)
++{
++	struct iscsi_session *session = conn->session;
++	struct iscsi_hdr *hdr = mtask->hdr;
++	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
++
++	if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) &&
++	    hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
++		nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
++	/*
++	 * pre-format CmdSN for outgoing PDU.
++	 */
++	nop->cmdsn = cpu_to_be32(session->cmdsn);
++	if (hdr->itt != RESERVED_ITT) {
++		hdr->itt = build_itt(mtask->itt, session->age);
++		/*
++		 * TODO: We always use immediate, so we never hit this.
++		 * If we start to send tmfs or nops as non-immediate then
++		 * we should start checking the cmdsn numbers for mgmt tasks.
++		 */
++		if (conn->c_stage == ISCSI_CONN_STARTED &&
++		    !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
++			session->queued_cmdsn++;
++			session->cmdsn++;
++		}
++	}
++
++	if (session->tt->init_mgmt_task)
++		session->tt->init_mgmt_task(conn, mtask);
++
++	debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
++		   hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt,
++		   mtask->data_count);
++}
++
++static int iscsi_xmit_mtask(struct iscsi_conn *conn)
++{
++	struct iscsi_hdr *hdr = conn->mtask->hdr;
++	int rc;
++
++	if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
++		conn->session->state = ISCSI_STATE_LOGGING_OUT;
++	spin_unlock_bh(&conn->session->lock);
++
++	rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask);
++	spin_lock_bh(&conn->session->lock);
++	if (rc)
++		return rc;
++
++	/* done with this in-progress mtask */
++	conn->mtask = NULL;
++	return 0;
++}
++
+ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
+ {
+ 	struct iscsi_session *session = conn->session;
+@@ -991,38 +827,37 @@ static int iscsi_check_cmdsn_window_clos
+ 	return 0;
+ }
+ 
+-static int iscsi_xmit_task(struct iscsi_conn *conn)
++static int iscsi_xmit_ctask(struct iscsi_conn *conn)
+ {
+-	struct iscsi_task *task = conn->task;
++	struct iscsi_cmd_task *ctask = conn->ctask;
+ 	int rc;
+ 
+-	__iscsi_get_task(task);
++	__iscsi_get_ctask(ctask);
+ 	spin_unlock_bh(&conn->session->lock);
+-	rc = conn->session->tt->xmit_task(task);
++	rc = conn->session->tt->xmit_cmd_task(conn, ctask);
+ 	spin_lock_bh(&conn->session->lock);
+-	__iscsi_put_task(task);
++	__iscsi_put_ctask(ctask);
+ 	if (!rc)
+-		/* done with this task */
+-		conn->task = NULL;
++		/* done with this ctask */
++		conn->ctask = NULL;
+ 	return rc;
+ }
+ 
+ /**
+- * iscsi_requeue_task - requeue task to run from session workqueue
+- * @task: task to requeue
++ * iscsi_requeue_ctask - requeue ctask to run from session workqueue
++ * @ctask: ctask to requeue
+  *
+- * LLDs that need to run a task from the session workqueue should call
+- * this. The session lock must be held. This should only be called
+- * by software drivers.
++ * LLDs that need to run a ctask from the session workqueue should call
++ * this. The session lock must be held.
+  */
+-void iscsi_requeue_task(struct iscsi_task *task)
++void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_conn *conn = task->conn;
++	struct iscsi_conn *conn = ctask->conn;
+ 
+-	list_move_tail(&task->running, &conn->requeue);
++	list_move_tail(&ctask->running, &conn->requeue);
+ 	scsi_queue_work(conn->session->host, &conn->xmitwork);
+ }
+-EXPORT_SYMBOL_GPL(iscsi_requeue_task);
++EXPORT_SYMBOL_GPL(iscsi_requeue_ctask);
+ 
+ /**
+  * iscsi_data_xmit - xmit any command into the scheduled connection
+@@ -1044,8 +879,14 @@ static int iscsi_data_xmit(struct iscsi_
+ 		return -ENODATA;
+ 	}
+ 
+-	if (conn->task) {
+-		rc = iscsi_xmit_task(conn);
++	if (conn->ctask) {
++		rc = iscsi_xmit_ctask(conn);
++		if (rc)
++			goto again;
++	}
++
++	if (conn->mtask) {
++		rc = iscsi_xmit_mtask(conn);
+ 	        if (rc)
+ 		        goto again;
+ 	}
+@@ -1057,14 +898,17 @@ static int iscsi_data_xmit(struct iscsi_
+ 	 */
+ check_mgmt:
+ 	while (!list_empty(&conn->mgmtqueue)) {
+-		conn->task = list_entry(conn->mgmtqueue.next,
+-					 struct iscsi_task, running);
+-		if (iscsi_prep_mgmt_task(conn, conn->task)) {
+-			__iscsi_put_task(conn->task);
+-			conn->task = NULL;
++		conn->mtask = list_entry(conn->mgmtqueue.next,
++					 struct iscsi_mgmt_task, running);
++		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
++			iscsi_free_mgmt_task(conn, conn->mtask);
++			conn->mtask = NULL;
+ 			continue;
+ 		}
+-		rc = iscsi_xmit_task(conn);
++
++		iscsi_prep_mtask(conn, conn->mtask);
++		list_move_tail(conn->mgmtqueue.next, &conn->mgmt_run_list);
++		rc = iscsi_xmit_mtask(conn);
+ 		if (rc)
+ 			goto again;
+ 	}
+@@ -1074,21 +918,24 @@ check_mgmt:
+ 		if (conn->tmf_state == TMF_QUEUED)
+ 			break;
+ 
+-		conn->task = list_entry(conn->xmitqueue.next,
+-					 struct iscsi_task, running);
++		conn->ctask = list_entry(conn->xmitqueue.next,
++					 struct iscsi_cmd_task, running);
+ 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
+-			fail_command(conn, conn->task, DID_IMM_RETRY << 16);
++			fail_command(conn, conn->ctask, DID_IMM_RETRY << 16);
+ 			continue;
+ 		}
+-		if (iscsi_prep_scsi_cmd_pdu(conn->task)) {
+-			fail_command(conn, conn->task, DID_ABORT << 16);
++		if (iscsi_prep_scsi_cmd_pdu(conn->ctask)) {
++			fail_command(conn, conn->ctask, DID_ABORT << 16);
+ 			continue;
+ 		}
+-		rc = iscsi_xmit_task(conn);
++
++		conn->ctask->state = ISCSI_TASK_RUNNING;
++		list_move_tail(conn->xmitqueue.next, &conn->run_list);
++		rc = iscsi_xmit_ctask(conn);
+ 		if (rc)
+ 			goto again;
+ 		/*
+-		 * we could continuously get new task requests so
++		 * we could continuously get new ctask requests so
+ 		 * we need to check the mgmt queue for nops that need to
+ 		 * be sent to aviod starvation
+ 		 */
+@@ -1106,11 +953,11 @@ check_mgmt:
+ 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
+ 			break;
+ 
+-		conn->task = list_entry(conn->requeue.next,
+-					 struct iscsi_task, running);
+-		conn->task->state = ISCSI_TASK_RUNNING;
++		conn->ctask = list_entry(conn->requeue.next,
++					 struct iscsi_cmd_task, running);
++		conn->ctask->state = ISCSI_TASK_RUNNING;
+ 		list_move_tail(conn->requeue.next, &conn->run_list);
+-		rc = iscsi_xmit_task(conn);
++		rc = iscsi_xmit_ctask(conn);
+ 		if (rc)
+ 			goto again;
+ 		if (!list_empty(&conn->mgmtqueue))
+@@ -1154,12 +1001,11 @@ enum {
+ 
+ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+ {
+-	struct iscsi_cls_session *cls_session;
+ 	struct Scsi_Host *host;
+ 	int reason = 0;
+ 	struct iscsi_session *session;
+ 	struct iscsi_conn *conn;
+-	struct iscsi_task *task = NULL;
++	struct iscsi_cmd_task *ctask = NULL;
+ 
+ 	sc->scsi_done = done;
+ 	sc->result = 0;
+@@ -1168,11 +1014,10 @@ int iscsi_queuecommand(struct scsi_cmnd 
+ 	host = sc->device->host;
+ 	spin_unlock(host->host_lock);
+ 
+-	cls_session = starget_to_session(scsi_target(sc->device));
+-	session = cls_session->dd_data;
++	session = iscsi_hostdata(host->hostdata);
+ 	spin_lock(&session->lock);
+ 
+-	reason = iscsi_session_chkready(cls_session);
++	reason = iscsi_session_chkready(session_to_cls(session));
+ 	if (reason) {
+ 		sc->result = reason;
+ 		goto fault;
+@@ -1227,39 +1072,26 @@ int iscsi_queuecommand(struct scsi_cmnd 
+ 		goto reject;
+ 	}
+ 
+-	if (!__kfifo_get(session->cmdpool.queue, (void*)&task,
++	if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
+ 			 sizeof(void*))) {
+ 		reason = FAILURE_OOM;
+ 		goto reject;
+ 	}
++	session->queued_cmdsn++;
++
+ 	sc->SCp.phase = session->age;
+-	sc->SCp.ptr = (char *)task;
++	sc->SCp.ptr = (char *)ctask;
+ 
+-	atomic_set(&task->refcount, 1);
+-	task->state = ISCSI_TASK_PENDING;
+-	task->conn = conn;
+-	task->sc = sc;
+-	INIT_LIST_HEAD(&task->running);
+-	list_add_tail(&task->running, &conn->xmitqueue);
+-
+-	if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) {
+-		if (iscsi_prep_scsi_cmd_pdu(task)) {
+-			sc->result = DID_ABORT << 16;
+-			sc->scsi_done = NULL;
+-			iscsi_complete_command(task);
+-			goto fault;
+-		}
+-		if (session->tt->xmit_task(task)) {
+-			sc->scsi_done = NULL;
+-			iscsi_complete_command(task);
+-			reason = FAILURE_SESSION_NOT_READY;
+-			goto reject;
+-		}
+-	} else
+-		scsi_queue_work(session->host, &conn->xmitwork);
++	atomic_set(&ctask->refcount, 1);
++	ctask->state = ISCSI_TASK_PENDING;
++	ctask->conn = conn;
++	ctask->sc = sc;
++	INIT_LIST_HEAD(&ctask->running);
+ 
+-	session->queued_cmdsn++;
++	list_add_tail(&ctask->running, &conn->xmitqueue);
+ 	spin_unlock(&session->lock);
++
++	scsi_queue_work(host, &conn->xmitwork);
+ 	spin_lock(host->host_lock);
+ 	return 0;
+ 
+@@ -1272,13 +1104,8 @@ reject:
+ fault:
+ 	spin_unlock(&session->lock);
+ 	debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
+-	if (!scsi_bidi_cmnd(sc))
+-		scsi_set_resid(sc, scsi_bufflen(sc));
+-	else {
+-		scsi_out(sc)->resid = scsi_out(sc)->length;
+-		scsi_in(sc)->resid = scsi_in(sc)->length;
+-	}
+-	done(sc);
++	scsi_set_resid(sc, scsi_bufflen(sc));
++	sc->scsi_done(sc);
+ 	spin_lock(host->host_lock);
+ 	return 0;
+ }
+@@ -1295,7 +1122,7 @@ EXPORT_SYMBOL_GPL(iscsi_change_queue_dep
+ 
+ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
+ {
+-	struct iscsi_session *session = cls_session->dd_data;
++	struct iscsi_session *session = class_to_transport_session(cls_session);
+ 
+ 	spin_lock_bh(&session->lock);
+ 	if (session->state != ISCSI_STATE_LOGGED_IN) {
+@@ -1309,13 +1136,9 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery
+ 
+ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
+ {
+-	struct iscsi_cls_session *cls_session;
+-	struct iscsi_session *session;
+-	struct iscsi_conn *conn;
+-
+-	cls_session = starget_to_session(scsi_target(sc->device));
+-	session = cls_session->dd_data;
+-	conn = session->leadconn;
++	struct Scsi_Host *host = sc->device->host;
++	struct iscsi_session *session = iscsi_hostdata(host->hostdata);
++	struct iscsi_conn *conn = session->leadconn;
+ 
+ 	mutex_lock(&session->eh_mutex);
+ 	spin_lock_bh(&session->lock);
+@@ -1377,11 +1200,11 @@ static int iscsi_exec_task_mgmt_fn(struc
+ 				   int timeout)
+ {
+ 	struct iscsi_session *session = conn->session;
+-	struct iscsi_task *task;
++	struct iscsi_mgmt_task *mtask;
+ 
+-	task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
++	mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
+ 				      NULL, 0);
+-	if (!task) {
++	if (!mtask) {
+ 		spin_unlock_bh(&session->lock);
+ 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ 		spin_lock_bh(&session->lock);
+@@ -1397,6 +1220,7 @@ static int iscsi_exec_task_mgmt_fn(struc
+ 
+ 	spin_unlock_bh(&session->lock);
+ 	mutex_unlock(&session->eh_mutex);
++	scsi_queue_work(session->host, &conn->xmitwork);
+ 
+ 	/*
+ 	 * block eh thread until:
+@@ -1415,7 +1239,7 @@ static int iscsi_exec_task_mgmt_fn(struc
+ 
+ 	mutex_lock(&session->eh_mutex);
+ 	spin_lock_bh(&session->lock);
+-	/* if the session drops it will clean up the task */
++	/* if the session drops it will clean up the mtask */
+ 	if (age != session->age ||
+ 	    session->state != ISCSI_STATE_LOGGED_IN)
+ 		return -ENOTCONN;
+@@ -1429,51 +1253,48 @@ static int iscsi_exec_task_mgmt_fn(struc
+ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
+ 			      int error)
+ {
+-	struct iscsi_task *task, *tmp;
++	struct iscsi_cmd_task *ctask, *tmp;
+ 
+-	if (conn->task && (conn->task->sc->device->lun == lun || lun == -1))
+-		conn->task = NULL;
++	if (conn->ctask && (conn->ctask->sc->device->lun == lun || lun == -1))
++		conn->ctask = NULL;
+ 
+ 	/* flush pending */
+-	list_for_each_entry_safe(task, tmp, &conn->xmitqueue, running) {
+-		if (lun == task->sc->device->lun || lun == -1) {
++	list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
++		if (lun == ctask->sc->device->lun || lun == -1) {
+ 			debug_scsi("failing pending sc %p itt 0x%x\n",
+-				   task->sc, task->itt);
+-			fail_command(conn, task, error << 16);
++				   ctask->sc, ctask->itt);
++			fail_command(conn, ctask, error << 16);
+ 		}
+ 	}
+ 
+-	list_for_each_entry_safe(task, tmp, &conn->requeue, running) {
+-		if (lun == task->sc->device->lun || lun == -1) {
++	list_for_each_entry_safe(ctask, tmp, &conn->requeue, running) {
++		if (lun == ctask->sc->device->lun || lun == -1) {
+ 			debug_scsi("failing requeued sc %p itt 0x%x\n",
+-				   task->sc, task->itt);
+-			fail_command(conn, task, error << 16);
++				   ctask->sc, ctask->itt);
++			fail_command(conn, ctask, error << 16);
+ 		}
+ 	}
+ 
+ 	/* fail all other running */
+-	list_for_each_entry_safe(task, tmp, &conn->run_list, running) {
+-		if (lun == task->sc->device->lun || lun == -1) {
++	list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) {
++		if (lun == ctask->sc->device->lun || lun == -1) {
+ 			debug_scsi("failing in progress sc %p itt 0x%x\n",
+-				   task->sc, task->itt);
+-			fail_command(conn, task, DID_BUS_BUSY << 16);
++				   ctask->sc, ctask->itt);
++			fail_command(conn, ctask, DID_BUS_BUSY << 16);
+ 		}
+ 	}
+ }
+ 
+-void iscsi_suspend_tx(struct iscsi_conn *conn)
++static void iscsi_suspend_tx(struct iscsi_conn *conn)
+ {
+ 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+-	if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD))
+-		scsi_flush_work(conn->session->host);
++	scsi_flush_work(conn->session->host);
+ }
+-EXPORT_SYMBOL_GPL(iscsi_suspend_tx);
+ 
+ static void iscsi_start_tx(struct iscsi_conn *conn)
+ {
+ 	clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+-	if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD))
+-		scsi_queue_work(conn->session->host, &conn->xmitwork);
++	scsi_queue_work(conn->session->host, &conn->xmitwork);
+ }
+ 
+ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
+@@ -1484,7 +1305,7 @@ static enum scsi_eh_timer_return iscsi_e
+ 	enum scsi_eh_timer_return rc = EH_NOT_HANDLED;
+ 
+ 	cls_session = starget_to_session(scsi_target(scmd->device));
+-	session = cls_session->dd_data;
++	session = class_to_transport_session(cls_session);
+ 
+ 	debug_scsi("scsi cmd %p timedout\n", scmd);
+ 
+@@ -1522,7 +1343,7 @@ static enum scsi_eh_timer_return iscsi_e
+ 			   jiffies))
+ 		rc = EH_RESET_TIMER;
+ 	/* if in the middle of checking the transport then give us more time */
+-	if (conn->ping_task)
++	if (conn->ping_mtask)
+ 		rc = EH_RESET_TIMER;
+ done:
+ 	spin_unlock(&session->lock);
+@@ -1546,7 +1367,7 @@ static void iscsi_check_transport_timeou
+ 
+ 	recv_timeout *= HZ;
+ 	last_recv = conn->last_recv;
+-	if (conn->ping_task &&
++	if (conn->ping_mtask &&
+ 	    time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
+ 			   jiffies)) {
+ 		iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
+@@ -1572,30 +1393,27 @@ done:
+ 	spin_unlock(&session->lock);
+ }
+ 
+-static void iscsi_prep_abort_task_pdu(struct iscsi_task *task,
++static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask,
+ 				      struct iscsi_tm *hdr)
+ {
+ 	memset(hdr, 0, sizeof(*hdr));
+ 	hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+ 	hdr->flags = ISCSI_TM_FUNC_ABORT_TASK & ISCSI_FLAG_TM_FUNC_MASK;
+ 	hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+-	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
+-	hdr->rtt = task->hdr->itt;
+-	hdr->refcmdsn = task->hdr->cmdsn;
++	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
++	hdr->rtt = ctask->hdr->itt;
++	hdr->refcmdsn = ctask->hdr->cmdsn;
+ }
+ 
+ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ {
+-	struct iscsi_cls_session *cls_session;
+-	struct iscsi_session *session;
++	struct Scsi_Host *host = sc->device->host;
++	struct iscsi_session *session = iscsi_hostdata(host->hostdata);
+ 	struct iscsi_conn *conn;
+-	struct iscsi_task *task;
++	struct iscsi_cmd_task *ctask;
+ 	struct iscsi_tm *hdr;
+ 	int rc, age;
+ 
+-	cls_session = starget_to_session(scsi_target(sc->device));
+-	session = cls_session->dd_data;
+-
+ 	mutex_lock(&session->eh_mutex);
+ 	spin_lock_bh(&session->lock);
+ 	/*
+@@ -1624,17 +1442,17 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ 	conn->eh_abort_cnt++;
+ 	age = session->age;
+ 
+-	task = (struct iscsi_task *)sc->SCp.ptr;
+-	debug_scsi("aborting [sc %p itt 0x%x]\n", sc, task->itt);
++	ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
++	debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
+ 
+-	/* task completed before time out */
+-	if (!task->sc) {
++	/* ctask completed before time out */
++	if (!ctask->sc) {
+ 		debug_scsi("sc completed while abort in progress\n");
+ 		goto success;
+ 	}
+ 
+-	if (task->state == ISCSI_TASK_PENDING) {
+-		fail_command(conn, task, DID_ABORT << 16);
++	if (ctask->state == ISCSI_TASK_PENDING) {
++		fail_command(conn, ctask, DID_ABORT << 16);
+ 		goto success;
+ 	}
+ 
+@@ -1644,7 +1462,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ 	conn->tmf_state = TMF_QUEUED;
+ 
+ 	hdr = &conn->tmhdr;
+-	iscsi_prep_abort_task_pdu(task, hdr);
++	iscsi_prep_abort_task_pdu(ctask, hdr);
+ 
+ 	if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) {
+ 		rc = FAILED;
+@@ -1654,20 +1472,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ 	switch (conn->tmf_state) {
+ 	case TMF_SUCCESS:
+ 		spin_unlock_bh(&session->lock);
+-		/*
+-		 * stop tx side incase the target had sent a abort rsp but
+-		 * the initiator was still writing out data.
+-		 */
+ 		iscsi_suspend_tx(conn);
+ 		/*
+-		 * we do not stop the recv side because targets have been
+-		 * good and have never sent us a successful tmf response
+-		 * then sent more data for the cmd.
++		 * clean up task if aborted. grab the recv lock as a writer
+ 		 */
++		write_lock_bh(conn->recv_lock);
+ 		spin_lock(&session->lock);
+-		fail_command(conn, task, DID_ABORT << 16);
++		fail_command(conn, ctask, DID_ABORT << 16);
+ 		conn->tmf_state = TMF_INITIAL;
+ 		spin_unlock(&session->lock);
++		write_unlock_bh(conn->recv_lock);
+ 		iscsi_start_tx(conn);
+ 		goto success_unlocked;
+ 	case TMF_TIMEDOUT:
+@@ -1677,7 +1491,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ 	case TMF_NOT_FOUND:
+ 		if (!sc->SCp.ptr) {
+ 			conn->tmf_state = TMF_INITIAL;
+-			/* task completed before tmf abort response */
++			/* ctask completed before tmf abort response */
+ 			debug_scsi("sc completed while abort in progress\n");
+ 			goto success;
+ 		}
+@@ -1690,7 +1504,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
+ success:
+ 	spin_unlock_bh(&session->lock);
+ success_unlocked:
+-	debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, task->itt);
++	debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+ 	mutex_unlock(&session->eh_mutex);
+ 	return SUCCESS;
+ 
+@@ -1698,7 +1512,7 @@ failed:
+ 	spin_unlock_bh(&session->lock);
+ failed_unlocked:
+ 	debug_scsi("abort failed [sc %p itt 0x%x]\n", sc,
+-		    task ? task->itt : 0);
++		    ctask ? ctask->itt : 0);
+ 	mutex_unlock(&session->eh_mutex);
+ 	return FAILED;
+ }
+@@ -1716,15 +1530,12 @@ static void iscsi_prep_lun_reset_pdu(str
+ 
+ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
+ {
+-	struct iscsi_cls_session *cls_session;
+-	struct iscsi_session *session;
++	struct Scsi_Host *host = sc->device->host;
++	struct iscsi_session *session = iscsi_hostdata(host->hostdata);
+ 	struct iscsi_conn *conn;
+ 	struct iscsi_tm *hdr;
+ 	int rc = FAILED;
+ 
+-	cls_session = starget_to_session(scsi_target(sc->device));
+-	session = cls_session->dd_data;
+-
+ 	debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun);
+ 
+ 	mutex_lock(&session->eh_mutex);
+@@ -1767,11 +1578,13 @@ int iscsi_eh_device_reset(struct scsi_cm
+ 	spin_unlock_bh(&session->lock);
+ 
+ 	iscsi_suspend_tx(conn);
+-
++	/* need to grab the recv lock then session lock */
++	write_lock_bh(conn->recv_lock);
+ 	spin_lock(&session->lock);
+ 	fail_all_commands(conn, sc->device->lun, DID_ERROR);
+ 	conn->tmf_state = TMF_INITIAL;
+ 	spin_unlock(&session->lock);
++	write_unlock_bh(conn->recv_lock);
+ 
+ 	iscsi_start_tx(conn);
+ 	goto done;
+@@ -1847,203 +1660,177 @@ void iscsi_pool_free(struct iscsi_pool *
+ }
+ EXPORT_SYMBOL_GPL(iscsi_pool_free);
+ 
+-/**
+- * iscsi_host_add - add host to system
+- * @shost: scsi host
+- * @pdev: parent device
+- *
+- * This should be called by partial offload and software iscsi drivers
+- * to add a host to the system.
+- */
+-int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
+-{
+-	if (!shost->can_queue)
+-		shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
+-
+-	return scsi_add_host(shost, pdev);
+-}
+-EXPORT_SYMBOL_GPL(iscsi_host_add);
+-
+-/**
+- * iscsi_host_alloc - allocate a host and driver data
+- * @sht: scsi host template
+- * @dd_data_size: driver host data size
+- * @qdepth: default device queue depth
++/*
++ * iSCSI Session's hostdata organization:
+  *
+- * This should be called by partial offload and software iscsi drivers.
+- * To access the driver specific memory use the iscsi_host_priv() macro.
++ *    *------------------* <== hostdata_session(host->hostdata)
++ *    | ptr to class sess|
++ *    |------------------| <== iscsi_hostdata(host->hostdata)
++ *    | iscsi_session    |
++ *    *------------------*
+  */
+-struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
+-				   int dd_data_size, uint16_t qdepth)
+-{
+-	struct Scsi_Host *shost;
+ 
+-	shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
+-	if (!shost)
+-		return NULL;
+-	shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
++#define hostdata_privsize(_sz)	(sizeof(unsigned long) + _sz + \
++				 _sz % sizeof(unsigned long))
+ 
+-	if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
+-		if (qdepth != 0)
+-			printk(KERN_ERR "iscsi: invalid queue depth of %d. "
+-			       "Queue depth must be between 1 and %d.\n",
+-			       qdepth, ISCSI_MAX_CMD_PER_LUN);
+-		qdepth = ISCSI_DEF_CMD_PER_LUN;
+-	}
+-	shost->cmd_per_lun = qdepth;
+-	return shost;
+-}
+-EXPORT_SYMBOL_GPL(iscsi_host_alloc);
+-
+-/**
+- * iscsi_host_remove - remove host and sessions
+- * @shost: scsi host
+- *
+- * This will also remove any sessions attached to the host, but if userspace
+- * is managing the session at the same time this will break. TODO: add
+- * refcounting to the netlink iscsi interface so a rmmod or host hot unplug
+- * does not remove the memory from under us.
+- */
+-void iscsi_host_remove(struct Scsi_Host *shost)
+-{
+-	iscsi_host_for_each_session(shost, iscsi_session_teardown);
+-	scsi_remove_host(shost);
+-}
+-EXPORT_SYMBOL_GPL(iscsi_host_remove);
+-
+-void iscsi_host_free(struct Scsi_Host *shost)
+-{
+-	struct iscsi_host *ihost = shost_priv(shost);
+-
+-	kfree(ihost->netdev);
+-	kfree(ihost->hwaddress);
+-	kfree(ihost->initiatorname);
+-	scsi_host_put(shost);
+-}
+-EXPORT_SYMBOL_GPL(iscsi_host_free);
++#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
+ 
+ /**
+  * iscsi_session_setup - create iscsi cls session and host and session
++ * @scsit: scsi transport template
+  * @iscsit: iscsi transport template
+- * @shost: scsi host
+- * @cmds_max: session can queue
+- * @cmd_task_size: LLD task private data size
++ * @cmds_max: scsi host can queue
++ * @qdepth: scsi host cmds per lun
++ * @cmd_task_size: LLD ctask private data size
++ * @mgmt_task_size: LLD mtask private data size
+  * @initial_cmdsn: initial CmdSN
++ * @hostno: host no allocated
+  *
+  * This can be used by software iscsi_transports that allocate
+  * a session per scsi host.
+- *
+- * Callers should set cmds_max to the largest total numer (mgmt + scsi) of
+- * tasks they support. The iscsi layer reserves ISCSI_MGMT_CMDS_MAX tasks
+- * for nop handling and login/logout requests.
+- */
++ **/
+ struct iscsi_cls_session *
+-iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
+-		    uint16_t cmds_max, int cmd_task_size,
+-		    uint32_t initial_cmdsn, unsigned int id)
++iscsi_session_setup(struct iscsi_transport *iscsit,
++		    struct scsi_transport_template *scsit,
++		    uint16_t cmds_max, uint16_t qdepth,
++		    int cmd_task_size, int mgmt_task_size,
++		    uint32_t initial_cmdsn, uint32_t *hostno)
+ {
++	struct Scsi_Host *shost;
+ 	struct iscsi_session *session;
+ 	struct iscsi_cls_session *cls_session;
+-	int cmd_i, scsi_cmds, total_cmds = cmds_max;
++	int cmd_i;
+ 
+-	if (!total_cmds)
+-		total_cmds = ISCSI_DEF_XMIT_CMDS_MAX;
+-	/*
+-	 * The iscsi layer needs some tasks for nop handling and tmfs,
+-	 * so the cmds_max must at least be greater than ISCSI_MGMT_CMDS_MAX
+-	 * + 1 command for scsi IO.
+-	 */
+-	if (total_cmds < ISCSI_TOTAL_CMDS_MIN) {
+-		printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
+-		       "must be a power of two that is at least %d.\n",
+-		       total_cmds, ISCSI_TOTAL_CMDS_MIN);
+-		return NULL;
+-	}
+-
+-	if (total_cmds > ISCSI_TOTAL_CMDS_MAX) {
+-		printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
+-		       "must be a power of 2 less than or equal to %d.\n",
+-		       cmds_max, ISCSI_TOTAL_CMDS_MAX);
+-		total_cmds = ISCSI_TOTAL_CMDS_MAX;
++	if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
++		if (qdepth != 0)
++			printk(KERN_ERR "iscsi: invalid queue depth of %d. "
++			      "Queue depth must be between 1 and %d.\n",
++			      qdepth, ISCSI_MAX_CMD_PER_LUN);
++		qdepth = ISCSI_DEF_CMD_PER_LUN;
+ 	}
+ 
+-	if (!is_power_of_2(total_cmds)) {
+-		printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
+-		       "must be a power of 2.\n", total_cmds);
+-		total_cmds = rounddown_pow_of_two(total_cmds);
+-		if (total_cmds < ISCSI_TOTAL_CMDS_MIN)
+-			return NULL;
+-		printk(KERN_INFO "iscsi: Rounding can_queue to %d.\n",
+-		       total_cmds);
++	if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET ||
++	    cmds_max < 2) {
++		if (cmds_max != 0)
++			printk(KERN_ERR "iscsi: invalid can_queue of %d. "
++			       "can_queue must be a power of 2 and between "
++			       "2 and %d - setting to %d.\n", cmds_max,
++			       ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX);
++		cmds_max = ISCSI_DEF_XMIT_CMDS_MAX;
+ 	}
+-	scsi_cmds = total_cmds - ISCSI_MGMT_CMDS_MAX;
+ 
+-	cls_session = iscsi_alloc_session(shost, iscsit,
+-					  sizeof(struct iscsi_session));
+-	if (!cls_session)
++	shost = scsi_host_alloc(iscsit->host_template,
++				hostdata_privsize(sizeof(*session)));
++	if (!shost)
+ 		return NULL;
+-	session = cls_session->dd_data;
+-	session->cls_session = cls_session;
++
++	/* the iscsi layer takes one task for reserve */
++	shost->can_queue = cmds_max - 1;
++	shost->cmd_per_lun = qdepth;
++	shost->max_id = 1;
++	shost->max_channel = 0;
++	shost->max_lun = iscsit->max_lun;
++	shost->max_cmd_len = iscsit->max_cmd_len;
++	shost->transportt = scsit;
++	shost->transportt->create_work_queue = 1;
++	shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
++	*hostno = shost->host_no;
++
++	session = iscsi_hostdata(shost->hostdata);
++	memset(session, 0, sizeof(struct iscsi_session));
+ 	session->host = shost;
+ 	session->state = ISCSI_STATE_FREE;
+ 	session->fast_abort = 1;
+ 	session->lu_reset_timeout = 15;
+ 	session->abort_timeout = 10;
+-	session->scsi_cmds_max = scsi_cmds;
+-	session->cmds_max = total_cmds;
++	session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
++	session->cmds_max = cmds_max;
+ 	session->queued_cmdsn = session->cmdsn = initial_cmdsn;
+ 	session->exp_cmdsn = initial_cmdsn + 1;
+ 	session->max_cmdsn = initial_cmdsn + 1;
+ 	session->max_r2t = 1;
+ 	session->tt = iscsit;
+ 	mutex_init(&session->eh_mutex);
+-	spin_lock_init(&session->lock);
+ 
+ 	/* initialize SCSI PDU commands pool */
+ 	if (iscsi_pool_init(&session->cmdpool, session->cmds_max,
+ 			    (void***)&session->cmds,
+-			    cmd_task_size + sizeof(struct iscsi_task)))
++			    cmd_task_size + sizeof(struct iscsi_cmd_task)))
+ 		goto cmdpool_alloc_fail;
+ 
+ 	/* pre-format cmds pool with ITT */
+ 	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
+-		struct iscsi_task *task = session->cmds[cmd_i];
++		struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
+ 
+ 		if (cmd_task_size)
+-			task->dd_data = &task[1];
+-		task->itt = cmd_i;
+-		INIT_LIST_HEAD(&task->running);
++			ctask->dd_data = &ctask[1];
++		ctask->itt = cmd_i;
++		INIT_LIST_HEAD(&ctask->running);
+ 	}
+ 
+-	if (!try_module_get(iscsit->owner))
+-		goto module_get_fail;
++	spin_lock_init(&session->lock);
+ 
+-	if (iscsi_add_session(cls_session, id))
++	/* initialize immediate command pool */
++	if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
++			   (void***)&session->mgmt_cmds,
++			   mgmt_task_size + sizeof(struct iscsi_mgmt_task)))
++		goto mgmtpool_alloc_fail;
++
++
++	/* pre-format immediate cmds pool with ITT */
++	for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
++		struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
++
++		if (mgmt_task_size)
++			mtask->dd_data = &mtask[1];
++		mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
++		INIT_LIST_HEAD(&mtask->running);
++	}
++
++	if (scsi_add_host(shost, NULL))
++		goto add_host_fail;
++
++	if (!try_module_get(iscsit->owner))
+ 		goto cls_session_fail;
++
++	cls_session = iscsi_create_session(shost, iscsit, 0);
++	if (!cls_session)
++		goto module_put;
++	*(unsigned long*)shost->hostdata = (unsigned long)cls_session;
++
+ 	return cls_session;
+ 
+-cls_session_fail:
++module_put:
+ 	module_put(iscsit->owner);
+-module_get_fail:
++cls_session_fail:
++	scsi_remove_host(shost);
++add_host_fail:
++	iscsi_pool_free(&session->mgmtpool);
++mgmtpool_alloc_fail:
+ 	iscsi_pool_free(&session->cmdpool);
+ cmdpool_alloc_fail:
+-	iscsi_free_session(cls_session);
++	scsi_host_put(shost);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_session_setup);
+ 
+ /**
+  * iscsi_session_teardown - destroy session, host, and cls_session
+- * @cls_session: iscsi session
++ * shost: scsi host
+  *
+- * The driver must have called iscsi_remove_session before
+- * calling this.
+- */
++ * This can be used by software iscsi_transports that allocate
++ * a session per scsi host.
++ **/
+ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
+ {
+-	struct iscsi_session *session = cls_session->dd_data;
++	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
++	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+ 	struct module *owner = cls_session->transport->owner;
+ 
++	iscsi_remove_session(cls_session);
++	scsi_remove_host(shost);
++
++	iscsi_pool_free(&session->mgmtpool);
+ 	iscsi_pool_free(&session->cmdpool);
+ 
+ 	kfree(session->password);
+@@ -2051,10 +1838,12 @@ void iscsi_session_teardown(struct iscsi
+ 	kfree(session->username);
+ 	kfree(session->username_in);
+ 	kfree(session->targetname);
++	kfree(session->netdev);
++	kfree(session->hwaddress);
+ 	kfree(session->initiatorname);
+-	kfree(session->ifacename);
+ 
+-	iscsi_destroy_session(cls_session);
++	iscsi_free_session(cls_session);
++	scsi_host_put(shost);
+ 	module_put(owner);
+ }
+ EXPORT_SYMBOL_GPL(iscsi_session_teardown);
+@@ -2062,26 +1851,22 @@ EXPORT_SYMBOL_GPL(iscsi_session_teardown
+ /**
+  * iscsi_conn_setup - create iscsi_cls_conn and iscsi_conn
+  * @cls_session: iscsi_cls_session
+- * @dd_size: private driver data size
+  * @conn_idx: cid
+- */
++ **/
+ struct iscsi_cls_conn *
+-iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
+-		 uint32_t conn_idx)
++iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
+ {
+-	struct iscsi_session *session = cls_session->dd_data;
++	struct iscsi_session *session = class_to_transport_session(cls_session);
+ 	struct iscsi_conn *conn;
+ 	struct iscsi_cls_conn *cls_conn;
+ 	char *data;
+ 
+-	cls_conn = iscsi_create_conn(cls_session, sizeof(*conn) + dd_size,
+-				     conn_idx);
++	cls_conn = iscsi_create_conn(cls_session, conn_idx);
+ 	if (!cls_conn)
+ 		return NULL;
+ 	conn = cls_conn->dd_data;
+-	memset(conn, 0, sizeof(*conn) + dd_size);
++	memset(conn, 0, sizeof(*conn));
+ 
+-	conn->dd_data = cls_conn->dd_data + sizeof(*conn);
+ 	conn->session = session;
+ 	conn->cls_conn = cls_conn;
+ 	conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
+@@ -2100,30 +1885,30 @@ iscsi_conn_setup(struct iscsi_cls_sessio
+ 	INIT_LIST_HEAD(&conn->requeue);
+ 	INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
+ 
+-	/* allocate login_task used for the login/text sequences */
++	/* allocate login_mtask used for the login/text sequences */
+ 	spin_lock_bh(&session->lock);
+-	if (!__kfifo_get(session->cmdpool.queue,
+-                         (void*)&conn->login_task,
++	if (!__kfifo_get(session->mgmtpool.queue,
++                         (void*)&conn->login_mtask,
+ 			 sizeof(void*))) {
+ 		spin_unlock_bh(&session->lock);
+-		goto login_task_alloc_fail;
++		goto login_mtask_alloc_fail;
+ 	}
+ 	spin_unlock_bh(&session->lock);
+ 
+ 	data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL);
+ 	if (!data)
+-		goto login_task_data_alloc_fail;
+-	conn->login_task->data = conn->data = data;
++		goto login_mtask_data_alloc_fail;
++	conn->login_mtask->data = conn->data = data;
+ 
+ 	init_timer(&conn->tmf_timer);
+ 	init_waitqueue_head(&conn->ehwait);
+ 
+ 	return cls_conn;
+ 
+-login_task_data_alloc_fail:
+-	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
++login_mtask_data_alloc_fail:
++	__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
+ 		    sizeof(void*));
+-login_task_alloc_fail:
++login_mtask_alloc_fail:
+ 	iscsi_destroy_conn(cls_conn);
+ 	return NULL;
+ }
+@@ -2183,7 +1968,7 @@ void iscsi_conn_teardown(struct iscsi_cl
+ 	spin_lock_bh(&session->lock);
+ 	kfree(conn->data);
+ 	kfree(conn->persistent_address);
+-	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
++	__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
+ 		    sizeof(void*));
+ 	if (session->leadconn == conn)
+ 		session->leadconn = NULL;
+@@ -2255,7 +2040,7 @@ int iscsi_conn_start(struct iscsi_cls_co
+ 	}
+ 	spin_unlock_bh(&session->lock);
+ 
+-	iscsi_unblock_session(session->cls_session);
++	iscsi_unblock_session(session_to_cls(session));
+ 	wake_up(&conn->ehwait);
+ 	return 0;
+ }
+@@ -2264,23 +2049,21 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start);
+ static void
+ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
+ {
+-	struct iscsi_task *task, *tmp;
++	struct iscsi_mgmt_task *mtask, *tmp;
+ 
+ 	/* handle pending */
+-	list_for_each_entry_safe(task, tmp, &conn->mgmtqueue, running) {
+-		debug_scsi("flushing pending mgmt task itt 0x%x\n", task->itt);
+-		/* release ref from prep task */
+-		__iscsi_put_task(task);
++	list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) {
++		debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt);
++		iscsi_free_mgmt_task(conn, mtask);
+ 	}
+ 
+ 	/* handle running */
+-	list_for_each_entry_safe(task, tmp, &conn->mgmt_run_list, running) {
+-		debug_scsi("flushing running mgmt task itt 0x%x\n", task->itt);
+-		/* release ref from prep task */
+-		__iscsi_put_task(task);
++	list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) {
++		debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt);
++		iscsi_free_mgmt_task(conn, mtask);
+ 	}
+ 
+-	conn->task = NULL;
++	conn->mtask = NULL;
+ }
+ 
+ static void iscsi_start_session_recovery(struct iscsi_session *session,
+@@ -2299,6 +2082,17 @@ static void iscsi_start_session_recovery
+ 	}
+ 
+ 	/*
++	 * The LLD either freed/unset the lock on us, or userspace called
++	 * stop but did not create a proper connection (connection was never
++	 * bound or it was unbound then stop was called).
++	 */
++	if (!conn->recv_lock) {
++		spin_unlock_bh(&session->lock);
++		mutex_unlock(&session->eh_mutex);
++		return;
++	}
++
++	/*
+ 	 * When this is called for the in_login state, we only want to clean
+ 	 * up the login task and connection. We do not need to block and set
+ 	 * the recovery state again
+@@ -2314,6 +2108,11 @@ static void iscsi_start_session_recovery
+ 	spin_unlock_bh(&session->lock);
+ 
+ 	iscsi_suspend_tx(conn);
++
++	write_lock_bh(conn->recv_lock);
++	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
++	write_unlock_bh(conn->recv_lock);
++
+ 	/*
+ 	 * for connection level recovery we should not calculate
+ 	 * header digest. conn->hdr_size used for optimization
+@@ -2326,7 +2125,7 @@ static void iscsi_start_session_recovery
+ 		if (session->state == ISCSI_STATE_IN_RECOVERY &&
+ 		    old_stop_stage != STOP_CONN_RECOVER) {
+ 			debug_scsi("blocking session\n");
+-			iscsi_block_session(session->cls_session);
++			iscsi_block_session(session_to_cls(session));
+ 		}
+ 	}
+ 
+@@ -2361,7 +2160,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_stop);
+ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
+ 		    struct iscsi_cls_conn *cls_conn, int is_leading)
+ {
+-	struct iscsi_session *session = cls_session->dd_data;
++	struct iscsi_session *session = class_to_transport_session(cls_session);
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+ 
+ 	spin_lock_bh(&session->lock);
+@@ -2500,14 +2299,6 @@ int iscsi_set_param(struct iscsi_cls_con
+ 		if (!conn->persistent_address)
+ 			return -ENOMEM;
+ 		break;
+-	case ISCSI_PARAM_IFACE_NAME:
+-		if (!session->ifacename)
+-			session->ifacename = kstrdup(buf, GFP_KERNEL);
+-		break;
+-	case ISCSI_PARAM_INITIATOR_NAME:
+-		if (!session->initiatorname)
+-			session->initiatorname = kstrdup(buf, GFP_KERNEL);
+-		break;
+ 	default:
+ 		return -ENOSYS;
+ 	}
+@@ -2519,7 +2310,8 @@ EXPORT_SYMBOL_GPL(iscsi_set_param);
+ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
+ 			    enum iscsi_param param, char *buf)
+ {
+-	struct iscsi_session *session = cls_session->dd_data;
++	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
++	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+ 	int len;
+ 
+ 	switch(param) {
+@@ -2574,15 +2366,6 @@ int iscsi_session_get_param(struct iscsi
+ 	case ISCSI_PARAM_PASSWORD_IN:
+ 		len = sprintf(buf, "%s\n", session->password_in);
+ 		break;
+-	case ISCSI_PARAM_IFACE_NAME:
+-		len = sprintf(buf, "%s\n", session->ifacename);
+-		break;
+-	case ISCSI_PARAM_INITIATOR_NAME:
+-		if (!session->initiatorname)
+-			len = sprintf(buf, "%s\n", "unknown");
+-		else
+-			len = sprintf(buf, "%s\n", session->initiatorname);
+-		break;
+ 	default:
+ 		return -ENOSYS;
+ 	}
+@@ -2642,35 +2425,29 @@ EXPORT_SYMBOL_GPL(iscsi_conn_get_param);
+ int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
+ 			 char *buf)
+ {
+-	struct iscsi_host *ihost = shost_priv(shost);
++	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+ 	int len;
+ 
+ 	switch (param) {
+ 	case ISCSI_HOST_PARAM_NETDEV_NAME:
+-		if (!ihost->netdev)
++		if (!session->netdev)
+ 			len = sprintf(buf, "%s\n", "default");
+ 		else
+-			len = sprintf(buf, "%s\n", ihost->netdev);
++			len = sprintf(buf, "%s\n", session->netdev);
+ 		break;
+ 	case ISCSI_HOST_PARAM_HWADDRESS:
+-		if (!ihost->hwaddress)
++		if (!session->hwaddress)
+ 			len = sprintf(buf, "%s\n", "default");
+ 		else
+-			len = sprintf(buf, "%s\n", ihost->hwaddress);
++			len = sprintf(buf, "%s\n", session->hwaddress);
+ 		break;
+ 	case ISCSI_HOST_PARAM_INITIATOR_NAME:
+-		if (!ihost->initiatorname)
+-			len = sprintf(buf, "%s\n", "unknown");
+-		else
+-			len = sprintf(buf, "%s\n", ihost->initiatorname);
+-		break;
+-	case ISCSI_HOST_PARAM_IPADDRESS:
+-		if (!strlen(ihost->local_address))
++		if (!session->initiatorname)
+ 			len = sprintf(buf, "%s\n", "unknown");
+ 		else
+-			len = sprintf(buf, "%s\n",
+-				      ihost->local_address);
++			len = sprintf(buf, "%s\n", session->initiatorname);
+ 		break;
++
+ 	default:
+ 		return -ENOSYS;
+ 	}
+@@ -2682,20 +2459,20 @@ EXPORT_SYMBOL_GPL(iscsi_host_get_param);
+ int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param,
+ 			 char *buf, int buflen)
+ {
+-	struct iscsi_host *ihost = shost_priv(shost);
++	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+ 
+ 	switch (param) {
+ 	case ISCSI_HOST_PARAM_NETDEV_NAME:
+-		if (!ihost->netdev)
+-			ihost->netdev = kstrdup(buf, GFP_KERNEL);
++		if (!session->netdev)
++			session->netdev = kstrdup(buf, GFP_KERNEL);
+ 		break;
+ 	case ISCSI_HOST_PARAM_HWADDRESS:
+-		if (!ihost->hwaddress)
+-			ihost->hwaddress = kstrdup(buf, GFP_KERNEL);
++		if (!session->hwaddress)
++			session->hwaddress = kstrdup(buf, GFP_KERNEL);
+ 		break;
+ 	case ISCSI_HOST_PARAM_INITIATOR_NAME:
+-		if (!ihost->initiatorname)
+-			ihost->initiatorname = kstrdup(buf, GFP_KERNEL);
++		if (!session->initiatorname)
++			session->initiatorname = kstrdup(buf, GFP_KERNEL);
+ 		break;
+ 	default:
+ 		return -ENOSYS;
+Index: ofed_kernel/drivers/scsi/scsi_transport_iscsi.c
+===================================================================
+--- ofed_kernel.orig/drivers/scsi/scsi_transport_iscsi.c
++++ ofed_kernel/drivers/scsi/scsi_transport_iscsi.c
+@@ -30,24 +30,23 @@
+ #include <scsi/scsi_transport_iscsi.h>
+ #include <scsi/iscsi_if.h>
+ 
+-#define ISCSI_SESSION_ATTRS 21
++#define ISCSI_SESSION_ATTRS 19
+ #define ISCSI_CONN_ATTRS 13
+ #define ISCSI_HOST_ATTRS 4
+-
+-#define ISCSI_TRANSPORT_VERSION "2.0-870"
++#define ISCSI_TRANSPORT_VERSION "2.0-869"
+ 
+ struct iscsi_internal {
+ 	int daemon_pid;
+ 	struct scsi_transport_template t;
+ 	struct iscsi_transport *iscsi_transport;
+ 	struct list_head list;
+-	struct device dev;
++	struct class_device cdev;
+ 
+-	struct device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
++	struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
+ 	struct transport_container conn_cont;
+-	struct device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
++	struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
+ 	struct transport_container session_cont;
+-	struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
++	struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
+ };
+ 
+ static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
+@@ -64,12 +63,12 @@ static DEFINE_SPINLOCK(iscsi_transport_l
+ #define to_iscsi_internal(tmpl) \
+ 	container_of(tmpl, struct iscsi_internal, t)
+ 
+-#define dev_to_iscsi_internal(_dev) \
+-	container_of(_dev, struct iscsi_internal, dev)
++#define cdev_to_iscsi_internal(_cdev) \
++	container_of(_cdev, struct iscsi_internal, cdev)
+ 
+-static void iscsi_transport_release(struct device *dev)
++static void iscsi_transport_release(struct class_device *cdev)
+ {
+-	struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
++	struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
+ 	kfree(priv);
+ }
+ 
+@@ -79,33 +78,37 @@ static void iscsi_transport_release(stru
+  */
+ static struct class iscsi_transport_class = {
+ 	.name = "iscsi_transport",
+-	.dev_release = iscsi_transport_release,
++	.release = iscsi_transport_release,
+ };
+ 
+ static ssize_t
+-show_transport_handle(struct device *dev, struct device_attribute *attr,
+-		      char *buf)
++show_transport_handle(struct class_device *cdev, char *buf)
+ {
+-	struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
++	struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
+ 	return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
+ }
+-static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
++static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
+ 
+ #define show_transport_attr(name, format)				\
+ static ssize_t								\
+-show_transport_##name(struct device *dev, 				\
+-		      struct device_attribute *attr,char *buf)		\
++show_transport_##name(struct class_device *cdev, char *buf)		\
+ {									\
+-	struct iscsi_internal *priv = dev_to_iscsi_internal(dev);	\
++	struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);	\
+ 	return sprintf(buf, format"\n", priv->iscsi_transport->name);	\
+ }									\
+-static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
++static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
+ 
+ show_transport_attr(caps, "0x%x");
++show_transport_attr(max_lun, "%d");
++show_transport_attr(max_conn, "%d");
++show_transport_attr(max_cmd_len, "%d");
+ 
+ static struct attribute *iscsi_transport_attrs[] = {
+-	&dev_attr_handle.attr,
+-	&dev_attr_caps.attr,
++	&class_device_attr_handle.attr,
++	&class_device_attr_caps.attr,
++	&class_device_attr_max_lun.attr,
++	&class_device_attr_max_conn.attr,
++	&class_device_attr_max_cmd_len.attr,
+ 	NULL,
+ };
+ 
+@@ -113,142 +116,21 @@ static struct attribute_group iscsi_tran
+ 	.attrs = iscsi_transport_attrs,
+ };
+ 
+-/*
+- * iSCSI endpoint attrs
+- */
+-#define iscsi_dev_to_endpoint(_dev) \
+-	container_of(_dev, struct iscsi_endpoint, dev)
+-
+-#define ISCSI_ATTR(_prefix,_name,_mode,_show,_store)	\
+-struct device_attribute dev_attr_##_prefix##_##_name =	\
+-        __ATTR(_name,_mode,_show,_store)
+-
+-static void iscsi_endpoint_release(struct device *dev)
+-{
+-	struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
+-	kfree(ep);
+-}
+-
+-static struct class iscsi_endpoint_class = {
+-	.name = "iscsi_endpoint",
+-	.dev_release = iscsi_endpoint_release,
+-};
+-
+-static ssize_t
+-show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf)
+-{
+-	struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
+-	return sprintf(buf, "%u\n", ep->id);
+-}
+-static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL);
+-
+-static struct attribute *iscsi_endpoint_attrs[] = {
+-	&dev_attr_ep_handle.attr,
+-	NULL,
+-};
+-
+-static struct attribute_group iscsi_endpoint_group = {
+-	.attrs = iscsi_endpoint_attrs,
+-};
+-
+-#define ISCSI_MAX_EPID -1
+-
+-static int iscsi_match_epid(struct device *dev, void *data)
+-{
+-	struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
+-	unsigned int *epid = (unsigned int *) data;
+-
+-	return *epid == ep->id;
+-}
+-
+-struct iscsi_endpoint *
+-iscsi_create_endpoint(int dd_size)
+-{
+-	struct device *dev;
+-	struct iscsi_endpoint *ep;
+-	unsigned int id;
+-	int err;
+-
+-	for (id = 1; id < ISCSI_MAX_EPID; id++) {
+-		dev = class_find_device(&iscsi_endpoint_class, NULL, &id,
+-					iscsi_match_epid);
+-		if (!dev)
+-			break;
+-	}
+-	if (id == ISCSI_MAX_EPID) {
+-		printk(KERN_ERR "Too many connections. Max supported %u\n",
+-		       ISCSI_MAX_EPID - 1);
+-		return NULL;
+-	}
+-
+-	ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL);
+-	if (!ep)
+-		return NULL;
+-
+-	ep->id = id;
+-	ep->dev.class = &iscsi_endpoint_class;
+-	snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%u", id);
+-	err = device_register(&ep->dev);
+-        if (err)
+-                goto free_ep;
+-
+-	err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
+-	if (err)
+-		goto unregister_dev;
+-
+-	if (dd_size)
+-		ep->dd_data = &ep[1];
+-	return ep;
+-
+-unregister_dev:
+-	device_unregister(&ep->dev);
+-	return NULL;
+-
+-free_ep:
+-	kfree(ep);
+-	return NULL;
+-}
+-EXPORT_SYMBOL_GPL(iscsi_create_endpoint);
+-
+-void iscsi_destroy_endpoint(struct iscsi_endpoint *ep)
+-{
+-	sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group);
+-	device_unregister(&ep->dev);
+-}
+-EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint);
+-
+-struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
+-{
+-	struct iscsi_endpoint *ep;
+-	struct device *dev;
+ 
+-	dev = class_find_device(&iscsi_endpoint_class, NULL, &handle,
+-				iscsi_match_epid);
+-	if (!dev)
+-		return NULL;
+-
+-	ep = iscsi_dev_to_endpoint(dev);
+-	/*
+-	 * we can drop this now because the interface will prevent
+-	 * removals and lookups from racing.
+-	 */
+-	put_device(dev);
+-	return ep;
+-}
+-EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
+ 
+ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
+-			    struct device *cdev)
++			    struct class_device *cdev)
+ {
+ 	struct Scsi_Host *shost = dev_to_shost(dev);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 
+ 	memset(ihost, 0, sizeof(*ihost));
+-	atomic_set(&ihost->nr_scans, 0);
++	INIT_LIST_HEAD(&ihost->sessions);
+ 	mutex_init(&ihost->mutex);
++	atomic_set(&ihost->nr_scans, 0);
+ 
+-	snprintf(ihost->scan_workq_name, sizeof(ihost->scan_workq_name),
+-		 "iscsi_scan_%d", shost->host_no);
++	snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d",
++		shost->host_no);
+ 	ihost->scan_workq = create_singlethread_workqueue(
+ 						ihost->scan_workq_name);
+ 	if (!ihost->scan_workq)
+@@ -257,10 +139,10 @@ static int iscsi_setup_host(struct trans
+ }
+ 
+ static int iscsi_remove_host(struct transport_container *tc, struct device *dev,
+-			     struct device *cdev)
++			     struct class_device *cdev)
+ {
+ 	struct Scsi_Host *shost = dev_to_shost(dev);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 
+ 	destroy_workqueue(ihost->scan_workq);
+ 	return 0;
+@@ -403,24 +285,6 @@ static int iscsi_is_session_dev(const st
+ 	return dev->release == iscsi_session_release;
+ }
+ 
+-static int iscsi_iter_session_fn(struct device *dev, void *data)
+-{
+-	void (* fn) (struct iscsi_cls_session *) = data;
+-
+-	if (!iscsi_is_session_dev(dev))
+-		return 0;
+-	fn(iscsi_dev_to_session(dev));
+-	return 0;
+-}
+-
+-void iscsi_host_for_each_session(struct Scsi_Host *shost,
+-				 void (*fn)(struct iscsi_cls_session *))
+-{
+-	device_for_each_child(&shost->shost_gendev, fn,
+-			      iscsi_iter_session_fn);
+-}
+-EXPORT_SYMBOL_GPL(iscsi_host_for_each_session);
+-
+ /**
+  * iscsi_scan_finished - helper to report when running scans are done
+  * @shost: scsi host
+@@ -431,7 +295,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_for_each_se
+  */
+ int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
+ {
+-	struct iscsi_cls_host *ihost = shost->shost_data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 	/*
+ 	 * qla4xxx will have kicked off some session unblocks before calling
+ 	 * scsi_scan_host, so just wait for them to complete.
+@@ -440,61 +304,22 @@ int iscsi_scan_finished(struct Scsi_Host
+ }
+ EXPORT_SYMBOL_GPL(iscsi_scan_finished);
+ 
+-struct iscsi_scan_data {
+-	unsigned int channel;
+-	unsigned int id;
+-	unsigned int lun;
+-};
+-
+-static int iscsi_user_scan_session(struct device *dev, void *data)
++static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
++			   uint id, uint lun)
+ {
+-	struct iscsi_scan_data *scan_data = data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 	struct iscsi_cls_session *session;
+-	struct Scsi_Host *shost;
+-	struct iscsi_cls_host *ihost;
+-	unsigned long flags;
+-	unsigned int id;
+-
+-	if (!iscsi_is_session_dev(dev))
+-		return 0;
+-
+-	session = iscsi_dev_to_session(dev);
+-	shost = iscsi_session_to_shost(session);
+-	ihost = shost->shost_data;
+ 
+ 	mutex_lock(&ihost->mutex);
+-	spin_lock_irqsave(&session->lock, flags);
+-	if (session->state != ISCSI_SESSION_LOGGED_IN) {
+-		spin_unlock_irqrestore(&session->lock, flags);
+-		mutex_unlock(&ihost->mutex);
+-		return 0;
+-	}
+-	id = session->target_id;
+-	spin_unlock_irqrestore(&session->lock, flags);
+-
+-	if (id != ISCSI_MAX_TARGET) {
+-		if ((scan_data->channel == SCAN_WILD_CARD ||
+-		     scan_data->channel == 0) &&
+-		    (scan_data->id == SCAN_WILD_CARD ||
+-		     scan_data->id == id))
+-			scsi_scan_target(&session->dev, 0, id,
+-					 scan_data->lun, 1);
++	list_for_each_entry(session, &ihost->sessions, host_list) {
++		if ((channel == SCAN_WILD_CARD || channel == 0) &&
++		    (id == SCAN_WILD_CARD || id == session->target_id))
++			scsi_scan_target(&session->dev, 0,
++					 session->target_id, lun, 1);
+ 	}
+ 	mutex_unlock(&ihost->mutex);
+-	return 0;
+-}
+-
+-static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
+-			   uint id, uint lun)
+-{
+-	struct iscsi_scan_data scan_data;
+-
+-	scan_data.channel = channel;
+-	scan_data.id = id;
+-	scan_data.lun = lun;
+ 
+-	return device_for_each_child(&shost->shost_gendev, &scan_data,
+-				     iscsi_user_scan_session);
++	return 0;
+ }
+ 
+ static void iscsi_scan_session(struct work_struct *work)
+@@ -502,14 +327,19 @@ static void iscsi_scan_session(struct wo
+ 	struct iscsi_cls_session *session =
+ 			container_of(work, struct iscsi_cls_session, scan_work);
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
+-	struct iscsi_scan_data scan_data;
++	struct iscsi_host *ihost = shost->shost_data;
++	unsigned long flags;
+ 
+-	scan_data.channel = 0;
+-	scan_data.id = SCAN_WILD_CARD;
+-	scan_data.lun = SCAN_WILD_CARD;
++	spin_lock_irqsave(&session->lock, flags);
++	if (session->state != ISCSI_SESSION_LOGGED_IN) {
++		spin_unlock_irqrestore(&session->lock, flags);
++		goto done;
++	}
++	spin_unlock_irqrestore(&session->lock, flags);
+ 
+-	iscsi_user_scan_session(&session->dev, &scan_data);
++	scsi_scan_target(&session->dev, 0, session->target_id,
++			 SCAN_WILD_CARD, 1);
++done:
+ 	atomic_dec(&ihost->nr_scans);
+ }
+ 
+@@ -549,7 +379,7 @@ static void __iscsi_unblock_session(stru
+ 			container_of(work, struct iscsi_cls_session,
+ 				     unblock_work);
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 	unsigned long flags;
+ 
+ 	/*
+@@ -617,19 +447,15 @@ static void __iscsi_unbind_session(struc
+ 			container_of(work, struct iscsi_cls_session,
+ 				     unbind_work);
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
+-	unsigned long flags;
++	struct iscsi_host *ihost = shost->shost_data;
+ 
+ 	/* Prevent new scans and make sure scanning is not in progress */
+ 	mutex_lock(&ihost->mutex);
+-	spin_lock_irqsave(&session->lock, flags);
+-	if (session->target_id == ISCSI_MAX_TARGET) {
+-		spin_unlock_irqrestore(&session->lock, flags);
++	if (list_empty(&session->host_list)) {
+ 		mutex_unlock(&ihost->mutex);
+ 		return;
+ 	}
+-	session->target_id = ISCSI_MAX_TARGET;
+-	spin_unlock_irqrestore(&session->lock, flags);
++	list_del_init(&session->host_list);
+ 	mutex_unlock(&ihost->mutex);
+ 
+ 	scsi_remove_target(&session->dev);
+@@ -639,18 +465,18 @@ static void __iscsi_unbind_session(struc
+ static int iscsi_unbind_session(struct iscsi_cls_session *session)
+ {
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 
+ 	return queue_work(ihost->scan_workq, &session->unbind_work);
+ }
+ 
+ struct iscsi_cls_session *
+-iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
+-		    int dd_size)
++iscsi_alloc_session(struct Scsi_Host *shost,
++		    struct iscsi_transport *transport)
+ {
+ 	struct iscsi_cls_session *session;
+ 
+-	session = kzalloc(sizeof(*session) + dd_size,
++	session = kzalloc(sizeof(*session) + transport->sessiondata_size,
+ 			  GFP_KERNEL);
+ 	if (!session)
+ 		return NULL;
+@@ -659,6 +485,7 @@ iscsi_alloc_session(struct Scsi_Host *sh
+ 	session->recovery_tmo = 120;
+ 	session->state = ISCSI_SESSION_FREE;
+ 	INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
++	INIT_LIST_HEAD(&session->host_list);
+ 	INIT_LIST_HEAD(&session->sess_list);
+ 	INIT_WORK(&session->unblock_work, __iscsi_unblock_session);
+ 	INIT_WORK(&session->block_work, __iscsi_block_session);
+@@ -671,57 +498,22 @@ iscsi_alloc_session(struct Scsi_Host *sh
+ 	session->dev.parent = &shost->shost_gendev;
+ 	session->dev.release = iscsi_session_release;
+ 	device_initialize(&session->dev);
+-	if (dd_size)
++	if (transport->sessiondata_size)
+ 		session->dd_data = &session[1];
+ 	return session;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_alloc_session);
+ 
+-static int iscsi_get_next_target_id(struct device *dev, void *data)
+-{
+-	struct iscsi_cls_session *session;
+-	unsigned long flags;
+-	int err = 0;
+-
+-	if (!iscsi_is_session_dev(dev))
+-		return 0;
+-
+-	session = iscsi_dev_to_session(dev);
+-	spin_lock_irqsave(&session->lock, flags);
+-	if (*((unsigned int *) data) == session->target_id)
+-		err = -EEXIST;
+-	spin_unlock_irqrestore(&session->lock, flags);
+-	return err;
+-}
+-
+ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
+ {
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+-	struct iscsi_cls_host *ihost;
++	struct iscsi_host *ihost;
+ 	unsigned long flags;
+-	unsigned int id = target_id;
+ 	int err;
+ 
+ 	ihost = shost->shost_data;
+ 	session->sid = atomic_add_return(1, &iscsi_session_nr);
+-
+-	if (id == ISCSI_MAX_TARGET) {
+-		for (id = 0; id < ISCSI_MAX_TARGET; id++) {
+-			err = device_for_each_child(&shost->shost_gendev, &id,
+-						    iscsi_get_next_target_id);
+-			if (!err)
+-				break;
+-		}
+-
+-		if (id == ISCSI_MAX_TARGET) {
+-			iscsi_cls_session_printk(KERN_ERR, session,
+-						 "Too many iscsi targets. Max "
+-						 "number of targets is %d.\n",
+-						 ISCSI_MAX_TARGET - 1);
+-			goto release_host;
+-		}
+-	}
+-	session->target_id = id;
++	session->target_id = target_id;
+ 
+ 	snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
+ 		 session->sid);
+@@ -737,6 +529,10 @@ int iscsi_add_session(struct iscsi_cls_s
+ 	list_add(&session->sess_list, &sesslist);
+ 	spin_unlock_irqrestore(&sesslock, flags);
+ 
++	mutex_lock(&ihost->mutex);
++	list_add(&session->host_list, &ihost->sessions);
++	mutex_unlock(&ihost->mutex);
++
+ 	iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION);
+ 	return 0;
+ 
+@@ -750,18 +546,18 @@ EXPORT_SYMBOL_GPL(iscsi_add_session);
+  * iscsi_create_session - create iscsi class session
+  * @shost: scsi host
+  * @transport: iscsi transport
+- * @dd_size: private driver data size
+  * @target_id: which target
+  *
+  * This can be called from a LLD or iscsi_transport.
+  */
+ struct iscsi_cls_session *
+-iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
+-		     int dd_size, unsigned int target_id)
++iscsi_create_session(struct Scsi_Host *shost,
++		     struct iscsi_transport *transport,
++		     unsigned int target_id)
+ {
+ 	struct iscsi_cls_session *session;
+ 
+-	session = iscsi_alloc_session(shost, transport, dd_size);
++	session = iscsi_alloc_session(shost, transport);
+ 	if (!session)
+ 		return NULL;
+ 
+@@ -797,7 +593,7 @@ static int iscsi_iter_destroy_conn_fn(st
+ void iscsi_remove_session(struct iscsi_cls_session *session)
+ {
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+-	struct iscsi_cls_host *ihost = shost->shost_data;
++	struct iscsi_host *ihost = shost->shost_data;
+ 	unsigned long flags;
+ 	int err;
+ 
+@@ -863,7 +659,6 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_session)
+ /**
+  * iscsi_create_conn - create iscsi class connection
+  * @session: iscsi cls session
+- * @dd_size: private driver data size
+  * @cid: connection id
+  *
+  * This can be called from a LLD or iscsi_transport. The connection
+@@ -876,17 +671,18 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_session)
+  * non-zero.
+  */
+ struct iscsi_cls_conn *
+-iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
++iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
+ {
+ 	struct iscsi_transport *transport = session->transport;
+ 	struct iscsi_cls_conn *conn;
+ 	unsigned long flags;
+ 	int err;
+ 
+-	conn = kzalloc(sizeof(*conn) + dd_size, GFP_KERNEL);
++	conn = kzalloc(sizeof(*conn) + transport->conndata_size, GFP_KERNEL);
+ 	if (!conn)
+ 		return NULL;
+-	if (dd_size)
++
++	if (transport->conndata_size)
+ 		conn->dd_data = &conn[1];
+ 
+ 	INIT_LIST_HEAD(&conn->conn_list);
+@@ -1219,20 +1015,21 @@ int iscsi_session_event(struct iscsi_cls
+ EXPORT_SYMBOL_GPL(iscsi_session_event);
+ 
+ static int
+-iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
+-			struct iscsi_uevent *ev, uint32_t initial_cmdsn,
+-			uint16_t cmds_max, uint16_t queue_depth)
++iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
+ {
+ 	struct iscsi_transport *transport = priv->iscsi_transport;
+ 	struct iscsi_cls_session *session;
+-	uint32_t host_no;
++	uint32_t hostno;
+ 
+-	session = transport->create_session(ep, cmds_max, queue_depth,
+-					    initial_cmdsn, &host_no);
++	session = transport->create_session(transport, &priv->t,
++					    ev->u.c_session.cmds_max,
++					    ev->u.c_session.queue_depth,
++					    ev->u.c_session.initial_cmdsn,
++					    &hostno);
+ 	if (!session)
+ 		return -ENOMEM;
+ 
+-	ev->r.c_session_ret.host_no = host_no;
++	ev->r.c_session_ret.host_no = hostno;
+ 	ev->r.c_session_ret.sid = session->sid;
+ 	return 0;
+ }
+@@ -1307,7 +1104,6 @@ static int
+ iscsi_if_transport_ep(struct iscsi_transport *transport,
+ 		      struct iscsi_uevent *ev, int msg_type)
+ {
+-	struct iscsi_endpoint *ep;
+ 	struct sockaddr *dst_addr;
+ 	int rc = 0;
+ 
+@@ -1317,33 +1113,22 @@ iscsi_if_transport_ep(struct iscsi_trans
+ 			return -EINVAL;
+ 
+ 		dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
+-		ep = transport->ep_connect(dst_addr,
+-					   ev->u.ep_connect.non_blocking);
+-		if (IS_ERR(ep))
+-			return PTR_ERR(ep);
+-
+-		ev->r.ep_connect_ret.handle = ep->id;
++		rc = transport->ep_connect(dst_addr,
++					   ev->u.ep_connect.non_blocking,
++					   &ev->r.ep_connect_ret.handle);
+ 		break;
+ 	case ISCSI_UEVENT_TRANSPORT_EP_POLL:
+ 		if (!transport->ep_poll)
+ 			return -EINVAL;
+ 
+-		ep = iscsi_lookup_endpoint(ev->u.ep_poll.ep_handle);
+-		if (!ep)
+-			return -EINVAL;
+-
+-		ev->r.retcode = transport->ep_poll(ep,
++		ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle,
+ 						   ev->u.ep_poll.timeout_ms);
+ 		break;
+ 	case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+ 		if (!transport->ep_disconnect)
+ 			return -EINVAL;
+ 
+-		ep = iscsi_lookup_endpoint(ev->u.ep_disconnect.ep_handle);
+-		if (!ep)
+-			return -EINVAL;
+-
+-		transport->ep_disconnect(ep);
++		transport->ep_disconnect(ev->u.ep_disconnect.ep_handle);
+ 		break;
+ 	}
+ 	return rc;
+@@ -1408,7 +1193,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
+ 	struct iscsi_internal *priv;
+ 	struct iscsi_cls_session *session;
+ 	struct iscsi_cls_conn *conn;
+-	struct iscsi_endpoint *ep = NULL;
+ 
+ 	priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
+ 	if (!priv)
+@@ -1422,22 +1206,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
+ 
+ 	switch (nlh->nlmsg_type) {
+ 	case ISCSI_UEVENT_CREATE_SESSION:
+-		err = iscsi_if_create_session(priv, ep, ev,
+-					      ev->u.c_session.initial_cmdsn,
+-					      ev->u.c_session.cmds_max,
+-					      ev->u.c_session.queue_depth);
+-		break;
+-	case ISCSI_UEVENT_CREATE_BOUND_SESSION:
+-		ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle);
+-		if (!ep) {
+-			err = -EINVAL;
+-			break;
+-		}
+-
+-		err = iscsi_if_create_session(priv, ep, ev,
+-					ev->u.c_bound_session.initial_cmdsn,
+-					ev->u.c_bound_session.cmds_max,
+-					ev->u.c_bound_session.queue_depth);
++		err = iscsi_if_create_session(priv, ev);
+ 		break;
+ 	case ISCSI_UEVENT_DESTROY_SESSION:
+ 		session = iscsi_session_lookup(ev->u.d_session.sid);
+@@ -1568,8 +1337,11 @@ iscsi_if_rx(struct sk_buff *skb)
+ 	mutex_unlock(&rx_queue_mutex);
+ }
+ 
++#define iscsi_cdev_to_conn(_cdev) \
++	iscsi_dev_to_conn(_cdev->dev)
++
+ #define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store)		\
+-struct device_attribute dev_attr_##_prefix##_##_name =	\
++struct class_device_attribute class_device_attr_##_prefix##_##_name =	\
+ 	__ATTR(_name,_mode,_show,_store)
+ 
+ /*
+@@ -1577,10 +1349,9 @@ struct device_attribute dev_attr_##_pref
+  */
+ #define iscsi_conn_attr_show(param)					\
+ static ssize_t								\
+-show_conn_param_##param(struct device *dev, 				\
+-			struct device_attribute *attr, char *buf)	\
++show_conn_param_##param(struct class_device *cdev, char *buf)		\
+ {									\
+-	struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent);	\
++	struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev);		\
+ 	struct iscsi_transport *t = conn->transport;			\
+ 	return t->get_conn_param(conn, param, buf);			\
+ }
+@@ -1604,16 +1375,17 @@ iscsi_conn_attr(address, ISCSI_PARAM_CON
+ iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO);
+ iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO);
+ 
++#define iscsi_cdev_to_session(_cdev) \
++	iscsi_dev_to_session(_cdev->dev)
++
+ /*
+  * iSCSI session attrs
+  */
+ #define iscsi_session_attr_show(param, perm)				\
+ static ssize_t								\
+-show_session_param_##param(struct device *dev,				\
+-			   struct device_attribute *attr, char *buf)	\
++show_session_param_##param(struct class_device *cdev, char *buf)	\
+ {									\
+-	struct iscsi_cls_session *session = 				\
+-		iscsi_dev_to_session(dev->parent);			\
++	struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
+ 	struct iscsi_transport *t = session->transport;			\
+ 									\
+ 	if (perm && !capable(CAP_SYS_ADMIN))				\
+@@ -1643,14 +1415,11 @@ iscsi_session_attr(password_in, ISCSI_PA
+ iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0);
+ iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0);
+ iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0);
+-iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0);
+-iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0)
+ 
+ static ssize_t
+-show_priv_session_state(struct device *dev, struct device_attribute *attr,
+-			char *buf)
++show_priv_session_state(struct class_device *cdev, char *buf)
+ {
+-	struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
++	struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);
+ 	return sprintf(buf, "%s\n", iscsi_session_state_name(session->state));
+ }
+ static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
+@@ -1658,11 +1427,9 @@ static ISCSI_CLASS_ATTR(priv_sess, state
+ 
+ #define iscsi_priv_session_attr_show(field, format)			\
+ static ssize_t								\
+-show_priv_session_##field(struct device *dev, 				\
+-			  struct device_attribute *attr, char *buf)	\
++show_priv_session_##field(struct class_device *cdev, char *buf)		\
+ {									\
+-	struct iscsi_cls_session *session = 				\
+-			iscsi_dev_to_session(dev->parent);		\
++	struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\
+ 	return sprintf(buf, format"\n", session->field);		\
+ }
+ 
+@@ -1677,10 +1444,9 @@ iscsi_priv_session_attr(recovery_tmo, "%
+  */
+ #define iscsi_host_attr_show(param)					\
+ static ssize_t								\
+-show_host_param_##param(struct device *dev, 				\
+-			struct device_attribute *attr, char *buf)	\
++show_host_param_##param(struct class_device *cdev, char *buf)		\
+ {									\
+-	struct Scsi_Host *shost = transport_class_to_shost(dev);	\
++	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
+ 	struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
+ 	return priv->iscsi_transport->get_host_param(shost, param, buf); \
+ }
+@@ -1697,7 +1463,7 @@ iscsi_host_attr(initiatorname, ISCSI_HOS
+ 
+ #define SETUP_PRIV_SESSION_RD_ATTR(field)				\
+ do {									\
+-	priv->session_attrs[count] = &dev_attr_priv_sess_##field; \
++	priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
+ 	count++;							\
+ } while (0)
+ 
+@@ -1705,7 +1471,7 @@ do {									\
+ #define SETUP_SESSION_RD_ATTR(field, param_flag)			\
+ do {									\
+ 	if (tt->param_mask & param_flag) {				\
+-		priv->session_attrs[count] = &dev_attr_sess_##field; \
++		priv->session_attrs[count] = &class_device_attr_sess_##field; \
+ 		count++;						\
+ 	}								\
+ } while (0)
+@@ -1713,7 +1479,7 @@ do {									\
+ #define SETUP_CONN_RD_ATTR(field, param_flag)				\
+ do {									\
+ 	if (tt->param_mask & param_flag) {				\
+-		priv->conn_attrs[count] = &dev_attr_conn_##field; \
++		priv->conn_attrs[count] = &class_device_attr_conn_##field; \
+ 		count++;						\
+ 	}								\
+ } while (0)
+@@ -1721,7 +1487,7 @@ do {									\
+ #define SETUP_HOST_RD_ATTR(field, param_flag)				\
+ do {									\
+ 	if (tt->host_param_mask & param_flag) {				\
+-		priv->host_attrs[count] = &dev_attr_host_##field; \
++		priv->host_attrs[count] = &class_device_attr_host_##field; \
+ 		count++;						\
+ 	}								\
+ } while (0)
+@@ -1811,24 +1577,22 @@ iscsi_register_transport(struct iscsi_tr
+ 	priv->daemon_pid = -1;
+ 	priv->iscsi_transport = tt;
+ 	priv->t.user_scan = iscsi_user_scan;
+-	if (!(tt->caps & CAP_DATA_PATH_OFFLOAD))
+-		priv->t.create_work_queue = 1;
+ 
+-	priv->dev.class = &iscsi_transport_class;
+-	snprintf(priv->dev.bus_id, BUS_ID_SIZE, "%s", tt->name);
+-	err = device_register(&priv->dev);
++	priv->cdev.class = &iscsi_transport_class;
++	snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
++	err = class_device_register(&priv->cdev);
+ 	if (err)
+ 		goto free_priv;
+ 
+-	err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
++	err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
+ 	if (err)
+-		goto unregister_dev;
++		goto unregister_cdev;
+ 
+ 	/* host parameters */
+ 	priv->t.host_attrs.ac.attrs = &priv->host_attrs[0];
+ 	priv->t.host_attrs.ac.class = &iscsi_host_class.class;
+ 	priv->t.host_attrs.ac.match = iscsi_host_match;
+-	priv->t.host_size = sizeof(struct iscsi_cls_host);
++	priv->t.host_size = sizeof(struct iscsi_host);
+ 	transport_container_register(&priv->t.host_attrs);
+ 
+ 	SETUP_HOST_RD_ATTR(netdev, ISCSI_HOST_NETDEV_NAME);
+@@ -1886,8 +1650,6 @@ iscsi_register_transport(struct iscsi_tr
+ 	SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT);
+ 	SETUP_SESSION_RD_ATTR(abort_tmo, ISCSI_ABORT_TMO);
+ 	SETUP_SESSION_RD_ATTR(lu_reset_tmo,ISCSI_LU_RESET_TMO);
+-	SETUP_SESSION_RD_ATTR(ifacename, ISCSI_IFACE_NAME);
+-	SETUP_SESSION_RD_ATTR(initiatorname, ISCSI_INITIATOR_NAME);
+ 	SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
+ 	SETUP_PRIV_SESSION_RD_ATTR(state);
+ 
+@@ -1901,9 +1663,8 @@ iscsi_register_transport(struct iscsi_tr
+ 	printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
+ 	return &priv->t;
+ 
+-unregister_dev:
+-	device_unregister(&priv->dev);
+-	return NULL;
++unregister_cdev:
++	class_device_unregister(&priv->cdev);
+ free_priv:
+ 	kfree(priv);
+ 	return NULL;
+@@ -1930,8 +1691,8 @@ int iscsi_unregister_transport(struct is
+ 	transport_container_unregister(&priv->session_cont);
+ 	transport_container_unregister(&priv->t.host_attrs);
+ 
+-	sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group);
+-	device_unregister(&priv->dev);
++	sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
++	class_device_unregister(&priv->cdev);
+ 	mutex_unlock(&rx_queue_mutex);
+ 
+ 	return 0;
+@@ -1951,13 +1712,9 @@ static __init int iscsi_transport_init(v
+ 	if (err)
+ 		return err;
+ 
+-	err = class_register(&iscsi_endpoint_class);
+-	if (err)
+-		goto unregister_transport_class;
+-
+ 	err = transport_class_register(&iscsi_host_class);
+ 	if (err)
+-		goto unregister_endpoint_class;
++		goto unregister_transport_class;
+ 
+ 	err = transport_class_register(&iscsi_connection_class);
+ 	if (err)
+@@ -1967,8 +1724,8 @@ static __init int iscsi_transport_init(v
+ 	if (err)
+ 		goto unregister_conn_class;
+ 
+-	nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx,
+-				    NULL, THIS_MODULE);
++	nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
++			THIS_MODULE);
+ 	if (!nls) {
+ 		err = -ENOBUFS;
+ 		goto unregister_session_class;
+@@ -1988,8 +1745,6 @@ unregister_conn_class:
+ 	transport_class_unregister(&iscsi_connection_class);
+ unregister_host_class:
+ 	transport_class_unregister(&iscsi_host_class);
+-unregister_endpoint_class:
+-	class_unregister(&iscsi_endpoint_class);
+ unregister_transport_class:
+ 	class_unregister(&iscsi_transport_class);
+ 	return err;
+@@ -2002,7 +1757,6 @@ static void __exit iscsi_transport_exit(
+ 	transport_class_unregister(&iscsi_connection_class);
+ 	transport_class_unregister(&iscsi_session_class);
+ 	transport_class_unregister(&iscsi_host_class);
+-	class_unregister(&iscsi_endpoint_class);
+ 	class_unregister(&iscsi_transport_class);
+ }
+ 
+Index: ofed_kernel/include/scsi/libiscsi.h
+===================================================================
+--- ofed_kernel.orig/include/scsi/libiscsi.h
++++ ofed_kernel/include/scsi/libiscsi.h
+@@ -24,7 +24,6 @@
+ #define LIBISCSI_H
+ 
+ #include <linux/types.h>
+-#include <linux/wait.h>
+ #include <linux/mutex.h>
+ #include <linux/timer.h>
+ #include <linux/workqueue.h>
+@@ -32,7 +31,6 @@
+ #include <scsi/iscsi_if.h>
+ 
+ struct scsi_transport_template;
+-struct scsi_host_template;
+ struct scsi_device;
+ struct Scsi_Host;
+ struct scsi_cmnd;
+@@ -42,7 +40,6 @@ struct iscsi_cls_session;
+ struct iscsi_cls_conn;
+ struct iscsi_session;
+ struct iscsi_nopin;
+-struct device;
+ 
+ /* #define DEBUG_SCSI */
+ #ifdef DEBUG_SCSI
+@@ -52,7 +49,9 @@ struct device;
+ #endif
+ 
+ #define ISCSI_DEF_XMIT_CMDS_MAX	128	/* must be power of 2 */
+-#define ISCSI_MGMT_CMDS_MAX	15
++#define ISCSI_MGMT_CMDS_MAX	16	/* must be power of 2 */
++
++#define ISCSI_MGMT_ITT_OFFSET	0xa00
+ 
+ #define ISCSI_DEF_CMD_PER_LUN		32
+ #define ISCSI_MAX_CMD_PER_LUN		128
+@@ -70,10 +69,7 @@ enum {
+ /* Connection suspend "bit" */
+ #define ISCSI_SUSPEND_BIT		1
+ 
+-#define ISCSI_ITT_MASK			(0x1fff)
+-#define ISCSI_TOTAL_CMDS_MAX		4096
+-/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */
+-#define ISCSI_TOTAL_CMDS_MIN		16
++#define ISCSI_ITT_MASK			(0xfff)
+ #define ISCSI_AGE_SHIFT			28
+ #define ISCSI_AGE_MASK			(0xf << ISCSI_AGE_SHIFT)
+ 
+@@ -86,6 +82,18 @@ enum {
+ 	ISCSI_DIGEST_SIZE = sizeof(__u32),
+ };
+ 
++struct iscsi_mgmt_task {
++	/*
++	 * Becuae LLDs allocate their hdr differently, this is a pointer to
++	 * that storage. It must be setup at session creation time.
++	 */
++	struct iscsi_hdr	*hdr;
++	char			*data;		/* mgmt payload */
++	unsigned		data_count;	/* counts data to be sent */
++	uint32_t		itt;		/* this ITT */
++	void			*dd_data;	/* driver/transport data */
++	struct list_head	running;
++};
+ 
+ enum {
+ 	ISCSI_TASK_COMPLETED,
+@@ -93,7 +101,7 @@ enum {
+ 	ISCSI_TASK_RUNNING,
+ };
+ 
+-struct iscsi_task {
++struct iscsi_cmd_task {
+ 	/*
+ 	 * Because LLDs allocate their hdr differently, this is a pointer
+ 	 * and length to that storage. It must be setup at session
+@@ -110,7 +118,6 @@ struct iscsi_task {
+ 	/* offset in unsolicited stream (bytes); */
+ 	unsigned		unsol_offset;
+ 	unsigned		data_count;	/* remaining Data-Out */
+-	char			*data;		/* mgmt payload */
+ 	struct scsi_cmnd	*sc;		/* associated SCSI cmd*/
+ 	struct iscsi_conn	*conn;		/* used connection    */
+ 
+@@ -121,9 +128,9 @@ struct iscsi_task {
+ 	void			*dd_data;	/* driver/transport data */
+ };
+ 
+-static inline void* iscsi_next_hdr(struct iscsi_task *task)
++static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask)
+ {
+-	return (void*)task->hdr + task->hdr_len;
++	return (void*)ctask->hdr + ctask->hdr_len;
+ }
+ 
+ /* Connection's states */
+@@ -139,6 +146,11 @@ struct iscsi_conn {
+ 	void			*dd_data;	/* iscsi_transport data */
+ 	struct iscsi_session	*session;	/* parent session */
+ 	/*
++	 * LLDs should set this lock. It protects the transport recv
++	 * code
++	 */
++	rwlock_t		*recv_lock;
++	/*
+ 	 * conn_stop() flag: stop to recover, stop to terminate
+ 	 */
+         int			stop_stage;
+@@ -147,7 +159,7 @@ struct iscsi_conn {
+ 	unsigned long		last_ping;
+ 	int			ping_timeout;
+ 	int			recv_timeout;
+-	struct iscsi_task 	*ping_task;
++	struct iscsi_mgmt_task	*ping_mtask;
+ 
+ 	/* iSCSI connection-wide sequencing */
+ 	uint32_t		exp_statsn;
+@@ -163,8 +175,9 @@ struct iscsi_conn {
+ 	 * should always fit in this buffer
+ 	 */
+ 	char			*data;
+-	struct iscsi_task 	*login_task;	/* mtask used for login/text */
+-	struct iscsi_task	*task;		/* xmit task in progress */
++	struct iscsi_mgmt_task	*login_mtask;	/* mtask used for login/text */
++	struct iscsi_mgmt_task	*mtask;		/* xmit mtask in progress */
++	struct iscsi_cmd_task	*ctask;		/* xmit ctask in progress */
+ 
+ 	/* xmit */
+ 	struct list_head	mgmtqueue;	/* mgmt (control) xmit queue */
+@@ -195,6 +208,9 @@ struct iscsi_conn {
+ 	/* remote portal currently connected to */
+ 	int			portal_port;
+ 	char			portal_address[ISCSI_ADDRESS_BUF_LEN];
++	/* local address */
++	int			local_port;
++	char			local_address[ISCSI_ADDRESS_BUF_LEN];
+ 
+ 	/* MIB-statistics */
+ 	uint64_t		txdata_octets;
+@@ -209,7 +225,6 @@ struct iscsi_conn {
+ 
+ 	/* custom statistics */
+ 	uint32_t		eh_abort_cnt;
+-	uint32_t		fmr_unalign_cnt;
+ };
+ 
+ struct iscsi_pool {
+@@ -230,7 +245,6 @@ enum {
+ };
+ 
+ struct iscsi_session {
+-	struct iscsi_cls_session *cls_session;
+ 	/*
+ 	 * Syncs up the scsi eh thread with the iscsi eh thread when sending
+ 	 * task management functions. This must be taken before the session
+@@ -266,8 +280,10 @@ struct iscsi_session {
+ 	char			*password;
+ 	char			*password_in;
+ 	char			*targetname;
+-	char			*ifacename;
+ 	char			*initiatorname;
++	/* hw address or netdev iscsi connection is bound to */
++	char			*hwaddress;
++	char			*netdev;
+ 	/* control data */
+ 	struct iscsi_transport	*tt;
+ 	struct Scsi_Host	*host;
+@@ -281,20 +297,12 @@ struct iscsi_session {
+ 	int			state;		/* session state           */
+ 	int			age;		/* counts session re-opens */
+ 
+-	int			scsi_cmds_max; 	/* max scsi commands */
+ 	int			cmds_max;	/* size of cmds array */
+-	struct iscsi_task	**cmds;		/* Original Cmds arr */
++	struct iscsi_cmd_task	**cmds;		/* Original Cmds arr */
+ 	struct iscsi_pool	cmdpool;	/* PDU's pool */
+-};
+-
+-struct iscsi_host {
+-	char			*initiatorname;
+-	/* hw address or netdev iscsi connection is bound to */
+-	char			*hwaddress;
+-	char			*netdev;
+-	/* local address */
+-	int			local_port;
+-	char			local_address[ISCSI_ADDRESS_BUF_LEN];
++	int			mgmtpool_max;	/* size of mgmt array */
++	struct iscsi_mgmt_task	**mgmt_cmds;	/* Original mgmt arr */
++	struct iscsi_pool	mgmtpool;	/* Mgmt PDU's pool */
+ };
+ 
+ /*
+@@ -307,44 +315,42 @@ extern int iscsi_eh_device_reset(struct 
+ extern int iscsi_queuecommand(struct scsi_cmnd *sc,
+ 			      void (*done)(struct scsi_cmnd *));
+ 
++
+ /*
+  * iSCSI host helpers.
+  */
+-#define iscsi_host_priv(_shost) \
+-	(shost_priv(_shost) + sizeof(struct iscsi_host))
+-
+ extern int iscsi_host_set_param(struct Scsi_Host *shost,
+ 				enum iscsi_host_param param, char *buf,
+ 				int buflen);
+ extern int iscsi_host_get_param(struct Scsi_Host *shost,
+ 				enum iscsi_host_param param, char *buf);
+-extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
+-extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
+-					  int dd_data_size, uint16_t qdepth);
+-extern void iscsi_host_remove(struct Scsi_Host *shost);
+-extern void iscsi_host_free(struct Scsi_Host *shost);
+ 
+ /*
+  * session management
+  */
+ extern struct iscsi_cls_session *
+-iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
+-		    uint16_t, int, uint32_t, unsigned int);
++iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
++		    uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
+ extern void iscsi_session_teardown(struct iscsi_cls_session *);
++extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
+ extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
+ extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
+ 			   enum iscsi_param param, char *buf, int buflen);
+ extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
+ 				   enum iscsi_param param, char *buf);
+ 
++#define session_to_cls(_sess) \
++	hostdata_session(_sess->host->hostdata)
++
+ #define iscsi_session_printk(prefix, _sess, fmt, a...)	\
+-	iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a)
++	iscsi_cls_session_printk(prefix,		\
++		(struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a)
+ 
+ /*
+  * connection management
+  */
+ extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *,
+-					       int, uint32_t);
++					       uint32_t);
+ extern void iscsi_conn_teardown(struct iscsi_cls_conn *);
+ extern int iscsi_conn_start(struct iscsi_cls_conn *);
+ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
+@@ -353,29 +359,25 @@ extern int iscsi_conn_bind(struct iscsi_
+ extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
+ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
+ 				enum iscsi_param param, char *buf);
+-extern void iscsi_suspend_tx(struct iscsi_conn *conn);
+ 
+ #define iscsi_conn_printk(prefix, _c, fmt, a...) \
+-	iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
+-			      fmt, ##a)
++	iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a)
+ 
+ /*
+  * pdu and task processing
+  */
+ extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
+-extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *,
++extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
+ 					struct iscsi_data *hdr);
+ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
+ 				char *, uint32_t);
+ extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
+ 			      char *, int);
+-extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
+-				char *, int);
+-extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
+-extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
+-extern void iscsi_requeue_task(struct iscsi_task *task);
+-extern void iscsi_put_task(struct iscsi_task *task);
+-extern void __iscsi_get_task(struct iscsi_task *task);
++extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *,
++			    uint32_t *);
++extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
++extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
++				 struct iscsi_mgmt_task *mtask);
+ 
+ /*
+  * generic helpers
+Index: ofed_kernel/include/scsi/scsi_transport_iscsi.h
+===================================================================
+--- ofed_kernel.orig/include/scsi/scsi_transport_iscsi.h
++++ ofed_kernel/include/scsi/scsi_transport_iscsi.h
+@@ -30,11 +30,11 @@
+ 
+ struct scsi_transport_template;
+ struct iscsi_transport;
+-struct iscsi_endpoint;
+ struct Scsi_Host;
+ struct iscsi_cls_conn;
+ struct iscsi_conn;
+-struct iscsi_task;
++struct iscsi_cmd_task;
++struct iscsi_mgmt_task;
+ struct sockaddr;
+ 
+ /**
+@@ -58,22 +58,19 @@ struct sockaddr;
+  * @stop_conn:		suspend/recover/terminate connection
+  * @send_pdu:		send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
+  * @session_recovery_timedout: notify LLD a block during recovery timed out
+- * @init_task:		Initialize a iscsi_task and any internal structs.
+- *			When offloading the data path, this is called from
+- *			queuecommand with the session lock, or from the
+- *			iscsi_conn_send_pdu context with the session lock.
+- *			When not offloading the data path, this is called
+- *			from the scsi work queue without the session lock.
+- * @xmit_task		Requests LLD to transfer cmd task. Returns 0 or the
++ * @init_cmd_task:	Initialize a iscsi_cmd_task and any internal structs.
++ *			Called from queuecommand with session lock held.
++ * @init_mgmt_task:	Initialize a iscsi_mgmt_task and any internal structs.
++ *			Called from iscsi_conn_send_generic with xmitmutex.
++ * @xmit_cmd_task:	Requests LLD to transfer cmd task. Returns 0 or the
+  *			the number of bytes transferred on success, and -Exyz
+- *			value on error. When offloading the data path, this
+- *			is called from queuecommand with the session lock, or
+- *			from the iscsi_conn_send_pdu context with the session
+- *			lock. When not offloading the data path, this is called
+- *			from the scsi work queue without the session lock.
+- * @cleanup_task:	requests LLD to fail task. Called with session lock
+- *			and after the connection has been suspended and
+- *			terminated during recovery. If called
++ *			value on error.
++ * @xmit_mgmt_task:	Requests LLD to transfer mgmt task. Returns 0 or the
++ *			the number of bytes transferred on success, and -Exyz
++ *			value on error.
++ * @cleanup_cmd_task:	requests LLD to fail cmd task. Called with xmitmutex
++ *			and session->lock after the connection has been
++ *			suspended and terminated during recovery. If called
+  *			from abort task then connection is not suspended
+  *			or terminated but sk_callback_lock is held
+  *
+@@ -86,9 +83,17 @@ struct iscsi_transport {
+ 	/* LLD sets this to indicate what values it can export to sysfs */
+ 	uint64_t param_mask;
+ 	uint64_t host_param_mask;
+-	struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,
+-					uint16_t cmds_max, uint16_t qdepth,
+-					uint32_t sn, uint32_t *hn);
++	struct scsi_host_template *host_template;
++	/* LLD connection data size */
++	int conndata_size;
++	/* LLD session data size */
++	int sessiondata_size;
++	int max_lun;
++	unsigned int max_conn;
++	unsigned int max_cmd_len;
++	struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
++		struct scsi_transport_template *t, uint16_t, uint16_t,
++		uint32_t sn, uint32_t *hn);
+ 	void (*destroy_session) (struct iscsi_cls_session *session);
+ 	struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
+ 				uint32_t cid);
+@@ -113,15 +118,20 @@ struct iscsi_transport {
+ 			 char *data, uint32_t data_size);
+ 	void (*get_stats) (struct iscsi_cls_conn *conn,
+ 			   struct iscsi_stats *stats);
+-	int (*init_task) (struct iscsi_task *task);
+-	int (*xmit_task) (struct iscsi_task *task);
+-	void (*cleanup_task) (struct iscsi_conn *conn,
+-				  struct iscsi_task *task);
++	int (*init_cmd_task) (struct iscsi_cmd_task *ctask);
++	void (*init_mgmt_task) (struct iscsi_conn *conn,
++				struct iscsi_mgmt_task *mtask);
++	int (*xmit_cmd_task) (struct iscsi_conn *conn,
++			      struct iscsi_cmd_task *ctask);
++	void (*cleanup_cmd_task) (struct iscsi_conn *conn,
++				  struct iscsi_cmd_task *ctask);
++	int (*xmit_mgmt_task) (struct iscsi_conn *conn,
++			       struct iscsi_mgmt_task *mtask);
+ 	void (*session_recovery_timedout) (struct iscsi_cls_session *session);
+-	struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr,
+-					      int non_blocking);
+-	int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms);
+-	void (*ep_disconnect) (struct iscsi_endpoint *ep);
++	int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking,
++			   uint64_t *ep_handle);
++	int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
++	void (*ep_disconnect) (uint64_t ep_handle);
+ 	int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
+ 			  uint32_t enable, struct sockaddr *dst_addr);
+ };
+@@ -162,10 +172,9 @@ enum {
+ 	ISCSI_SESSION_FREE,
+ };
+ 
+-#define ISCSI_MAX_TARGET -1
+-
+ struct iscsi_cls_session {
+ 	struct list_head sess_list;		/* item in session_list */
++	struct list_head host_list;
+ 	struct iscsi_transport *transport;
+ 	spinlock_t lock;
+ 	struct work_struct block_work;
+@@ -177,7 +186,7 @@ struct iscsi_cls_session {
+ 	int recovery_tmo;
+ 	struct delayed_work recovery_work;
+ 
+-	unsigned int target_id;
++	int target_id;
+ 
+ 	int state;
+ 	int sid;				/* session id */
+@@ -194,20 +203,12 @@ struct iscsi_cls_session {
+ #define starget_to_session(_stgt) \
+ 	iscsi_dev_to_session(_stgt->dev.parent)
+ 
+-struct iscsi_cls_host {
++struct iscsi_host {
++	struct list_head sessions;
+ 	atomic_t nr_scans;
+ 	struct mutex mutex;
+ 	struct workqueue_struct *scan_workq;
+-	char scan_workq_name[20];
+-};
+-
+-extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
+-				void (*fn)(struct iscsi_cls_session *));
+-
+-struct iscsi_endpoint {
+-	void *dd_data;			/* LLD private data */
+-	struct device dev;
+-	unsigned int id;
++	char scan_workq_name[KOBJ_NAME_LEN];
+ };
+ 
+ /*
+@@ -221,26 +222,22 @@ struct iscsi_endpoint {
+ 
+ extern int iscsi_session_chkready(struct iscsi_cls_session *session);
+ extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost,
+-				struct iscsi_transport *transport, int dd_size);
++					struct iscsi_transport *transport);
+ extern int iscsi_add_session(struct iscsi_cls_session *session,
+ 			     unsigned int target_id);
+ extern int iscsi_session_event(struct iscsi_cls_session *session,
+ 			       enum iscsi_uevent_e event);
+ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
+ 						struct iscsi_transport *t,
+-						int dd_size,
+ 						unsigned int target_id);
+ extern void iscsi_remove_session(struct iscsi_cls_session *session);
+ extern void iscsi_free_session(struct iscsi_cls_session *session);
+ extern int iscsi_destroy_session(struct iscsi_cls_session *session);
+ extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
+-						int dd_size, uint32_t cid);
++					    uint32_t cid);
+ extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
+ extern void iscsi_unblock_session(struct iscsi_cls_session *session);
+ extern void iscsi_block_session(struct iscsi_cls_session *session);
+ extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
+-extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
+-extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
+-extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
+ 
+ #endif
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_02_count_fmr_align_violations.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_02_count_fmr_align_violations.patch
new file mode 100644
index 0000000..1375b29
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_02_count_fmr_align_violations.patch
@@ -0,0 +1,25 @@
+From 02753dd2caabfe6b1885cb80a8fb8532b416108d Mon Sep 17 00:00:00 2001
+From: Eli Dorfman <elid at voltaire.com>
+Date: Tue, 29 Apr 2008 10:12:39 +0300
+Subject: [PATCH] IB/iSER: Count fmr alignment violations per session
+
+Count fmr alignment violations per session
+as part of the iscsi statistics.
+
+Signed-off-by: Eli Dorfman <elid at voltaire.com>
+---
+ include/scsi/libiscsi.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: ofed_kernel/include/scsi/libiscsi.h
+===================================================================
+--- ofed_kernel.orig/include/scsi/libiscsi.h
++++ ofed_kernel/include/scsi/libiscsi.h
+@@ -225,6 +225,7 @@ struct iscsi_conn {
+ 
+ 	/* custom statistics */
+ 	uint32_t		eh_abort_cnt;
++	uint32_t		fmr_unalign_cnt;
+ };
+ 
+ struct iscsi_pool {
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_03_compat_patch_for_RHEL5_and_SLES10.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_03_compat_patch_for_RHEL5_and_SLES10.patch
new file mode 100644
index 0000000..57fd421
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iscsi_03_compat_patch_for_RHEL5_and_SLES10.patch
@@ -0,0 +1,160 @@
+From 66ab30f8dadef133bd04bbdcb434a7f742821bed Mon Sep 17 00:00:00 2001
+From: Doron Shoham <dorons at voltaire.com>
+Date: Sun, 29 Jun 2008 15:41:12 +0300
+Subject: [PATCH] copmat patch for RHEL5 and SLES10
+
+Signed-off-by: Doron Shoham <dorons at voltaire.com>
+---
+ drivers/scsi/scsi_transport_iscsi.c |   97 +++++++++++++++++++++---------------
+ 1 file changed, 57 insertions(+), 40 deletions(-)
+
+Index: ofa_kernel-1.4/drivers/scsi/scsi_transport_iscsi.c
+===================================================================
+--- ofa_kernel-1.4.orig/drivers/scsi/scsi_transport_iscsi.c
++++ ofa_kernel-1.4/drivers/scsi/scsi_transport_iscsi.c
+@@ -20,6 +20,8 @@
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
++#include <linux/version.h>
++#include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <net/tcp.h>
+@@ -378,8 +380,10 @@ static void __iscsi_unblock_session(stru
+ 	struct iscsi_cls_session *session =
+ 			container_of(work, struct iscsi_cls_session,
+ 				     unblock_work);
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+ 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
+ 	struct iscsi_host *ihost = shost->shost_data;
++#endif
+ 	unsigned long flags;
+ 
+ 	/*
+@@ -397,10 +401,12 @@ static void __iscsi_unblock_session(stru
+ 	 * the async scanning code (drivers like iscsi_tcp do login and
+ 	 * scanning from userspace).
+ 	 */
+-	if (shost->hostt->scan_finished) {
+-		if (queue_work(ihost->scan_workq, &session->scan_work))
+-			atomic_inc(&ihost->nr_scans);
+-	}
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
++		if (shost->hostt->scan_finished) {
++			if (queue_work(ihost->scan_workq, &session->scan_work))
++				atomic_inc(&ihost->nr_scans);
++		}
++#endif
+ }
+ 
+ /**
+@@ -1294,45 +1300,56 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
+  * Malformed skbs with wrong lengths or invalid creds are not processed.
+  */
+ static void
+-iscsi_if_rx(struct sk_buff *skb)
++iscsi_if_rx(struct sock *sk, int len)
+ {
++	struct sk_buff *skb;
++
+ 	mutex_lock(&rx_queue_mutex);
+-	while (skb->len >= NLMSG_SPACE(0)) {
+-		int err;
+-		uint32_t rlen;
+-		struct nlmsghdr	*nlh;
+-		struct iscsi_uevent *ev;
+-
+-		nlh = nlmsg_hdr(skb);
+-		if (nlh->nlmsg_len < sizeof(*nlh) ||
+-		    skb->len < nlh->nlmsg_len) {
+-			break;
++	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
++		if (NETLINK_CREDS(skb)->uid) {
++			skb_pull(skb, skb->len);
++			goto free_skb;
+ 		}
+ 
+-		ev = NLMSG_DATA(nlh);
+-		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
+-		if (rlen > skb->len)
+-			rlen = skb->len;
+-
+-		err = iscsi_if_recv_msg(skb, nlh);
+-		if (err) {
+-			ev->type = ISCSI_KEVENT_IF_ERROR;
+-			ev->iferror = err;
+-		}
+-		do {
+-			/*
+-			 * special case for GET_STATS:
+-			 * on success - sending reply and stats from
+-			 * inside of if_recv_msg(),
+-			 * on error - fall through.
+-			 */
+-			if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
++		while (skb->len >= NLMSG_SPACE(0)) {
++			int err;
++			uint32_t rlen;
++			struct nlmsghdr	*nlh;
++			struct iscsi_uevent *ev;
++
++			nlh = nlmsg_hdr(skb);
++			if (nlh->nlmsg_len < sizeof(*nlh) ||
++			    skb->len < nlh->nlmsg_len) {
+ 				break;
+-			err = iscsi_if_send_reply(
+-				NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
+-				nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
+-		} while (err < 0 && err != -ECONNREFUSED);
+-		skb_pull(skb, rlen);
++			}
++
++			ev = NLMSG_DATA(nlh);
++			rlen = NLMSG_ALIGN(nlh->nlmsg_len);
++			if (rlen > skb->len)
++				rlen = skb->len;
++
++			err = iscsi_if_recv_msg(skb, nlh);
++			if (err) {
++				ev->type = ISCSI_KEVENT_IF_ERROR;
++				ev->iferror = err;
++			}
++			do {
++				/*
++				 * special case for GET_STATS:
++				 * on success - sending reply and stats from
++				 * inside of if_recv_msg(),
++				 * on error - fall through.
++				 */
++				if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
++					break;
++				err = iscsi_if_send_reply(
++					NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
++					nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
++			} while (err < 0 && err != -ECONNREFUSED);
++			skb_pull(skb, rlen);
++		}
++free_skb:
++		kfree_skb(skb);
+ 	}
+ 	mutex_unlock(&rx_queue_mutex);
+ }
+@@ -1738,7 +1755,7 @@ static __init int iscsi_transport_init(v
+ 	return 0;
+ 
+ release_nls:
+-	netlink_kernel_release(nls);
++	sock_release(nls->sk_socket);
+ unregister_session_class:
+ 	transport_class_unregister(&iscsi_session_class);
+ unregister_conn_class:
+@@ -1753,7 +1770,7 @@ unregister_transport_class:
+ static void __exit iscsi_transport_exit(void)
+ {
+ 	destroy_workqueue(iscsi_eh_timer_workq);
+-	netlink_kernel_release(nls);
++	sock_release(nls->sk_socket);
+ 	transport_class_unregister(&iscsi_connection_class);
+ 	transport_class_unregister(&iscsi_session_class);
+ 	transport_class_unregister(&iscsi_host_class);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iser_01_sync_kernel_code_with_2.6.26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iser_01_sync_kernel_code_with_2.6.26.patch
new file mode 100644
index 0000000..a147ee2
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iser_01_sync_kernel_code_with_2.6.26.patch
@@ -0,0 +1,1548 @@
+From ad1e1df62ff096cc90257b0b42e843d0773ae981 Mon Sep 17 00:00:00 2001
+From: Doron Shoham <dorons at voltaire.com>
+Date: Tue, 26 Aug 2008 11:37:50 +0300
+Subject: [PATCH] iser backports
+
+Signed-off-by: Doron Shoham <dorons at voltaire.com>
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c     |  363 ++++++++++++---------------
+ drivers/infiniband/ulp/iser/iscsi_iser.h     |   46 +--
+ drivers/infiniband/ulp/iser/iser_initiator.c |  211 +++++++--------
+ drivers/infiniband/ulp/iser/iser_memory.c    |   79 ++---
+ drivers/infiniband/ulp/iser/iser_verbs.c     |   31 +-
+ 5 files changed, 347 insertions(+), 383 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -42,6 +42,9 @@
+  *	Zhenyu Wang
+  * Modified by:
+  *      Erez Zilber
++ *
++ *
++ * $Id: iscsi_iser.c 6965 2006-05-07 11:36:20Z ogerlitz $
+  */
+ 
+ #include <linux/types.h>
+@@ -71,10 +74,6 @@
+ 
+ #include "iscsi_iser.h"
+ 
+-static struct scsi_host_template iscsi_iser_sht;
+-static struct iscsi_transport iscsi_iser_transport;
+-static struct scsi_transport_template *iscsi_iser_scsi_transport;
+-
+ static unsigned int iscsi_max_lun = 512;
+ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
+ 
+@@ -95,6 +94,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
+ 		struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
+ {
+ 	int rc = 0;
++	uint32_t ret_itt;
+ 	int datalen;
+ 	int ahslen;
+ 
+@@ -110,7 +110,12 @@ iscsi_iser_recv(struct iscsi_conn *conn,
+ 	/* read AHS */
+ 	ahslen = hdr->hlength * 4;
+ 
+-	rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
++	/* verify itt (itt encoding: age+cid+itt) */
++	rc = iscsi_verify_itt(conn, hdr, &ret_itt);
++
++	if (!rc)
++		rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
++
+ 	if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
+ 		goto error;
+ 
+@@ -121,33 +126,25 @@ error:
+ 
+ 
+ /**
+- * iscsi_iser_task_init - Initialize task
+- * @task: iscsi task
++ * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
+  *
+- * Initialize the task for the scsi command or mgmt command.
+- */
++ **/
+ static int
+-iscsi_iser_task_init(struct iscsi_task *task)
++iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_iser_conn *iser_conn  = task->conn->dd_data;
+-	struct iscsi_iser_task *iser_task = task->dd_data;
+-
+-	/* mgmt task */
+-	if (!task->sc) {
+-		iser_task->desc.data = task->data;
+-		return 0;
+-	}
++	struct iscsi_iser_conn     *iser_conn  = ctask->conn->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 
+-	iser_task->command_sent = 0;
+-	iser_task->iser_conn    = iser_conn;
+-	iser_task_rdma_init(iser_task);
++	iser_ctask->command_sent = 0;
++	iser_ctask->iser_conn    = iser_conn;
++	iser_ctask_rdma_init(iser_ctask);
+ 	return 0;
+ }
+ 
+ /**
+- * iscsi_iser_mtask_xmit - xmit management(immediate) task
++ * iscsi_mtask_xmit - xmit management(immediate) task
+  * @conn: iscsi connection
+- * @task: task management task
++ * @mtask: task management task
+  *
+  * Notes:
+  *	The function can return -EAGAIN in which case caller must
+@@ -156,19 +153,20 @@ iscsi_iser_task_init(struct iscsi_task *
+  *
+  **/
+ static int
+-iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
++iscsi_iser_mtask_xmit(struct iscsi_conn *conn,
++		      struct iscsi_mgmt_task *mtask)
+ {
+ 	int error = 0;
+ 
+-	debug_scsi("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
++	debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
+ 
+-	error = iser_send_control(conn, task);
++	error = iser_send_control(conn, mtask);
+ 
+-	/* since iser xmits control with zero copy, tasks can not be recycled
++	/* since iser xmits control with zero copy, mtasks can not be recycled
+ 	 * right after sending them.
+ 	 * The recycling scheme is based on whether a response is expected
+-	 * - if yes, the task is recycled at iscsi_complete_pdu
+-	 * - if no,  the task is recycled at iser_snd_completion
++	 * - if yes, the mtask is recycled at iscsi_complete_pdu
++	 * - if no,  the mtask is recycled at iser_snd_completion
+ 	 */
+ 	if (error && error != -ENOBUFS)
+ 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+@@ -177,86 +175,97 @@ iscsi_iser_mtask_xmit(struct iscsi_conn 
+ }
+ 
+ static int
+-iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn,
+-				 struct iscsi_task *task)
++iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn,
++				 struct iscsi_cmd_task *ctask)
+ {
+ 	struct iscsi_data  hdr;
+ 	int error = 0;
+ 
+ 	/* Send data-out PDUs while there's still unsolicited data to send */
+-	while (task->unsol_count > 0) {
+-		iscsi_prep_unsolicit_data_pdu(task, &hdr);
++	while (ctask->unsol_count > 0) {
++		iscsi_prep_unsolicit_data_pdu(ctask, &hdr);
+ 		debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
+-			   hdr.itt, task->data_count);
++			   hdr.itt, ctask->data_count);
+ 
+ 		/* the buffer description has been passed with the command */
+ 		/* Send the command */
+-		error = iser_send_data_out(conn, task, &hdr);
++		error = iser_send_data_out(conn, ctask, &hdr);
+ 		if (error) {
+-			task->unsol_datasn--;
+-			goto iscsi_iser_task_xmit_unsol_data_exit;
++			ctask->unsol_datasn--;
++			goto iscsi_iser_ctask_xmit_unsol_data_exit;
+ 		}
+-		task->unsol_count -= task->data_count;
++		ctask->unsol_count -= ctask->data_count;
+ 		debug_scsi("Need to send %d more as data-out PDUs\n",
+-			   task->unsol_count);
++			   ctask->unsol_count);
+ 	}
+ 
+-iscsi_iser_task_xmit_unsol_data_exit:
++iscsi_iser_ctask_xmit_unsol_data_exit:
+ 	return error;
+ }
+ 
+ static int
+-iscsi_iser_task_xmit(struct iscsi_task *task)
++iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
++		      struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_conn *conn = task->conn;
+-	struct iscsi_iser_task *iser_task = task->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 	int error = 0;
+ 
+-	if (!task->sc)
+-		return iscsi_iser_mtask_xmit(conn, task);
+-
+-	if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
+-		BUG_ON(scsi_bufflen(task->sc) == 0);
++	if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
++		BUG_ON(scsi_bufflen(ctask->sc) == 0);
+ 
+ 		debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
+-			   task->itt, scsi_bufflen(task->sc),
+-			   task->imm_count, task->unsol_count);
++			   ctask->itt, scsi_bufflen(ctask->sc),
++			   ctask->imm_count, ctask->unsol_count);
+ 	}
+ 
+-	debug_scsi("task deq [cid %d itt 0x%x]\n",
+-		   conn->id, task->itt);
++	debug_scsi("ctask deq [cid %d itt 0x%x]\n",
++		   conn->id, ctask->itt);
+ 
+ 	/* Send the cmd PDU */
+-	if (!iser_task->command_sent) {
+-		error = iser_send_command(conn, task);
++	if (!iser_ctask->command_sent) {
++		error = iser_send_command(conn, ctask);
+ 		if (error)
+-			goto iscsi_iser_task_xmit_exit;
+-		iser_task->command_sent = 1;
++			goto iscsi_iser_ctask_xmit_exit;
++		iser_ctask->command_sent = 1;
+ 	}
+ 
+ 	/* Send unsolicited data-out PDU(s) if necessary */
+-	if (task->unsol_count)
+-		error = iscsi_iser_task_xmit_unsol_data(conn, task);
++	if (ctask->unsol_count)
++		error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask);
+ 
+- iscsi_iser_task_xmit_exit:
++ iscsi_iser_ctask_xmit_exit:
+ 	if (error && error != -ENOBUFS)
+ 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ 	return error;
+ }
+ 
+ static void
+-iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
++iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+ {
+-	struct iscsi_iser_task *iser_task = task->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 
+-	/* mgmt tasks do not need special cleanup */
+-	if (!task->sc)
+-		return;
++	if (iser_ctask->status == ISER_TASK_STATUS_STARTED) {
++		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
++		iser_ctask_rdma_finalize(iser_ctask);
++	}
++}
+ 
+-	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
+-		iser_task->status = ISER_TASK_STATUS_COMPLETED;
+-		iser_task_rdma_finalize(iser_task);
++static struct iser_conn *
++iscsi_iser_ib_conn_lookup(__u64 ep_handle)
++{
++	struct iser_conn *ib_conn;
++	struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle;
++
++	mutex_lock(&ig.connlist_mutex);
++	list_for_each_entry(ib_conn, &ig.connlist, conn_list) {
++		if (ib_conn == uib_conn) {
++			mutex_unlock(&ig.connlist_mutex);
++			return ib_conn;
++		}
+ 	}
++	mutex_unlock(&ig.connlist_mutex);
++	iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle);
++	return NULL;
+ }
+ 
+ static struct iscsi_cls_conn *
+@@ -266,7 +275,7 @@ iscsi_iser_conn_create(struct iscsi_cls_
+ 	struct iscsi_cls_conn *cls_conn;
+ 	struct iscsi_iser_conn *iser_conn;
+ 
+-	cls_conn = iscsi_conn_setup(cls_session, sizeof(*iser_conn), conn_idx);
++	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
+ 	if (!cls_conn)
+ 		return NULL;
+ 	conn = cls_conn->dd_data;
+@@ -277,11 +286,21 @@ iscsi_iser_conn_create(struct iscsi_cls_
+ 	 */
+ 	conn->max_recv_dlength = 128;
+ 
+-	iser_conn = conn->dd_data;
++	iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL);
++	if (!iser_conn)
++		goto conn_alloc_fail;
++
++	/* currently this is the only field which need to be initiated */
++	rwlock_init(&iser_conn->lock);
++
+ 	conn->dd_data = iser_conn;
+ 	iser_conn->iscsi_conn = conn;
+ 
+ 	return cls_conn;
++
++conn_alloc_fail:
++	iscsi_conn_teardown(cls_conn);
++	return NULL;
+ }
+ 
+ static void
+@@ -289,18 +308,11 @@ iscsi_iser_conn_destroy(struct iscsi_cls
+ {
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+ 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+-	struct iser_conn *ib_conn = iser_conn->ib_conn;
+ 
+ 	iscsi_conn_teardown(cls_conn);
+-	/*
+-	 * Userspace will normally call the stop callback and
+-	 * already have freed the ib_conn, but if it goofed up then
+-	 * we free it here.
+-	 */
+-	if (ib_conn) {
+-		ib_conn->iser_conn = NULL;
+-		iser_conn_put(ib_conn);
+-	}
++	if (iser_conn->ib_conn)
++		iser_conn->ib_conn->iser_conn = NULL;
++	kfree(iser_conn);
+ }
+ 
+ static int
+@@ -311,7 +323,6 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+ 	struct iscsi_iser_conn *iser_conn;
+ 	struct iser_conn *ib_conn;
+-	struct iscsi_endpoint *ep;
+ 	int error;
+ 
+ 	error = iscsi_conn_bind(cls_session, cls_conn, is_leading);
+@@ -320,14 +331,12 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
+ 
+ 	/* the transport ep handle comes from user space so it must be
+ 	 * verified against the global ib connections list */
+-	ep = iscsi_lookup_endpoint(transport_eph);
+-	if (!ep) {
++	ib_conn = iscsi_iser_ib_conn_lookup(transport_eph);
++	if (!ib_conn) {
+ 		iser_err("can't bind eph %llx\n",
+ 			 (unsigned long long)transport_eph);
+ 		return -EINVAL;
+ 	}
+-	ib_conn = ep->dd_data;
+-
+ 	/* binds the iSER connection retrieved from the previously
+ 	 * connected ep_handle to the iSCSI layer connection. exchanges
+ 	 * connection pointers */
+@@ -335,30 +344,10 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
+ 	iser_conn = conn->dd_data;
+ 	ib_conn->iser_conn = iser_conn;
+ 	iser_conn->ib_conn  = ib_conn;
+-	iser_conn_get(ib_conn);
+-	return 0;
+-}
+ 
+-static void
+-iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
+-{
+-	struct iscsi_conn *conn = cls_conn->dd_data;
+-	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+-	struct iser_conn *ib_conn = iser_conn->ib_conn;
++	conn->recv_lock = &iser_conn->lock;
+ 
+-	/*
+-	 * Userspace may have goofed up and not bound the connection or
+-	 * might have only partially setup the connection.
+-	 */
+-	if (ib_conn) {
+-		iscsi_conn_stop(cls_conn, flag);
+-		/*
+-		 * There is no unbind event so the stop callback
+-		 * must release the ref from the bind.
+-		 */
+-		iser_conn_put(ib_conn);
+-	}
+-	iser_conn->ib_conn = NULL;
++	return 0;
+ }
+ 
+ static int
+@@ -374,75 +363,55 @@ iscsi_iser_conn_start(struct iscsi_cls_c
+ 	return iscsi_conn_start(cls_conn);
+ }
+ 
+-static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
+-{
+-	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+-
+-	iscsi_host_remove(shost);
+-	iscsi_host_free(shost);
+-}
++static struct iscsi_transport iscsi_iser_transport;
+ 
+ static struct iscsi_cls_session *
+-iscsi_iser_session_create(struct iscsi_endpoint *ep,
+-			  uint16_t cmds_max, uint16_t qdepth,
+-			  uint32_t initial_cmdsn, uint32_t *hostno)
++iscsi_iser_session_create(struct iscsi_transport *iscsit,
++			 struct scsi_transport_template *scsit,
++			 uint16_t cmds_max, uint16_t qdepth,
++			 uint32_t initial_cmdsn, uint32_t *hostno)
+ {
+ 	struct iscsi_cls_session *cls_session;
+ 	struct iscsi_session *session;
+-	struct Scsi_Host *shost;
+ 	int i;
+-	struct iscsi_task *task;
+-	struct iscsi_iser_task *iser_task;
+-	struct iser_conn *ib_conn;
+-
+-	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
+-	if (!shost)
+-		return NULL;
+-	shost->transportt = iscsi_iser_scsi_transport;
+-	shost->max_lun = iscsi_max_lun;
+-	shost->max_id = 0;
+-	shost->max_channel = 0;
+-	shost->max_cmd_len = 16;
+-
+-	/*
+-	 * older userspace tools (before 2.0-870) did not pass us
+-	 * the leading conn's ep so this will be NULL;
+-	 */
+-	if (ep)
+-		ib_conn = ep->dd_data;
+-
+-	if (iscsi_host_add(shost,
+-			   ep ? ib_conn->device->ib_device->dma_device : NULL))
+-		goto free_host;
+-	*hostno = shost->host_no;
++	uint32_t hn;
++	struct iscsi_cmd_task  *ctask;
++	struct iscsi_mgmt_task *mtask;
++	struct iscsi_iser_cmd_task *iser_ctask;
++	struct iser_desc *desc;
+ 
+ 	/*
+ 	 * we do not support setting can_queue cmd_per_lun from userspace yet
+ 	 * because we preallocate so many resources
+ 	 */
+-	cls_session = iscsi_session_setup(&iscsi_iser_transport, shost,
++	cls_session = iscsi_session_setup(iscsit, scsit,
+ 					  ISCSI_DEF_XMIT_CMDS_MAX,
+-					  sizeof(struct iscsi_iser_task),
+-					  initial_cmdsn, 0);
++					  ISCSI_MAX_CMD_PER_LUN,
++					  sizeof(struct iscsi_iser_cmd_task),
++					  sizeof(struct iser_desc),
++					  initial_cmdsn, &hn);
+ 	if (!cls_session)
+-		goto remove_host;
+-	session = cls_session->dd_data;
++	return NULL;
++
++	*hostno = hn;
++	session = class_to_transport_session(cls_session);
+ 
+-	shost->can_queue = session->scsi_cmds_max;
+ 	/* libiscsi setup itts, data and pool so just set desc fields */
+ 	for (i = 0; i < session->cmds_max; i++) {
+-		task = session->cmds[i];
+-		iser_task = task->dd_data;
+-		task->hdr = (struct iscsi_cmd *)&iser_task->desc.iscsi_header;
+-		task->hdr_max = sizeof(iser_task->desc.iscsi_header);
++		ctask      = session->cmds[i];
++		iser_ctask = ctask->dd_data;
++		ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header;
++		ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header);
+ 	}
+-	return cls_session;
+ 
+-remove_host:
+-	iscsi_host_remove(shost);
+-free_host:
+-	iscsi_host_free(shost);
+-	return NULL;
++	for (i = 0; i < session->mgmtpool_max; i++) {
++		mtask      = session->mgmt_cmds[i];
++		desc       = mtask->dd_data;
++		mtask->hdr = &desc->iscsi_header;
++		desc->data = mtask->data;
++	}
++
++	return cls_session;
+ }
+ 
+ static int
+@@ -515,37 +484,34 @@ iscsi_iser_conn_get_stats(struct iscsi_c
+ 	stats->custom[3].value = conn->fmr_unalign_cnt;
+ }
+ 
+-static struct iscsi_endpoint *
+-iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking)
++static int
++iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking,
++		      __u64 *ep_handle)
+ {
+ 	int err;
+ 	struct iser_conn *ib_conn;
+-	struct iscsi_endpoint *ep;
+ 
+-	ep = iscsi_create_endpoint(sizeof(*ib_conn));
+-	if (!ep)
+-		return ERR_PTR(-ENOMEM);
+-
+-	ib_conn = ep->dd_data;
+-	ib_conn->ep = ep;
+-	iser_conn_init(ib_conn);
+-
+-	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr,
+-			   non_blocking);
+-	if (err) {
+-		iscsi_destroy_endpoint(ep);
+-		return ERR_PTR(err);
+-	}
+-	return ep;
++	err = iser_conn_init(&ib_conn);
++	if (err)
++		goto out;
++
++	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking);
++	if (!err)
++		*ep_handle = (__u64)(unsigned long)ib_conn;
++
++out:
++	return err;
+ }
+ 
+ static int
+-iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
++iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms)
+ {
+-	struct iser_conn *ib_conn;
++	struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
+ 	int rc;
+ 
+-	ib_conn = ep->dd_data;
++	if (!ib_conn)
++		return -EINVAL;
++
+ 	rc = wait_event_interruptible_timeout(ib_conn->wait,
+ 			     ib_conn->state == ISER_CONN_UP,
+ 			     msecs_to_jiffies(timeout_ms));
+@@ -567,21 +533,13 @@ iscsi_iser_ep_poll(struct iscsi_endpoint
+ }
+ 
+ static void
+-iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
++iscsi_iser_ep_disconnect(__u64 ep_handle)
+ {
+ 	struct iser_conn *ib_conn;
+ 
+-	ib_conn = ep->dd_data;
+-	if (ib_conn->iser_conn)
+-		/*
+-		 * Must suspend xmit path if the ep is bound to the
+-		 * iscsi_conn, so we know we are not accessing the ib_conn
+-		 * when we free it.
+-		 *
+-		 * This may not be bound if the ep poll failed.
+-		 */
+-		iscsi_suspend_tx(ib_conn->iser_conn->iscsi_conn);
+-
++	ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
++	if (!ib_conn)
++		return;
+ 
+ 	iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state);
+ 	iser_conn_terminate(ib_conn);
+@@ -592,6 +550,7 @@ static struct scsi_host_template iscsi_i
+ 	.name                   = "iSCSI Initiator over iSER, v." DRV_VER,
+ 	.queuecommand           = iscsi_queuecommand,
+ 	.change_queue_depth	= iscsi_change_queue_depth,
++	.can_queue		= ISCSI_DEF_XMIT_CMDS_MAX - 1,
+ 	.sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
+ 	.max_sectors		= 1024,
+ 	.cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
+@@ -625,14 +584,17 @@ static struct iscsi_transport iscsi_iser
+ 				  ISCSI_USERNAME | ISCSI_PASSWORD |
+ 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
+ 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+-				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
+-				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
++				  ISCSI_PING_TMO | ISCSI_RECV_TMO,
+ 	.host_param_mask	= ISCSI_HOST_HWADDRESS |
+ 				  ISCSI_HOST_NETDEV_NAME |
+ 				  ISCSI_HOST_INITIATOR_NAME,
++	.host_template          = &iscsi_iser_sht,
++	.conndata_size		= sizeof(struct iscsi_conn),
++	.max_lun                = ISCSI_ISER_MAX_LUN,
++	.max_cmd_len            = ISCSI_ISER_MAX_CMD_LEN,
+ 	/* session management */
+ 	.create_session         = iscsi_iser_session_create,
+-	.destroy_session        = iscsi_iser_session_destroy,
++	.destroy_session        = iscsi_session_teardown,
+ 	/* connection management */
+ 	.create_conn            = iscsi_iser_conn_create,
+ 	.bind_conn              = iscsi_iser_conn_bind,
+@@ -641,16 +603,17 @@ static struct iscsi_transport iscsi_iser
+ 	.get_conn_param		= iscsi_conn_get_param,
+ 	.get_session_param	= iscsi_session_get_param,
+ 	.start_conn             = iscsi_iser_conn_start,
+-	.stop_conn              = iscsi_iser_conn_stop,
++	.stop_conn              = iscsi_conn_stop,
+ 	/* iscsi host params */
+ 	.get_host_param		= iscsi_host_get_param,
+ 	.set_host_param		= iscsi_host_set_param,
+ 	/* IO */
+ 	.send_pdu		= iscsi_conn_send_pdu,
+ 	.get_stats		= iscsi_iser_conn_get_stats,
+-	.init_task		= iscsi_iser_task_init,
+-	.xmit_task		= iscsi_iser_task_xmit,
+-	.cleanup_task		= iscsi_iser_cleanup_task,
++	.init_cmd_task		= iscsi_iser_cmd_init,
++	.xmit_cmd_task		= iscsi_iser_ctask_xmit,
++	.xmit_mgmt_task		= iscsi_iser_mtask_xmit,
++	.cleanup_cmd_task	= iscsi_iser_cleanup_ctask,
+ 	/* recovery */
+ 	.session_recovery_timedout = iscsi_session_recovery_timedout,
+ 
+@@ -670,6 +633,8 @@ static int __init iser_init(void)
+ 		return -EINVAL;
+ 	}
+ 
++	iscsi_iser_transport.max_lun = iscsi_max_lun;
++
+ 	memset(&ig, 0, sizeof(struct iser_global));
+ 
+ 	ig.desc_cache = kmem_cache_create("iser_descriptors",
+@@ -685,9 +650,7 @@ static int __init iser_init(void)
+ 	mutex_init(&ig.connlist_mutex);
+ 	INIT_LIST_HEAD(&ig.connlist);
+ 
+-	iscsi_iser_scsi_transport = iscsi_register_transport(
+-							&iscsi_iser_transport);
+-	if (!iscsi_iser_scsi_transport) {
++	if (!iscsi_register_transport(&iscsi_iser_transport)) {
+ 		iser_err("iscsi_register_transport failed\n");
+ 		err = -EINVAL;
+ 		goto register_transport_failure;
+Index: ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
++++ ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.h
+@@ -36,6 +36,8 @@
+  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  * SOFTWARE.
++ *
++ * $Id: iscsi_iser.h 7051 2006-05-10 12:29:11Z ogerlitz $
+  */
+ #ifndef __ISCSI_ISER_H__
+ #define __ISCSI_ISER_H__
+@@ -94,6 +96,7 @@
+ 					/* support upto 512KB in one RDMA */
+ #define ISCSI_ISER_SG_TABLESIZE         (0x80000 >> SHIFT_4K)
+ #define ISCSI_ISER_MAX_LUN		256
++#define ISCSI_ISER_MAX_CMD_LEN		16
+ 
+ /* QP settings */
+ /* Maximal bounds on received asynchronous PDUs */
+@@ -171,8 +174,7 @@ struct iser_data_buf {
+ /* fwd declarations */
+ struct iser_device;
+ struct iscsi_iser_conn;
+-struct iscsi_iser_task;
+-struct iscsi_endpoint;
++struct iscsi_iser_cmd_task;
+ 
+ struct iser_mem_reg {
+ 	u32  lkey;
+@@ -196,7 +198,7 @@ struct iser_regd_buf {
+ #define MAX_REGD_BUF_VECTOR_LEN	2
+ 
+ struct iser_dto {
+-	struct iscsi_iser_task *task;
++	struct iscsi_iser_cmd_task *ctask;
+ 	struct iser_conn *ib_conn;
+ 	int                        notify_enable;
+ 
+@@ -240,9 +242,7 @@ struct iser_device {
+ 
+ struct iser_conn {
+ 	struct iscsi_iser_conn       *iser_conn; /* iser conn for upcalls  */
+-	struct iscsi_endpoint	     *ep;
+ 	enum iser_ib_conn_state	     state;	    /* rdma connection state   */
+-	atomic_t		     refcount;
+ 	spinlock_t		     lock;	    /* used for state changes  */
+ 	struct iser_device           *device;       /* device context          */
+ 	struct rdma_cm_id            *cma_id;       /* CMA ID		       */
+@@ -261,9 +261,11 @@ struct iser_conn {
+ struct iscsi_iser_conn {
+ 	struct iscsi_conn            *iscsi_conn;/* ptr to iscsi conn */
+ 	struct iser_conn             *ib_conn;   /* iSER IB conn      */
++
++	rwlock_t		     lock;
+ };
+ 
+-struct iscsi_iser_task {
++struct iscsi_iser_cmd_task {
+ 	struct iser_desc             desc;
+ 	struct iscsi_iser_conn	     *iser_conn;
+ 	enum iser_task_status 	     status;
+@@ -296,26 +298,22 @@ extern int iser_debug_level;
+ /* allocate connection resources needed for rdma functionality */
+ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn);
+ 
+-int iser_send_control(struct iscsi_conn *conn,
+-		      struct iscsi_task *task);
++int iser_send_control(struct iscsi_conn      *conn,
++		      struct iscsi_mgmt_task *mtask);
+ 
+-int iser_send_command(struct iscsi_conn *conn,
+-		      struct iscsi_task *task);
++int iser_send_command(struct iscsi_conn      *conn,
++		      struct iscsi_cmd_task  *ctask);
+ 
+-int iser_send_data_out(struct iscsi_conn *conn,
+-		       struct iscsi_task *task,
+-		       struct iscsi_data *hdr);
++int iser_send_data_out(struct iscsi_conn     *conn,
++		       struct iscsi_cmd_task *ctask,
++		       struct iscsi_data          *hdr);
+ 
+ void iscsi_iser_recv(struct iscsi_conn *conn,
+ 		     struct iscsi_hdr       *hdr,
+ 		     char                   *rx_data,
+ 		     int                    rx_data_len);
+ 
+-void iser_conn_init(struct iser_conn *ib_conn);
+-
+-void iser_conn_get(struct iser_conn *ib_conn);
+-
+-void iser_conn_put(struct iser_conn *ib_conn);
++int  iser_conn_init(struct iser_conn **ib_conn);
+ 
+ void iser_conn_terminate(struct iser_conn *ib_conn);
+ 
+@@ -324,9 +322,9 @@ void iser_rcv_completion(struct iser_des
+ 
+ void iser_snd_completion(struct iser_desc *desc);
+ 
+-void iser_task_rdma_init(struct iscsi_iser_task *task);
++void iser_ctask_rdma_init(struct iscsi_iser_cmd_task     *ctask);
+ 
+-void iser_task_rdma_finalize(struct iscsi_iser_task *task);
++void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask);
+ 
+ void iser_dto_buffs_release(struct iser_dto *dto);
+ 
+@@ -336,10 +334,10 @@ void iser_reg_single(struct iser_device 
+ 		     struct iser_regd_buf    *regd_buf,
+ 		     enum dma_data_direction direction);
+ 
+-void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
++void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask,
+ 				     enum iser_data_dir         cmd_dir);
+ 
+-int  iser_reg_rdma_mem(struct iscsi_iser_task *task,
++int  iser_reg_rdma_mem(struct iscsi_iser_cmd_task *ctask,
+ 		       enum   iser_data_dir        cmd_dir);
+ 
+ int  iser_connect(struct iser_conn   *ib_conn,
+@@ -359,10 +357,10 @@ int  iser_post_send(struct iser_desc *tx
+ int iser_conn_state_comp(struct iser_conn *ib_conn,
+ 			 enum iser_ib_conn_state comp);
+ 
+-int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
++int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
+ 			    struct iser_data_buf       *data,
+ 			    enum   iser_data_dir       iser_dir,
+ 			    enum   dma_data_direction  dma_dir);
+ 
+-void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
++void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask);
+ #endif
+Index: ofed_kernel/drivers/infiniband/ulp/iser/iser_initiator.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/iser/iser_initiator.c
++++ ofed_kernel/drivers/infiniband/ulp/iser/iser_initiator.c
+@@ -28,6 +28,8 @@
+  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  * SOFTWARE.
++ *
++ * $Id: iser_initiator.c 6964 2006-05-07 11:11:43Z ogerlitz $
+  */
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+@@ -64,46 +66,46 @@ static void iser_dto_add_regd_buff(struc
+ 
+ /* Register user buffer memory and initialize passive rdma
+  *  dto descriptor. Total data size is stored in
+- *  iser_task->data[ISER_DIR_IN].data_len
++ *  iser_ctask->data[ISER_DIR_IN].data_len
+  */
+-static int iser_prepare_read_cmd(struct iscsi_task *task,
++static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask,
+ 				 unsigned int edtl)
+ 
+ {
+-	struct iscsi_iser_task *iser_task = task->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 	struct iser_regd_buf *regd_buf;
+ 	int err;
+-	struct iser_hdr *hdr = &iser_task->desc.iser_header;
+-	struct iser_data_buf *buf_in = &iser_task->data[ISER_DIR_IN];
++	struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
++	struct iser_data_buf *buf_in = &iser_ctask->data[ISER_DIR_IN];
+ 
+-	err = iser_dma_map_task_data(iser_task,
++	err = iser_dma_map_task_data(iser_ctask,
+ 				     buf_in,
+ 				     ISER_DIR_IN,
+ 				     DMA_FROM_DEVICE);
+ 	if (err)
+ 		return err;
+ 
+-	if (edtl > iser_task->data[ISER_DIR_IN].data_len) {
++	if (edtl > iser_ctask->data[ISER_DIR_IN].data_len) {
+ 		iser_err("Total data length: %ld, less than EDTL: "
+ 			 "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
+-			 iser_task->data[ISER_DIR_IN].data_len, edtl,
+-			 task->itt, iser_task->iser_conn);
++			 iser_ctask->data[ISER_DIR_IN].data_len, edtl,
++			 ctask->itt, iser_ctask->iser_conn);
+ 		return -EINVAL;
+ 	}
+ 
+-	err = iser_reg_rdma_mem(iser_task,ISER_DIR_IN);
++	err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_IN);
+ 	if (err) {
+ 		iser_err("Failed to set up Data-IN RDMA\n");
+ 		return err;
+ 	}
+-	regd_buf = &iser_task->rdma_regd[ISER_DIR_IN];
++	regd_buf = &iser_ctask->rdma_regd[ISER_DIR_IN];
+ 
+ 	hdr->flags    |= ISER_RSV;
+ 	hdr->read_stag = cpu_to_be32(regd_buf->reg.rkey);
+ 	hdr->read_va   = cpu_to_be64(regd_buf->reg.va);
+ 
+ 	iser_dbg("Cmd itt:%d READ tags RKEY:%#.4X VA:%#llX\n",
+-		 task->itt, regd_buf->reg.rkey,
++		 ctask->itt, regd_buf->reg.rkey,
+ 		 (unsigned long long)regd_buf->reg.va);
+ 
+ 	return 0;
+@@ -111,43 +113,43 @@ static int iser_prepare_read_cmd(struct 
+ 
+ /* Register user buffer memory and initialize passive rdma
+  *  dto descriptor. Total data size is stored in
+- *  task->data[ISER_DIR_OUT].data_len
++ *  ctask->data[ISER_DIR_OUT].data_len
+  */
+ static int
+-iser_prepare_write_cmd(struct iscsi_task *task,
++iser_prepare_write_cmd(struct iscsi_cmd_task *ctask,
+ 		       unsigned int imm_sz,
+ 		       unsigned int unsol_sz,
+ 		       unsigned int edtl)
+ {
+-	struct iscsi_iser_task *iser_task = task->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 	struct iser_regd_buf *regd_buf;
+ 	int err;
+-	struct iser_dto *send_dto = &iser_task->desc.dto;
+-	struct iser_hdr *hdr = &iser_task->desc.iser_header;
+-	struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
++	struct iser_dto *send_dto = &iser_ctask->desc.dto;
++	struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
++	struct iser_data_buf *buf_out = &iser_ctask->data[ISER_DIR_OUT];
+ 
+-	err = iser_dma_map_task_data(iser_task,
++	err = iser_dma_map_task_data(iser_ctask,
+ 				     buf_out,
+ 				     ISER_DIR_OUT,
+ 				     DMA_TO_DEVICE);
+ 	if (err)
+ 		return err;
+ 
+-	if (edtl > iser_task->data[ISER_DIR_OUT].data_len) {
++	if (edtl > iser_ctask->data[ISER_DIR_OUT].data_len) {
+ 		iser_err("Total data length: %ld, less than EDTL: %d, "
+ 			 "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
+-			 iser_task->data[ISER_DIR_OUT].data_len,
+-			 edtl, task->itt, task->conn);
++			 iser_ctask->data[ISER_DIR_OUT].data_len,
++			 edtl, ctask->itt, ctask->conn);
+ 		return -EINVAL;
+ 	}
+ 
+-	err = iser_reg_rdma_mem(iser_task,ISER_DIR_OUT);
++	err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_OUT);
+ 	if (err != 0) {
+ 		iser_err("Failed to register write cmd RDMA mem\n");
+ 		return err;
+ 	}
+ 
+-	regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
++	regd_buf = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+ 
+ 	if (unsol_sz < edtl) {
+ 		hdr->flags     |= ISER_WSV;
+@@ -156,13 +158,13 @@ iser_prepare_write_cmd(struct iscsi_task
+ 
+ 		iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X "
+ 			 "VA:%#llX + unsol:%d\n",
+-			 task->itt, regd_buf->reg.rkey,
++			 ctask->itt, regd_buf->reg.rkey,
+ 			 (unsigned long long)regd_buf->reg.va, unsol_sz);
+ 	}
+ 
+ 	if (imm_sz > 0) {
+ 		iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
+-			 task->itt, imm_sz);
++			 ctask->itt, imm_sz);
+ 		iser_dto_add_regd_buff(send_dto,
+ 				       regd_buf,
+ 				       0,
+@@ -314,38 +316,38 @@ iser_check_xmit(struct iscsi_conn *conn,
+ /**
+  * iser_send_command - send command PDU
+  */
+-int iser_send_command(struct iscsi_conn *conn,
+-		      struct iscsi_task *task)
++int iser_send_command(struct iscsi_conn     *conn,
++		      struct iscsi_cmd_task *ctask)
+ {
+ 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+-	struct iscsi_iser_task *iser_task = task->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 	struct iser_dto *send_dto = NULL;
+ 	unsigned long edtl;
+ 	int err = 0;
+ 	struct iser_data_buf *data_buf;
+ 
+-	struct iscsi_cmd *hdr =  task->hdr;
+-	struct scsi_cmnd *sc  =  task->sc;
++	struct iscsi_cmd *hdr =  ctask->hdr;
++	struct scsi_cmnd *sc  =  ctask->sc;
+ 
+ 	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
+ 		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
+ 		return -EPERM;
+ 	}
+-	if (iser_check_xmit(conn, task))
++	if (iser_check_xmit(conn, ctask))
+ 		return -ENOBUFS;
+ 
+ 	edtl = ntohl(hdr->data_length);
+ 
+ 	/* build the tx desc regd header and add it to the tx desc dto */
+-	iser_task->desc.type = ISCSI_TX_SCSI_COMMAND;
+-	send_dto = &iser_task->desc.dto;
+-	send_dto->task = iser_task;
+-	iser_create_send_desc(iser_conn, &iser_task->desc);
++	iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND;
++	send_dto = &iser_ctask->desc.dto;
++	send_dto->ctask = iser_ctask;
++	iser_create_send_desc(iser_conn, &iser_ctask->desc);
+ 
+ 	if (hdr->flags & ISCSI_FLAG_CMD_READ)
+-		data_buf = &iser_task->data[ISER_DIR_IN];
++		data_buf = &iser_ctask->data[ISER_DIR_IN];
+ 	else
+-		data_buf = &iser_task->data[ISER_DIR_OUT];
++		data_buf = &iser_ctask->data[ISER_DIR_OUT];
+ 
+ 	if (scsi_sg_count(sc)) { /* using a scatter list */
+ 		data_buf->buf  = scsi_sglist(sc);
+@@ -355,15 +357,15 @@ int iser_send_command(struct iscsi_conn 
+ 	data_buf->data_len = scsi_bufflen(sc);
+ 
+ 	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
+-		err = iser_prepare_read_cmd(task, edtl);
++		err = iser_prepare_read_cmd(ctask, edtl);
+ 		if (err)
+ 			goto send_command_error;
+ 	}
+ 	if (hdr->flags & ISCSI_FLAG_CMD_WRITE) {
+-		err = iser_prepare_write_cmd(task,
+-					     task->imm_count,
+-				             task->imm_count +
+-					     task->unsol_count,
++		err = iser_prepare_write_cmd(ctask,
++					     ctask->imm_count,
++				             ctask->imm_count +
++					     ctask->unsol_count,
+ 					     edtl);
+ 		if (err)
+ 			goto send_command_error;
+@@ -378,27 +380,27 @@ int iser_send_command(struct iscsi_conn 
+ 		goto send_command_error;
+ 	}
+ 
+-	iser_task->status = ISER_TASK_STATUS_STARTED;
++	iser_ctask->status = ISER_TASK_STATUS_STARTED;
+ 
+-	err = iser_post_send(&iser_task->desc);
++	err = iser_post_send(&iser_ctask->desc);
+ 	if (!err)
+ 		return 0;
+ 
+ send_command_error:
+ 	iser_dto_buffs_release(send_dto);
+-	iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
++	iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err);
+ 	return err;
+ }
+ 
+ /**
+  * iser_send_data_out - send data out PDU
+  */
+-int iser_send_data_out(struct iscsi_conn *conn,
+-		       struct iscsi_task *task,
++int iser_send_data_out(struct iscsi_conn     *conn,
++		       struct iscsi_cmd_task *ctask,
+ 		       struct iscsi_data *hdr)
+ {
+ 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+-	struct iscsi_iser_task *iser_task = task->dd_data;
++	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+ 	struct iser_desc *tx_desc = NULL;
+ 	struct iser_dto *send_dto = NULL;
+ 	unsigned long buf_offset;
+@@ -411,7 +413,7 @@ int iser_send_data_out(struct iscsi_conn
+ 		return -EPERM;
+ 	}
+ 
+-	if (iser_check_xmit(conn, task))
++	if (iser_check_xmit(conn, ctask))
+ 		return -ENOBUFS;
+ 
+ 	itt = (__force uint32_t)hdr->itt;
+@@ -432,7 +434,7 @@ int iser_send_data_out(struct iscsi_conn
+ 
+ 	/* build the tx desc regd header and add it to the tx desc dto */
+ 	send_dto = &tx_desc->dto;
+-	send_dto->task = iser_task;
++	send_dto->ctask = iser_ctask;
+ 	iser_create_send_desc(iser_conn, tx_desc);
+ 
+ 	iser_reg_single(iser_conn->ib_conn->device,
+@@ -440,15 +442,15 @@ int iser_send_data_out(struct iscsi_conn
+ 
+ 	/* all data was registered for RDMA, we can use the lkey */
+ 	iser_dto_add_regd_buff(send_dto,
+-			       &iser_task->rdma_regd[ISER_DIR_OUT],
++			       &iser_ctask->rdma_regd[ISER_DIR_OUT],
+ 			       buf_offset,
+ 			       data_seg_len);
+ 
+-	if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
++	if (buf_offset + data_seg_len > iser_ctask->data[ISER_DIR_OUT].data_len) {
+ 		iser_err("Offset:%ld & DSL:%ld in Data-Out "
+ 			 "inconsistent with total len:%ld, itt:%d\n",
+ 			 buf_offset, data_seg_len,
+-			 iser_task->data[ISER_DIR_OUT].data_len, itt);
++			 iser_ctask->data[ISER_DIR_OUT].data_len, itt);
+ 		err = -EINVAL;
+ 		goto send_data_out_error;
+ 	}
+@@ -468,11 +470,10 @@ send_data_out_error:
+ }
+ 
+ int iser_send_control(struct iscsi_conn *conn,
+-		      struct iscsi_task *task)
++		      struct iscsi_mgmt_task *mtask)
+ {
+ 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+-	struct iscsi_iser_task *iser_task = task->dd_data;
+-	struct iser_desc *mdesc = &iser_task->desc;
++	struct iser_desc *mdesc = mtask->dd_data;
+ 	struct iser_dto *send_dto = NULL;
+ 	unsigned long data_seg_len;
+ 	int err = 0;
+@@ -484,27 +485,27 @@ int iser_send_control(struct iscsi_conn 
+ 		return -EPERM;
+ 	}
+ 
+-	if (iser_check_xmit(conn, task))
++	if (iser_check_xmit(conn,mtask))
+ 		return -ENOBUFS;
+ 
+ 	/* build the tx desc regd header and add it to the tx desc dto */
+ 	mdesc->type = ISCSI_TX_CONTROL;
+ 	send_dto = &mdesc->dto;
+-	send_dto->task = NULL;
++	send_dto->ctask = NULL;
+ 	iser_create_send_desc(iser_conn, mdesc);
+ 
+ 	device = iser_conn->ib_conn->device;
+ 
+ 	iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
+ 
+-	data_seg_len = ntoh24(task->hdr->dlength);
++	data_seg_len = ntoh24(mtask->hdr->dlength);
+ 
+ 	if (data_seg_len > 0) {
+ 		regd_buf = &mdesc->data_regd_buf;
+ 		memset(regd_buf, 0, sizeof(struct iser_regd_buf));
+ 		regd_buf->device = device;
+-		regd_buf->virt_addr = task->data;
+-		regd_buf->data_size = task->data_count;
++		regd_buf->virt_addr = mtask->data;
++		regd_buf->data_size = mtask->data_count;
+ 		iser_reg_single(device, regd_buf,
+ 				DMA_TO_DEVICE);
+ 		iser_dto_add_regd_buff(send_dto, regd_buf,
+@@ -534,13 +535,15 @@ send_control_error:
+ void iser_rcv_completion(struct iser_desc *rx_desc,
+ 			 unsigned long dto_xfer_len)
+ {
+-	struct iser_dto *dto = &rx_desc->dto;
++	struct iser_dto        *dto = &rx_desc->dto;
+ 	struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
+-	struct iscsi_task *task;
+-	struct iscsi_iser_task *iser_task;
++	struct iscsi_session *session = conn->iscsi_conn->session;
++	struct iscsi_cmd_task *ctask;
++	struct iscsi_iser_cmd_task *iser_ctask;
+ 	struct iscsi_hdr *hdr;
+ 	char   *rx_data = NULL;
+ 	int     rx_data_len = 0;
++	unsigned int itt;
+ 	unsigned char opcode;
+ 
+ 	hdr = &rx_desc->iscsi_header;
+@@ -556,24 +559,19 @@ void iser_rcv_completion(struct iser_des
+ 	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
+ 
+ 	if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
+-		spin_lock(&conn->iscsi_conn->session->lock);
+-		task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
+-		if (task)
+-			__iscsi_get_task(task);
+-		spin_unlock(&conn->iscsi_conn->session->lock);
+-
+-		if (!task)
++	        itt = get_itt(hdr->itt); /* mask out cid and age bits */
++		if (!(itt < session->cmds_max))
+ 			iser_err("itt can't be matched to task!!! "
+-				 "conn %p opcode %d itt %d\n",
+-				 conn->iscsi_conn, opcode, hdr->itt);
+-		else {
+-			iser_task = task->dd_data;
+-			iser_dbg("itt %d task %p\n",hdr->itt, task);
+-			iser_task->status = ISER_TASK_STATUS_COMPLETED;
+-			iser_task_rdma_finalize(iser_task);
+-			iscsi_put_task(task);
+-		}
++				 "conn %p opcode %d cmds_max %d itt %d\n",
++				 conn->iscsi_conn,opcode,session->cmds_max,itt);
++		/* use the mapping given with the cmds array indexed by itt */
++		ctask = (struct iscsi_cmd_task *)session->cmds[itt];
++		iser_ctask = ctask->dd_data;
++		iser_dbg("itt %d ctask %p\n",itt,ctask);
++		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
++		iser_ctask_rdma_finalize(iser_ctask);
+ 	}
++
+ 	iser_dto_buffs_release(dto);
+ 
+ 	iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
+@@ -594,7 +592,7 @@ void iser_snd_completion(struct iser_des
+ 	struct iser_conn       *ib_conn = dto->ib_conn;
+ 	struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
+ 	struct iscsi_conn      *conn = iser_conn->iscsi_conn;
+-	struct iscsi_task *task;
++	struct iscsi_mgmt_task *mtask;
+ 	int resume_tx = 0;
+ 
+ 	iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
+@@ -617,31 +615,36 @@ void iser_snd_completion(struct iser_des
+ 
+ 	if (tx_desc->type == ISCSI_TX_CONTROL) {
+ 		/* this arithmetic is legal by libiscsi dd_data allocation */
+-		task = (void *) ((long)(void *)tx_desc -
+-				  sizeof(struct iscsi_task));
+-		if (task->hdr->itt == RESERVED_ITT)
+-			iscsi_put_task(task);
++		mtask = (void *) ((long)(void *)tx_desc -
++				  sizeof(struct iscsi_mgmt_task));
++		if (mtask->hdr->itt == RESERVED_ITT) {
++			struct iscsi_session *session = conn->session;
++
++			spin_lock(&conn->session->lock);
++			iscsi_free_mgmt_task(conn, mtask);
++			spin_unlock(&session->lock);
++		}
+ 	}
+ }
+ 
+-void iser_task_rdma_init(struct iscsi_iser_task *iser_task)
++void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask)
+ 
+ {
+-	iser_task->status = ISER_TASK_STATUS_INIT;
++	iser_ctask->status = ISER_TASK_STATUS_INIT;
+ 
+-	iser_task->dir[ISER_DIR_IN] = 0;
+-	iser_task->dir[ISER_DIR_OUT] = 0;
++	iser_ctask->dir[ISER_DIR_IN] = 0;
++	iser_ctask->dir[ISER_DIR_OUT] = 0;
+ 
+-	iser_task->data[ISER_DIR_IN].data_len  = 0;
+-	iser_task->data[ISER_DIR_OUT].data_len = 0;
++	iser_ctask->data[ISER_DIR_IN].data_len  = 0;
++	iser_ctask->data[ISER_DIR_OUT].data_len = 0;
+ 
+-	memset(&iser_task->rdma_regd[ISER_DIR_IN], 0,
++	memset(&iser_ctask->rdma_regd[ISER_DIR_IN], 0,
+ 	       sizeof(struct iser_regd_buf));
+-	memset(&iser_task->rdma_regd[ISER_DIR_OUT], 0,
++	memset(&iser_ctask->rdma_regd[ISER_DIR_OUT], 0,
+ 	       sizeof(struct iser_regd_buf));
+ }
+ 
+-void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
++void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
+ {
+ 	int deferred;
+ 	int is_rdma_aligned = 1;
+@@ -650,17 +653,17 @@ void iser_task_rdma_finalize(struct iscs
+ 	/* if we were reading, copy back to unaligned sglist,
+ 	 * anyway dma_unmap and free the copy
+ 	 */
+-	if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) {
++	if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) {
+ 		is_rdma_aligned = 0;
+-		iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_IN);
++		iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
+ 	}
+-	if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
++	if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
+ 		is_rdma_aligned = 0;
+-		iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_OUT);
++		iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
+ 	}
+ 
+-	if (iser_task->dir[ISER_DIR_IN]) {
+-		regd = &iser_task->rdma_regd[ISER_DIR_IN];
++	if (iser_ctask->dir[ISER_DIR_IN]) {
++		regd = &iser_ctask->rdma_regd[ISER_DIR_IN];
+ 		deferred = iser_regd_buff_release(regd);
+ 		if (deferred) {
+ 			iser_err("%d references remain for BUF-IN rdma reg\n",
+@@ -668,8 +671,8 @@ void iser_task_rdma_finalize(struct iscs
+ 		}
+ 	}
+ 
+-	if (iser_task->dir[ISER_DIR_OUT]) {
+-		regd = &iser_task->rdma_regd[ISER_DIR_OUT];
++	if (iser_ctask->dir[ISER_DIR_OUT]) {
++		regd = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+ 		deferred = iser_regd_buff_release(regd);
+ 		if (deferred) {
+ 			iser_err("%d references remain for BUF-OUT rdma reg\n",
+@@ -679,7 +682,7 @@ void iser_task_rdma_finalize(struct iscs
+ 
+        /* if the data was unaligned, it was already unmapped and then copied */
+        if (is_rdma_aligned)
+-		iser_dma_unmap_task_data(iser_task);
++		iser_dma_unmap_task_data(iser_ctask);
+ }
+ 
+ void iser_dto_buffs_release(struct iser_dto *dto)
+Index: ofed_kernel/drivers/infiniband/ulp/iser/iser_memory.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/iser/iser_memory.c
++++ ofed_kernel/drivers/infiniband/ulp/iser/iser_memory.c
+@@ -28,6 +28,8 @@
+  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  * SOFTWARE.
++ *
++ * $Id: iser_memory.c 6964 2006-05-07 11:11:43Z ogerlitz $
+  */
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -99,13 +101,13 @@ void iser_reg_single(struct iser_device 
+ /**
+  * iser_start_rdma_unaligned_sg
+  */
+-static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
++static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
+ 					enum iser_data_dir cmd_dir)
+ {
+ 	int dma_nents;
+ 	struct ib_device *dev;
+ 	char *mem = NULL;
+-	struct iser_data_buf *data = &iser_task->data[cmd_dir];
++	struct iser_data_buf *data = &iser_ctask->data[cmd_dir];
+ 	unsigned long  cmd_data_len = data->data_len;
+ 
+ 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
+@@ -138,37 +140,37 @@ static int iser_start_rdma_unaligned_sg(
+ 		}
+ 	}
+ 
+-	sg_init_one(&iser_task->data_copy[cmd_dir].sg_single, mem, cmd_data_len);
+-	iser_task->data_copy[cmd_dir].buf  =
+-		&iser_task->data_copy[cmd_dir].sg_single;
+-	iser_task->data_copy[cmd_dir].size = 1;
++	sg_init_one(&iser_ctask->data_copy[cmd_dir].sg_single, mem, cmd_data_len);
++	iser_ctask->data_copy[cmd_dir].buf  =
++		&iser_ctask->data_copy[cmd_dir].sg_single;
++	iser_ctask->data_copy[cmd_dir].size = 1;
+ 
+-	iser_task->data_copy[cmd_dir].copy_buf  = mem;
++	iser_ctask->data_copy[cmd_dir].copy_buf  = mem;
+ 
+-	dev = iser_task->iser_conn->ib_conn->device->ib_device;
++	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
+ 	dma_nents = ib_dma_map_sg(dev,
+-				  &iser_task->data_copy[cmd_dir].sg_single,
++				  &iser_ctask->data_copy[cmd_dir].sg_single,
+ 				  1,
+ 				  (cmd_dir == ISER_DIR_OUT) ?
+ 				  DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ 	BUG_ON(dma_nents == 0);
+ 
+-	iser_task->data_copy[cmd_dir].dma_nents = dma_nents;
++	iser_ctask->data_copy[cmd_dir].dma_nents = dma_nents;
+ 	return 0;
+ }
+ 
+ /**
+  * iser_finalize_rdma_unaligned_sg
+  */
+-void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
++void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
+ 				     enum iser_data_dir         cmd_dir)
+ {
+ 	struct ib_device *dev;
+ 	struct iser_data_buf *mem_copy;
+ 	unsigned long  cmd_data_len;
+ 
+-	dev = iser_task->iser_conn->ib_conn->device->ib_device;
+-	mem_copy = &iser_task->data_copy[cmd_dir];
++	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
++	mem_copy = &iser_ctask->data_copy[cmd_dir];
+ 
+ 	ib_dma_unmap_sg(dev, &mem_copy->sg_single, 1,
+ 			(cmd_dir == ISER_DIR_OUT) ?
+@@ -184,8 +186,8 @@ void iser_finalize_rdma_unaligned_sg(str
+ 		/* copy back read RDMA to unaligned sg */
+ 		mem	= mem_copy->copy_buf;
+ 
+-		sgl	= (struct scatterlist *)iser_task->data[ISER_DIR_IN].buf;
+-		sg_size = iser_task->data[ISER_DIR_IN].size;
++		sgl	= (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf;
++		sg_size = iser_ctask->data[ISER_DIR_IN].size;
+ 
+ 		p = mem;
+ 		for_each_sg(sgl, sg, sg_size, i) {
+@@ -198,7 +200,7 @@ void iser_finalize_rdma_unaligned_sg(str
+ 		}
+ 	}
+ 
+-	cmd_data_len = iser_task->data[cmd_dir].data_len;
++	cmd_data_len = iser_ctask->data[cmd_dir].data_len;
+ 
+ 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
+ 		free_pages((unsigned long)mem_copy->copy_buf,
+@@ -376,15 +378,15 @@ static void iser_page_vec_build(struct i
+ 	}
+ }
+ 
+-int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
+-			    struct iser_data_buf *data,
+-			    enum iser_data_dir iser_dir,
+-			    enum dma_data_direction dma_dir)
++int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
++			    struct iser_data_buf       *data,
++			    enum   iser_data_dir       iser_dir,
++			    enum   dma_data_direction  dma_dir)
+ {
+ 	struct ib_device *dev;
+ 
+-	iser_task->dir[iser_dir] = 1;
+-	dev = iser_task->iser_conn->ib_conn->device->ib_device;
++	iser_ctask->dir[iser_dir] = 1;
++	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
+ 
+ 	data->dma_nents = ib_dma_map_sg(dev, data->buf, data->size, dma_dir);
+ 	if (data->dma_nents == 0) {
+@@ -394,20 +396,20 @@ int iser_dma_map_task_data(struct iscsi_
+ 	return 0;
+ }
+ 
+-void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task)
++void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
+ {
+ 	struct ib_device *dev;
+ 	struct iser_data_buf *data;
+ 
+-	dev = iser_task->iser_conn->ib_conn->device->ib_device;
++	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
+ 
+-	if (iser_task->dir[ISER_DIR_IN]) {
+-		data = &iser_task->data[ISER_DIR_IN];
++	if (iser_ctask->dir[ISER_DIR_IN]) {
++		data = &iser_ctask->data[ISER_DIR_IN];
+ 		ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE);
+ 	}
+ 
+-	if (iser_task->dir[ISER_DIR_OUT]) {
+-		data = &iser_task->data[ISER_DIR_OUT];
++	if (iser_ctask->dir[ISER_DIR_OUT]) {
++		data = &iser_ctask->data[ISER_DIR_OUT];
+ 		ib_dma_unmap_sg(dev, data->buf, data->size, DMA_TO_DEVICE);
+ 	}
+ }
+@@ -418,21 +420,21 @@ void iser_dma_unmap_task_data(struct isc
+  *
+  * returns 0 on success, errno code on failure
+  */
+-int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task,
++int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
+ 		      enum   iser_data_dir        cmd_dir)
+ {
+-	struct iscsi_conn    *iscsi_conn = iser_task->iser_conn->iscsi_conn;
+-	struct iser_conn     *ib_conn = iser_task->iser_conn->ib_conn;
++	struct iscsi_conn    *iscsi_conn = iser_ctask->iser_conn->iscsi_conn;
++	struct iser_conn     *ib_conn = iser_ctask->iser_conn->ib_conn;
+ 	struct iser_device   *device = ib_conn->device;
+ 	struct ib_device     *ibdev = device->ib_device;
+-	struct iser_data_buf *mem = &iser_task->data[cmd_dir];
++	struct iser_data_buf *mem = &iser_ctask->data[cmd_dir];
+ 	struct iser_regd_buf *regd_buf;
+ 	int aligned_len;
+ 	int err;
+ 	int i;
+ 	struct scatterlist *sg;
+ 
+-	regd_buf = &iser_task->rdma_regd[cmd_dir];
++	regd_buf = &iser_ctask->rdma_regd[cmd_dir];
+ 
+ 	aligned_len = iser_data_buf_aligned_len(mem, ibdev);
+ 	if (aligned_len != mem->dma_nents) {
+@@ -442,13 +444,13 @@ int iser_reg_rdma_mem(struct iscsi_iser_
+ 		iser_data_buf_dump(mem, ibdev);
+ 
+ 		/* unmap the command data before accessing it */
+-		iser_dma_unmap_task_data(iser_task);
++		iser_dma_unmap_task_data(iser_ctask);
+ 
+ 		/* allocate copy buf, if we are writing, copy the */
+ 		/* unaligned scatterlist, dma map the copy        */
+-		if (iser_start_rdma_unaligned_sg(iser_task, cmd_dir) != 0)
++		if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0)
+ 				return -ENOMEM;
+-		mem = &iser_task->data_copy[cmd_dir];
++		mem = &iser_ctask->data_copy[cmd_dir];
+ 	}
+ 
+ 	/* if there a single dma entry, FMR is not needed */
+@@ -472,9 +474,8 @@ int iser_reg_rdma_mem(struct iscsi_iser_
+ 		err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg);
+ 		if (err) {
+ 			iser_data_buf_dump(mem, ibdev);
+-			iser_err("mem->dma_nents = %d (dlength = 0x%x)\n",
+-				 mem->dma_nents,
+-				 ntoh24(iser_task->desc.iscsi_header.dlength));
++			iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", mem->dma_nents,
++				 ntoh24(iser_ctask->desc.iscsi_header.dlength));
+ 			iser_err("page_vec: data_size = 0x%x, length = %d, offset = 0x%x\n",
+ 				 ib_conn->page_vec->data_size, ib_conn->page_vec->length,
+ 				 ib_conn->page_vec->offset);
+Index: ofed_kernel/drivers/infiniband/ulp/iser/iser_verbs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/iser/iser_verbs.c
++++ ofed_kernel/drivers/infiniband/ulp/iser/iser_verbs.c
+@@ -29,6 +29,8 @@
+  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  * SOFTWARE.
++ *
++ * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $
+  */
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -322,18 +324,7 @@ static void iser_conn_release(struct ise
+ 		iser_device_try_release(device);
+ 	if (ib_conn->iser_conn)
+ 		ib_conn->iser_conn->ib_conn = NULL;
+-	iscsi_destroy_endpoint(ib_conn->ep);
+-}
+-
+-void iser_conn_get(struct iser_conn *ib_conn)
+-{
+-	atomic_inc(&ib_conn->refcount);
+-}
+-
+-void iser_conn_put(struct iser_conn *ib_conn)
+-{
+-	if (atomic_dec_and_test(&ib_conn->refcount))
+-		iser_conn_release(ib_conn);
++	kfree(ib_conn);
+ }
+ 
+ /**
+@@ -357,7 +348,7 @@ void iser_conn_terminate(struct iser_con
+ 	wait_event_interruptible(ib_conn->wait,
+ 				 ib_conn->state == ISER_CONN_DOWN);
+ 
+-	iser_conn_put(ib_conn);
++	iser_conn_release(ib_conn);
+ }
+ 
+ static void iser_connect_error(struct rdma_cm_id *cma_id)
+@@ -482,7 +473,6 @@ static int iser_cma_handler(struct rdma_
+ 		break;
+ 	case RDMA_CM_EVENT_DISCONNECTED:
+ 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
+-	case RDMA_CM_EVENT_ADDR_CHANGE:
+ 		iser_disconnected_handler(cma_id);
+ 		break;
+ 	default:
+@@ -492,15 +482,24 @@ static int iser_cma_handler(struct rdma_
+ 	return ret;
+ }
+ 
+-void iser_conn_init(struct iser_conn *ib_conn)
++int iser_conn_init(struct iser_conn **ibconn)
+ {
++	struct iser_conn *ib_conn;
++
++	ib_conn = kzalloc(sizeof *ib_conn, GFP_KERNEL);
++	if (!ib_conn) {
++		iser_err("can't alloc memory for struct iser_conn\n");
++		return -ENOMEM;
++	}
+ 	ib_conn->state = ISER_CONN_INIT;
+ 	init_waitqueue_head(&ib_conn->wait);
+ 	atomic_set(&ib_conn->post_recv_buf_count, 0);
+ 	atomic_set(&ib_conn->post_send_buf_count, 0);
+-	atomic_set(&ib_conn->refcount, 1);
+ 	INIT_LIST_HEAD(&ib_conn->conn_list);
+ 	spin_lock_init(&ib_conn->lock);
++
++	*ibconn = ib_conn;
++	return 0;
+ }
+ 
+  /**
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iser_02_fix_iscsi_if_h.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iser_02_fix_iscsi_if_h.patch
new file mode 100644
index 0000000..4371ddd
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iser_02_fix_iscsi_if_h.patch
@@ -0,0 +1,142 @@
+From c703d2c0ca18a6a5b8f4ecbd5c02654a15fb11ff Mon Sep 17 00:00:00 2001
+From: Doron Shoham <dorons at voltaire.com>
+Date: Tue, 26 Aug 2008 14:26:17 +0300
+Subject: [PATCH] fix iscsi_if.h
+
+Signed-off-by: Doron Shoham <dorons at voltaire.com>
+---
+ include/scsi/iscsi_if.h |   93 ++++++++++++++++++++++--------------------------
+ 1 file changed, 43 insertions(+), 50 deletions(-)
+
+Index: ofed_kernel/include/scsi/iscsi_if.h
+===================================================================
+--- ofed_kernel.orig/include/scsi/iscsi_if.h
++++ ofed_kernel/include/scsi/iscsi_if.h
+@@ -50,7 +50,6 @@ enum iscsi_uevent_e {
+ 	ISCSI_UEVENT_TGT_DSCVR		= UEVENT_BASE + 15,
+ 	ISCSI_UEVENT_SET_HOST_PARAM	= UEVENT_BASE + 16,
+ 	ISCSI_UEVENT_UNBIND_SESSION	= UEVENT_BASE + 17,
+-	ISCSI_UEVENT_CREATE_BOUND_SESSION	= UEVENT_BASE + 18,
+ 
+ 	/* up events */
+ 	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1,
+@@ -79,12 +78,6 @@ struct iscsi_uevent {
+ 			uint16_t	cmds_max;
+ 			uint16_t	queue_depth;
+ 		} c_session;
+-		struct msg_create_bound_session {
+-			uint64_t	ep_handle;
+-			uint32_t	initial_cmdsn;
+-			uint16_t	cmds_max;
+-			uint16_t	queue_depth;
+-		} c_bound_session;
+ 		struct msg_destroy_session {
+ 			uint32_t	sid;
+ 		} d_session;
+@@ -257,49 +250,42 @@ enum iscsi_param {
+ 
+ 	ISCSI_PARAM_PING_TMO,
+ 	ISCSI_PARAM_RECV_TMO,
+-
+-	ISCSI_PARAM_IFACE_NAME,
+-	ISCSI_PARAM_ISID,
+-	ISCSI_PARAM_INITIATOR_NAME,
+ 	/* must always be last */
+ 	ISCSI_PARAM_MAX,
+ };
+ 
+-#define ISCSI_MAX_RECV_DLENGTH		(1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH)
+-#define ISCSI_MAX_XMIT_DLENGTH		(1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH)
+-#define ISCSI_HDRDGST_EN		(1ULL << ISCSI_PARAM_HDRDGST_EN)
+-#define ISCSI_DATADGST_EN		(1ULL << ISCSI_PARAM_DATADGST_EN)
+-#define ISCSI_INITIAL_R2T_EN		(1ULL << ISCSI_PARAM_INITIAL_R2T_EN)
+-#define ISCSI_MAX_R2T			(1ULL << ISCSI_PARAM_MAX_R2T)
+-#define ISCSI_IMM_DATA_EN		(1ULL << ISCSI_PARAM_IMM_DATA_EN)
+-#define ISCSI_FIRST_BURST		(1ULL << ISCSI_PARAM_FIRST_BURST)
+-#define ISCSI_MAX_BURST			(1ULL << ISCSI_PARAM_MAX_BURST)
+-#define ISCSI_PDU_INORDER_EN		(1ULL << ISCSI_PARAM_PDU_INORDER_EN)
+-#define ISCSI_DATASEQ_INORDER_EN	(1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN)
+-#define ISCSI_ERL			(1ULL << ISCSI_PARAM_ERL)
+-#define ISCSI_IFMARKER_EN		(1ULL << ISCSI_PARAM_IFMARKER_EN)
+-#define ISCSI_OFMARKER_EN		(1ULL << ISCSI_PARAM_OFMARKER_EN)
+-#define ISCSI_EXP_STATSN		(1ULL << ISCSI_PARAM_EXP_STATSN)
+-#define ISCSI_TARGET_NAME		(1ULL << ISCSI_PARAM_TARGET_NAME)
+-#define ISCSI_TPGT			(1ULL << ISCSI_PARAM_TPGT)
+-#define ISCSI_PERSISTENT_ADDRESS	(1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS)
+-#define ISCSI_PERSISTENT_PORT		(1ULL << ISCSI_PARAM_PERSISTENT_PORT)
+-#define ISCSI_SESS_RECOVERY_TMO		(1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO)
+-#define ISCSI_CONN_PORT			(1ULL << ISCSI_PARAM_CONN_PORT)
+-#define ISCSI_CONN_ADDRESS		(1ULL << ISCSI_PARAM_CONN_ADDRESS)
+-#define ISCSI_USERNAME			(1ULL << ISCSI_PARAM_USERNAME)
+-#define ISCSI_USERNAME_IN		(1ULL << ISCSI_PARAM_USERNAME_IN)
+-#define ISCSI_PASSWORD			(1ULL << ISCSI_PARAM_PASSWORD)
+-#define ISCSI_PASSWORD_IN		(1ULL << ISCSI_PARAM_PASSWORD_IN)
+-#define ISCSI_FAST_ABORT		(1ULL << ISCSI_PARAM_FAST_ABORT)
+-#define ISCSI_ABORT_TMO			(1ULL << ISCSI_PARAM_ABORT_TMO)
+-#define ISCSI_LU_RESET_TMO		(1ULL << ISCSI_PARAM_LU_RESET_TMO)
+-#define ISCSI_HOST_RESET_TMO		(1ULL << ISCSI_PARAM_HOST_RESET_TMO)
+-#define ISCSI_PING_TMO			(1ULL << ISCSI_PARAM_PING_TMO)
+-#define ISCSI_RECV_TMO			(1ULL << ISCSI_PARAM_RECV_TMO)
+-#define ISCSI_IFACE_NAME		(1ULL << ISCSI_PARAM_IFACE_NAME)
+-#define ISCSI_ISID			(1ULL << ISCSI_PARAM_ISID)
+-#define ISCSI_INITIATOR_NAME		(1ULL << ISCSI_PARAM_INITIATOR_NAME)
++#define ISCSI_MAX_RECV_DLENGTH		(1 << ISCSI_PARAM_MAX_RECV_DLENGTH)
++#define ISCSI_MAX_XMIT_DLENGTH		(1 << ISCSI_PARAM_MAX_XMIT_DLENGTH)
++#define ISCSI_HDRDGST_EN		(1 << ISCSI_PARAM_HDRDGST_EN)
++#define ISCSI_DATADGST_EN		(1 << ISCSI_PARAM_DATADGST_EN)
++#define ISCSI_INITIAL_R2T_EN		(1 << ISCSI_PARAM_INITIAL_R2T_EN)
++#define ISCSI_MAX_R2T			(1 << ISCSI_PARAM_MAX_R2T)
++#define ISCSI_IMM_DATA_EN		(1 << ISCSI_PARAM_IMM_DATA_EN)
++#define ISCSI_FIRST_BURST		(1 << ISCSI_PARAM_FIRST_BURST)
++#define ISCSI_MAX_BURST			(1 << ISCSI_PARAM_MAX_BURST)
++#define ISCSI_PDU_INORDER_EN		(1 << ISCSI_PARAM_PDU_INORDER_EN)
++#define ISCSI_DATASEQ_INORDER_EN	(1 << ISCSI_PARAM_DATASEQ_INORDER_EN)
++#define ISCSI_ERL			(1 << ISCSI_PARAM_ERL)
++#define ISCSI_IFMARKER_EN		(1 << ISCSI_PARAM_IFMARKER_EN)
++#define ISCSI_OFMARKER_EN		(1 << ISCSI_PARAM_OFMARKER_EN)
++#define ISCSI_EXP_STATSN		(1 << ISCSI_PARAM_EXP_STATSN)
++#define ISCSI_TARGET_NAME		(1 << ISCSI_PARAM_TARGET_NAME)
++#define ISCSI_TPGT			(1 << ISCSI_PARAM_TPGT)
++#define ISCSI_PERSISTENT_ADDRESS	(1 << ISCSI_PARAM_PERSISTENT_ADDRESS)
++#define ISCSI_PERSISTENT_PORT		(1 << ISCSI_PARAM_PERSISTENT_PORT)
++#define ISCSI_SESS_RECOVERY_TMO		(1 << ISCSI_PARAM_SESS_RECOVERY_TMO)
++#define ISCSI_CONN_PORT			(1 << ISCSI_PARAM_CONN_PORT)
++#define ISCSI_CONN_ADDRESS		(1 << ISCSI_PARAM_CONN_ADDRESS)
++#define ISCSI_USERNAME			(1 << ISCSI_PARAM_USERNAME)
++#define ISCSI_USERNAME_IN		(1 << ISCSI_PARAM_USERNAME_IN)
++#define ISCSI_PASSWORD			(1 << ISCSI_PARAM_PASSWORD)
++#define ISCSI_PASSWORD_IN		(1 << ISCSI_PARAM_PASSWORD_IN)
++#define ISCSI_FAST_ABORT		(1 << ISCSI_PARAM_FAST_ABORT)
++#define ISCSI_ABORT_TMO			(1 << ISCSI_PARAM_ABORT_TMO)
++#define ISCSI_LU_RESET_TMO		(1 << ISCSI_PARAM_LU_RESET_TMO)
++#define ISCSI_HOST_RESET_TMO		(1 << ISCSI_PARAM_HOST_RESET_TMO)
++#define ISCSI_PING_TMO			(1 << ISCSI_PARAM_PING_TMO)
++#define ISCSI_RECV_TMO			(1 << ISCSI_PARAM_RECV_TMO)
+ 
+ /* iSCSI HBA params */
+ enum iscsi_host_param {
+@@ -310,13 +296,20 @@ enum iscsi_host_param {
+ 	ISCSI_HOST_PARAM_MAX,
+ };
+ 
+-#define ISCSI_HOST_HWADDRESS		(1ULL << ISCSI_HOST_PARAM_HWADDRESS)
+-#define ISCSI_HOST_INITIATOR_NAME	(1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME)
+-#define ISCSI_HOST_NETDEV_NAME		(1ULL << ISCSI_HOST_PARAM_NETDEV_NAME)
+-#define ISCSI_HOST_IPADDRESS		(1ULL << ISCSI_HOST_PARAM_IPADDRESS)
++#define ISCSI_HOST_HWADDRESS		(1 << ISCSI_HOST_PARAM_HWADDRESS)
++#define ISCSI_HOST_INITIATOR_NAME	(1 << ISCSI_HOST_PARAM_INITIATOR_NAME)
++#define ISCSI_HOST_NETDEV_NAME		(1 << ISCSI_HOST_PARAM_NETDEV_NAME)
++#define ISCSI_HOST_IPADDRESS		(1 << ISCSI_HOST_PARAM_IPADDRESS)
+ 
+ #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
+ #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
++#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
++
++/**
++ * iscsi_hostdata - get LLD hostdata from scsi_host
++ * @_hostdata: pointer to scsi host's hostdata
++ **/
++#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
+ 
+ /*
+  * These flags presents iSCSI Data-Path capabilities.
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iw_cxgb3_0010_states.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_cxgb3_0010_states.patch
new file mode 100644
index 0000000..6b73778
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_cxgb3_0010_states.patch
@@ -0,0 +1,24 @@
+---
+ drivers/infiniband/hw/cxgb3/iwch_cm.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+Index: ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_cm.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/cxgb3/iwch_cm.c
++++ ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_cm.c
+@@ -47,6 +47,7 @@
+ #include "iwch_provider.h"
+ #include "iwch_cm.h"
+ 
++#ifdef DEBUG
+ static char *states[] = {
+ 	"idle",
+ 	"listen",
+@@ -62,6 +63,7 @@ static char *states[] = {
+ 	"dead",
+ 	NULL,
+ };
++#endif
+ 
+ int peer2peer = 0;
+ module_param(peer2peer, int, 0644);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_050_to_2_6_24.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_050_to_2_6_24.patch
new file mode 100644
index 0000000..55ca7f8
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_050_to_2_6_24.patch
@@ -0,0 +1,31 @@
+diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
+index 0696b4c..f81379d 100644
+--- a/drivers/infiniband/hw/nes/nes.c
++++ b/drivers/infiniband/hw/nes/nes.c
+@@ -1118,19 +1118,19 @@ static ssize_t nes_show_wqm_quanta(struct device_driver *ddp, char *buf)
+ static ssize_t nes_store_wqm_quanta(struct device_driver *ddp,
+ 					const char *buf, size_t count)
+ {
+-	unsigned long wqm_quanta_value;
++	u32 wqm_quanta;
+ 	u32 wqm_config1;
+ 	u32 i = 0;
+ 	struct nes_device *nesdev;
+ 
+-	strict_strtoul(buf, 0, &wqm_quanta_value);
++	wqm_quanta = simple_strtoul(buf, NULL, 0);
+ 	list_for_each_entry(nesdev, &nes_dev_list, list) {
+ 		if (i == ee_flsh_adapter) {
+-			nesdev->nesadapter->wqm_quanta = wqm_quanta_value;
++			nesdev->nesadapter->wqm_quanta = wqm_quanta;
+ 			wqm_config1 = nes_read_indexed(nesdev,
+ 						NES_IDX_WQM_CONFIG1);
+ 			nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG1,
+-					((wqm_quanta_value << 1) |
++					((wqm_quanta << 1) |
+ 					(wqm_config1 & 0x00000001)));
+ 			break;
+ 		}
+-- 
+1.5.3.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_100_to_2_6_23.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_100_to_2_6_23.patch
new file mode 100644
index 0000000..f8629a1
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_100_to_2_6_23.patch
@@ -0,0 +1,387 @@
+diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig
+index d449eb6..2aeb7ac 100644
+--- a/drivers/infiniband/hw/nes/Kconfig
++++ b/drivers/infiniband/hw/nes/Kconfig
+@@ -2,7 +2,6 @@ config INFINIBAND_NES
+ 	tristate "NetEffect RNIC Driver"
+ 	depends on PCI && INET && INFINIBAND
+ 	select LIBCRC32C
+-	select INET_LRO
+ 	---help---
+ 	  This is a low-level driver for NetEffect RDMA enabled
+ 	  Network Interface Cards (RNIC).
+diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
+index f81379d..e3668df 100644
+--- a/drivers/infiniband/hw/nes/nes.c
++++ b/drivers/infiniband/hw/nes/nes.c
+@@ -360,10 +360,11 @@ struct ib_qp *nes_get_qp(struct ib_device *device, int qpn)
+  */
+ static void nes_print_macaddr(struct net_device *netdev)
+ {
+-	DECLARE_MAC_BUF(mac);
+-
+-	nes_debug(NES_DBG_INIT, "%s: %s, IRQ %u\n",
+-		  netdev->name, print_mac(mac, netdev->dev_addr), netdev->irq);
++	nes_debug(NES_DBG_INIT, "%s: MAC %02X:%02X:%02X:%02X:%02X:%02X, IRQ %u\n",
++			netdev->name,
++			netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
++			netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5],
++			netdev->irq);
+ }
+ 
+ /**
+diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
+index 91d5372..ff384f1 100644
+--- a/drivers/infiniband/hw/nes/nes_cm.c
++++ b/drivers/infiniband/hw/nes/nes_cm.c
+@@ -1086,7 +1086,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
+ 	struct flowi fl;
+ 	struct neighbour *neigh;
+ 	int rc = -1;
+-	DECLARE_MAC_BUF(mac);
+ 
+ 	memset(&fl, 0, sizeof fl);
+ 	fl.nl_u.ip4_u.daddr = htonl(dst_ip);
+@@ -1100,8 +1099,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
+ 	if (neigh) {
+ 		if (neigh->nud_state & NUD_VALID) {
+ 			nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
+-				  " is %s, Gateway is 0x%08X \n", dst_ip,
+-				  print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
++				" is %02X:%02X:%02X:%02X:%02X:%02X, Gateway is"
++				" 0x%08X \n",
++				dst_ip, neigh->ha[0], neigh->ha[1], neigh->ha[2],
++				neigh->ha[3], neigh->ha[4], neigh->ha[5],
++				ntohl(rt->rt_gateway));
+ 			nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
+ 					     dst_ip, NES_ARP_ADD);
+ 			rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
+@@ -1130,7 +1132,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
+ 	int arpindex = 0;
+ 	struct nes_device *nesdev;
+ 	struct nes_adapter *nesadapter;
+-	DECLARE_MAC_BUF(mac);
+ 
+ 	/* create an hte and cm_node for this instance */
+ 	cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC);
+@@ -1197,8 +1198,11 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
+ 
+ 	/* copy the mac addr to node context */
+ 	memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN);
+-	nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %s\n",
+-		  print_mac(mac, cm_node->rem_mac));
++	nes_debug(NES_DBG_CM, "Remote mac addr from arp table:%02x,"
++			" %02x, %02x, %02x, %02x, %02x\n",
++			cm_node->rem_mac[0], cm_node->rem_mac[1],
++			cm_node->rem_mac[2], cm_node->rem_mac[3],
++			cm_node->rem_mac[4], cm_node->rem_mac[5]);
+ 
+ 	add_hte_node(cm_core, cm_node);
+ 	atomic_inc(&cm_nodes_created);
+diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
+index f0fe63d..6386c65 100644
+--- a/drivers/infiniband/hw/nes/nes_hw.c
++++ b/drivers/infiniband/hw/nes/nes_hw.c
+@@ -38,14 +38,9 @@
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+ #include <linux/if_vlan.h>
+-#include <linux/inet_lro.h>
+ 
+ #include "nes.h"
+ 
+-static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
+-module_param(nes_lro_max_aggr, uint, 0444);
+-MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
+-
+ static int wide_ppm_offset;
+ module_param(wide_ppm_offset, int, 0644);
+ MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm");
+@@ -1450,25 +1445,6 @@ static void nes_rq_wqes_timeout(unsigned long parm)
+ }
+ 
+ 
+-static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr,
+-			       void **tcph, u64 *hdr_flags, void *priv)
+-{
+-	unsigned int ip_len;
+-	struct iphdr *iph;
+-	skb_reset_network_header(skb);
+-	iph = ip_hdr(skb);
+-	if (iph->protocol != IPPROTO_TCP)
+-		return -1;
+-	ip_len = ip_hdrlen(skb);
+-	skb_set_transport_header(skb, ip_len);
+-	*tcph = tcp_hdr(skb);
+-
+-	*hdr_flags = LRO_IPV4 | LRO_TCP;
+-	*iphdr = iph;
+-	return 0;
+-}
+-
+-
+ /**
+  * nes_init_nic_qp
+  */
+@@ -1692,14 +1668,6 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
+ 			jumbomode = 1;
+ 		nes_nic_init_timer_defaults(nesdev, jumbomode);
+ 	}
+-	nesvnic->lro_mgr.max_aggr       = nes_lro_max_aggr;
+-	nesvnic->lro_mgr.max_desc       = NES_MAX_LRO_DESCRIPTORS;
+-	nesvnic->lro_mgr.lro_arr        = nesvnic->lro_desc;
+-	nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
+-	nesvnic->lro_mgr.features       = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
+-	nesvnic->lro_mgr.dev            = netdev;
+-	nesvnic->lro_mgr.ip_summed      = CHECKSUM_UNNECESSARY;
+-	nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ 	return 0;
+ }
+ 
+@@ -2475,7 +2443,7 @@ static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic
+ {
+ 	struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
+ 
+-	netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi);
++	netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index]);
+ }
+ 
+ 
+@@ -2510,13 +2478,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
+ 	u16 pkt_type;
+ 	u16 rqes_processed = 0;
+ 	u8 sq_cqes = 0;
+-	u8 nes_use_lro = 0;
+ 
+ 	head = cq->cq_head;
+ 	cq_size = cq->cq_size;
+ 	cq->cqes_pending = 1;
+-	if (nesvnic->netdev->features & NETIF_F_LRO)
+-		nes_use_lro = 1;
+ 	do {
+ 		if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
+ 				NES_NIC_CQE_VALID) {
+@@ -2648,17 +2613,9 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
+ 							>> 16);
+ 					nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
+ 							nesvnic->netdev->name, vlan_tag);
+-					if (nes_use_lro)
+-						lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
+-								nesvnic->vlan_grp, vlan_tag, NULL);
+-					else
+-						nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
+-				} else {
+-					if (nes_use_lro)
+-						lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
+-					else
+-						nes_netif_rx(rx_skb);
+-				}
++					nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
++				} else
++					nes_netif_rx(rx_skb);
+ 
+ skip_rx_indicate0:
+ 				nesvnic->netdev->last_rx = jiffies;
+@@ -2689,8 +2646,6 @@ skip_rx_indicate0:
+ 
+ 	} while (1);
+ 
+-	if (nes_use_lro)
+-		lro_flush_all(&nesvnic->lro_mgr);
+ 	if (sq_cqes) {
+ 		barrier();
+ 		/* restart the queue if it had been stopped */
+diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
+index c3654c6..1a81bbb 100644
+--- a/drivers/infiniband/hw/nes/nes_hw.h
++++ b/drivers/infiniband/hw/nes/nes_hw.h
+@@ -33,8 +33,6 @@
+ #ifndef __NES_HW_H
+ #define __NES_HW_H
+ 
+-#include <linux/inet_lro.h>
+-
+ #define NES_PHY_TYPE_CX4       1
+ #define NES_PHY_TYPE_1G        2
+ #define NES_PHY_TYPE_IRIS      3
+@@ -993,8 +991,6 @@ struct nes_hw_tune_timer {
+ #define NES_TIMER_ENABLE_LIMIT      4
+ #define NES_MAX_LINK_INTERRUPTS     128
+ #define NES_MAX_LINK_CHECK          200
+-#define NES_MAX_LRO_DESCRIPTORS     32
+-#define NES_LRO_MAX_AGGR            64
+ 
+ struct nes_adapter {
+ 	u64              fw_ver;
+@@ -1169,7 +1165,6 @@ struct nes_vnic {
+ 	u32               msg_enable;
+ 	/* u32 tx_avail; */
+ 	__be32            local_ipaddr;
+-	struct napi_struct   napi;
+ 	spinlock_t           tx_lock;	/* could use netdev tx lock? */
+ 	struct timer_list    rq_wqes_timer;
+ 	u32                  nic_mem_size;
+@@ -1197,9 +1192,6 @@ struct nes_vnic {
+ 	u8  of_device_registered;
+ 	u8  rdma_enabled;
+ 	u8  rx_checksum_disabled;
+-	u32 lro_max_aggr;
+-	struct net_lro_mgr lro_mgr;
+-	struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
+ };
+ 
+ struct nes_ib_device {
+diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
+index ef13030..12d9cc6 100644
+--- a/drivers/infiniband/hw/nes/nes_nic.c
++++ b/drivers/infiniband/hw/nes/nes_nic.c
+@@ -96,35 +96,38 @@ static int nics_per_function = 1;
+ /**
+  * nes_netdev_poll
+  */
+-static int nes_netdev_poll(struct napi_struct *napi, int budget)
++static int nes_netdev_poll(struct net_device *netdev, int *budget_ptr)
+ {
+-	struct nes_vnic *nesvnic = container_of(napi, struct nes_vnic, napi);
+-	struct net_device *netdev = nesvnic->netdev;
++	struct nes_vnic *nesvnic = netdev_priv(netdev);
+ 	struct nes_device *nesdev = nesvnic->nesdev;
+ 	struct nes_hw_nic_cq *nescq = &nesvnic->nic_cq;
+-
+-	nesvnic->budget = budget;
++	nesvnic->budget = min(netdev->quota, *budget_ptr);
+ 	nescq->cqes_pending = 0;
+ 	nescq->rx_cqes_completed = 0;
+ 	nescq->cqe_allocs_pending = 0;
+ 	nescq->rx_pkts_indicated = 0;
+ 
+ 	nes_nic_ce_handler(nesdev, nescq);
++	netdev->quota -= nescq->rx_pkts_indicated;
++	*budget_ptr -= nescq->rx_pkts_indicated;
+ 
+-	if (nescq->cqes_pending == 0) {
+-		netif_rx_complete(netdev, napi);
++	if ((nescq->cqes_pending == 0) && (netdev->quota != 0)) {
++		netif_rx_complete(netdev);
+ 		/* clear out completed cqes and arm */
+ 		nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
+ 				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
+ 		nes_read32(nesdev->regs+NES_CQE_ALLOC);
++
++		return 0;
+ 	} else {
+ 		/* clear out completed cqes but don't arm */
+ 		nes_write32(nesdev->regs+NES_CQE_ALLOC,
+ 				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
+ 		nes_debug(NES_DBG_NETDEV, "%s: exiting with work pending\n",
+ 				nesvnic->netdev->name);
++
++		return 1;
+ 	}
+-	return nescq->rx_pkts_indicated;
+ }
+ 
+ 
+@@ -238,7 +241,6 @@ static int nes_netdev_open(struct net_device *netdev)
+ 		netif_start_queue(netdev);
+ 		netif_carrier_on(netdev);
+ 	}
+-	napi_enable(&nesvnic->napi);
+ 	nesvnic->netdev_open = 1;
+ 
+ 	return 0;
+@@ -266,7 +268,6 @@ static int nes_netdev_stop(struct net_device *netdev)
+ 		printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name);
+ 
+ 	/* Disable network packets */
+-	napi_disable(&nesvnic->napi);
+ 	netif_stop_queue(netdev);
+ 	list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
+ 		first_nesvnic = container_of(list_pos, struct nes_vnic, list);
+@@ -775,14 +776,16 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
+ 	int i;
+ 	u32 macaddr_low;
+ 	u16 macaddr_high;
+-	DECLARE_MAC_BUF(mac);
+ 
+ 	if (!is_valid_ether_addr(mac_addr->sa_data))
+ 		return -EADDRNOTAVAIL;
+ 
+ 	memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
+-	printk(PFX "%s: Address length = %d, Address = %s\n",
+-	       __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data));
++	printk(PFX "%s: Address length = %d, Address = %02X%02X%02X%02X%02X%02X..\n",
++		   __func__, netdev->addr_len,
++		   mac_addr->sa_data[0], mac_addr->sa_data[1],
++		   mac_addr->sa_data[2], mac_addr->sa_data[3],
++		   mac_addr->sa_data[4], mac_addr->sa_data[5]);
+ 	macaddr_high  = ((u16)netdev->dev_addr[0]) << 8;
+ 	macaddr_high += (u16)netdev->dev_addr[1];
+ 	macaddr_low   = ((u32)netdev->dev_addr[2]) << 24;
+@@ -887,11 +890,11 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
+ 			if (mc_index >= max_pft_entries_avaiable)
+ 				break;
+ 			if (multicast_addr) {
+-				DECLARE_MAC_BUF(mac);
+-				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n",
+-					  print_mac(mac, multicast_addr->dmi_addr),
+-					  perfect_filter_register_address+(mc_index * 8),
+-					  mc_nic_index);
++				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address = %02X%02X%02X%02X%02X%02X to register 0x%04X nic_idx=%d\n",
++						  multicast_addr->dmi_addr[0], multicast_addr->dmi_addr[1],
++						  multicast_addr->dmi_addr[2], multicast_addr->dmi_addr[3],
++						  multicast_addr->dmi_addr[4], multicast_addr->dmi_addr[5],
++						  perfect_filter_register_address+(mc_index * 8), mc_nic_index);
+ 				macaddr_high  = ((u16)multicast_addr->dmi_addr[0]) << 8;
+ 				macaddr_high += (u16)multicast_addr->dmi_addr[1];
+ 				macaddr_low   = ((u32)multicast_addr->dmi_addr[2]) << 24;
+@@ -1040,9 +1043,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
+ 	"CQ Depth 32",
+ 	"CQ Depth 128",
+ 	"CQ Depth 256",
+-	"LRO aggregated",
+-	"LRO flushed",
+-	"LRO no_desc",
+ };
+ 
+ #define NES_ETHTOOL_STAT_COUNT  ARRAY_SIZE(nes_ethtool_stringset)
+@@ -1240,9 +1240,6 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
+ 	target_stat_values[++index] = int_mod_cq_depth_32;
+ 	target_stat_values[++index] = int_mod_cq_depth_128;
+ 	target_stat_values[++index] = int_mod_cq_depth_256;
+-	target_stat_values[++index] = nesvnic->lro_mgr.stats.aggregated;
+-	target_stat_values[++index] = nesvnic->lro_mgr.stats.flushed;
+-	target_stat_values[++index] = nesvnic->lro_mgr.stats.no_desc;
+ 
+ }
+ 
+@@ -1525,8 +1522,6 @@ static struct ethtool_ops nes_ethtool_ops = {
+ 	.set_sg = ethtool_op_set_sg,
+ 	.get_tso = ethtool_op_get_tso,
+ 	.set_tso = ethtool_op_set_tso,
+-	.get_flags = ethtool_op_get_flags,
+-	.set_flags = ethtool_op_set_flags,
+ };
+ 
+ 
+@@ -1598,7 +1593,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ 	netdev->type = ARPHRD_ETHER;
+ 	netdev->features = NETIF_F_HIGHDMA;
+ 	netdev->ethtool_ops = &nes_ethtool_ops;
+-	netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
++	netdev->poll = nes_netdev_poll;
++	netdev->weight = 128;
+ 	nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
+ 	netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ 	netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
+@@ -1630,7 +1626,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ 
+ 	if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) {
+ 		netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
+-		netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
+ 	} else {
+ 		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+ 	}
+-- 
+1.5.3.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_200_to_2_6_22.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_200_to_2_6_22.patch
new file mode 100644
index 0000000..941a042
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_200_to_2_6_22.patch
@@ -0,0 +1,60 @@
+diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
+index e3668df..d1bf14b 100644
+--- a/drivers/infiniband/hw/nes/nes.c
++++ b/drivers/infiniband/hw/nes/nes.c
+@@ -593,16 +593,22 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
+ 						nesdev->nesadapter->port_count;
+ 	}
+ 
+-	if ((limit_maxrdreqsz ||
+-	     ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) &&
+-	      (hw_rev == NE020_REV1))) &&
+-	    (pcie_get_readrq(pcidev) > 256)) {
+-		if (pcie_set_readrq(pcidev, 256))
+-			printk(KERN_ERR PFX "Unable to set max read request"
+-				" to 256 bytes\n");
+-		else
+-			nes_debug(NES_DBG_INIT, "Max read request size set"
+-				" to 256 bytes\n");
++	if (limit_maxrdreqsz ||
++	    ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) &&
++	     (hw_rev == NE020_REV1))) {
++		u16 maxrdreqword;
++		pci_read_config_word(pcidev, 0x68, &maxrdreqword);
++		/* set bits 12-14 to 001b = 256 bytes */
++		if ((maxrdreqword & 0x7000) > 0x1000) {
++			maxrdreqword &= 0x8fff;
++			maxrdreqword |= 0x1000;
++			if (pci_write_config_word(pcidev, 0x68, maxrdreqword))
++				printk(KERN_ERR PFX "Unable to set max read "
++					"request to 256 bytes\n");
++			else
++				nes_debug(NES_DBG_INIT, "Max read request size"
++					"set to 256 bytes\n");
++		}
+ 	}
+ 
+ 	tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev);
+diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
+index 2872e1b..55e6900 100644
+--- a/drivers/infiniband/hw/nes/nes.h
++++ b/drivers/infiniband/hw/nes/nes.h
+@@ -274,14 +274,7 @@ static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
+ 	u32 crc_value;
+ 	crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad));
+ 
+-	/*
+-	 * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc
+-	 * state in cpu order"), behavior of crc32c changes on
+-	 * big-endian platforms.  Our algorithm expects the previous
+-	 * behavior; otherwise we have RDMA connection establishment
+-	 * issue on big-endian.
+-	 */
+-	return cpu_to_le32(crc_value);
++	return crc_value;
+ }
+ 
+ static inline void
+-- 
+1.5.3.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_210_to_2_6_21.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_210_to_2_6_21.patch
new file mode 100644
index 0000000..4a20493
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/iw_nes_210_to_2_6_21.patch
@@ -0,0 +1,27 @@
+diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
+index 12d9cc6..95f5a3f 100644
+--- a/drivers/infiniband/hw/nes/nes_nic.c
++++ b/drivers/infiniband/hw/nes/nes_nic.c
+@@ -1549,6 +1549,11 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
+ 	spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
+ }
+ 
++static void nes_netdev_vlan_rx_kill_vid(struct net_device *netdev, 
++					unsigned short vid)
++{
++}
++
+ 
+ /**
+  * nes_netdev_init - initialize network device
+@@ -1598,6 +1603,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
+ 	nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
+ 	netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ 	netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
++	netdev->vlan_rx_kill_vid = nes_netdev_vlan_rx_kill_vid;
+ 
+ 	/* Fill in the port structure */
+ 	nesvnic->netdev = netdev;
+-- 
+1.5.3.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/linux_genalloc_to_2_6_20.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/linux_genalloc_to_2_6_20.patch
new file mode 100644
index 0000000..f14bb75
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/linux_genalloc_to_2_6_20.patch
@@ -0,0 +1,21 @@
+---
+ drivers/infiniband/core/Makefile   |    2 ++
+ drivers/infiniband/core/genalloc.c |    1 +
+ 2 files changed, 3 insertions(+)
+
+Index: ofed_kernel/drivers/infiniband/core/Makefile
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/Makefile
++++ ofed_kernel/drivers/infiniband/core/Makefile
+@@ -30,3 +30,5 @@ ib_umad-y :=			user_mad.o
+ ib_ucm-y :=			ucm.o
+ 
+ ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_marshall.o
++
++ib_core-y +=			genalloc.o
+Index: ofed_kernel/drivers/infiniband/core/genalloc.c
+===================================================================
+--- /dev/null
++++ ofed_kernel/drivers/infiniband/core/genalloc.c
+@@ -0,0 +1 @@
++#include "src/genalloc.c"
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0030_smp_call_function.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0030_smp_call_function.patch
new file mode 100644
index 0000000..72c9dcf
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0030_smp_call_function.patch
@@ -0,0 +1,35 @@
+---
+ drivers/infiniband/hw/mlx4/wc.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/mlx4/wc.c
++++ ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
+@@ -111,7 +111,7 @@ static int read_and_modify_pat(void)
+ 	preempt_disable();
+ 	rd_old_pat(&ret);
+ 	if (!ret)
+-		smp_call_function(rd_old_pat, &ret, 1);
++		smp_call_function(rd_old_pat, &ret, 1, 1);
+ 	if (ret)
+ 		goto out;
+ 
+@@ -119,7 +119,7 @@ static int read_and_modify_pat(void)
+ 	if (ret)
+ 		goto out;
+ 
+-	smp_call_function(wr_new_pat, &ret, 1);
++	smp_call_function(wr_new_pat, &ret, 1, 1);
+ 	BUG_ON(ret); /* have inconsistent PAT state */
+ out:
+ 	preempt_enable();
+@@ -133,7 +133,7 @@ static int restore_pat(void)
+ 	preempt_disable();
+ 	wr_old_pat(&ret);
+ 	if (!ret) {
+-		smp_call_function(wr_old_pat, &ret, 1);
++		smp_call_function(wr_old_pat, &ret, 1, 1);
+ 		BUG_ON(ret); /* have inconsistent PAT state */
+ 	}
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0040_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0040_pci_dma_mapping_error_to_2_6_26.patch
new file mode 100644
index 0000000..79c71db
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0040_pci_dma_mapping_error_to_2_6_26.patch
@@ -0,0 +1,17 @@
+---
+ drivers/net/mlx4/eq.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: ofed_kernel/drivers/net/mlx4/eq.c
+===================================================================
+--- ofed_kernel.orig/drivers/net/mlx4/eq.c
++++ ofed_kernel/drivers/net/mlx4/eq.c
+@@ -532,7 +532,7 @@ int mlx4_map_eq_icm(struct mlx4_dev *dev
+ 		return -ENOMEM;
+ 	priv->eq_table.icm_dma  = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0,
+ 					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+-	if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) {
++	if (pci_dma_mapping_error(priv->eq_table.icm_dma)) {
+ 		__free_page(priv->eq_table.icm_page);
+ 		return -ENOMEM;
+ 	}
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0050_wc.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0050_wc.patch
new file mode 100644
index 0000000..1506824
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0050_wc.patch
@@ -0,0 +1,17 @@
+---
+ drivers/infiniband/hw/mlx4/wc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/mlx4/wc.c
++++ ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
+@@ -143,7 +143,7 @@ static int restore_pat(void)
+ 
+ int mlx4_enable_wc(void)
+ {
+-	struct cpuinfo_x86 *c = &cpu_data(0);
++	struct cpuinfo_x86 *c = &(cpu_data)[0];
+ 	int ret;
+ 
+ 	if (wc_enabled)
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0060_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0060_sysfs.patch
new file mode 100644
index 0000000..d195c0b
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_0060_sysfs.patch
@@ -0,0 +1,236 @@
+---
+ drivers/infiniband/hw/mlx4/main.c |  153 +++++++++++++++++---------------------
+ 1 file changed, 71 insertions(+), 82 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/mlx4/main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/mlx4/main.c
++++ ofed_kernel/drivers/infiniband/hw/mlx4/main.c
+@@ -581,51 +581,42 @@ out:
+ 	return err;
+ }
+ 
+-static ssize_t show_hca(struct device *device, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_hca(struct class_device *cdev, char *buf)
+ {
+-	struct mlx4_ib_dev *dev =
+-		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
++	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
+ 	return sprintf(buf, "MT%d\n", dev->dev->pdev->device);
+ }
+ 
+-static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
+-			   char *buf)
++static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
+ {
+-	struct mlx4_ib_dev *dev =
+-		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
++	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
+ 	return sprintf(buf, "%d.%d.%d\n", (int) (dev->dev->caps.fw_ver >> 32),
+ 		       (int) (dev->dev->caps.fw_ver >> 16) & 0xffff,
+ 		       (int) dev->dev->caps.fw_ver & 0xffff);
+ }
+ 
+-static ssize_t show_rev(struct device *device, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_rev(struct class_device *cdev, char *buf)
+ {
+-	struct mlx4_ib_dev *dev =
+-		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
++	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
+ 	return sprintf(buf, "%x\n", dev->dev->rev_id);
+ }
+ 
+-static ssize_t show_board(struct device *device, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_board(struct class_device *cdev, char *buf)
+ {
+-	struct mlx4_ib_dev *dev =
+-		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
+-	return sprintf(buf, "%.*s\n", MLX4_BOARD_ID_LEN,
+-		       dev->dev->board_id);
+-}
+-
+-static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
+-static DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
+-static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
+-static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
+-
+-static struct device_attribute *mlx4_class_attributes[] = {
+-	&dev_attr_hw_rev,
+-	&dev_attr_fw_ver,
+-	&dev_attr_hca_type,
+-	&dev_attr_board_id
++	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
++	return sprintf(buf, "%.*s\n", MLX4_BOARD_ID_LEN, dev->dev->board_id);
++}
++
++static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
++static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
++static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
++static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
++
++static struct class_device_attribute *mlx4_class_attributes[] = {
++	&class_device_attr_hw_rev,
++	&class_device_attr_fw_ver,
++	&class_device_attr_hca_type,
++	&class_device_attr_board_id
+ };
+ 
+ /*
+@@ -633,23 +624,22 @@ static struct device_attribute *mlx4_cla
+  * the function for _name
+  */
+ #define DEVICE_DIAG_RPRT_ATTR(_name, _offset, _op_mod)		\
+-static ssize_t show_rprt_##_name(struct device *dev,		\
+-				 struct device_attribute *attr,	\
++static ssize_t show_rprt_##_name(struct class_device *cdev,	\
+ 				 char *buf){			\
+-	return show_diag_rprt(dev, buf, _offset, _op_mod);	\
++	return show_diag_rprt(cdev, buf, _offset, _op_mod);	\
+ }								\
+-static DEVICE_ATTR(_name, S_IRUGO, show_rprt_##_name, NULL);
++static CLASS_DEVICE_ATTR(_name, S_IRUGO, show_rprt_##_name, NULL);
+ 
+ #define MLX4_DIAG_RPRT_CLEAR_DIAGS 3
+ 
+-static size_t show_diag_rprt(struct device *device, char *buf,
++static size_t show_diag_rprt(struct class_device *cdev, char *buf,
+                               u32 offset, u8 op_modifier)
+ {
+ 	size_t ret;
+ 	u32 counter_offset = offset;
+ 	u32 diag_counter = 0;
+-	struct mlx4_ib_dev *dev = container_of(device, struct mlx4_ib_dev,
+-					       ib_dev.dev);
++	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev,
++					       ib_dev.class_dev);
+ 
+ 	ret = mlx4_query_diag_counters(dev->dev, 1, op_modifier,
+ 				       &counter_offset, &diag_counter);
+@@ -659,13 +649,12 @@ static size_t show_diag_rprt(struct devi
+ 	return sprintf(buf,"%d\n", diag_counter);
+ }
+ 
+-static ssize_t clear_diag_counters(struct device *device,
+-				   struct device_attribute *attr,
++static ssize_t clear_diag_counters(struct class_device *cdev,
+ 				   const char *buf, size_t length)
+ {
+ 	size_t ret;
+-	struct mlx4_ib_dev *dev = container_of(device, struct mlx4_ib_dev,
+-					       ib_dev.dev);
++	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev,
++					       ib_dev.class_dev);
+ 
+ 	ret = mlx4_query_diag_counters(dev->dev, 0, MLX4_DIAG_RPRT_CLEAR_DIAGS,
+ 				       NULL, NULL);
+@@ -711,45 +700,45 @@ DEVICE_DIAG_RPRT_ATTR(num_cqovf		, 0x1A0
+ DEVICE_DIAG_RPRT_ATTR(num_eqovf		, 0x1A4, 2);
+ DEVICE_DIAG_RPRT_ATTR(num_baddb		, 0x1A8, 2);
+ 
+-static DEVICE_ATTR(clear_diag, S_IWUGO, NULL, clear_diag_counters);
++static CLASS_DEVICE_ATTR(clear_diag, S_IWUGO, NULL, clear_diag_counters);
+ 
+ static struct attribute *diag_rprt_attrs[] = {
+-	&dev_attr_rq_num_lle.attr,
+-	&dev_attr_sq_num_lle.attr,
+-	&dev_attr_rq_num_lqpoe.attr,
+-	&dev_attr_sq_num_lqpoe.attr,
+-	&dev_attr_rq_num_leeoe.attr,
+-	&dev_attr_sq_num_leeoe.attr,
+-	&dev_attr_rq_num_lpe.attr,
+-	&dev_attr_sq_num_lpe.attr,
+-	&dev_attr_rq_num_wrfe.attr,
+-	&dev_attr_sq_num_wrfe.attr,
+-	&dev_attr_sq_num_mwbe.attr,
+-	&dev_attr_sq_num_bre.attr,
+-	&dev_attr_rq_num_lae.attr,
+-	&dev_attr_sq_num_rire.attr,
+-	&dev_attr_rq_num_rire.attr,
+-	&dev_attr_sq_num_rae.attr,
+-	&dev_attr_rq_num_rae.attr,
+-	&dev_attr_sq_num_roe.attr,
+-	&dev_attr_sq_num_tree.attr,
+-	&dev_attr_sq_num_rree.attr,
+-	&dev_attr_rq_num_rnr.attr,
+-	&dev_attr_sq_num_rnr.attr,
+-	&dev_attr_sq_num_rabrte.attr,
+-	&dev_attr_sq_num_ieecne.attr,
+-	&dev_attr_sq_num_ieecse.attr,
+-	&dev_attr_rq_num_oos.attr,
+-	&dev_attr_sq_num_oos.attr,
+-	&dev_attr_rq_num_mce.attr,
+-	&dev_attr_rq_num_rsync.attr,
+-	&dev_attr_sq_num_rsync.attr,
+-	&dev_attr_rq_num_udsdprd.attr,
+-	&dev_attr_rq_num_ucsdprd.attr,
+-	&dev_attr_num_cqovf.attr,
+-	&dev_attr_num_eqovf.attr,
+-	&dev_attr_num_baddb.attr,
+-	&dev_attr_clear_diag.attr,
++	&class_device_attr_rq_num_lle.attr,
++	&class_device_attr_sq_num_lle.attr,
++	&class_device_attr_rq_num_lqpoe.attr,
++	&class_device_attr_sq_num_lqpoe.attr,
++	&class_device_attr_rq_num_leeoe.attr,
++	&class_device_attr_sq_num_leeoe.attr,
++	&class_device_attr_rq_num_lpe.attr,
++	&class_device_attr_sq_num_lpe.attr,
++	&class_device_attr_rq_num_wrfe.attr,
++	&class_device_attr_sq_num_wrfe.attr,
++	&class_device_attr_sq_num_mwbe.attr,
++	&class_device_attr_sq_num_bre.attr,
++	&class_device_attr_rq_num_lae.attr,
++	&class_device_attr_sq_num_rire.attr,
++	&class_device_attr_rq_num_rire.attr,
++	&class_device_attr_sq_num_rae.attr,
++	&class_device_attr_rq_num_rae.attr,
++	&class_device_attr_sq_num_roe.attr,
++	&class_device_attr_sq_num_tree.attr,
++	&class_device_attr_sq_num_rree.attr,
++	&class_device_attr_rq_num_rnr.attr,
++	&class_device_attr_sq_num_rnr.attr,
++	&class_device_attr_sq_num_rabrte.attr,
++	&class_device_attr_sq_num_ieecne.attr,
++	&class_device_attr_sq_num_ieecse.attr,
++	&class_device_attr_rq_num_oos.attr,
++	&class_device_attr_sq_num_oos.attr,
++	&class_device_attr_rq_num_mce.attr,
++	&class_device_attr_rq_num_rsync.attr,
++	&class_device_attr_sq_num_rsync.attr,
++	&class_device_attr_rq_num_udsdprd.attr,
++	&class_device_attr_rq_num_ucsdprd.attr,
++	&class_device_attr_num_cqovf.attr,
++	&class_device_attr_num_eqovf.attr,
++	&class_device_attr_num_baddb.attr,
++	&class_device_attr_clear_diag.attr,
+ 	NULL
+ };
+ 
+@@ -906,12 +895,12 @@ static void *mlx4_ib_add(struct mlx4_dev
+ 		goto err_reg;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(mlx4_class_attributes); ++i) {
+-		if (device_create_file(&ibdev->ib_dev.dev,
+-				       mlx4_class_attributes[i]))
++		if (class_device_create_file(&ibdev->ib_dev.class_dev,
++					       mlx4_class_attributes[i]))
+ 			goto err_reg;
+ 	}
+ 
+-	if(sysfs_create_group(&ibdev->ib_dev.dev.kobj, &diag_counters_group))
++	if(sysfs_create_group(&ibdev->ib_dev.class_dev.kobj, &diag_counters_group))
+ 		goto err_reg;
+ 
+ 	return ibdev;
+@@ -942,7 +931,7 @@ static void mlx4_ib_remove(struct mlx4_d
+ 	if (!ibdev->num_ports)
+ 		return;
+ 
+-	sysfs_remove_group(&ibdev->ib_dev.dev.kobj, &diag_counters_group);
++	sysfs_remove_group(&ibdev->ib_dev.class_dev.kobj, &diag_counters_group);
+ 
+ 	for (p = 1; p <= ibdev->num_ports; ++p)
+ 		mlx4_CLOSE_PORT(dev, p);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0010_do_not_use_netdev_ops.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0010_do_not_use_netdev_ops.patch
new file mode 100644
index 0000000..4d3b269
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0010_do_not_use_netdev_ops.patch
@@ -0,0 +1,65 @@
+From 34a43622ec035aa41a5383c31245838472784c1b Mon Sep 17 00:00:00 2001
+From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+Date: Sun, 31 May 2009 11:59:25 +0300
+Subject: [PATCH 1/8] mlx4_en: Don't use netdev_ops
+
+Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+---
+ drivers/net/mlx4/en_netdev.c |   34 +++++++++++++++-------------------
+ 1 files changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
+index a38adf5..4ad5f3c 100644
+--- a/drivers/net/mlx4/en_netdev.c
++++ b/drivers/net/mlx4/en_netdev.c
+@@ -933,24 +933,6 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
+ 	return 0;
+ }
+ 
+-static const struct net_device_ops mlx4_netdev_ops = {
+-	.ndo_open		= mlx4_en_open,
+-	.ndo_stop		= mlx4_en_close,
+-	.ndo_start_xmit		= mlx4_en_xmit,
+-	.ndo_select_queue	= mlx4_en_select_queue,
+-	.ndo_get_stats		= mlx4_en_get_stats,
+-	.ndo_set_multicast_list	= mlx4_en_set_multicast,
+-	.ndo_set_mac_address	= mlx4_en_set_mac,
+-	.ndo_validate_addr	= eth_validate_addr,
+-	.ndo_change_mtu		= mlx4_en_change_mtu,
+-	.ndo_tx_timeout		= mlx4_en_tx_timeout,
+-	.ndo_vlan_rx_register	= mlx4_en_vlan_rx_register,
+-	.ndo_vlan_rx_add_vid	= mlx4_en_vlan_rx_add_vid,
+-	.ndo_vlan_rx_kill_vid	= mlx4_en_vlan_rx_kill_vid,
+-#ifdef CONFIG_NET_POLL_CONTROLLER
+-	.ndo_poll_controller	= mlx4_en_netpoll,
+-#endif
+-};
+ 
+ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+ 			struct mlx4_en_port_profile *prof)
+@@ -1026,7 +1008,21 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+ 	/*
+ 	 * Initialize netdev entry points
+ 	 */
+-	dev->netdev_ops = &mlx4_netdev_ops;
++	dev->open		= mlx4_en_open;
++	dev->stop		= mlx4_en_close;
++	dev->hard_start_xmit	= mlx4_en_xmit,
++	dev->select_queue	= mlx4_en_select_queue,
++	dev->get_stats		= mlx4_en_get_stats,
++	dev->set_multicast_list	= mlx4_en_set_multicast,
++	dev->set_mac_address	= mlx4_en_set_mac,
++	dev->change_mtu		= mlx4_en_change_mtu,
++	dev->tx_timeout		= mlx4_en_tx_timeout,
++	dev->vlan_rx_register	= mlx4_en_vlan_rx_register,
++	dev->vlan_rx_add_vid	= mlx4_en_vlan_rx_add_vid,
++	dev->vlan_rx_kill_vid	= mlx4_en_vlan_rx_kill_vid,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller	= mlx4_en_netpoll,
++#endif
+ 	dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
+ 
+ 	SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
+-- 
+1.6.1.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0020_cancel_multiqueue.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0020_cancel_multiqueue.patch
new file mode 100644
index 0000000..693e14f
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0020_cancel_multiqueue.patch
@@ -0,0 +1,88 @@
+From b0f37433227a9c88f289f7ff69d7b7d11b5c0ba4 Mon Sep 17 00:00:00 2001
+From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+Date: Sun, 31 May 2009 13:00:22 +0300
+Subject: [PATCH 2/8] mlx4_en: cancel multiqueue
+
+Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+---
+ drivers/net/mlx4/en_netdev.c |    3 +--
+ drivers/net/mlx4/en_tx.c     |    8 ++++----
+ drivers/net/mlx4/mlx4_en.h   |    1 -
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
+index 4ad5f3c..34e082c 100644
+--- a/drivers/net/mlx4/en_netdev.c
++++ b/drivers/net/mlx4/en_netdev.c
+@@ -942,7 +942,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+ 	int i;
+ 	int err;
+ 
+-	dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num);
++	dev = alloc_etherdev(sizeof(struct mlx4_en_priv));
+ 	if (dev == NULL) {
+ 		mlx4_err(mdev, "Net device allocation failed\n");
+ 		return -ENOMEM;
+@@ -1011,7 +1011,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+ 	dev->open		= mlx4_en_open;
+ 	dev->stop		= mlx4_en_close;
+ 	dev->hard_start_xmit	= mlx4_en_xmit,
+-	dev->select_queue	= mlx4_en_select_queue,
+ 	dev->get_stats		= mlx4_en_get_stats,
+ 	dev->set_multicast_list	= mlx4_en_set_multicast,
+ 	dev->set_mac_address	= mlx4_en_set_mac,
+diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
+index 2a86d08..cba7a02 100644
+--- a/drivers/net/mlx4/en_tx.c
++++ b/drivers/net/mlx4/en_tx.c
+@@ -386,7 +386,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
+ 		if ((u32) (ring->prod - ring->cons) <=
+ 		     ring->size - HEADROOM - MAX_DESC_TXBBS) {
+ 			ring->blocked = 0;
+-			netif_tx_wake_queue(netdev_get_tx_queue(dev, cq->ring));
++			netif_wake_queue(dev);
+ 			priv->port_stats.wake_queue++;
+ 		}
+ 	}
+@@ -605,7 +605,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
+ 	tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
+ }
+ 
+-u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
++static int mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
+ {
+ 	struct mlx4_en_priv *priv = netdev_priv(dev);
+ 	u16 vlan_tag = 0;
+@@ -697,7 +697,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		return NETDEV_TX_OK;
+ 	}
+ 
+-	tx_ind = skb->queue_mapping;
++	tx_ind = mlx4_en_select_queue(dev, skb);
+ 	ring = &priv->tx_ring[tx_ind];
+ 	if (priv->vlgrp && vlan_tx_tag_present(skb))
+ 		vlan_tag = vlan_tx_tag_get(skb);
+@@ -706,7 +706,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	if (unlikely(((int)(ring->prod - ring->cons)) >
+ 		     ring->size - HEADROOM - MAX_DESC_TXBBS)) {
+ 		/* every full Tx ring stops queue */
+-		netif_tx_stop_queue(netdev_get_tx_queue(dev, tx_ind));
++		netif_stop_queue(dev);
+ 		ring->blocked = 1;
+ 		priv->port_stats.queue_stopped++;
+ 
+diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
+index b45774c..f35f318 100644
+--- a/drivers/net/mlx4/mlx4_en.h
++++ b/drivers/net/mlx4/mlx4_en.h
+@@ -556,7 +556,6 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
+ 
+ void mlx4_en_poll_tx_cq(unsigned long data);
+ void mlx4_en_tx_irq(struct mlx4_cq *mcq);
+-u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb);
+ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
+ 
+ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring,
+-- 
+1.6.1.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0030_lro_backport.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0030_lro_backport.patch
new file mode 100644
index 0000000..eefeae0
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0030_lro_backport.patch
@@ -0,0 +1,893 @@
+From 4f3262d88349cd4ac0cc0b8ecd458b7db4fe63e5 Mon Sep 17 00:00:00 2001
+From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+Date: Sun, 31 May 2009 14:57:40 +0300
+Subject: [PATCH] mlx4_en: use own lro implemetation
+
+Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+---
+ drivers/net/mlx4/Makefile     |    2 +-
+ drivers/net/mlx4/en_ethtool.c |   17 --
+ drivers/net/mlx4/en_lro.c     |  540 +++++++++++++++++++++++++++++++++++++++++
+ drivers/net/mlx4/en_rx.c      |  109 +++------
+ drivers/net/mlx4/mlx4_en.h    |   52 ++++-
+ 5 files changed, 623 insertions(+), 97 deletions(-)
+ create mode 100644 drivers/net/mlx4/en_lro.c
+
+diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
+index 87c2259..ed94870 100644
+--- a/drivers/net/mlx4/Makefile
++++ b/drivers/net/mlx4/Makefile
+@@ -6,4 +6,4 @@ mlx4_core-y :=	alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
+ obj-$(CONFIG_MLX4_EN)               += mlx4_en.o
+ 
+ mlx4_en-y := 	en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
+-		en_resources.o en_netdev.o en_frag.o
++		en_resources.o en_netdev.o en_frag.o en_lro.o
+diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
+index 091f990..19a10f3 100644
+--- a/drivers/net/mlx4/en_ethtool.c
++++ b/drivers/net/mlx4/en_ethtool.c
+@@ -39,21 +39,6 @@
+ #include "en_port.h"
+ 
+ 
+-static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
+-{
+-	int i;
+-
+-	priv->port_stats.lro_aggregated = 0;
+-	priv->port_stats.lro_flushed = 0;
+-	priv->port_stats.lro_no_desc = 0;
+-
+-	for (i = 0; i < priv->rx_ring_num; i++) {
+-		priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
+-		priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
+-		priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
+-	}
+-}
+-
+ static void
+ mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+ {
+@@ -163,8 +148,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
+ 
+ 	spin_lock_bh(&priv->stats_lock);
+ 
+-	mlx4_en_update_lro_stats(priv);
+-
+ 	for (i = 0; i < NUM_MAIN_STATS; i++)
+ 		data[index++] = ((unsigned long *) &priv->stats)[i];
+ 	for (i = 0; i < NUM_PORT_STATS; i++)
+diff --git a/drivers/net/mlx4/en_lro.c b/drivers/net/mlx4/en_lro.c
+new file mode 100644
+index 0000000..bb5563f
+--- /dev/null
++++ b/drivers/net/mlx4/en_lro.c
+@@ -0,0 +1,540 @@
++/*
++ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
++ *
++ * This software is available to you under a choice of one of two
++ * licenses.  You may choose to be licensed under the terms of the GNU
++ * General Public License (GPL) Version 2, available from the file
++ * COPYING in the main directory of this source tree, or the
++ * OpenIB.org BSD license below:
++ *
++ *     Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *      - Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *
++ *      - Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ *
++ */
++
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ip.h>
++#include <linux/tcp.h>
++#include <net/tcp.h>
++#include <linux/if_vlan.h>
++#include <linux/delay.h>
++
++#include "mlx4_en.h"
++
++/* LRO hash function - using sum of source and destination port LSBs is
++ * good enough */
++#define LRO_INDEX(th, size) \
++	((*((u8*) &th->source + 1) + *((u8*) &th->dest + 1)) & (size - 1))
++
++/* #define CONFIG_MLX4_EN_DEBUG_LRO */
++
++#ifdef CONFIG_MLX4_EN_DEBUG_LRO
++static void mlx4_en_lro_validate(struct mlx4_en_priv* priv, struct mlx4_en_lro *lro)
++{
++	int i;
++	int size, size2;
++	struct sk_buff *skb = lro->skb;
++	skb_frag_t *frags;
++	int len, len2;
++	int cur_skb = 0;
++
++	/* Sum fragment sizes of first skb */
++	len = skb->len;
++	size = skb_headlen(skb);
++	frags = skb_shinfo(skb)->frags;
++	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
++		size += frags[i].size;
++	}
++
++	/* Add in fragments of linked skb's */
++	skb = skb_shinfo(skb)->frag_list;
++	while (skb) {
++		cur_skb++;
++		len2 = skb->len;
++		if (skb_headlen(skb)) {
++			mlx4_err(priv->mdev, "Bad LRO format: non-zero headlen "
++				  "in fraglist (skb:%d)\n", cur_skb);
++			return;
++		}
++
++		size2 = 0;
++		frags = skb_shinfo(skb)->frags;
++		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
++			size2 += frags[i].size;
++		}
++
++		if (size2 != len2) {
++			mlx4_err(priv->mdev, "Bad skb size:%d in LRO fraglist. "
++			          "Expected:%d (skb:%d)\n", size2, len2, cur_skb);
++			return;
++		}
++		size += size2;
++		skb = skb->next;
++	}
++
++	if (size != len)
++		mlx4_err(priv->mdev, "Bad LRO size:%d expected:%d\n", size, len);
++}
++#endif /* MLX4_EN_DEBUG_LRO */
++
++static void mlx4_en_lro_flush_single(struct mlx4_en_priv* priv,
++		   struct mlx4_en_rx_ring* ring, struct mlx4_en_lro *lro)
++{
++	struct sk_buff *skb = lro->skb;
++	struct iphdr *iph = (struct iphdr *) skb->data;
++	struct tcphdr *th = (struct tcphdr *)(iph + 1);
++	unsigned int headlen = skb_headlen(skb);
++	__wsum tcp_hdr_csum;
++	u32 *ts;
++
++	/* Update IP length and checksum */
++	iph->tot_len = htons(lro->tot_len);
++	iph->check = 0;
++	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
++
++	/* Update latest TCP ack, window, psh, and timestamp */
++	th->ack_seq = lro->ack_seq;
++	th->window = lro->window;
++	th->psh = !!lro->psh;
++	if (lro->has_timestamp) {
++		ts = (u32 *) (th + 1);
++		ts[1] = htonl(lro->tsval);
++		ts[2] = lro->tsecr;
++	}
++	th->check = 0;
++	tcp_hdr_csum = csum_partial((u8 *)th, th->doff << 2, 0);
++	lro->data_csum = csum_add(lro->data_csum, tcp_hdr_csum);
++	th->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
++				      lro->tot_len - (iph->ihl << 2),
++				      IPPROTO_TCP, lro->data_csum);
++
++	/* Update skb */
++	skb->len = lro->tot_len;
++	skb->data_len = lro->tot_len - headlen;
++	skb->truesize = skb->len + sizeof(struct sk_buff);
++	skb_shinfo(skb)->gso_size = lro->mss;
++
++#ifdef CONFIG_MLX4_EN_DEBUG_LRO
++	mlx4_en_lro_validate(priv, lro);
++#endif /* CONFIG_MLX4_EN_DEBUG_LRO */
++
++	/* Push it up the stack */
++	if (priv->vlgrp && lro->has_vlan)
++		vlan_hwaccel_receive_skb(skb, priv->vlgrp,
++					be16_to_cpu(lro->vlan_prio));
++	else
++		netif_receive_skb(skb);
++	priv->dev->last_rx = jiffies;
++
++	/* Increment stats */
++	priv->port_stats.lro_flushed++;
++
++	/* Move session back to the free list */
++	hlist_del(&lro->node);
++	hlist_del(&lro->flush_node);
++	hlist_add_head(&lro->node, &ring->lro_free);
++}
++
++void mlx4_en_lro_flush(struct mlx4_en_priv* priv, struct mlx4_en_rx_ring *ring, u8 all)
++{
++	struct mlx4_en_lro *lro;
++	struct hlist_node *node, *tmp;
++
++	hlist_for_each_entry_safe(lro, node, tmp, &ring->lro_flush, flush_node) {
++		if (all || time_after(jiffies, lro->expires))
++			mlx4_en_lro_flush_single(priv, ring, lro);
++	}
++}
++
++static inline int mlx4_en_lro_append(struct mlx4_en_priv *priv,
++				   struct mlx4_en_lro *lro,
++				   struct mlx4_en_rx_desc *rx_desc,
++				   struct skb_frag_struct *skb_frags,
++				   struct mlx4_en_rx_alloc *page_alloc,
++				   unsigned int data_len,
++				   int hlen)
++{
++	struct sk_buff *skb = lro->skb_last;
++	struct skb_shared_info *info;
++	struct skb_frag_struct *frags_copy;
++	int nr_frags;
++
++	if (skb_shinfo(skb)->nr_frags + priv->num_frags > MAX_SKB_FRAGS)
++		return -ENOMEM;
++
++	info = skb_shinfo(skb);
++
++	/* Copy fragments from descriptor ring to skb */
++	frags_copy = info->frags + info->nr_frags;
++	nr_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags,
++						frags_copy,
++						page_alloc,
++						data_len + hlen);
++	if (!nr_frags) {
++		en_dbg(DRV, priv, "Failed completing rx desc during LRO append\n");
++		return -ENOMEM;
++	}
++
++	/* Skip over headers */
++	frags_copy[0].page_offset += hlen;
++
++	if (nr_frags == 1)
++		frags_copy[0].size = data_len;
++	else {
++		/* Adjust size of last fragment to match packet length.
++		 * Note: if this fragment is also the first one, the
++		 *       operation is completed in the next line */
++		frags_copy[nr_frags - 1].size = hlen + data_len -
++				priv->frag_info[nr_frags - 1].frag_prefix_size;
++
++		/* Adjust size of first fragment */
++		frags_copy[0].size -= hlen;
++	}
++
++	/* Update skb bookkeeping */
++	skb->len += data_len;
++	skb->data_len += data_len;
++	info->nr_frags += nr_frags;
++	return 0;
++}
++
++static inline struct mlx4_en_lro *mlx4_en_lro_find_session(struct mlx4_en_dev *mdev,
++						       struct mlx4_en_rx_ring *ring,
++						       struct iphdr *iph,
++						       struct tcphdr *th)
++{
++	struct mlx4_en_lro *lro;
++	struct hlist_node *node;
++	int index = LRO_INDEX(th, mdev->profile.num_lro);
++	struct hlist_head *list = &ring->lro_hash[index];
++
++	hlist_for_each_entry(lro, node, list, node) {
++		if (lro->sport_dport == *((u32*) &th->source) &&
++		    lro->saddr == iph->saddr &&
++		    lro->daddr == iph->daddr)
++			return lro;
++	}
++	return NULL;
++}
++
++static inline struct mlx4_en_lro *mlx4_en_lro_alloc_session(struct mlx4_en_priv *priv,
++							struct mlx4_en_rx_ring *ring)
++{
++	return hlist_empty(&ring->lro_free) ? NULL :
++		hlist_entry(ring->lro_free.first, struct mlx4_en_lro, node);
++}
++
++static __wsum mlx4_en_lro_tcp_data_csum(struct iphdr *iph,
++					struct tcphdr *th, int len)
++{
++	__wsum tcp_csum;
++	__wsum tcp_hdr_csum;
++	__wsum tcp_ps_hdr_csum;
++
++	tcp_csum = ~csum_unfold(th->check);
++	tcp_hdr_csum = csum_partial((u8 *)th, th->doff << 2, tcp_csum);
++
++	tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
++					     len + (th->doff << 2),
++					     IPPROTO_TCP, 0);
++
++	return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum),
++			tcp_ps_hdr_csum);
++}
++
++int mlx4_en_lro_rx(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring,
++					  struct mlx4_en_rx_desc *rx_desc,
++					  struct skb_frag_struct *skb_frags,
++					  unsigned int length,
++					  struct mlx4_cqe *cqe)
++{
++	struct mlx4_en_dev *mdev = priv->mdev;
++	struct mlx4_en_lro *lro;
++	struct sk_buff *skb;
++	struct iphdr *iph;
++	struct tcphdr *th;
++	dma_addr_t dma;
++	int tcp_hlen;
++	int tcp_data_len;
++	int hlen;
++	u16 ip_len;
++	void *va;
++	u32 *ts;
++	u32 seq;
++	u32 tsval = (u32) ~0UL;
++	u32 tsecr = 0;
++	u32 ack_seq;
++	u16 window;
++
++	/* This packet is eligible for LRO if it is:
++	 * - DIX Ethernet (type interpretation)
++	 * - TCP/IP (v4)
++	 * - without IP options
++	 * - not an IP fragment */
++	if (!mlx4_en_can_lro(cqe->status))
++			return -1;
++
++	/* Get pointer to TCP header. We already know that the packet is DIX Ethernet/IPv4/TCP
++	 * with no VLAN (HW stripped it) and no IP options */
++	va = page_address(skb_frags[0].page) + skb_frags[0].page_offset;
++	iph = va + ETH_HLEN;
++	th = (struct tcphdr *)(iph + 1);
++
++	/* Synchronsize headers for processing */
++	dma = be64_to_cpu(rx_desc->data[0].addr);
++#define MAX_LRO_HEADER		(ETH_HLEN + \
++				 sizeof(*iph) + \
++				 sizeof(*th) + \
++				 TCPOLEN_TSTAMP_ALIGNED)
++	dma_sync_single_range_for_cpu(&mdev->pdev->dev, dma, 0,
++				      MAX_LRO_HEADER, DMA_FROM_DEVICE);
++
++	/* We only handle aligned timestamp options */
++	tcp_hlen = (th->doff << 2);
++	if (tcp_hlen == sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) {
++		ts = (u32*) (th + 1);
++		if (unlikely(*ts != htonl((TCPOPT_NOP << 24) |
++					  (TCPOPT_NOP << 16) |
++					  (TCPOPT_TIMESTAMP << 8) |
++					  TCPOLEN_TIMESTAMP)))
++			goto sync_device;
++		tsval = ntohl(ts[1]);
++		tsecr = ts[2];
++	} else if (tcp_hlen != sizeof(*th))
++		goto sync_device;
++	
++
++	/* At this point we know we have a TCP packet that is likely to be
++	 * eligible for LRO. Therefore, see now if we have an oustanding
++	 * session that corresponds to this packet so we could flush it if
++	 * something still prevents LRO */
++	lro = mlx4_en_lro_find_session(mdev, ring, iph, th);
++
++	/* ensure no bits set besides ack or psh */
++	if (th->fin || th->syn || th->rst || th->urg || th->ece ||
++	    th->cwr || !th->ack) {
++		if (lro) {
++			/* First flush session to keep packets in-order */
++			mlx4_en_lro_flush_single(priv, ring, lro);
++		}
++		goto sync_device;
++	}
++
++	/* Get ip length and verify that the frame is big enough */
++	ip_len = ntohs(iph->tot_len);
++	if (unlikely(length < ETH_HLEN + ip_len)) {
++		en_warn(priv, "Cannot LRO - ip payload exceeds frame!\n");
++		goto sync_device;
++	}
++
++	/* Get TCP payload length */
++	tcp_data_len = ip_len - tcp_hlen - sizeof(struct iphdr);
++	seq = ntohl(th->seq);
++	if (!tcp_data_len)
++		goto flush_session;
++
++	if (lro) {
++		/* Check VLAN tag */
++		if (cqe->vlan_my_qpn & MLX4_CQE_VLAN_PRESENT_MASK) {
++			if (cqe->sl_vid != lro->vlan_prio || !lro->has_vlan) {
++				mlx4_en_lro_flush_single(priv, ring, lro);
++				goto sync_device;
++			}
++		} else if (lro->has_vlan) {
++			mlx4_en_lro_flush_single(priv, ring, lro);
++			goto sync_device;
++		}
++
++		/* Check sequence number */
++		if (unlikely(seq != lro->next_seq)) {
++			mlx4_en_lro_flush_single(priv, ring, lro);
++			goto sync_device;
++		}
++
++		/* If the cummulative IP length is over 64K, flush and start
++		 * a new session */
++		if (lro->tot_len + tcp_data_len > 0xffff) {
++			mlx4_en_lro_flush_single(priv, ring, lro);
++			goto new_session;
++		}
++
++		/* Check timestamps */
++		if (tcp_hlen != sizeof(*th)) {
++			if (unlikely(lro->tsval > tsval || !tsecr))
++				goto sync_device;
++		}
++
++		window = th->window;
++		ack_seq = th->ack_seq;
++		if (likely(tcp_data_len)) {
++			/* Append the data! */
++			hlen = ETH_HLEN + sizeof(struct iphdr) + tcp_hlen;
++			if (mlx4_en_lro_append(priv, lro, rx_desc, skb_frags,
++							ring->page_alloc,
++							tcp_data_len, hlen)) {
++				mlx4_en_lro_flush_single(priv, ring, lro);
++				goto sync_device;
++			}
++		} else {
++			/* No data */
++			dma_sync_single_range_for_device(&mdev->dev->pdev->dev, dma,
++							 0, MAX_LRO_HEADER,
++							 DMA_FROM_DEVICE);
++		}
++
++		/* Update session */
++		lro->psh |= th->psh;
++		lro->next_seq += tcp_data_len;
++		lro->data_csum = csum_block_add(lro->data_csum,
++					mlx4_en_lro_tcp_data_csum(iph, th,
++								  tcp_data_len),
++					lro->tot_len);
++		lro->tot_len += tcp_data_len;
++		lro->tsval = tsval;
++		lro->tsecr = tsecr;
++		lro->ack_seq = ack_seq;
++		lro->window = window;
++		if (tcp_data_len > lro->mss)
++			lro->mss = tcp_data_len;
++		priv->port_stats.lro_aggregated++;
++		if (th->psh)
++			mlx4_en_lro_flush_single(priv, ring, lro);
++		return 0;
++	}
++
++new_session:
++	if (th->psh)
++		goto sync_device;
++	lro = mlx4_en_lro_alloc_session(priv, ring);
++	if (lro) {
++		skb = mlx4_en_rx_skb(priv, rx_desc, skb_frags, ring->page_alloc,
++							     ETH_HLEN + ip_len);
++		if (skb) {
++			int index;
++
++			/* Add in the skb */
++			lro->skb = skb;
++			lro->skb_last = skb;
++			skb->protocol = eth_type_trans(skb, priv->dev);
++			skb->ip_summed = CHECKSUM_UNNECESSARY;
++
++			/* Initialize session */
++			lro->saddr = iph->saddr;
++			lro->daddr = iph->daddr;
++			lro->sport_dport = *((u32*) &th->source);
++
++			lro->next_seq = seq + tcp_data_len;
++			lro->tot_len = ip_len;
++			lro->psh = th->psh;
++			lro->ack_seq = th->ack_seq;
++			lro->window = th->window;
++			lro->mss = tcp_data_len;
++			lro->data_csum = mlx4_en_lro_tcp_data_csum(iph, th,
++						tcp_data_len);
++
++			/* Handle vlans */
++			if (cqe->vlan_my_qpn & MLX4_CQE_VLAN_PRESENT_MASK) {
++				lro->vlan_prio = cqe->sl_vid;
++				lro->has_vlan = 1;
++			} else
++				lro->has_vlan = 0;
++
++			/* Handle timestamps */
++			if (tcp_hlen != sizeof(*th)) {
++				lro->tsval = tsval;
++				lro->tsecr = tsecr;
++				lro->has_timestamp = 1;
++			} else {
++				lro->tsval = (u32) ~0UL;
++				lro->has_timestamp = 0;
++			}
++
++			/* Activate this session */
++			lro->expires = jiffies + HZ / 25;
++			hlist_del(&lro->node);
++			index = LRO_INDEX(th, mdev->profile.num_lro);
++
++			hlist_add_head(&lro->node, &ring->lro_hash[index]);
++			hlist_add_head(&lro->flush_node, &ring->lro_flush);
++			priv->port_stats.lro_aggregated++;
++			return 0;
++		} else {
++			/* Packet is dropped because we were not able to allocate new
++			 * page for fragments */
++			dma_sync_single_range_for_device(&mdev->pdev->dev, dma,
++							 0, MAX_LRO_HEADER,
++							 DMA_FROM_DEVICE);
++			return 0;
++		}
++	} else {
++		priv->port_stats.lro_no_desc++;
++	}
++
++flush_session:
++	if (lro)
++		mlx4_en_lro_flush_single(priv, ring, lro);
++sync_device:
++	dma_sync_single_range_for_device(&mdev->pdev->dev, dma, 0,
++					 MAX_LRO_HEADER, DMA_FROM_DEVICE);
++	return -1;
++}
++
++void mlx4_en_lro_destroy(struct mlx4_en_rx_ring *ring)
++{
++	struct mlx4_en_lro *lro;
++	struct hlist_node *node, *tmp;
++
++	hlist_for_each_entry_safe(lro, node, tmp, &ring->lro_free, node) {
++		hlist_del(&lro->node);
++		kfree(lro);
++	}
++	kfree(ring->lro_hash);
++}
++
++int mlx4_en_lro_init(struct mlx4_en_rx_ring *ring, int num_lro)
++{
++	struct mlx4_en_lro *lro;
++	int i;
++
++	INIT_HLIST_HEAD(&ring->lro_free);
++	INIT_HLIST_HEAD(&ring->lro_flush);
++	ring->lro_hash = kmalloc(sizeof(struct hlist_head) * num_lro,
++				 GFP_KERNEL);
++	if (!ring->lro_hash)
++		return -ENOMEM;
++
++	for (i = 0; i < num_lro; i++) {
++		INIT_HLIST_HEAD(&ring->lro_hash[i]);
++		lro = kzalloc(sizeof(struct mlx4_en_lro), GFP_KERNEL);
++		if (!lro) {
++			mlx4_en_lro_destroy(ring);
++			return -ENOMEM;
++		}
++		INIT_HLIST_NODE(&lro->node);
++		INIT_HLIST_NODE(&lro->flush_node);
++		hlist_add_head(&lro->node, &ring->lro_free);
++	}
++	return 0;
++}
++
++
+diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
+index a4b1203..6bc6113 100644
+--- a/drivers/net/mlx4/en_rx.c
++++ b/drivers/net/mlx4/en_rx.c
+@@ -51,18 +51,6 @@ static void mlx4_en_srq_event(struct mlx4_srq *srq, enum mlx4_event type)
+ 	return;
+ }
+ 
+-static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
+-				   void **ip_hdr, void **tcpudp_hdr,
+-				   u64 *hdr_flags, void *priv)
+-{
+-	*mac_hdr = page_address(frags->page) + frags->page_offset;
+-	*ip_hdr = *mac_hdr + ETH_HLEN;
+-	*tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr));
+-	*hdr_flags = LRO_IPV4 | LRO_TCP;
+-
+-	return 0;
+-}
+-
+ static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
+ 			      struct mlx4_en_rx_desc *rx_desc,
+ 			      struct skb_frag_struct *skb_frags,
+@@ -455,23 +443,14 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
+ 	}
+ 	ring->buf = ring->wqres.buf.direct.buf;
+ 
+-	/* Configure lro mngr */
+-	memset(&ring->lro, 0, sizeof(struct net_lro_mgr));
+-	ring->lro.dev = priv->dev;
+-	ring->lro.features = LRO_F_NAPI;
+-	ring->lro.frag_align_pad = NET_IP_ALIGN;
+-	ring->lro.ip_summed = CHECKSUM_UNNECESSARY;
+-	ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+-	ring->lro.max_desc = mdev->profile.num_lro;
+-	ring->lro.max_aggr = MAX_SKB_FRAGS;
+-	ring->lro.lro_arr = kzalloc(mdev->profile.num_lro *
+-				    sizeof(struct net_lro_desc),
+-				    GFP_KERNEL);
+-	if (!ring->lro.lro_arr) {
+-		en_err(priv, "Failed to allocate lro array\n");
+-		goto err_map;
++	/* Allocate LRO sessions */
++	if (mdev->profile.num_lro) {
++		err =  mlx4_en_lro_init(ring, mdev->profile.num_lro);
++		if (err) {
++			en_err(priv, "Failed allocating lro sessions\n");
++			goto err_map;
++		}
+ 	}
+-	ring->lro.get_frag_header = mlx4_en_get_frag_header;
+ 
+ 	return 0;
+ 
+@@ -588,7 +567,8 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
+ {
+ 	struct mlx4_en_dev *mdev = priv->mdev;
+ 
+-	kfree(ring->lro.lro_arr);
++	if (mdev->profile.num_lro)
++		mlx4_en_lro_destroy(ring);
+ 	mlx4_en_unmap_buffer(&ring->wqres.buf);
+ 	mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
+ 	vfree(ring->rx_info);
+@@ -608,12 +588,12 @@ void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
+ 
+ 
+ /* Unmap a completed descriptor and free unused pages */
+-static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
+-				    struct mlx4_en_rx_desc *rx_desc,
+-				    struct skb_frag_struct *skb_frags,
+-				    struct skb_frag_struct *skb_frags_rx,
+-				    struct mlx4_en_rx_alloc *page_alloc,
+-				    int length)
++int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
++			     struct mlx4_en_rx_desc *rx_desc,
++			     struct skb_frag_struct *skb_frags,
++			     struct skb_frag_struct *skb_frags_rx,
++			     struct mlx4_en_rx_alloc *page_alloc,
++			     int length)
+ {
+ 	struct mlx4_en_dev *mdev = priv->mdev;
+ 	struct mlx4_en_frag_info *frag_info;
+@@ -656,11 +636,11 @@ fail:
+ }
+ 
+ 
+-static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
+-				      struct mlx4_en_rx_desc *rx_desc,
+-				      struct skb_frag_struct *skb_frags,
+-				      struct mlx4_en_rx_alloc *page_alloc,
+-				      unsigned int length)
++struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
++			       struct mlx4_en_rx_desc *rx_desc,
++			       struct skb_frag_struct *skb_frags,
++			       struct mlx4_en_rx_alloc *page_alloc,
++			       unsigned int length)
+ {
+ 	struct mlx4_en_dev *mdev = priv->mdev;
+ 	struct sk_buff *skb;
+@@ -901,14 +881,13 @@ out:
+ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
+ {
+ 	struct mlx4_en_priv *priv = netdev_priv(dev);
++	struct mlx4_en_dev *mdev = priv->mdev;
+ 	struct mlx4_cqe *cqe;
+ 	struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
+ 	struct skb_frag_struct *skb_frags;
+-	struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS];
+ 	struct mlx4_en_rx_desc *rx_desc;
+ 	struct sk_buff *skb;
+ 	int index;
+-	int nr;
+ 	unsigned int length;
+ 	int polled = 0;
+ 	int ip_summed;
+@@ -946,40 +925,12 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
+ 
+ 		if (likely(priv->rx_csum)) {
+ 			if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
+-			    (cqe->checksum == cpu_to_be16(0xffff))) {
++			    (cqe->checksum == 0xffff)) {
+ 				priv->port_stats.rx_chksum_good++;
+-				/* This packet is eligible for LRO if it is:
+-				 * - DIX Ethernet (type interpretation)
+-				 * - TCP/IP (v4)
+-				 * - without IP options
+-				 * - not an IP fragment */
+-				if (mlx4_en_can_lro(cqe->status) &&
+-				    dev->features & NETIF_F_LRO) {
+-
+-					nr = mlx4_en_complete_rx_desc(
+-						priv, rx_desc,
+-						skb_frags, lro_frags,
+-						ring->page_alloc, length);
+-					if (!nr)
+-						goto next;
+-
+-					if (priv->vlgrp && (cqe->vlan_my_qpn &
+-							    cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) {
+-						lro_vlan_hwaccel_receive_frags(
+-						       &ring->lro, lro_frags,
+-						       length, length,
+-						       priv->vlgrp,
+-						       be16_to_cpu(cqe->sl_vid),
+-						       NULL, 0);
+-					} else
+-						lro_receive_frags(&ring->lro,
+-								  lro_frags,
+-								  length,
+-								  length,
+-								  NULL, 0);
+-
++				if (mdev->profile.num_lro &&
++				    !mlx4_en_lro_rx(priv, ring, rx_desc,
++						    skb_frags, length, cqe))
+ 					goto next;
+-				}
+ 
+ 				/* LRO not possible, complete processing here */
+ 				ip_summed = CHECKSUM_UNNECESSARY;
+@@ -1002,7 +953,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
+ 
+ 		skb->ip_summed = ip_summed;
+ 		skb->protocol = eth_type_trans(skb, dev);
+-		skb_record_rx_queue(skb, cq->ring);
+ 
+ 		/* Push it up the stack */
+ 		if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) &
+@@ -1012,6 +962,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
+ 		} else
+ 			netif_receive_skb(skb);
+ 
++		dev->last_rx = jiffies;
++
+ next:
+ 		++cq->mcq.cons_index;
+ 		index = (cq->mcq.cons_index) & ring->size_mask;
+@@ -1019,13 +971,15 @@ next:
+ 		if (++polled == budget) {
+ 			/* We are here because we reached the NAPI budget -
+ 			 * flush only pending LRO sessions */
+-			lro_flush_all(&ring->lro);
++			if (mdev->profile.num_lro)
++				mlx4_en_lro_flush(priv, ring, 0);
+ 			goto out;
+ 		}
+ 	}
+ 
+ 	/* If CQ is empty flush all LRO sessions unconditionally */
+-	lro_flush_all(&ring->lro);
++	if (mdev->profile.num_lro)
++		mlx4_en_lro_flush(priv, ring, 1);
+ 
+ out:
+ 	AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
+@@ -1042,7 +996,6 @@ out:
+ 	return polled;
+ }
+ 
+-
+ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
+ {
+ 	struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
+diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
+index b45774c..e9174c4 100644
+--- a/drivers/net/mlx4/mlx4_en.h
++++ b/drivers/net/mlx4/mlx4_en.h
+@@ -296,11 +296,41 @@ struct mlx4_en_rx_desc {
+ 	struct mlx4_wqe_data_seg data[0];
+ };
+ 
++struct mlx4_en_lro {
++	struct hlist_node node;
++	struct hlist_node flush_node;
++
++	/* Id fields come first: */
++	u32 saddr;
++	u32 daddr;
++	u32 sport_dport;
++	u32 next_seq;
++	u16 tot_len;
++	u8 psh;
++
++	u32 tsval;
++	u32 tsecr;
++	u32 ack_seq;
++	u16 window;
++	__be16 vlan_prio;
++	u16 has_vlan;
++	u16 has_timestamp;
++	u16 mss;
++	__wsum  data_csum;
++
++	unsigned long expires;
++	struct sk_buff *skb;
++	struct sk_buff *skb_last;
++};
++
+ struct mlx4_en_rx_ring {
+ 	struct mlx4_srq srq;
+ 	struct mlx4_hwq_resources wqres;
+ 	struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
+-	struct net_lro_mgr lro;
++	struct mlx4_en_lro lro;
++	struct hlist_head *lro_hash;
++	struct hlist_head lro_free;
++	struct hlist_head lro_flush;
+ 	u32 size ;	/* number of Rx descs*/
+ 	u32 actual_size;
+ 	u32 size_mask;
+@@ -592,12 +622,32 @@ void mlx4_en_calc_rx_buf(struct net_device *dev);
+ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
+ 				 struct mlx4_en_rss_map *rss_map,
+ 				 int num_entries, int num_rings);
++
++void mlx4_en_lro_flush(struct mlx4_en_priv* priv, struct mlx4_en_rx_ring *ring, u8 all);
++int mlx4_en_lro_rx(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring,
++		   struct mlx4_en_rx_desc *rx_desc,
++		   struct skb_frag_struct *skb_frags,
++		   unsigned int length, struct mlx4_cqe *cqe);
++void mlx4_en_lro_destroy(struct mlx4_en_rx_ring *ring);
++int mlx4_en_lro_init(struct mlx4_en_rx_ring *ring, int num_lro);
++
+ void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num);
+ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
+ void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv);
+ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
+ void mlx4_en_rx_refill(struct work_struct *work);
+ void mlx4_en_rx_irq(struct mlx4_cq *mcq);
++struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
++			       struct mlx4_en_rx_desc *rx_desc,
++			       struct skb_frag_struct *skb_frags,
++			       struct mlx4_en_rx_alloc *page_alloc,
++			       unsigned int length);
++int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
++			     struct mlx4_en_rx_desc *rx_desc,
++			     struct skb_frag_struct *skb_frags,
++			     struct skb_frag_struct *skb_frags_rx,
++			     struct mlx4_en_rx_alloc *page_alloc,
++			     int length);
+ 
+ int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, u64 mac, u64 clear, u8 mode);
+ int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp);
+-- 
+1.6.0
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0040_napi_backports.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0040_napi_backports.patch
new file mode 100644
index 0000000..34b579f
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0040_napi_backports.patch
@@ -0,0 +1,160 @@
+From 455790331499dd90a37c14cebdeef88fbee15357 Mon Sep 17 00:00:00 2001
+From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+Date: Sun, 31 May 2009 15:11:45 +0300
+Subject: [PATCH 4/8] mlx4_en: napi backport
+
+Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+---
+ drivers/net/mlx4/en_cq.c     |   21 +++++++++++++++++----
+ drivers/net/mlx4/en_netdev.c |    5 ++---
+ drivers/net/mlx4/en_rx.c     |   26 +++++++++++++++-----------
+ drivers/net/mlx4/mlx4_en.h   |    4 ++--
+ 4 files changed, 36 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c
+index 17bf8f5..2da0976 100644
+--- a/drivers/net/mlx4/en_cq.c
++++ b/drivers/net/mlx4/en_cq.c
+@@ -34,6 +34,7 @@
+ #include <linux/mlx4/cq.h>
+ #include <linux/mlx4/qp.h>
+ #include <linux/mlx4/cmd.h>
++#include <linux/delay.h>
+ 
+ #include "mlx4_en.h"
+ 
+@@ -106,8 +107,17 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+ 		cq->timer.function = mlx4_en_poll_tx_cq;
+ 		cq->timer.data = (unsigned long) cq;
+ 	} else {
+-		netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
+-		napi_enable(&cq->napi);
++		char name[IFNAMSIZ];
++
++		snprintf(name, IFNAMSIZ, "mlx4_en-%d-%d", priv->port, cq->ring);
++		cq->poll_dev = alloc_netdev(0, name, ether_setup);
++		if (!cq->poll_dev)
++			return -ENOMEM;
++
++		cq->poll_dev->priv = cq;
++		cq->poll_dev->weight = 64;
++		cq->poll_dev->poll = mlx4_en_poll_rx_cq;
++		set_bit(__LINK_STATE_START, &cq->poll_dev->state);
+ 	}
+ 
+ 	return 0;
+@@ -130,8 +140,11 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
+ 	if (cq->is_tx)
+ 		del_timer(&cq->timer);
+ 	else {
+-		napi_disable(&cq->napi);
+-		netif_napi_del(&cq->napi);
++		while (test_bit(__LINK_STATE_RX_SCHED,
++				&cq->poll_dev->state))
++			msleep(1);
++		free_netdev(cq->poll_dev);
++		cq->poll_dev = NULL;
+ 	}
+ 
+ 	mlx4_cq_free(mdev->dev, &cq->mcq);
+diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
+index 34e082c..cb34cc4 100644
+--- a/drivers/net/mlx4/en_netdev.c
++++ b/drivers/net/mlx4/en_netdev.c
+@@ -329,7 +329,8 @@ static void mlx4_en_netpoll(struct net_device *dev)
+ 	for (i = 0; i < priv->rx_ring_num; i++) {
+ 		cq = &priv->rx_cq[i];
+ 		spin_lock_irqsave(&cq->lock, flags);
+-		napi_synchronize(&cq->napi);
++		while (test_bit(__LINK_STATE_RX_SCHED, &cq->poll_dev->state))
++			msleep(1);
+ 		if (priv->rx_ring[i].use_frags)
+ 			mlx4_en_process_rx_cq(dev, cq, 0);
+ 		else
+@@ -734,8 +735,6 @@ void mlx4_en_stop_port(struct net_device *dev)
+ 	/* Free RX Rings */
+ 	for (i = 0; i < priv->rx_ring_num; i++) {
+ 		mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
+-		while (test_bit(NAPI_STATE_SCHED, &priv->rx_cq[i].napi.state))
+-			msleep(1);
+ 		mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
+ 	}
+ }
+diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
+index f079888..1f5a8d2 100644
+--- a/drivers/net/mlx4/en_rx.c
++++ b/drivers/net/mlx4/en_rx.c
+@@ -1002,33 +1002,37 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
+ 	struct mlx4_en_priv *priv = netdev_priv(cq->dev);
+ 
+ 	if (priv->port_up)
+-		napi_schedule(&cq->napi);
++		netif_rx_schedule(cq->poll_dev);
+ 	else
+ 		mlx4_en_arm_cq(priv, cq);
+ }
+ 
+ /* Rx CQ polling - called by NAPI */
+-int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
++int mlx4_en_poll_rx_cq(struct net_device *poll_dev, int *budget)
+ {
+-	struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
++	struct mlx4_en_cq *cq = poll_dev->priv;
+ 	struct net_device *dev = cq->dev;
+ 	struct mlx4_en_priv *priv = netdev_priv(dev);
+ 	int done;
++	int work = min(*budget, poll_dev->quota);
+ 
+ 	if (priv->rx_ring[cq->ring].use_frags)
+-		done = mlx4_en_process_rx_cq(dev, cq, budget);
++		done = mlx4_en_process_rx_cq(dev, cq, work);
+ 	else
+-		done = mlx4_en_process_rx_cq_skb(dev, cq, budget);
++		done = mlx4_en_process_rx_cq_skb(dev, cq, work);
++	dev->quota -= done;
++	*budget -= done;
+ 
+ 	/* If we used up all the quota - we're probably not done yet... */
+-	if (done == budget)
++	if (done == work) {
+ 		INC_PERF_COUNTER(priv->pstats.napi_quota);
+-	else {
+-		/* Done for now */
+-		napi_complete(napi);
+-		mlx4_en_arm_cq(priv, cq);
++		return 1;
+ 	}
+-	return done;
++
++	/* Done for now */
++	netif_rx_complete(poll_dev);
++	mlx4_en_arm_cq(priv, cq);
++	return 0;
+ }
+ 
+ 
+diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
+index ac1164c..ec318a7 100644
+--- a/drivers/net/mlx4/mlx4_en.h
++++ b/drivers/net/mlx4/mlx4_en.h
+@@ -371,7 +371,7 @@ struct mlx4_en_cq {
+ 	int                     ring;
+ 	spinlock_t              lock;
+ 	struct net_device      *dev;
+-	struct napi_struct	napi;
++	struct net_device      *poll_dev; /* for napi */
+ 	/* Per-core Tx cq processing support */
+ 	struct timer_list timer;
+ 	int size;
+@@ -610,7 +610,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev,
+ int mlx4_en_process_rx_cq_skb(struct net_device *dev,
+ 			      struct mlx4_en_cq *cq,
+ 			      int budget);
+-int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
++int mlx4_en_poll_rx_cq(struct net_device *poll_dev, int *budget);;
+ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
+ 			     int is_tx, int rss, int qpn, int cqn, int srqn,
+ 			     struct mlx4_qp_context *context);
+-- 
+1.6.1.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0050_no_set_flags_support.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0050_no_set_flags_support.patch
new file mode 100644
index 0000000..da1c443
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0050_no_set_flags_support.patch
@@ -0,0 +1,26 @@
+From 9e8b37de6c50238ded500d77e7a6317798842fc5 Mon Sep 17 00:00:00 2001
+From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+Date: Sun, 31 May 2009 15:17:17 +0300
+Subject: [PATCH 5/8] mlx4_en: no set_flag support
+
+Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+---
+ drivers/net/mlx4/en_ethtool.c |    2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
+index 397ceb9..a30ba2c 100644
+--- a/drivers/net/mlx4/en_ethtool.c
++++ b/drivers/net/mlx4/en_ethtool.c
+@@ -414,8 +414,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
+ 	.set_pauseparam = mlx4_en_set_pauseparam,
+ 	.get_ringparam = mlx4_en_get_ringparam,
+ 	.set_ringparam = mlx4_en_set_ringparam,
+-	.get_flags = ethtool_op_get_flags,
+-	.set_flags = ethtool_op_set_flags,
+ };
+ 
+ 
+-- 
+1.6.1.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0060_ethtool_interface.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0060_ethtool_interface.patch
new file mode 100644
index 0000000..4ec818b
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mlx4_en_0060_ethtool_interface.patch
@@ -0,0 +1,41 @@
+From 0096a7c598645ee54f98af40e96c98ff45b190eb Mon Sep 17 00:00:00 2001
+From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+Date: Sun, 31 May 2009 15:20:43 +0300
+Subject: [PATCH 6/8] mlx4_en: ethtool interface
+
+Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
+---
+ drivers/net/mlx4/en_ethtool.c |    7 ++-----
+ 1 files changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
+index a30ba2c..973416a 100644
+--- a/drivers/net/mlx4/en_ethtool.c
++++ b/drivers/net/mlx4/en_ethtool.c
+@@ -144,13 +144,10 @@ static void mlx4_en_get_wol(struct net_device *netdev,
+ 	return;
+ }
+ 
+-static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
++static int mlx4_en_get_sset_count(struct net_device *dev)
+ {
+ 	struct mlx4_en_priv *priv = netdev_priv(dev);
+ 
+-	if (sset != ETH_SS_STATS)
+-		return -EOPNOTSUPP;
+-
+ 	return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
+ }
+ 
+@@ -403,7 +400,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
+ 	.get_tx_csum = ethtool_op_get_tx_csum,
+ 	.set_tx_csum = ethtool_op_set_tx_ipv6_csum,
+ 	.get_strings = mlx4_en_get_strings,
+-	.get_sset_count = mlx4_en_get_sset_count,
++	.get_stats_count = mlx4_en_get_sset_count,
+ 	.get_ethtool_stats = mlx4_en_get_ethtool_stats,
+ 	.get_wol = mlx4_en_get_wol,
+ 	.get_msglevel = mlx4_en_get_msglevel,
+-- 
+1.6.1.3
+
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0000_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0000_pci_dma_mapping_error_to_2_6_26.patch
new file mode 100644
index 0000000..ac803bf
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0000_pci_dma_mapping_error_to_2_6_26.patch
@@ -0,0 +1,17 @@
+---
+ drivers/infiniband/hw/mthca/mthca_eq.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/mthca/mthca_eq.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/mthca/mthca_eq.c
++++ ofed_kernel/drivers/infiniband/hw/mthca/mthca_eq.c
+@@ -780,7 +780,7 @@ int mthca_map_eq_icm(struct mthca_dev *d
+ 		return -ENOMEM;
+ 	dev->eq_table.icm_dma  = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0,
+ 					      PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+-	if (pci_dma_mapping_error(dev->pdev, dev->eq_table.icm_dma)) {
++	if (pci_dma_mapping_error(dev->eq_table.icm_dma)) {
+ 		__free_page(dev->eq_table.icm_page);
+ 		return -ENOMEM;
+ 	}
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0001_pcix_to_2_6_22.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0001_pcix_to_2_6_22.patch
new file mode 100644
index 0000000..4d81461
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0001_pcix_to_2_6_22.patch
@@ -0,0 +1,57 @@
+---
+ drivers/infiniband/hw/mthca/mthca_main.c |   33 +++++++++++++++++++++++--------
+ 1 file changed, 25 insertions(+), 8 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/mthca/mthca_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/mthca/mthca_main.c
++++ ofed_kernel/drivers/infiniband/hw/mthca/mthca_main.c
+@@ -131,23 +131,40 @@ static char mthca_version[] __devinitdat
+ 
+ static int mthca_tune_pci(struct mthca_dev *mdev)
+ {
++	int cap;
++	u16 val;
++
+ 	if (!tune_pci)
+ 		return 0;
+ 
+ 	/* First try to max out Read Byte Count */
+-	if (pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX)) {
+-		if (pcix_set_mmrbc(mdev->pdev, pcix_get_max_mmrbc(mdev->pdev))) {
+-			mthca_err(mdev, "Couldn't set PCI-X max read count, "
+-				"aborting.\n");
++	cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
++	if (cap) {
++		if (pci_read_config_word(mdev->pdev, cap + PCI_X_CMD, &val)) {
++			mthca_err(mdev, "Couldn't read PCI-X command register, "
++				  "aborting.\n");
++			return -ENODEV;
++		}
++		val = (val & ~PCI_X_CMD_MAX_READ) | (3 << 2);
++		if (pci_write_config_word(mdev->pdev, cap + PCI_X_CMD, val)) {
++			mthca_err(mdev, "Couldn't write PCI-X command register, "
++				  "aborting.\n");
+ 			return -ENODEV;
+ 		}
+ 	} else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE))
+ 		mthca_info(mdev, "No PCI-X capability, not setting RBC.\n");
+ 
+-	if (pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP)) {
+-		if (pcie_set_readrq(mdev->pdev, 4096)) {
+-			mthca_err(mdev, "Couldn't write PCI Express read request, "
+-				"aborting.\n");
++	cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP);
++	if (cap) {
++		if (pci_read_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, &val)) {
++			mthca_err(mdev, "Couldn't read PCI Express device control "
++				  "register, aborting.\n");
++			return -ENODEV;
++		}
++		val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12);
++		if (pci_write_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, val)) {
++			mthca_err(mdev, "Couldn't write PCI Express device control "
++				  "register, aborting.\n");
+ 			return -ENODEV;
+ 		}
+ 	} else if (mdev->mthca_flags & MTHCA_FLAG_PCIE)
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0010_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0010_sysfs.patch
new file mode 100644
index 0000000..473aa45
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/mthca_0010_sysfs.patch
@@ -0,0 +1,94 @@
+---
+ drivers/infiniband/hw/mthca/mthca_provider.c |   50 +++++++++++----------------
+ 1 file changed, 21 insertions(+), 29 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/mthca/mthca_provider.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/mthca/mthca_provider.c
++++ ofed_kernel/drivers/infiniband/hw/mthca/mthca_provider.c
+@@ -1186,29 +1186,23 @@ static int mthca_unmap_fmr(struct list_h
+ 	return 0;
+ }
+ 
+-static ssize_t show_rev(struct device *device, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_rev(struct class_device *cdev, char *buf)
+ {
+-	struct mthca_dev *dev =
+-		container_of(device, struct mthca_dev, ib_dev.dev);
++	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+ 	return sprintf(buf, "%x\n", dev->rev_id);
+ }
+ 
+-static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
+-			   char *buf)
++static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
+ {
+-	struct mthca_dev *dev =
+-		container_of(device, struct mthca_dev, ib_dev.dev);
++	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+ 	return sprintf(buf, "%d.%d.%d\n", (int) (dev->fw_ver >> 32),
+ 		       (int) (dev->fw_ver >> 16) & 0xffff,
+ 		       (int) dev->fw_ver & 0xffff);
+ }
+ 
+-static ssize_t show_hca(struct device *device, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_hca(struct class_device *cdev, char *buf)
+ {
+-	struct mthca_dev *dev =
+-		container_of(device, struct mthca_dev, ib_dev.dev);
++	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+ 	switch (dev->pdev->device) {
+ 	case PCI_DEVICE_ID_MELLANOX_TAVOR:
+ 		return sprintf(buf, "MT23108\n");
+@@ -1224,24 +1218,22 @@ static ssize_t show_hca(struct device *d
+ 	}
+ }
+ 
+-static ssize_t show_board(struct device *device, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_board(struct class_device *cdev, char *buf)
+ {
+-	struct mthca_dev *dev =
+-		container_of(device, struct mthca_dev, ib_dev.dev);
++	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+ 	return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
+ }
+ 
+-static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
+-static DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
+-static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
+-static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
+-
+-static struct device_attribute *mthca_dev_attributes[] = {
+-	&dev_attr_hw_rev,
+-	&dev_attr_fw_ver,
+-	&dev_attr_hca_type,
+-	&dev_attr_board_id
++static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
++static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
++static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
++static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
++
++static struct class_device_attribute *mthca_class_attributes[] = {
++	&class_device_attr_hw_rev,
++	&class_device_attr_fw_ver,
++	&class_device_attr_hca_type,
++	&class_device_attr_board_id
+ };
+ 
+ static int mthca_init_node_data(struct mthca_dev *dev)
+@@ -1403,9 +1395,9 @@ int mthca_register_device(struct mthca_d
+ 	if (ret)
+ 		return ret;
+ 
+-	for (i = 0; i < ARRAY_SIZE(mthca_dev_attributes); ++i) {
+-		ret = device_create_file(&dev->ib_dev.dev,
+-					 mthca_dev_attributes[i]);
++	for (i = 0; i < ARRAY_SIZE(mthca_class_attributes); ++i) {
++		ret = class_device_create_file(&dev->ib_dev.class_dev,
++					       mthca_class_attributes[i]);
+ 		if (ret) {
+ 			ib_unregister_device(&dev->ib_dev);
+ 			return ret;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/nes_0010_sysfs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/nes_0010_sysfs.patch
new file mode 100644
index 0000000..8df7939
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/nes_0010_sysfs.patch
@@ -0,0 +1,120 @@
+---
+ drivers/infiniband/hw/nes/nes_verbs.c |   50 +++++++++++++++-------------------
+ 1 file changed, 23 insertions(+), 27 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/hw/nes/nes_verbs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/nes/nes_verbs.c
++++ ofed_kernel/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -2676,11 +2676,10 @@ static int nes_dereg_mr(struct ib_mr *ib
+ /**
+  * show_rev
+  */
+-static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
+-			char *buf)
++static ssize_t show_rev(struct class_device *cdev, char *buf)
+ {
+ 	struct nes_ib_device *nesibdev =
+-			container_of(dev, struct nes_ib_device, ibdev.dev);
++			container_of(cdev, struct nes_ib_device, ibdev.class_dev);
+ 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
+ 
+ 	nes_debug(NES_DBG_INIT, "\n");
+@@ -2691,11 +2690,10 @@ static ssize_t show_rev(struct device *d
+ /**
+  * show_fw_ver
+  */
+-static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
+-			   char *buf)
++static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
+ {
+ 	struct nes_ib_device *nesibdev =
+-			container_of(dev, struct nes_ib_device, ibdev.dev);
++			container_of(cdev, struct nes_ib_device, ibdev.class_dev);
+ 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
+ 
+ 	nes_debug(NES_DBG_INIT, "\n");
+@@ -2709,8 +2707,7 @@ static ssize_t show_fw_ver(struct device
+ /**
+  * show_hca
+  */
+-static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
+-		        char *buf)
++static ssize_t show_hca(struct class_device *cdev, char *buf)
+ {
+ 	nes_debug(NES_DBG_INIT, "\n");
+ 	return sprintf(buf, "NES020\n");
+@@ -2720,24 +2717,23 @@ static ssize_t show_hca(struct device *d
+ /**
+  * show_board
+  */
+-static ssize_t show_board(struct device *dev, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_board(struct class_device *cdev, char *buf)
+ {
+ 	nes_debug(NES_DBG_INIT, "\n");
+ 	return sprintf(buf, "%.*s\n", 32, "NES020 Board ID");
+ }
+ 
+ 
+-static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
+-static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
+-static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
+-static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
+-
+-static struct device_attribute *nes_dev_attributes[] = {
+-	&dev_attr_hw_rev,
+-	&dev_attr_fw_ver,
+-	&dev_attr_hca_type,
+-	&dev_attr_board_id
++static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
++static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
++static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
++static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
++
++static struct class_device_attribute *nes_class_attributes[] = {
++	&class_device_attr_hw_rev,
++	&class_device_attr_fw_ver,
++	&class_device_attr_hca_type,
++	&class_device_attr_board_id
+ };
+ 
+ 
+@@ -3646,7 +3642,7 @@ struct nes_ib_device *nes_init_ofa_devic
+ 	nesibdev->ibdev.phys_port_cnt = 1;
+ 	nesibdev->ibdev.num_comp_vectors = 1;
+ 	nesibdev->ibdev.dma_device = &nesdev->pcidev->dev;
+-	nesibdev->ibdev.dev.parent = &nesdev->pcidev->dev;
++	nesibdev->ibdev.class_dev.dev = &nesdev->pcidev->dev;
+ 	nesibdev->ibdev.query_device = nes_query_device;
+ 	nesibdev->ibdev.query_port = nes_query_port;
+ 	nesibdev->ibdev.modify_port = nes_modify_port;
+@@ -3741,13 +3737,13 @@ int nes_register_ofa_device(struct nes_i
+ 	nesibdev->max_qp = (nesadapter->max_qp-NES_FIRST_QPN) / nesadapter->port_count;
+ 	nesibdev->max_pd = nesadapter->max_pd / nesadapter->port_count;
+ 
+-	for (i = 0; i < ARRAY_SIZE(nes_dev_attributes); ++i) {
+-		ret = device_create_file(&nesibdev->ibdev.dev, nes_dev_attributes[i]);
++	for (i = 0; i < ARRAY_SIZE(nes_class_attributes); ++i) {
++		ret = class_device_create_file(&nesibdev->ibdev.class_dev, nes_class_attributes[i]);
+ 		if (ret) {
+ 			while (i > 0) {
+ 				i--;
+-				device_remove_file(&nesibdev->ibdev.dev,
+-						   nes_dev_attributes[i]);
++				class_device_remove_file(&nesibdev->ibdev.class_dev,
++						nes_class_attributes[i]);
+ 			}
+ 			ib_unregister_device(&nesibdev->ibdev);
+ 			return ret;
+@@ -3768,8 +3764,8 @@ static void nes_unregister_ofa_device(st
+ 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
+ 	int i;
+ 
+-	for (i = 0; i < ARRAY_SIZE(nes_dev_attributes); ++i) {
+-		device_remove_file(&nesibdev->ibdev.dev, nes_dev_attributes[i]);
++	for (i = 0; i < ARRAY_SIZE(nes_class_attributes); ++i) {
++		class_device_remove_file(&nesibdev->ibdev.class_dev, nes_class_attributes[i]);
+ 	}
+ 
+ 	if (nesvnic->of_device_registered) {
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/qlgc_vnic_01_class_device.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/qlgc_vnic_01_class_device.patch
new file mode 100644
index 0000000..e4ec8f8
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/qlgc_vnic_01_class_device.patch
@@ -0,0 +1,1099 @@
+---
+ drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c      |   75 ++++---
+ drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h      |    2 +-
+ drivers/infiniband/ulp/qlgc_vnic/vnic_main.c    |   11 +-
+ drivers/infiniband/ulp/qlgc_vnic/vnic_main.h    |    5 +-
+ drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c |    6 +-
+ drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h |    2 +-
+ drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c   |  126 ++++++------
+ drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h   |   18 +-
+ drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c     |  257 ++++++++++++-----------
+ drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h     |   18 +-
+ 10 files changed, 266 insertions(+), 254 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c
+@@ -89,33 +89,34 @@ int vnic_ib_init(void)
+ 		goto err_ib_reg;
+ 	}
+ 
+-	interface_dev.dev.class = &vnic_class;
+-	interface_dev.dev.release = vnic_release_dev;
+-	snprintf(interface_dev.dev.bus_id,
++ 	interface_cdev.class_dev.class = &vnic_class;
++ 	snprintf(interface_cdev.class_dev.class_id,
+ 		 BUS_ID_SIZE, "interfaces");
+-	init_completion(&interface_dev.released);
+-	ret = device_register(&interface_dev.dev);
++ 	init_completion(&interface_cdev.released);
++  	ret = class_device_register(&interface_cdev.class_dev);
+ 	if (ret) {
+ 		printk(KERN_ERR PFX "couldn't register class interfaces;"
+ 		       " error %d", ret);
+ 		goto err_class_dev;
+ 	}
+-	ret = device_create_file(&interface_dev.dev,
+-				       &dev_attr_delete_vnic);
++ 	ret = class_device_create_file(&interface_cdev.class_dev,
++ 				       &class_device_attr_delete_vnic);
+ 	if (ret) {
+ 		printk(KERN_ERR PFX "couldn't create class file"
+ 		       " 'delete_vnic'; error %d", ret);
+ 		goto err_class_file;
+ 	}
+ 
+-	ret = device_create_file(&interface_dev.dev, &dev_attr_force_failover);
++	ret = class_device_create_file(&interface_cdev.class_dev,
++					&class_device_attr_force_failover);
+ 	if (ret) {
+ 		printk(KERN_ERR PFX "couldn't create class file"
+ 		       " 'force_failover'; error %d", ret);
+ 		goto err_force_failover_file;
+ 	}
+ 
+-	ret = device_create_file(&interface_dev.dev, &dev_attr_unfailover);
++	ret = class_device_create_file(&interface_cdev.class_dev,
++					&class_device_attr_unfailover);
+ 	if (ret) {
+ 		printk(KERN_ERR PFX "couldn't create class file"
+ 		       " 'unfailover'; error %d", ret);
+@@ -125,11 +126,13 @@ int vnic_ib_init(void)
+ 
+ 	return ret;
+ err_unfailover_file:
+-	device_remove_file(&interface_dev.dev, &dev_attr_force_failover);
++	class_device_remove_file(&interface_cdev.class_dev,
++				 &class_device_attr_force_failover);
+ err_force_failover_file:
+-	device_remove_file(&interface_dev.dev, &dev_attr_delete_vnic);
++	class_device_remove_file(&interface_cdev.class_dev,
++				 &class_device_attr_delete_vnic);
+ err_class_file:
+-	device_unregister(&interface_dev.dev);
++	class_device_unregister(&interface_cdev.class_dev);
+ err_class_dev:
+ 	ib_unregister_client(&vnic_client);
+ err_ib_reg:
+@@ -148,29 +151,29 @@ static struct vnic_ib_port *vnic_add_port(struct vnic_ib_device *device,
+ 	if (!port)
+ 		return NULL;
+ 
+-	init_completion(&port->pdev_info.released);
++	init_completion(&port->cdev_info.released);
+ 	port->dev = device;
+ 	port->port_num = port_num;
+ 
+-	port->pdev_info.dev.class = &vnic_class;
+-	port->pdev_info.dev.parent = NULL;
+-	port->pdev_info.dev.release = vnic_release_dev;
+-	snprintf(port->pdev_info.dev.bus_id, BUS_ID_SIZE,
++	port->cdev_info.class_dev.class = &vnic_class;
++	port->cdev_info.class_dev.dev = device->dev->dma_device;
++	snprintf(port->cdev_info.class_dev.class_id, BUS_ID_SIZE,
+ 		 "vnic-%s-%d", device->dev->name, port_num);
+ 
+-	if (device_register(&port->pdev_info.dev))
++ 	if (class_device_register(&port->cdev_info.class_dev))
+ 		goto free_port;
+ 
+-	if (device_create_file(&port->pdev_info.dev,
+-				     &dev_attr_create_primary))
++ 	if (class_device_create_file(&port->cdev_info.class_dev,
++ 				     &class_device_attr_create_primary))
+ 		goto err_class;
+-	if (device_create_file(&port->pdev_info.dev,
+-				     &dev_attr_create_secondary))
++
++ 	if (class_device_create_file(&port->cdev_info.class_dev,
++ 				     &class_device_attr_create_secondary))
+ 		goto err_class;
+ 
+ 	return port;
+ err_class:
+-	device_unregister(&port->pdev_info.dev);
++	class_device_unregister(&port->cdev_info.class_dev);
+ free_port:
+ 	kfree(port);
+ 
+@@ -219,14 +222,16 @@ static void vnic_remove_one(struct ib_device *device)
+ 	list_for_each_entry_safe(port, tmp_port,
+ 				 &vnic_dev->port_list, list) {
+ 
+-		device_remove_file(&port->pdev_info.dev, &dev_attr_create_primary);
+-		device_remove_file(&port->pdev_info.dev, &dev_attr_create_secondary);
+-		device_unregister(&port->pdev_info.dev);
++		class_device_remove_file(&port->cdev_info.class_dev,
++				&class_device_attr_create_primary);
++		class_device_remove_file(&port->cdev_info.class_dev,
++				&class_device_attr_create_secondary);
++		class_device_unregister(&port->cdev_info.class_dev);
+ 		/*
+ 		 * wait for sysfs entries to go away, so that no new vnics
+ 		 * are created
+ 		 */
+-		wait_for_completion(&port->pdev_info.released);
++		wait_for_completion(&port->cdev_info.released);
+ 		kfree(port);
+ 
+ 	}
+@@ -254,13 +259,15 @@ void vnic_ib_cleanup(void)
+ 
+ 	if (!vnic_ib_inited)
+ 		return;
+-
+-	device_remove_file(&interface_dev.dev, &dev_attr_unfailover);
+-	device_remove_file(&interface_dev.dev, &dev_attr_force_failover);
+-	device_remove_file(&interface_dev.dev, &dev_attr_delete_vnic);
+-
+-	device_unregister(&interface_dev.dev);
+-	wait_for_completion(&interface_dev.released);
++	class_device_remove_file(&interface_cdev.class_dev,
++				&class_device_attr_unfailover);
++	class_device_remove_file(&interface_cdev.class_dev,
++				&class_device_attr_force_failover);
++	class_device_remove_file(&interface_cdev.class_dev,
++				&class_device_attr_delete_vnic);
++
++ 	class_device_unregister(&interface_cdev.class_dev);
++ 	wait_for_completion(&interface_cdev.released);
+ 
+ 	ib_unregister_client(&vnic_client);
+ 	ib_sa_unregister_client(&vnic_sa_client);
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h
+@@ -109,7 +109,7 @@ struct vnic_ib_device {
+ struct vnic_ib_port {
+ 	struct vnic_ib_device	*dev;
+ 	u8			port_num;
+-	struct dev_info		pdev_info;
++	struct class_dev_info	cdev_info;
+ 	struct list_head	list;
+ };
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
+@@ -770,11 +770,11 @@ static void vnic_handle_free_vnic_evt(struct vnic *vnic)
+ 		kfree(vnic->mc_list);
+ 	}
+ 
+-	sysfs_remove_group(&vnic->dev_info.dev.kobj,
+-			   &vnic_dev_attr_group);
+-	vnic_cleanup_stats_files(vnic);
+-	device_unregister(&vnic->dev_info.dev);
+-	wait_for_completion(&vnic->dev_info.released);
++ 	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);
++  	wait_for_completion(&vnic->class_dev_info.released);
+ 	free_netdev(vnic->netdevice);
+ }
+ 
+@@ -1092,6 +1092,7 @@ struct vnic *vnic_allocate(struct vnic_config *config)
+ 	vnic->state = VNIC_UNINITIALIZED;
+ 	vnic->config = config;
+ 
++
+ 	netpath_init(&vnic->primary_path, vnic, 0);
+ 	netpath_init(&vnic->secondary_path, vnic, 1);
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
+@@ -36,7 +36,6 @@
+ #include <linux/timex.h>
+ #include <linux/netdevice.h>
+ #include <linux/kthread.h>
+-#include <linux/fs.h>
+ 
+ #include "vnic_config.h"
+ #include "vnic_netpath.h"
+@@ -104,7 +103,7 @@ struct vnic {
+ 	int				failed_over;
+ 	int				mac_set;
+ 	struct net_device		*netdevice;
+-	struct dev_info			dev_info;
++	struct class_dev_info		class_dev_info;
+ 	struct dev_mc_list		*mc_list;
+ 	int				mc_list_len;
+ 	int				mc_count;
+@@ -130,7 +129,7 @@ struct vnic {
+ 		cycles_t	carrier_off_time;
+ 		u32		carrier_off_num;
+ 	} statistics;
+-	struct dev_info		stat_info;
++	struct class_dev_info	stat_info;
+ #endif	/* CONFIG_INFINIBAND_QLGC_VNIC_STATS */
+ };
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c
+@@ -82,10 +82,10 @@ void netpath_free(struct netpath *netpath)
+ 		return;
+ 	viport_free(netpath->viport);
+ 	netpath->viport = NULL;
+-	sysfs_remove_group(&netpath->dev_info.dev.kobj,
++	sysfs_remove_group(&netpath->class_dev_info.class_dev.kobj,
+ 			   &vnic_path_attr_group);
+-	device_unregister(&netpath->dev_info.dev);
+-	wait_for_completion(&netpath->dev_info.released);
++	class_device_unregister(&netpath->class_dev_info.class_dev);
++	wait_for_completion(&netpath->class_dev_info.released);
+ }
+ 
+ void netpath_init(struct netpath *netpath, struct vnic *vnic,
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h
+@@ -57,7 +57,7 @@ struct netpath {
+ 	u8 			delay_reconnect;
+ 	struct timer_list	timer;
+ 	enum netpath_ts		timer_state;
+-	struct dev_info		dev_info;
++	struct class_dev_info	class_dev_info;
+ };
+ 
+ void netpath_init(struct netpath *netpath, struct vnic *vnic,
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c
+@@ -43,22 +43,22 @@ cycles_t vnic_recv_ref;
+  *       RDMA times, IOs etc
+  *
+  */
+-static ssize_t show_lifetime(struct device *dev,
+-			     struct device_attribute *dev_attr, char *buf)
++static ssize_t show_lifetime(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 	cycles_t time = get_cycles() - vnic->statistics.start_time;
+ 
+ 	return sprintf(buf, "%llu\n", (unsigned long long)time);
+ }
+ 
+-static DEVICE_ATTR(lifetime, S_IRUGO, show_lifetime, NULL);
++static CLASS_DEVICE_ATTR(lifetime, S_IRUGO, show_lifetime, NULL);
+ 
+-static ssize_t show_conntime(struct device *dev,
+-			     struct device_attribute *dev_attr, char *buf)
++static ssize_t show_conntime(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	if (vnic->statistics.conn_time)
+@@ -67,12 +67,12 @@ static ssize_t show_conntime(struct device *dev,
+ 	return 0;
+ }
+ 
+-static DEVICE_ATTR(connection_time, S_IRUGO, show_conntime, NULL);
++static CLASS_DEVICE_ATTR(connection_time, S_IRUGO, show_conntime, NULL);
+ 
+-static ssize_t show_disconnects(struct device *dev,
+-				struct device_attribute *dev_attr, char *buf)
++static ssize_t show_disconnects(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 	u32 num;
+ 
+@@ -84,13 +84,13 @@ static ssize_t show_disconnects(struct device *dev,
+ 	return sprintf(buf, "%d\n", num);
+ }
+ 
+-static DEVICE_ATTR(disconnects, S_IRUGO, show_disconnects, NULL);
++static CLASS_DEVICE_ATTR(disconnects, S_IRUGO, show_disconnects, NULL);
+ 
+-static ssize_t show_total_disconn_time(struct device *dev,
+-				       struct device_attribute *dev_attr,
++static ssize_t show_total_disconn_time(struct class_device *class_dev,
+ 				       char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 	cycles_t time;
+ 
+@@ -103,12 +103,14 @@ static ssize_t show_total_disconn_time(struct device *dev,
+ 	return sprintf(buf, "%llu\n", (unsigned long long)time);
+ }
+ 
+-static DEVICE_ATTR(total_disconn_time, S_IRUGO, show_total_disconn_time, NULL);
++static CLASS_DEVICE_ATTR(total_disconn_time, S_IRUGO,
++			 show_total_disconn_time, NULL);
+ 
+-static ssize_t show_carrier_losses(struct device *dev,
+-				   struct device_attribute *dev_attr, char *buf)
++static ssize_t show_carrier_losses(struct class_device *class_dev,
++				   char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 	u32 num;
+ 
+@@ -120,13 +122,14 @@ static ssize_t show_carrier_losses(struct device *dev,
+ 	return sprintf(buf, "%d\n", num);
+ }
+ 
+-static DEVICE_ATTR(carrier_losses, S_IRUGO, show_carrier_losses, NULL);
++static CLASS_DEVICE_ATTR(carrier_losses, S_IRUGO,
++			 show_carrier_losses, NULL);
+ 
+-static ssize_t show_total_carr_loss_time(struct device *dev,
+-					 struct device_attribute *dev_attr,
++static ssize_t show_total_carr_loss_time(struct class_device *class_dev,
+ 					 char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 	cycles_t time;
+ 
+@@ -139,93 +142,94 @@ static ssize_t show_total_carr_loss_time(struct device *dev,
+ 	return sprintf(buf, "%llu\n", (unsigned long long)time);
+ }
+ 
+-static DEVICE_ATTR(total_carrier_loss_time, S_IRUGO,
++static CLASS_DEVICE_ATTR(total_carrier_loss_time, S_IRUGO,
+ 			 show_total_carr_loss_time, NULL);
+ 
+-static ssize_t show_total_recv_time(struct device *dev,
+-				    struct device_attribute *dev_attr,
++static ssize_t show_total_recv_time(struct class_device *class_dev,
+ 				    char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	return sprintf(buf, "%llu\n",
+ 		       (unsigned long long)vnic->statistics.recv_time);
+ }
+ 
+-static DEVICE_ATTR(total_recv_time, S_IRUGO, show_total_recv_time, NULL);
++static CLASS_DEVICE_ATTR(total_recv_time, S_IRUGO,
++			 show_total_recv_time, NULL);
+ 
+-static ssize_t show_recvs(struct device *dev,
+-			  struct device_attribute *dev_attr, char *buf)
++static ssize_t show_recvs(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	return sprintf(buf, "%d\n", vnic->statistics.recv_num);
+ }
+ 
+-static DEVICE_ATTR(recvs, S_IRUGO, show_recvs, NULL);
++static CLASS_DEVICE_ATTR(recvs, S_IRUGO, show_recvs, NULL);
+ 
+-static ssize_t show_multicast_recvs(struct device *dev,
+-				    struct device_attribute *dev_attr,
+-				    char *buf)
++static ssize_t show_multicast_recvs(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	return sprintf(buf, "%d\n", vnic->statistics.multicast_recv_num);
+ }
+ 
+-static DEVICE_ATTR(multicast_recvs, S_IRUGO, show_multicast_recvs, NULL);
++static CLASS_DEVICE_ATTR(multicast_recvs, S_IRUGO, show_multicast_recvs, NULL);
+ 
+-static ssize_t show_total_xmit_time(struct device *dev,
+-				    struct device_attribute *dev_attr,
++static ssize_t show_total_xmit_time(struct class_device *class_dev,
+ 				    char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	return sprintf(buf, "%llu\n",
+ 		       (unsigned long long)vnic->statistics.xmit_time);
+ }
+ 
+-static DEVICE_ATTR(total_xmit_time, S_IRUGO, show_total_xmit_time, NULL);
++static CLASS_DEVICE_ATTR(total_xmit_time, S_IRUGO,
++			 show_total_xmit_time, NULL);
+ 
+-static ssize_t show_xmits(struct device *dev,
+-			  struct device_attribute *dev_attr, char *buf)
++static ssize_t show_xmits(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	return sprintf(buf, "%d\n", vnic->statistics.xmit_num);
+ }
+ 
+-static DEVICE_ATTR(xmits, S_IRUGO, show_xmits, NULL);
++static CLASS_DEVICE_ATTR(xmits, S_IRUGO, show_xmits, NULL);
+ 
+-static ssize_t show_failed_xmits(struct device *dev,
+-				 struct device_attribute *dev_attr, char *buf)
++static ssize_t show_failed_xmits(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
+ 
+ 	return sprintf(buf, "%d\n", vnic->statistics.xmit_fail);
+ }
+ 
+-static DEVICE_ATTR(failed_xmits, S_IRUGO, show_failed_xmits, NULL);
++static CLASS_DEVICE_ATTR(failed_xmits, S_IRUGO, show_failed_xmits, NULL);
+ 
+ static struct attribute *vnic_stats_attrs[] = {
+-	&dev_attr_lifetime.attr,
+-	&dev_attr_xmits.attr,
+-	&dev_attr_total_xmit_time.attr,
+-	&dev_attr_failed_xmits.attr,
+-	&dev_attr_recvs.attr,
+-	&dev_attr_multicast_recvs.attr,
+-	&dev_attr_total_recv_time.attr,
+-	&dev_attr_connection_time.attr,
+-	&dev_attr_disconnects.attr,
+-	&dev_attr_total_disconn_time.attr,
+-	&dev_attr_carrier_losses.attr,
+-	&dev_attr_total_carrier_loss_time.attr,
++	&class_device_attr_lifetime.attr,
++	&class_device_attr_xmits.attr,
++	&class_device_attr_total_xmit_time.attr,
++	&class_device_attr_failed_xmits.attr,
++	&class_device_attr_recvs.attr,
++	&class_device_attr_multicast_recvs.attr,
++	&class_device_attr_total_recv_time.attr,
++	&class_device_attr_connection_time.attr,
++	&class_device_attr_disconnects.attr,
++	&class_device_attr_total_disconn_time.attr,
++	&class_device_attr_carrier_losses.attr,
++	&class_device_attr_total_carrier_loss_time.attr,
+ 	NULL
+ };
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h
+@@ -35,7 +35,6 @@
+ 
+ #include "vnic_main.h"
+ #include "vnic_ib.h"
+-#include "vnic_sys.h"
+ 
+ #ifdef CONFIG_INFINIBAND_QLGC_VNIC_STATS
+ 
+@@ -113,25 +112,24 @@ static inline void vnic_carrier_loss_stats(struct vnic *vnic)
+ static inline int vnic_setup_stats_files(struct vnic *vnic)
+ {
+ 	init_completion(&vnic->stat_info.released);
+-	vnic->stat_info.dev.class = NULL;
+-	vnic->stat_info.dev.parent = &vnic->dev_info.dev;
+-	vnic->stat_info.dev.release = vnic_release_dev;
+-	snprintf(vnic->stat_info.dev.bus_id, BUS_ID_SIZE,
++	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 (device_register(&vnic->stat_info.dev)) {
++	if (class_device_register(&vnic->stat_info.class_dev)) {
+ 		SYS_ERROR("create_vnic: error in registering"
+ 			  " stat class dev\n");
+ 		goto stats_out;
+ 	}
+ 
+-	if (sysfs_create_group(&vnic->stat_info.dev.kobj,
++	if (sysfs_create_group(&vnic->stat_info.class_dev.kobj,
+ 			       &vnic_stats_attr_group))
+ 		goto err_stats_file;
+ 
+ 	return 0;
+ err_stats_file:
+-	device_unregister(&vnic->stat_info.dev);
++	class_device_unregister(&vnic->stat_info.class_dev);
+ 	wait_for_completion(&vnic->stat_info.released);
+ stats_out:
+ 	return -1;
+@@ -139,9 +137,9 @@ stats_out:
+ 
+ static inline void vnic_cleanup_stats_files(struct vnic *vnic)
+ {
+-	sysfs_remove_group(&vnic->dev_info.dev.kobj,
++	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
+ 			   &vnic_stats_attr_group);
+-	device_unregister(&vnic->stat_info.dev);
++	class_device_unregister(&vnic->stat_info.class_dev);
+ 	wait_for_completion(&vnic->stat_info.released);
+ }
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c
+@@ -77,21 +77,20 @@ static match_table_t vnic_opt_tokens = {
+ 	{VNIC_OPT_ERR, NULL}
+ };
+ 
+-void vnic_release_dev(struct device *dev)
++static void vnic_release_class_dev(struct class_device *class_dev)
+ {
+-	struct dev_info *dev_info =
+-	    container_of(dev, struct dev_info, dev);
+-
+-	complete(&dev_info->released);
++	struct class_dev_info *cdev_info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
+ 
++	complete(&cdev_info->released);
+ }
+ 
+ struct class vnic_class = {
+ 	.name = "infiniband_qlgc_vnic",
+-	.dev_release = vnic_release_dev
++	.release = vnic_release_class_dev
+ };
+ 
+-struct dev_info interface_dev;
++struct class_dev_info interface_cdev;
+ 
+ static int vnic_parse_options(const char *buf, struct path_param *param)
+ {
+@@ -285,11 +284,11 @@ out:
+ 
+ }
+ 
+-static ssize_t show_vnic_state(struct device *dev,
+-			       struct device_attribute *dev_attr, char *buf)
++static ssize_t show_vnic_state(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
+-	struct vnic *vnic = container_of(info, struct vnic, dev_info);
++	struct class_dev_info *info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
++	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
+ 	switch (vnic->state) {
+ 	case VNIC_UNINITIALIZED:
+ 		return sprintf(buf, "VNIC_UNINITIALIZED\n");
+@@ -301,13 +300,13 @@ static ssize_t show_vnic_state(struct device *dev,
+ 
+ }
+ 
+-static DEVICE_ATTR(vnic_state, S_IRUGO, show_vnic_state, NULL);
++static CLASS_DEVICE_ATTR(vnic_state, S_IRUGO, show_vnic_state, NULL);
+ 
+-static ssize_t show_rx_csum(struct device *dev,
+-			    struct device_attribute *dev_attr, char *buf)
++static ssize_t show_rx_csum(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
+-	struct vnic *vnic = container_of(info, struct vnic, dev_info);
++	struct class_dev_info *info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
++	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
+ 
+ 	if (vnic->config->use_rx_csum)
+ 		return sprintf(buf, "true\n");
+@@ -315,13 +314,13 @@ static ssize_t show_rx_csum(struct device *dev,
+ 		return sprintf(buf, "false\n");
+ }
+ 
+-static DEVICE_ATTR(rx_csum, S_IRUGO, show_rx_csum, NULL);
++static CLASS_DEVICE_ATTR(rx_csum, S_IRUGO, show_rx_csum, NULL);
+ 
+-static ssize_t show_tx_csum(struct device *dev,
+-			    struct device_attribute *dev_attr, char *buf)
++static ssize_t show_tx_csum(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
+-	struct vnic *vnic = container_of(info, struct vnic, dev_info);
++	struct class_dev_info *info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
++	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
+ 
+ 	if (vnic->config->use_tx_csum)
+ 		return sprintf(buf, "true\n");
+@@ -329,13 +328,13 @@ static ssize_t show_tx_csum(struct device *dev,
+ 		return sprintf(buf, "false\n");
+ }
+ 
+-static DEVICE_ATTR(tx_csum, S_IRUGO, show_tx_csum, NULL);
++static CLASS_DEVICE_ATTR(tx_csum, S_IRUGO, show_tx_csum, NULL);
+ 
+-static ssize_t show_current_path(struct device *dev,
+-				 struct device_attribute *dev_attr, char *buf)
+-{
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
+-	struct vnic *vnic = container_of(info, struct vnic, dev_info);
++static ssize_t show_current_path(struct class_device *class_dev, char *buf)
++ {
++ 	struct class_dev_info *info =
++ 	    container_of(class_dev, struct class_dev_info, class_dev);
++ 	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
+ 	unsigned long flags;
+ 	size_t length;
+ 
+@@ -350,13 +349,13 @@ static ssize_t show_current_path(struct device *dev,
+ 	return length;
+ }
+ 
+-static DEVICE_ATTR(current_path, S_IRUGO, show_current_path, NULL);
++static CLASS_DEVICE_ATTR(current_path, S_IRUGO, show_current_path, NULL);
+ 
+ static struct attribute *vnic_dev_attrs[] = {
+-	&dev_attr_vnic_state.attr,
+-	&dev_attr_rx_csum.attr,
+-	&dev_attr_tx_csum.attr,
+-	&dev_attr_current_path.attr,
++	&class_device_attr_vnic_state.attr,
++	&class_device_attr_rx_csum.attr,
++	&class_device_attr_tx_csum.attr,
++	&class_device_attr_current_path.attr,
+ 	NULL
+ };
+ 
+@@ -513,21 +512,20 @@ static struct vnic *create_vnic(struct path_param *param)
+ 		goto free_vnic_config;
+ 	}
+ 
+-	init_completion(&vnic->dev_info.released);
++	init_completion(&vnic->class_dev_info.released);
+ 
+-	vnic->dev_info.dev.class = NULL;
+-	vnic->dev_info.dev.parent = &interface_dev.dev;
+-	vnic->dev_info.dev.release = vnic_release_dev;
+-	snprintf(vnic->dev_info.dev.bus_id, BUS_ID_SIZE,
++	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 (device_register(&vnic->dev_info.dev)) {
++	if (class_device_register(&vnic->class_dev_info.class_dev)) {
+ 		SYS_ERROR("create_vnic: error in registering"
+ 			  " vnic class dev\n");
+ 		goto free_vnic;
+ 	}
+ 
+-	if (sysfs_create_group(&vnic->dev_info.dev.kobj,
++	if (sysfs_create_group(&vnic->class_dev_info.class_dev.kobj,
+ 			       &vnic_dev_attr_group)) {
+ 		SYS_ERROR("create_vnic: error in creating"
+ 			  "vnic attr group\n");
+@@ -540,11 +538,11 @@ static struct vnic *create_vnic(struct path_param *param)
+ 
+ 	return vnic;
+ err_stats:
+-	sysfs_remove_group(&vnic->dev_info.dev.kobj,
++	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
+ 			   &vnic_dev_attr_group);
+ err_attr:
+-	device_unregister(&vnic->dev_info.dev);
+-	wait_for_completion(&vnic->dev_info.released);
++	class_device_unregister(&vnic->class_dev_info.class_dev);
++	wait_for_completion(&vnic->class_dev_info.released);
+ free_vnic:
+ 	list_del(&vnic->list_ptrs);
+ 	kfree(vnic);
+@@ -553,9 +551,8 @@ free_vnic_config:
+ 	return NULL;
+ }
+ 
+-static ssize_t vnic_sysfs_force_failover(struct device *dev,
+-					struct device_attribute *dev_attr, const char *buf,
+-					size_t count)
++static ssize_t vnic_sysfs_force_failover(struct class_device *class_dev,
++				  const char *buf, size_t count)
+ {
+ 	struct vnic *vnic;
+ 	struct list_head *ptr;
+@@ -579,11 +576,10 @@ static ssize_t vnic_sysfs_force_failover(struct device *dev,
+ 	return ret;
+ }
+ 
+-DEVICE_ATTR(force_failover, S_IWUSR, NULL, vnic_sysfs_force_failover);
++CLASS_DEVICE_ATTR(force_failover, S_IWUSR, NULL, vnic_sysfs_force_failover);
+ 
+-static ssize_t vnic_sysfs_unfailover(struct device *dev,
+-					struct device_attribute *dev_attr, const char *buf,
+-					size_t count)
++static ssize_t vnic_sysfs_unfailover(struct class_device *class_dev,
++			      const char *buf, size_t count)
+ {
+ 	struct vnic *vnic;
+ 	struct list_head *ptr;
+@@ -607,9 +603,9 @@ static ssize_t vnic_sysfs_unfailover(struct device *dev,
+ 	return ret;
+ }
+ 
+-DEVICE_ATTR(unfailover, S_IWUSR, NULL, vnic_sysfs_unfailover);
++CLASS_DEVICE_ATTR(unfailover, S_IWUSR, NULL, vnic_sysfs_unfailover);
+ 
+-static ssize_t vnic_delete(struct device *dev, struct device_attribute *dev_attr,
++static ssize_t vnic_delete(struct class_device *class_dev,
+ 			   const char *buf, size_t count)
+ {
+ 	struct vnic *vnic;
+@@ -634,13 +630,14 @@ static ssize_t vnic_delete(struct device *dev, struct device_attribute *dev_attr
+ 	return ret;
+ }
+ 
+-DEVICE_ATTR(delete_vnic, S_IWUSR, NULL, vnic_delete);
++CLASS_DEVICE_ATTR(delete_vnic, S_IWUSR, NULL, vnic_delete);
+ 
+-static ssize_t show_viport_state(struct device *dev,
+-				 struct device_attribute *dev_attr, char *buf)
++static ssize_t show_viport_state(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct class_dev_info *info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
++	struct netpath *path =
++	    container_of(info, struct netpath, class_dev_info);
+ 	switch (path->viport->state) {
+ 	case VIPORT_DISCONNECTED:
+ 		return sprintf(buf, "VIPORT_DISCONNECTED\n");
+@@ -652,13 +649,14 @@ static ssize_t show_viport_state(struct device *dev,
+ 
+ }
+ 
+-static DEVICE_ATTR(viport_state, S_IRUGO, show_viport_state, NULL);
++static CLASS_DEVICE_ATTR(viport_state, S_IRUGO, show_viport_state, NULL);
+ 
+-static ssize_t show_link_state(struct device *dev,
+-			       struct device_attribute *dev_attr, char *buf)
++static ssize_t show_link_state(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct class_dev_info *info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
++	struct netpath *path =
++	    container_of(info, struct netpath, class_dev_info);
+ 
+ 	switch (path->viport->link_state) {
+ 	case LINK_UNINITIALIZED:
+@@ -739,14 +737,15 @@ static ssize_t show_link_state(struct device *dev,
+ 	}
+ 
+ }
+-static DEVICE_ATTR(link_state, S_IRUGO, show_link_state, NULL);
++static CLASS_DEVICE_ATTR(link_state, S_IRUGO, show_link_state, NULL);
+ 
+-static ssize_t show_heartbeat(struct device *dev,
+-			      struct device_attribute *dev_attr, char *buf)
++static ssize_t show_heartbeat(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++	    container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++	    container_of(info, struct netpath, class_dev_info);
+ 
+ 	/* hb_inteval is in jiffies, convert it back to
+ 	 * 1/100ths of a second
+@@ -755,20 +754,21 @@ static ssize_t show_heartbeat(struct device *dev,
+ 		(jiffies_to_msecs(path->viport->config->hb_interval)/10));
+ }
+ 
+-static DEVICE_ATTR(heartbeat, S_IRUGO, show_heartbeat, NULL);
++static CLASS_DEVICE_ATTR(heartbeat, S_IRUGO, show_heartbeat, NULL);
+ 
+-static ssize_t show_ioc_guid(struct device *dev,
+-			     struct device_attribute *dev_attr, char *buf)
++static ssize_t show_ioc_guid(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++		container_of(info, struct netpath, class_dev_info);
+ 
+ 	return sprintf(buf, "%llx\n",
+ 				__be64_to_cpu(path->viport->config->ioc_guid));
+ }
+ 
+-static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
++static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
+ 
+ static inline void get_dgid_string(u8 *dgid, char *buf)
+ {
+@@ -783,64 +783,68 @@ static inline void get_dgid_string(u8 *dgid, char *buf)
+ 	strcat(buf, "\n");
+ }
+ 
+-static ssize_t show_dgid(struct device *dev,
+-			 struct device_attribute *dev_attr, char *buf)
++static ssize_t show_dgid(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++		container_of(info, struct netpath, class_dev_info);
+ 
+ 	get_dgid_string(path->viport->config->path_info.path.dgid.raw, buf);
+ 
+ 	return strlen(buf);
+ }
+ 
+-static DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL);
++static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL);
+ 
+-static ssize_t show_pkey(struct device *dev,
+-			 struct device_attribute *dev_attr, char *buf)
++static ssize_t show_pkey(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++		container_of(info, struct netpath, class_dev_info);
+ 
+ 	return sprintf(buf, "%x\n", path->viport->config->path_info.path.pkey);
+ }
+ 
+-static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
++static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
+ 
+-static ssize_t show_hca_info(struct device *dev,
+-			     struct device_attribute *dev_attr, char *buf)
++static ssize_t show_hca_info(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++		container_of(info, struct netpath, class_dev_info);
+ 
+ 	return sprintf(buf, "vnic-%s-%d\n", path->viport->config->ibdev->name,
+ 						path->viport->config->port);
+ }
+ 
+-static DEVICE_ATTR(hca_info, S_IRUGO, show_hca_info, NULL);
++static CLASS_DEVICE_ATTR(hca_info, S_IRUGO, show_hca_info, NULL);
+ 
+-static ssize_t show_ioc_string(struct device *dev,
+-			       struct device_attribute *dev_attr, char *buf)
++static ssize_t show_ioc_string(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++		container_of(info, struct netpath, class_dev_info);
+ 
+ 	return sprintf(buf, "%s\n", path->viport->config->ioc_string);
+ }
+ 
+-static  DEVICE_ATTR(ioc_string, S_IRUGO, show_ioc_string, NULL);
++static  CLASS_DEVICE_ATTR(ioc_string, S_IRUGO, show_ioc_string, NULL);
+ 
+-static ssize_t show_multicast_state(struct device *dev,
+-				    struct device_attribute *dev_attr,
+-				    char *buf)
++static ssize_t show_multicast_state(struct class_device *class_dev, char *buf)
+ {
+-	struct dev_info *info =	container_of(dev, struct dev_info, dev);
++	struct class_dev_info *info =
++		container_of(class_dev, struct class_dev_info, class_dev);
+ 
+-	struct netpath *path = container_of(info, struct netpath, dev_info);
++	struct netpath *path =
++		container_of(info, struct netpath, class_dev_info);
+ 
+ 	if (!(path->viport->features_supported & VNIC_FEAT_INBOUND_IB_MC))
+ 		return sprintf(buf, "feature not enabled\n");
+@@ -871,18 +875,18 @@ static ssize_t show_multicast_state(struct device *dev,
+ 	return sprintf(buf, "invalid state\n");
+ }
+ 
+-static  DEVICE_ATTR(multicast_state, S_IRUGO, show_multicast_state, NULL);
++static  CLASS_DEVICE_ATTR(multicast_state, S_IRUGO, show_multicast_state, NULL);
+ 
+ static struct attribute *vnic_path_attrs[] = {
+-	&dev_attr_viport_state.attr,
+-	&dev_attr_link_state.attr,
+-	&dev_attr_heartbeat.attr,
+-	&dev_attr_ioc_guid.attr,
+-	&dev_attr_dgid.attr,
+-	&dev_attr_pkey.attr,
+-	&dev_attr_hca_info.attr,
+-	&dev_attr_ioc_string.attr,
+-	&dev_attr_multicast_state.attr,
++	&class_device_attr_viport_state.attr,
++	&class_device_attr_link_state.attr,
++	&class_device_attr_heartbeat.attr,
++	&class_device_attr_ioc_guid.attr,
++	&class_device_attr_dgid.attr,
++	&class_device_attr_pkey.attr,
++	&class_device_attr_hca_info.attr,
++	&class_device_attr_ioc_string.attr,
++	&class_device_attr_multicast_state.attr,
+ 	NULL
+ };
+ 
+@@ -893,19 +897,20 @@ struct attribute_group vnic_path_attr_group = {
+ 
+ static int setup_path_class_files(struct netpath *path, char *name)
+ {
+-	init_completion(&path->dev_info.released);
++	init_completion(&path->class_dev_info.released);
+ 
+-	path->dev_info.dev.class = NULL;
+-	path->dev_info.dev.parent = &path->parent->dev_info.dev;
+-	path->dev_info.dev.release = vnic_release_dev;
+-	snprintf(path->dev_info.dev.bus_id, BUS_ID_SIZE, name);
++	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 (device_register(&path->dev_info.dev)) {
++	if (class_device_register(&path->class_dev_info.class_dev)) {
+ 		SYS_ERROR("error in registering path class dev\n");
+ 		goto out;
+ 	}
+ 
+-	if (sysfs_create_group(&path->dev_info.dev.kobj,
++	if (sysfs_create_group(&path->class_dev_info.class_dev.kobj,
+ 			       &vnic_path_attr_group)) {
+ 		SYS_ERROR("error in creating vnic path group attrs");
+ 		goto err_path;
+@@ -914,8 +919,8 @@ static int setup_path_class_files(struct netpath *path, char *name)
+ 	return 0;
+ 
+ err_path:
+-	device_unregister(&path->dev_info.dev);
+-	wait_for_completion(&path->dev_info.released);
++	class_device_unregister(&path->class_dev_info.class_dev);
++	wait_for_completion(&path->class_dev_info.released);
+ out:
+ 	return -1;
+ 
+@@ -1046,13 +1051,13 @@ static ssize_t update_params_and_connect(struct path_param *params,
+ 	}
+ }
+ 
+-static ssize_t vnic_create_primary(struct device *dev,
+-				   struct device_attribute *dev_attr,
++static ssize_t vnic_create_primary(struct class_device *class_dev,
+ 				   const char *buf, size_t count)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
++	struct class_dev_info *cdev =
++	    container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic_ib_port *target =
+-	    container_of(info, struct vnic_ib_port, pdev_info);
++	    container_of(cdev, struct vnic_ib_port, cdev_info);
+ 
+ 	struct path_param param;
+ 	int ret = -EINVAL;
+@@ -1114,15 +1119,15 @@ out:
+ 	return ret;
+ }
+ 
+-DEVICE_ATTR(create_primary, S_IWUSR, NULL, vnic_create_primary);
++CLASS_DEVICE_ATTR(create_primary, S_IWUSR, NULL, vnic_create_primary);
+ 
+-static ssize_t vnic_create_secondary(struct device *dev,
+-				     struct device_attribute *dev_attr,
++static ssize_t vnic_create_secondary(struct class_device *class_dev,
+ 				     const char *buf, size_t count)
+ {
+-	struct dev_info *info = container_of(dev, struct dev_info, dev);
++	struct class_dev_info *cdev =
++	    container_of(class_dev, struct class_dev_info, class_dev);
+ 	struct vnic_ib_port *target =
+-	    container_of(info, struct vnic_ib_port, pdev_info);
++	    container_of(cdev, struct vnic_ib_port, cdev_info);
+ 
+ 	struct path_param param;
+ 	struct vnic *vnic = NULL;
+@@ -1186,4 +1191,4 @@ out:
+ 	return ret;
+ }
+ 
+-DEVICE_ATTR(create_secondary, S_IWUSR, NULL, vnic_create_secondary);
++CLASS_DEVICE_ATTR(create_secondary, S_IWUSR, NULL, vnic_create_secondary);
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h
+@@ -33,21 +33,19 @@
+ #ifndef VNIC_SYS_H_INCLUDED
+ #define VNIC_SYS_H_INCLUDED
+ 
+-struct dev_info {
+-	struct device		dev;
++struct class_dev_info {
++	struct class_device	class_dev;
+ 	struct completion	released;
+ };
+ 
+ extern struct class vnic_class;
+-extern struct dev_info interface_dev;
++extern struct class_dev_info interface_cdev;
+ extern struct attribute_group vnic_dev_attr_group;
+ extern struct attribute_group vnic_path_attr_group;
+-extern struct device_attribute dev_attr_create_primary;
+-extern struct device_attribute dev_attr_create_secondary;
+-extern struct device_attribute dev_attr_delete_vnic;
+-extern struct device_attribute dev_attr_force_failover;
+-extern struct device_attribute dev_attr_unfailover;
+-
+-extern void vnic_release_dev(struct device *dev);
++extern struct class_device_attribute class_device_attr_create_primary;
++extern struct class_device_attribute class_device_attr_create_secondary;
++extern struct class_device_attribute class_device_attr_delete_vnic;
++extern struct class_device_attribute class_device_attr_force_failover;
++extern struct class_device_attribute class_device_attr_unfailover;
+ 
+ #endif	/*VNIC_SYS_H_INCLUDED*/
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/qlgc_vnic_02_dev_stats.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/qlgc_vnic_02_dev_stats.patch
new file mode 100644
index 0000000..0c86da1
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/qlgc_vnic_02_dev_stats.patch
@@ -0,0 +1,46 @@
+---
+ drivers/infiniband/ulp/qlgc_vnic/vnic_main.c |    6 +++---
+ drivers/infiniband/ulp/qlgc_vnic/vnic_main.h |    1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
+@@ -204,13 +204,13 @@ static struct net_device_stats *vnic_get
+ 	if (np && np->viport) {
+ 		atomic_inc(&np->viport->reference_count);
+ 		spin_unlock_irqrestore(&vnic->current_path_lock, flags);
+-		viport_get_stats(np->viport, &vnic->netdevice->stats);
++		viport_get_stats(np->viport, &vnic->stats);
+ 		atomic_dec(&np->viport->reference_count);
+ 		wake_up(&np->viport->reference_queue);
+ 	} else
+ 		spin_unlock_irqrestore(&vnic->current_path_lock, flags);
+ 
+-	return &vnic->netdevice->stats;
++	return &vnic->stats;
+ }
+ 
+ static int vnic_open(struct net_device *device)
+@@ -259,7 +259,7 @@ static int vnic_hard_start_xmit(struct s
+ 	if (ret) {
+ 		vnic_xmit_fail_stats(vnic);
+ 		dev_kfree_skb_any(skb);
+-		vnic->netdevice->stats.tx_dropped++;
++		vnic->stats.tx_dropped++;
+ 		goto out;
+ 	}
+ 
+Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
++++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
+@@ -102,6 +102,7 @@ struct vnic {
+ 	int				forced_failover;
+ 	int				failed_over;
+ 	int				mac_set;
++	struct net_device_stats 	stats;
+ 	struct net_device		*netdevice;
+ 	struct class_dev_info		class_dev_info;
+ 	struct dev_mc_list		*mc_list;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/rds_to_2_6_26.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/rds_to_2_6_26.patch
new file mode 100644
index 0000000..c4503f3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/rds_to_2_6_26.patch
@@ -0,0 +1,18 @@
+---
+ net/rds/connection.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+Index: ofed_kernel/net/rds/connection.c
+===================================================================
+--- ofed_kernel.orig/net/rds/connection.c
++++ ofed_kernel/net/rds/connection.c
+@@ -51,8 +51,7 @@ static struct kmem_cache *rds_conn_slab;
+ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
+ {
+ 	/* Pass NULL, don't need struct net for hash */
+-	unsigned long hash = inet_ehashfn(NULL,
+-					  be32_to_cpu(laddr), 0, 
++	unsigned long hash = inet_ehashfn(be32_to_cpu(laddr), 0,
+ 					  be32_to_cpu(faddr), 0);
+ 	return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
+ }
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/rnfs_fs.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/rnfs_fs.patch
new file mode 100644
index 0000000..a7687ad
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/rnfs_fs.patch
@@ -0,0 +1,2841 @@
+diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
+index 03acfd6..992e4aa 100644
+--- a/drivers/infiniband/core/Makefile
++++ b/drivers/infiniband/core/Makefile
+@@ -31,4 +31,4 @@ ib_ucm-y :=			ucm.o
+ 
+ ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_marshall.o
+ 
+-ib_core-y +=			genalloc.o
++ib_core-y +=			genalloc.o namespace.o writeback.o
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 8ea4d01..5d49041 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -39,7 +39,7 @@
+ #include <linux/init.h>
+ #include <linux/mutex.h>
+ #include <linux/workqueue.h>
+-
++#include <linux/mount.h>
+ #include "core_priv.h"
+ 
+ MODULE_AUTHOR("Roland Dreier");
+@@ -735,6 +735,10 @@ static int __init ib_core_init(void)
+ 		dma_map_sg_hp_wa = 1;
+ #endif
+ 
++	ret = init_mnt_writers();
++	if (ret)
++		printk(KERN_WARNING "Couldn't init mnt_writers\n");
++
+ 	ret = ib_sysfs_setup();
+ 	if (ret)
+ 		printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
+diff --git a/drivers/infiniband/core/namespace.c b/drivers/infiniband/core/namespace.c
+new file mode 100644
+index 0000000..de57f8b
+--- /dev/null
++++ b/drivers/infiniband/core/namespace.c
+@@ -0,0 +1 @@
++#include "src/namespace.c"
+diff --git a/drivers/infiniband/core/writeback.c b/drivers/infiniband/core/writeback.c
+new file mode 100644
+index 0000000..b838ead
+--- /dev/null
++++ b/drivers/infiniband/core/writeback.c
+@@ -0,0 +1 @@
++#include "src/writeback.c"
+diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
+index cc91227..262397b 100644
+--- a/fs/exportfs/expfs.c
++++ b/fs/exportfs/expfs.c
+@@ -361,11 +361,14 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ 	const struct export_operations *nop = mnt->mnt_sb->s_export_op;
+ 	struct dentry *result, *alias;
+ 	int err;
++	__u32 objp[2];
+ 
++	objp[0] = fid->i32.ino;
++	objp[1] = fid->i32.gen;
+ 	/*
+ 	 * Try to get any dentry for the given file handle from the filesystem.
+ 	 */
+-	result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
++	result = nop->get_dentry(mnt->mnt_sb, &objp);
+ 	if (!result)
+ 		result = ERR_PTR(-ESTALE);
+ 	if (IS_ERR(result))
+@@ -417,11 +420,10 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ 		 * file handle.  If this fails we'll have to give up.
+ 		 */
+ 		err = -ESTALE;
+-		if (!nop->fh_to_parent)
++		if (!nop->get_parent)
+ 			goto err_result;
+ 
+-		target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
+-				fh_len, fileid_type);
++		target_dir = nop->get_parent(result);
+ 		if (!target_dir)
+ 			goto err_result;
+ 		err = PTR_ERR(target_dir);
+diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
+index 0b45fd3..2c45814 100644
+--- a/fs/lockd/clntlock.c
++++ b/fs/lockd/clntlock.c
+@@ -168,7 +168,7 @@ __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock
+ 			continue;
+ 		if (!nlm_cmp_addr(&block->b_host->h_addr, addr))
+ 			continue;
+-		if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0)
++		if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_dentry->d_inode), fh) != 0)
+ 			continue;
+ 		/* Alright, we found a lock. Set the return status
+ 		 * and wake up the caller
+diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
+index 31668b6..8c72d30 100644
+--- a/fs/lockd/clntproc.c
++++ b/fs/lockd/clntproc.c
+@@ -128,12 +128,12 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
+ 
+ 	nlmclnt_next_cookie(&argp->cookie);
+ 	argp->state   = nsm_local_state;
+-	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_path.dentry->d_inode), sizeof(struct nfs_fh));
+-	lock->caller  = utsname()->nodename;
++	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
++	lock->caller  = system_utsname.nodename;
+ 	lock->oh.data = req->a_owner;
+ 	lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
+ 				(unsigned int)fl->fl_u.nfs_fl.owner->pid,
+-				utsname()->nodename);
++				system_utsname.nodename);
+ 	lock->svid = fl->fl_u.nfs_fl.owner->pid;
+ 	lock->fl.fl_start = fl->fl_start;
+ 	lock->fl.fl_end = fl->fl_end;
+diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
+index e4d5635..771edc1 100644
+--- a/fs/lockd/mon.c
++++ b/fs/lockd/mon.c
+@@ -194,7 +194,7 @@ static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
+  */
+ static __be32 *xdr_encode_my_id(__be32 *p, struct nsm_args *argp)
+ {
+-	p = xdr_encode_nsm_string(p, utsname()->nodename);
++	p = xdr_encode_nsm_string(p, system_utsname.nodename);
+ 	if (!p)
+ 		return ERR_PTR(-EIO);
+ 
+diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
+index cf0d5c2..2e6ec1b 100644
+--- a/fs/lockd/svclock.c
++++ b/fs/lockd/svclock.c
+@@ -304,7 +304,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
+ {
+ 	locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
+ 	memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
+-	call->a_args.lock.caller = utsname()->nodename;
++	call->a_args.lock.caller = system_utsname.nodename;
+ 	call->a_args.lock.oh.len = lock->oh.len;
+ 
+ 	/* set default data area */
+@@ -367,8 +367,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
+ 	__be32			ret;
+ 
+ 	dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_type, lock->fl.fl_pid,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end,
+@@ -417,11 +417,18 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
+ 			ret = nlm_granted;
+ 			goto out;
+ 		case -EAGAIN:
+-			ret = nlm_lck_denied;
+-			goto out;
++			if (wait) {
++				ret = nlm_lck_blocked;
++				break;
++			} else {
++				ret = nlm_lck_denied;
++				goto out;
++			}
+ 		case FILE_LOCK_DEFERRED:
+-			if (wait)
++			if (wait) {
++				ret = nlm_lck_blocked;
+ 				break;
++			}
+ 			/* Filesystem lock operation is in progress
+ 			   Add it to the queue waiting for callback */
+ 			ret = nlmsvc_defer_lock_rqst(rqstp, block);
+@@ -434,8 +441,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
+ 			goto out;
+ 	}
+ 
+-	ret = nlm_lck_blocked;
+-
+ 	/* Append to list of blocked */
+ 	nlmsvc_insert_block(block, NLM_NEVER);
+ out:
+@@ -458,8 +463,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
+ 	__be32			ret;
+ 
+ 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_type,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end);
+@@ -547,8 +552,8 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
+ 	int	error;
+ 
+ 	dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_pid,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end);
+@@ -576,8 +581,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
+ 	int status = 0;
+ 
+ 	dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_pid,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end);
+@@ -595,63 +600,6 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
+ }
+ 
+ /*
+- * This is a callback from the filesystem for VFS file lock requests.
+- * It will be used if fl_grant is defined and the filesystem can not
+- * respond to the request immediately.
+- * For GETLK request it will copy the reply to the nlm_block.
+- * For SETLK or SETLKW request it will get the local posix lock.
+- * In all cases it will move the block to the head of nlm_blocked q where
+- * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
+- * deferred rpc for GETLK and SETLK.
+- */
+-static void
+-nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
+-			     int result)
+-{
+-	block->b_flags |= B_GOT_CALLBACK;
+-	if (result == 0)
+-		block->b_granted = 1;
+-	else
+-		block->b_flags |= B_TIMED_OUT;
+-	if (conf) {
+-		if (block->b_fl)
+-			__locks_copy_lock(block->b_fl, conf);
+-	}
+-}
+-
+-static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf,
+-					int result)
+-{
+-	struct nlm_block *block;
+-	int rc = -ENOENT;
+-
+-	lock_kernel();
+-	list_for_each_entry(block, &nlm_blocked, b_list) {
+-		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
+-			dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
+-							block, block->b_flags);
+-			if (block->b_flags & B_QUEUED) {
+-				if (block->b_flags & B_TIMED_OUT) {
+-					rc = -ENOLCK;
+-					break;
+-				}
+-				nlmsvc_update_deferred_block(block, conf, result);
+-			} else if (result == 0)
+-				block->b_granted = 1;
+-
+-			nlmsvc_insert_block(block, 0);
+-			svc_wake_up(block->b_daemon);
+-			rc = 0;
+-			break;
+-		}
+-	}
+-	unlock_kernel();
+-	if (rc == -ENOENT)
+-		printk(KERN_WARNING "lockd: grant for unknown block\n");
+-	return rc;
+-}
+-
+-/*
+  * Unblock a blocked lock request. This is a callback invoked from the
+  * VFS layer when a lock on which we blocked is removed.
+  *
+@@ -683,7 +631,6 @@ static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
+ struct lock_manager_operations nlmsvc_lock_operations = {
+ 	.fl_compare_owner = nlmsvc_same_owner,
+ 	.fl_notify = nlmsvc_notify_blocked,
+-	.fl_grant = nlmsvc_grant_deferred,
+ };
+ 
+ /*
+diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
+index 198b4e5..2109091 100644
+--- a/fs/lockd/svcsubs.c
++++ b/fs/lockd/svcsubs.c
+@@ -45,7 +45,7 @@ static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
+ 
+ static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
+ {
+-	struct inode *inode = file->f_file->f_path.dentry->d_inode;
++	struct inode *inode = file->f_file->f_dentry->d_inode;
+ 
+ 	dprintk("lockd: %s %s/%ld\n",
+ 		msg, inode->i_sb->s_id, inode->i_ino);
+@@ -396,7 +396,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file)
+ {
+ 	struct super_block *sb = datap;
+ 
+-	return sb == file->f_file->f_path.mnt->mnt_sb;
++	return sb == file->f_file->f_vfsmnt->mnt_sb;
+ }
+ 
+ /**
+diff --git a/fs/nfs/client.c b/fs/nfs/client.c
+index 5ee23e7..afbb834 100644
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -248,6 +248,7 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
+ 				(const struct sockaddr_in6 *)sa2);
+ 	}
+ 	BUG();
++	return -EINVAL;
+ }
+ 
+ /*
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index 74f92b7..90d0a97 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -66,7 +66,7 @@ const struct file_operations nfs_dir_operations = {
+ 	.fsync		= nfs_fsync_dir,
+ };
+ 
+-const struct inode_operations nfs_dir_inode_operations = {
++struct inode_operations nfs_dir_inode_operations = {
+ 	.create		= nfs_create,
+ 	.lookup		= nfs_lookup,
+ 	.link		= nfs_link,
+@@ -82,7 +82,7 @@ const struct inode_operations nfs_dir_inode_operations = {
+ };
+ 
+ #ifdef CONFIG_NFS_V3
+-const struct inode_operations nfs3_dir_inode_operations = {
++struct inode_operations nfs3_dir_inode_operations = {
+ 	.create		= nfs_create,
+ 	.lookup		= nfs_lookup,
+ 	.link		= nfs_link,
+@@ -105,7 +105,7 @@ const struct inode_operations nfs3_dir_inode_operations = {
+ #ifdef CONFIG_NFS_V4
+ 
+ static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
+-const struct inode_operations nfs4_dir_inode_operations = {
++struct inode_operations nfs4_dir_inode_operations = {
+ 	.create		= nfs_create,
+ 	.lookup		= nfs_atomic_lookup,
+ 	.link		= nfs_link,
+@@ -134,8 +134,8 @@ nfs_opendir(struct inode *inode, struct file *filp)
+ 	int res;
+ 
+ 	dfprintk(FILE, "NFS: open dir(%s/%s)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name);
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name);
+ 
+ 	nfs_inc_stats(inode, NFSIOS_VFSOPEN);
+ 
+@@ -175,7 +175,7 @@ static
+ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
+ {
+ 	struct file	*file = desc->file;
+-	struct inode	*inode = file->f_path.dentry->d_inode;
++	struct inode	*inode = file->f_dentry->d_inode;
+ 	struct rpc_cred	*cred = nfs_file_cred(file);
+ 	unsigned long	timestamp;
+ 	int		error;
+@@ -186,7 +186,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
+ 
+  again:
+ 	timestamp = jiffies;
+-	error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page,
++	error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page,
+ 					  NFS_SERVER(inode)->dtsize, desc->plus);
+ 	if (error < 0) {
+ 		/* We requested READDIRPLUS, but the server doesn't grok it */
+@@ -311,7 +311,7 @@ int find_dirent_index(nfs_readdir_descriptor_t *desc)
+ static inline
+ int find_dirent_page(nfs_readdir_descriptor_t *desc)
+ {
+-	struct inode	*inode = desc->file->f_path.dentry->d_inode;
++	struct inode	*inode = desc->file->f_dentry->d_inode;
+ 	struct page	*page;
+ 	int		status;
+ 
+@@ -467,7 +467,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
+ 		     filldir_t filldir)
+ {
+ 	struct file	*file = desc->file;
+-	struct inode	*inode = file->f_path.dentry->d_inode;
++	struct inode	*inode = file->f_dentry->d_inode;
+ 	struct rpc_cred	*cred = nfs_file_cred(file);
+ 	struct page	*page = NULL;
+ 	int		status;
+@@ -482,7 +482,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
+ 		goto out;
+ 	}
+ 	timestamp = jiffies;
+-	status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred,
++	status = NFS_PROTO(inode)->readdir(file->f_dentry, cred,
+ 						*desc->dir_cookie, page,
+ 						NFS_SERVER(inode)->dtsize,
+ 						desc->plus);
+@@ -520,7 +520,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
+  */
+ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+-	struct dentry	*dentry = filp->f_path.dentry;
++	struct dentry	*dentry = filp->f_dentry;
+ 	struct inode	*inode = dentry->d_inode;
+ 	nfs_readdir_descriptor_t my_desc,
+ 			*desc = &my_desc;
+@@ -601,7 +601,7 @@ out:
+ 
+ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
+ {
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 	struct inode *inode = dentry->d_inode;
+ 
+ 	dfprintk(FILE, "NFS: llseek dir(%s/%s, %lld, %d)\n",
+@@ -973,7 +973,7 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd)
+ 	if (nd->flags & LOOKUP_DIRECTORY)
+ 		return 0;
+ 	/* Are we trying to write to a read only partition? */
+-	if (__mnt_is_readonly(nd->path.mnt) &&
++	if (__mnt_is_readonly(nd->mnt) &&
+ 	    (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+ 		return 0;
+ 	return 1;
+@@ -1083,7 +1083,7 @@ no_open:
+ 
+ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
+ {
+-	struct dentry *parent = desc->file->f_path.dentry;
++	struct dentry *parent = desc->file->f_dentry;
+ 	struct inode *dir = parent->d_inode;
+ 	struct nfs_entry *entry = desc->entry;
+ 	struct dentry *dentry, *alias;
+@@ -1907,7 +1907,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
+ 	return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
+ }
+ 
+-int nfs_permission(struct inode *inode, int mask)
++int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+ {
+ 	struct rpc_cred *cred;
+ 	int res = 0;
+@@ -1917,7 +1917,7 @@ int nfs_permission(struct inode *inode, int mask)
+ 	if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
+ 		goto out;
+ 	/* Is this sys_access() ? */
+-	if (mask & MAY_ACCESS)
++	if (nd != NULL && (nd->flags & LOOKUP_ACCESS))
+ 		goto force_lookup;
+ 
+ 	switch (inode->i_mode & S_IFMT) {
+@@ -1926,7 +1926,8 @@ int nfs_permission(struct inode *inode, int mask)
+ 		case S_IFREG:
+ 			/* NFSv4 has atomic_open... */
+ 			if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
+-					&& (mask & MAY_OPEN))
++					&& nd != NULL
++					&& (nd->flags & LOOKUP_OPEN))
+ 				goto out;
+ 			break;
+ 		case S_IFDIR:
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index 08f6b04..91f5069 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -116,7 +116,7 @@ static inline int put_dreq(struct nfs_direct_req *dreq)
+ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs)
+ {
+ 	dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n",
+-			iocb->ki_filp->f_path.dentry->d_name.name,
++			iocb->ki_filp->f_dentry->d_name.name,
+ 			(long long) pos, nr_segs);
+ 
+ 	return -EINVAL;
+@@ -891,8 +891,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
+ 	nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
+ 
+ 	dfprintk(FILE, "NFS: direct read(%s/%s, %zd@%Ld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
++		file->f_dentry->d_parent->d_name.name,
++		file->f_dentry->d_name.name,
+ 		count, (long long) pos);
+ 
+ 	retval = 0;
+@@ -948,8 +948,8 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
+ 	nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
+ 
+ 	dfprintk(FILE, "NFS: direct write(%s/%s, %zd@%Ld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
++		file->f_dentry->d_parent->d_name.name,
++		file->f_dentry->d_name.name,
+ 		count, (long long) pos);
+ 
+ 	retval = generic_write_checks(file, &pos, &count, 0);
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index 7846065..7962293 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -45,16 +45,13 @@ static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
+ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
+ 					struct pipe_inode_info *pipe,
+ 					size_t count, unsigned int flags);
+-static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
+-				unsigned long nr_segs, loff_t pos);
+-static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
+-				unsigned long nr_segs, loff_t pos);
++static ssize_t nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos);
++static ssize_t nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos);
+ static int  nfs_file_flush(struct file *, fl_owner_t id);
+ static int  nfs_file_fsync(struct file *, struct dentry *dentry, int datasync);
+ static int nfs_check_flags(int flags);
+ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
+ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
+-static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
+ 
+ static struct vm_operations_struct nfs_file_vm_ops;
+ 
+@@ -77,17 +74,16 @@ const struct file_operations nfs_file_operations = {
+ 	.flock		= nfs_flock,
+ 	.splice_read	= nfs_file_splice_read,
+ 	.check_flags	= nfs_check_flags,
+-	.setlease	= nfs_setlease,
+ };
+ 
+-const struct inode_operations nfs_file_inode_operations = {
++struct inode_operations nfs_file_inode_operations = {
+ 	.permission	= nfs_permission,
+ 	.getattr	= nfs_getattr,
+ 	.setattr	= nfs_setattr,
+ };
+ 
+ #ifdef CONFIG_NFS_V3
+-const struct inode_operations nfs3_file_inode_operations = {
++struct inode_operations nfs3_file_inode_operations = {
+ 	.permission	= nfs_permission,
+ 	.getattr	= nfs_getattr,
+ 	.setattr	= nfs_setattr,
+@@ -120,8 +116,8 @@ nfs_file_open(struct inode *inode, struct file *filp)
+ 	int res;
+ 
+ 	dprintk("NFS: open file(%s/%s)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name);
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name);
+ 
+ 	res = nfs_check_flags(filp->f_flags);
+ 	if (res)
+@@ -135,7 +131,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
+ static int
+ nfs_file_release(struct inode *inode, struct file *filp)
+ {
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 
+ 	dprintk("NFS: release(%s/%s)\n",
+ 			dentry->d_parent->d_name.name,
+@@ -178,11 +174,9 @@ force_reval:
+ 
+ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
+ {
+-	loff_t loff;
+-
+ 	dprintk("NFS: llseek file(%s/%s, %lld, %d)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name,
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name,
+ 			offset, origin);
+ 
+ 	/* origin == SEEK_END => we must revalidate the cached file length */
+@@ -192,10 +186,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
+ 		if (retval < 0)
+ 			return (loff_t)retval;
+ 	}
+-	lock_kernel();	/* BKL needed? */
+-	loff = generic_file_llseek_unlocked(filp, offset, origin);
+-	unlock_kernel();
+-	return loff;
++	return remote_llseek(filp, offset, origin);
+ }
+ 
+ /*
+@@ -230,7 +221,7 @@ static int
+ nfs_file_flush(struct file *file, fl_owner_t id)
+ {
+ 	struct nfs_open_context *ctx = nfs_file_open_context(file);
+-	struct dentry	*dentry = file->f_path.dentry;
++	struct dentry	*dentry = file->f_dentry;
+ 	struct inode	*inode = dentry->d_inode;
+ 	int		status;
+ 
+@@ -250,16 +241,15 @@ nfs_file_flush(struct file *file, fl_owner_t id)
+ }
+ 
+ static ssize_t
+-nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
+-		unsigned long nr_segs, loff_t pos)
++nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
+ {
+-	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
++	struct dentry * dentry = iocb->ki_filp->f_dentry;
+ 	struct inode * inode = dentry->d_inode;
+ 	ssize_t result;
+-	size_t count = iov_length(iov, nr_segs);
++	struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+ 
+ 	if (iocb->ki_filp->f_flags & O_DIRECT)
+-		return nfs_file_direct_read(iocb, iov, nr_segs, pos);
++		return nfs_file_direct_read(iocb, &local_iov, 1, pos);
+ 
+ 	dprintk("NFS: read(%s/%s, %lu@%lu)\n",
+ 		dentry->d_parent->d_name.name, dentry->d_name.name,
+@@ -268,7 +258,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
+ 	result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
+ 	nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
+ 	if (!result)
+-		result = generic_file_aio_read(iocb, iov, nr_segs, pos);
++		result = generic_file_aio_read(iocb, buf, count, pos);
+ 	return result;
+ }
+ 
+@@ -277,7 +267,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
+ 		     struct pipe_inode_info *pipe, size_t count,
+ 		     unsigned int flags)
+ {
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 	struct inode *inode = dentry->d_inode;
+ 	ssize_t res;
+ 
+@@ -294,7 +284,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
+ static int
+ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
+ {
+-	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *dentry = file->f_dentry;
+ 	struct inode *inode = dentry->d_inode;
+ 	int	status;
+ 
+@@ -337,44 +327,15 @@ nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
+  * If the writer ends up delaying the write, the writer needs to
+  * increment the page use counts until he is done with the page.
+  */
+-static int nfs_write_begin(struct file *file, struct address_space *mapping,
+-			loff_t pos, unsigned len, unsigned flags,
+-			struct page **pagep, void **fsdata)
++static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+ {
+-	int ret;
+-	pgoff_t index;
+-	struct page *page;
+-	index = pos >> PAGE_CACHE_SHIFT;
+-
+-	dfprintk(PAGECACHE, "NFS: write_begin(%s/%s(%ld), %u@%lld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
+-		mapping->host->i_ino, len, (long long) pos);
+-
+-	page = __grab_cache_page(mapping, index);
+-	if (!page)
+-		return -ENOMEM;
+-	*pagep = page;
+-
+-	ret = nfs_flush_incompatible(file, page);
+-	if (ret) {
+-		unlock_page(page);
+-		page_cache_release(page);
+-	}
+-	return ret;
++	return nfs_flush_incompatible(file, page);
+ }
+ 
+-static int nfs_write_end(struct file *file, struct address_space *mapping,
+-			loff_t pos, unsigned len, unsigned copied,
+-			struct page *page, void *fsdata)
++static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+ {
+-	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+ 	int status;
+-
+-	dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
+-		mapping->host->i_ino, len, (long long) pos);
++	unsigned copied = to - offset;
+ 
+ 	/*
+ 	 * Zero any uninitialised parts of the page, and then mark the page
+@@ -382,14 +343,13 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
+ 	 */
+ 	if (!PageUptodate(page)) {
+ 		unsigned pglen = nfs_page_length(page);
+-		unsigned end = offset + len;
+ 
+ 		if (pglen == 0) {
+ 			zero_user_segments(page, 0, offset,
+-					end, PAGE_CACHE_SIZE);
++					to, PAGE_CACHE_SIZE);
+ 			SetPageUptodate(page);
+-		} else if (end >= pglen) {
+-			zero_user_segment(page, end, PAGE_CACHE_SIZE);
++		} else if (to >= pglen) {
++			zero_user_segment(page, to, PAGE_CACHE_SIZE);
+ 			if (offset == 0)
+ 				SetPageUptodate(page);
+ 		} else
+@@ -398,9 +358,6 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
+ 
+ 	status = nfs_updatepage(file, page, offset, copied);
+ 
+-	unlock_page(page);
+-	page_cache_release(page);
+-
+ 	if (status < 0)
+ 		return status;
+ 	return copied;
+@@ -424,34 +381,23 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
+ 	return 0;
+ }
+ 
+-static int nfs_launder_page(struct page *page)
+-{
+-	struct inode *inode = page->mapping->host;
+-
+-	dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
+-		inode->i_ino, (long long)page_offset(page));
+-
+-	return nfs_wb_page(inode, page);
+-}
+-
+ const struct address_space_operations nfs_file_aops = {
+ 	.readpage = nfs_readpage,
+ 	.readpages = nfs_readpages,
+ 	.set_page_dirty = __set_page_dirty_nobuffers,
+ 	.writepage = nfs_writepage,
+ 	.writepages = nfs_writepages,
+-	.write_begin = nfs_write_begin,
+-	.write_end = nfs_write_end,
++	.prepare_write = nfs_prepare_write,
++	.commit_write = nfs_commit_write,
+ 	.invalidatepage = nfs_invalidate_page,
+ 	.releasepage = nfs_release_page,
+ 	.direct_IO = nfs_direct_IO,
+-	.launder_page = nfs_launder_page,
+ };
+ 
+ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+ {
+ 	struct file *filp = vma->vm_file;
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 	unsigned pagelen;
+ 	int ret = -EINVAL;
+ 	struct address_space *mapping;
+@@ -484,7 +430,8 @@ out_unlock:
+ }
+ 
+ static struct vm_operations_struct nfs_file_vm_ops = {
+-	.fault = filemap_fault,
++	.nopage		= filemap_nopage,
++	.populate	= filemap_populate,
+ 	.page_mkwrite = nfs_vm_page_mkwrite,
+ };
+ 
+@@ -500,16 +447,16 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
+ 	return 0;
+ }
+ 
+-static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
+-				unsigned long nr_segs, loff_t pos)
++static ssize_t
++nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
+ {
+-	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
++	struct dentry * dentry = iocb->ki_filp->f_dentry;
+ 	struct inode * inode = dentry->d_inode;
+ 	ssize_t result;
+-	size_t count = iov_length(iov, nr_segs);
++	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
+ 
+ 	if (iocb->ki_filp->f_flags & O_DIRECT)
+-		return nfs_file_direct_write(iocb, iov, nr_segs, pos);
++		return nfs_file_direct_write(iocb, &local_iov, 1, pos);
+ 
+ 	dprintk("NFS: write(%s/%s, %lu@%Ld)\n",
+ 		dentry->d_parent->d_name.name, dentry->d_name.name,
+@@ -532,7 +479,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
+ 		goto out;
+ 
+ 	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
+-	result = generic_file_aio_write(iocb, iov, nr_segs, pos);
++	result = generic_file_aio_write(iocb, buf, count, pos);
+ 	/* Return error values for O_SYNC and IS_SYNC() */
+ 	if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
+ 		int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
+@@ -549,14 +496,19 @@ out_swapfile:
+ 
+ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
+ {
++	struct file_lock cfl;
+ 	struct inode *inode = filp->f_mapping->host;
+ 	int status = 0;
+ 
+ 	lock_kernel();
+ 	/* Try local locking first */
+-	posix_test_lock(filp, fl);
+-	if (fl->fl_type != F_UNLCK) {
++	if (posix_test_lock(filp, fl, &cfl)) {
+ 		/* found a conflict */
++		fl->fl_start = cfl.fl_start;
++		fl->fl_end = cfl.fl_end;
++		fl->fl_type = cfl.fl_type;
++		fl->fl_pid = cfl.fl_pid;
++
+ 		goto out;
+ 	}
+ 
+@@ -662,8 +614,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
+ 	int ret = -ENOLCK;
+ 
+ 	dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name,
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name,
+ 			fl->fl_type, fl->fl_flags,
+ 			(long long)fl->fl_start, (long long)fl->fl_end);
+ 
+@@ -695,8 +647,8 @@ out_err:
+ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+ 	dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name,
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name,
+ 			fl->fl_type, fl->fl_flags);
+ 
+ 	/*
+@@ -718,16 +670,3 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
+ 		return do_unlk(filp, cmd, fl);
+ 	return do_setlk(filp, cmd, fl);
+ }
+-
+-/*
+- * There is no protocol support for leases, so we have no way to implement
+- * them correctly in the face of opens by other clients.
+- */
+-static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
+-{
+-	dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
+-			file->f_path.dentry->d_parent->d_name.name,
+-			file->f_path.dentry->d_name.name, arg);
+-
+-	return -EINVAL;
+-}
+diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
+index fae9719..5bf9b3c 100644
+--- a/fs/nfs/getroot.c
++++ b/fs/nfs/getroot.c
+@@ -30,7 +30,6 @@
+ #include <linux/nfs_idmap.h>
+ #include <linux/vfs.h>
+ #include <linux/namei.h>
+-#include <linux/mnt_namespace.h>
+ #include <linux/security.h>
+ 
+ #include <asm/system.h>
+diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
+index 86147b0..148aebe 100644
+--- a/fs/nfs/idmap.c
++++ b/fs/nfs/idmap.c
+@@ -376,7 +376,7 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
+ static ssize_t
+ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ {
+-	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
++	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+ 	struct idmap *idmap = (struct idmap *)rpci->private;
+ 	struct idmap_msg im_in, *im = &idmap->idmap_im;
+ 	struct idmap_hashtable *h;
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 52daefa..6a5b54c 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -612,7 +612,7 @@ static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
+  */
+ static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+ 
+ 	filp->private_data = get_nfs_open_context(ctx);
+@@ -644,7 +644,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
+ 
+ static void nfs_file_clear_open_context(struct file *filp)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct nfs_open_context *ctx = nfs_file_open_context(filp);
+ 
+ 	if (ctx) {
+@@ -667,7 +667,7 @@ int nfs_open(struct inode *inode, struct file *filp)
+ 	cred = rpc_lookup_cred();
+ 	if (IS_ERR(cred))
+ 		return PTR_ERR(cred);
+-	ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred);
++	ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
+ 	put_rpccred(cred);
+ 	if (ctx == NULL)
+ 		return -ENOMEM;
+@@ -1242,7 +1242,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
+ #endif
+ }
+ 
+-static void init_once(void *foo)
++static void init_once(void *foo, struct kmem_cache *cachep, unsigned long temp)
+ {
+ 	struct nfs_inode *nfsi = (struct nfs_inode *) foo;
+ 
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 66df08d..1e11b1d 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -107,29 +107,29 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
+ 
+ 	BUG_ON(IS_ROOT(dentry));
+ 	dprintk("%s: enter\n", __func__);
+-	dput(nd->path.dentry);
+-	nd->path.dentry = dget(dentry);
++	dput(nd->dentry);
++	nd->dentry = dget(dentry);
+ 
+ 	/* Look it up again */
+-	parent = dget_parent(nd->path.dentry);
++	parent = dget_parent(nd->dentry);
+ 	err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
+-						  &nd->path.dentry->d_name,
++						  &nd->dentry->d_name,
+ 						  &fh, &fattr);
+ 	dput(parent);
+ 	if (err != 0)
+ 		goto out_err;
+ 
+ 	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
+-		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
++		mnt = nfs_do_refmount(nd->mnt, nd->dentry);
+ 	else
+-		mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh,
++		mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh,
+ 				      &fattr);
+ 	err = PTR_ERR(mnt);
+ 	if (IS_ERR(mnt))
+ 		goto out_err;
+ 
+ 	mntget(mnt);
+-	err = do_add_mount(mnt, &nd->path, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
++	err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE,
+ 			   &nfs_automount_list);
+ 	if (err < 0) {
+ 		mntput(mnt);
+@@ -137,9 +137,9 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
+ 			goto out_follow;
+ 		goto out_err;
+ 	}
+-	path_put(&nd->path);
+-	nd->path.mnt = mnt;
+-	nd->path.dentry = dget(mnt->mnt_root);
++	backport_path_put(nd);
++	nd->mnt = mnt;
++	nd->dentry = dget(mnt->mnt_root);
+ 	schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
+ out:
+ 	dprintk("%s: done, returned %d\n", __func__, err);
+@@ -147,22 +147,22 @@ out:
+ 	dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
+ 	return ERR_PTR(err);
+ out_err:
+-	path_put(&nd->path);
++	backport_path_put(nd);
+ 	goto out;
+ out_follow:
+-	while (d_mountpoint(nd->path.dentry) &&
+-	       follow_down(&nd->path.mnt, &nd->path.dentry))
++	while (d_mountpoint(nd->dentry) &&
++	       follow_down(&nd->mnt, &nd->dentry))
+ 		;
+ 	err = 0;
+ 	goto out;
+ }
+ 
+-const struct inode_operations nfs_mountpoint_inode_operations = {
++struct inode_operations nfs_mountpoint_inode_operations = {
+ 	.follow_link	= nfs_follow_mountpoint,
+ 	.getattr	= nfs_getattr,
+ };
+ 
+-const struct inode_operations nfs_referral_inode_operations = {
++struct inode_operations nfs_referral_inode_operations = {
+ 	.follow_link	= nfs_follow_mountpoint,
+ };
+ 
+diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
+index 1e750e4..bdeef69 100644
+--- a/fs/nfs/nfs3proc.c
++++ b/fs/nfs/nfs3proc.c
+@@ -779,7 +779,7 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
+ static int
+ nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 
+ 	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
+ }
+diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
+index ea79064..7a8e6fa 100644
+--- a/fs/nfs/nfs4_fs.h
++++ b/fs/nfs/nfs4_fs.h
+@@ -165,7 +165,7 @@ struct nfs4_state_recovery_ops {
+ };
+ 
+ extern struct dentry_operations nfs4_dentry_operations;
+-extern const struct inode_operations nfs4_dir_inode_operations;
++extern struct inode_operations nfs4_dir_inode_operations;
+ 
+ /* inode.c */
+ extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index c910413..02f1156 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -1384,7 +1384,7 @@ struct dentry *
+ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+ {
+ 	struct path path = {
+-		.mnt = nd->path.mnt,
++		.mnt = nd->mnt,
+ 		.dentry = dentry,
+ 	};
+ 	struct dentry *parent;
+@@ -1421,8 +1421,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+ 	}
+ 	res = d_add_unique(dentry, igrab(state->inode));
+ 	if (res != NULL)
+-		path.dentry = res;
+-	nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
++		dentry = res;
++	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+ 	nfs_unblock_sillyrename(parent);
+ 	nfs4_intent_set_file(nd, &path, state);
+ 	return res;
+@@ -1432,7 +1432,7 @@ int
+ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
+ {
+ 	struct path path = {
+-		.mnt = nd->path.mnt,
++		.mnt = nd->mnt,
+ 		.dentry = dentry,
+ 	};
+ 	struct rpc_cred *cred;
+@@ -1880,7 +1880,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+                  int flags, struct nameidata *nd)
+ {
+ 	struct path path = {
+-		.mnt = nd->path.mnt,
++		.mnt = nd->mnt,
+ 		.dentry = dentry,
+ 	};
+ 	struct nfs4_state *state;
+@@ -3671,7 +3671,7 @@ struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops = {
+ 	.recover_lock	= nfs4_lock_expired,
+ };
+ 
+-static const struct inode_operations nfs4_file_inode_operations = {
++static struct inode_operations nfs4_file_inode_operations = {
+ 	.permission	= nfs_permission,
+ 	.getattr	= nfs_getattr,
+ 	.setattr	= nfs_setattr,
+diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
+index 4dbb84d..c351a41 100644
+--- a/fs/nfs/proc.c
++++ b/fs/nfs/proc.c
+@@ -595,7 +595,7 @@ nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
+ static int
+ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 
+ 	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
+ }
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index e9b2017..85ea5fd 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -201,7 +201,7 @@ static match_table_t nfs_secflavor_tokens = {
+ };
+ 
+ 
+-static void nfs_umount_begin(struct super_block *);
++static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags);
+ static int  nfs_statfs(struct dentry *, struct kstatfs *);
+ static int  nfs_show_options(struct seq_file *, struct vfsmount *);
+ static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
+@@ -228,7 +228,7 @@ struct file_system_type nfs_xdev_fs_type = {
+ 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+ };
+ 
+-static const struct super_operations nfs_sops = {
++static struct super_operations nfs_sops = {
+ 	.alloc_inode	= nfs_alloc_inode,
+ 	.destroy_inode	= nfs_destroy_inode,
+ 	.write_inode	= nfs_write_inode,
+@@ -274,7 +274,7 @@ struct file_system_type nfs4_referral_fs_type = {
+ 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+ };
+ 
+-static const struct super_operations nfs4_sops = {
++static struct super_operations nfs4_sops = {
+ 	.alloc_inode	= nfs_alloc_inode,
+ 	.destroy_inode	= nfs_destroy_inode,
+ 	.write_inode	= nfs_write_inode,
+@@ -287,10 +287,7 @@ static const struct super_operations nfs4_sops = {
+ };
+ #endif
+ 
+-static struct shrinker acl_shrinker = {
+-	.shrink		= nfs_access_cache_shrinker,
+-	.seeks		= DEFAULT_SEEKS,
+-};
++static struct shrinker *acl_shrinker;
+ 
+ /*
+  * Register the NFS filesystems
+@@ -311,7 +308,7 @@ int __init register_nfs_fs(void)
+ 	if (ret < 0)
+ 		goto error_2;
+ #endif
+-	register_shrinker(&acl_shrinker);
++	acl_shrinker = set_shrinker(DEFAULT_SEEKS, nfs_access_cache_shrinker);
+ 	return 0;
+ 
+ #ifdef CONFIG_NFS_V4
+@@ -329,7 +326,8 @@ error_0:
+  */
+ void __exit unregister_nfs_fs(void)
+ {
+-	unregister_shrinker(&acl_shrinker);
++	if (acl_shrinker != NULL)
++		remove_shrinker(acl_shrinker);
+ #ifdef CONFIG_NFS_V4
+ 	unregister_filesystem(&nfs4_fs_type);
+ #endif
+@@ -649,11 +647,13 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
+  * Begin unmount by attempting to remove all automounted mountpoints we added
+  * in response to xdev traversals and referrals
+  */
+-static void nfs_umount_begin(struct super_block *sb)
++static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
+ {
+-	struct nfs_server *server = NFS_SB(sb);
++	struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
+ 	struct rpc_clnt *rpc;
+ 
++	if (!(flags & MNT_FORCE))
++		return;
+ 	/* -EIO all pending I/O */
+ 	rpc = server->client_acl;
+ 	if (!IS_ERR(rpc))
+diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
+index 412738d..b17f14a 100644
+--- a/fs/nfs/symlink.c
++++ b/fs/nfs/symlink.c
+@@ -70,7 +70,7 @@ read_failed:
+ /*
+  * symlinks can't do much...
+  */
+-const struct inode_operations nfs_symlink_inode_operations = {
++struct inode_operations nfs_symlink_inode_operations = {
+ 	.readlink	= generic_readlink,
+ 	.follow_link	= nfs_follow_link,
+ 	.put_link	= page_put_link,
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index 3229e21..7dd87ba 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -20,6 +20,8 @@
+ #include <linux/nfs_page.h>
+ #include <linux/backing-dev.h>
+ 
++#include <linux/mpage.h>
++
+ #include <asm/uaccess.h>
+ 
+ #include "delegation.h"
+@@ -198,7 +200,7 @@ static int nfs_set_page_writeback(struct page *page)
+ 		struct inode *inode = page->mapping->host;
+ 		struct nfs_server *nfss = NFS_SERVER(inode);
+ 
+-		if (atomic_long_inc_return(&nfss->writeback) >
++		if (atomic_long_inc_return((atomic_long_t *)&nfss->writeback) >
+ 				NFS_CONGESTION_ON_THRESH)
+ 			set_bdi_congested(&nfss->backing_dev_info, WRITE);
+ 	}
+@@ -211,7 +213,7 @@ static void nfs_end_page_writeback(struct page *page)
+ 	struct nfs_server *nfss = NFS_SERVER(inode);
+ 
+ 	end_page_writeback(page);
+-	if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
++	if (atomic_long_dec_return((atomic_long_t *)&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
+ 		clear_bdi_congested(&nfss->backing_dev_info, WRITE);
+ }
+ 
+@@ -726,8 +728,8 @@ int nfs_updatepage(struct file *file, struct page *page,
+ 	nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
+ 
+ 	dprintk("NFS:       nfs_updatepage(%s/%s %d@%lld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name, count,
++		file->f_dentry->d_parent->d_name.name,
++		file->f_dentry->d_name.name, count,
+ 		(long long)(page_offset(page) + offset));
+ 
+ 	/* If we're not using byte range locks, and we know the page
+diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
+index 9dc036f..4bafc01 100644
+--- a/fs/nfsd/export.c
++++ b/fs/nfsd/export.c
+@@ -168,14 +168,15 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 			goto out;
+ 
+ 		dprintk("Found the path %s\n", buf);
+-		key.ek_path = nd.path;
++		key.ek_path.dentry = nd.dentry;
++		key.ek_path.mnt = nd.mnt;
+ 
+ 		ek = svc_expkey_update(&key, ek);
+ 		if (ek)
+ 			cache_put(&ek->h, &svc_expkey_cache);
+ 		else
+ 			err = -ENOMEM;
+-		path_put(&nd.path);
++		backport_path_put(&nd);
+ 	}
+ 	cache_flush();
+  out:
+@@ -204,7 +205,7 @@ static int expkey_show(struct seq_file *m,
+ 	if (test_bit(CACHE_VALID, &h->flags) && 
+ 	    !test_bit(CACHE_NEGATIVE, &h->flags)) {
+ 		seq_printf(m, " ");
+-		seq_path(m, &ek->ek_path, "\\ \t\n");
++		seq_path(m, ek->ek_path.mnt, ek->ek_path.dentry, "\\ \t\n");
+ 	}
+ 	seq_printf(m, "\n");
+ 	return 0;
+@@ -346,7 +347,7 @@ static void svc_export_request(struct cache_detail *cd,
+ 	char *pth;
+ 
+ 	qword_add(bpp, blen, exp->ex_client->name);
+-	pth = d_path(&exp->ex_path, *bpp, *blen);
++	pth = d_path(exp->ex_path.dentry, exp->ex_path.mnt, *bpp, *blen);
+ 	if (IS_ERR(pth)) {
+ 		/* is this correct? */
+ 		(*bpp)[0] = '\n';
+@@ -385,7 +386,7 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
+ 	}
+ 
+ 	if (!inode->i_sb->s_export_op ||
+-	    !inode->i_sb->s_export_op->fh_to_dentry) {
++	    !inode->i_sb->s_export_op->get_dentry) {
+ 		dprintk("exp_export: export of invalid fs type.\n");
+ 		return -EINVAL;
+ 	}
+@@ -504,7 +505,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 	struct svc_export exp, *expp;
+ 	int an_int;
+ 
+-	nd.path.dentry = NULL;
++	nd.dentry = NULL;
+ 	exp.ex_pathname = NULL;
+ 
+ 	/* fs locations */
+@@ -544,8 +545,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 
+ 	exp.h.flags = 0;
+ 	exp.ex_client = dom;
+-	exp.ex_path.mnt = nd.path.mnt;
+-	exp.ex_path.dentry = nd.path.dentry;
++	exp.ex_path.mnt = nd.mnt;
++	exp.ex_path.dentry = nd.dentry;
+ 	exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
+ 	err = -ENOMEM;
+ 	if (!exp.ex_pathname)
+@@ -607,7 +608,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 				goto out;
+ 		}
+ 
+-		err = check_export(nd.path.dentry->d_inode, exp.ex_flags,
++		err = check_export(nd.dentry->d_inode, exp.ex_flags,
+ 				   exp.ex_uuid);
+ 		if (err) goto out;
+ 	}
+@@ -626,8 +627,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 	nfsd4_fslocs_free(&exp.ex_fslocs);
+ 	kfree(exp.ex_uuid);
+ 	kfree(exp.ex_pathname);
+-	if (nd.path.dentry)
+-		path_put(&nd.path);
++	if (nd.dentry)
++		backport_path_put(&nd);
+  out_no_path:
+ 	if (dom)
+ 		auth_domain_put(dom);
+@@ -650,7 +651,7 @@ static int svc_export_show(struct seq_file *m,
+ 		return 0;
+ 	}
+ 	exp = container_of(h, struct svc_export, h);
+-	seq_path(m, &exp->ex_path, " \t\n\\");
++	seq_path(m, exp->ex_path.mnt, exp->ex_path.dentry, " \t\n\\");
+ 	seq_putc(m, '\t');
+ 	seq_escape(m, exp->ex_client->name, " \t\n\\");
+ 	seq_putc(m, '(');
+@@ -1026,7 +1027,7 @@ exp_export(struct nfsctl_export *nxp)
+ 		goto out_put_clp;
+ 	err = -EINVAL;
+ 
+-	exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);
++	exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
+ 
+ 	memset(&new, 0, sizeof(new));
+ 
+@@ -1034,8 +1035,8 @@ exp_export(struct nfsctl_export *nxp)
+ 	if ((nxp->ex_flags & NFSEXP_FSID) &&
+ 	    (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
+ 	    fsid_key->ek_path.mnt &&
+-	    (fsid_key->ek_path.mnt != nd.path.mnt ||
+-	     fsid_key->ek_path.dentry != nd.path.dentry))
++	    (fsid_key->ek_path.mnt != nd.mnt ||
++	     fsid_key->ek_path.dentry != nd.dentry))
+ 		goto finish;
+ 
+ 	if (!IS_ERR(exp)) {
+@@ -1051,7 +1052,7 @@ exp_export(struct nfsctl_export *nxp)
+ 		goto finish;
+ 	}
+ 
+-	err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
++	err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL);
+ 	if (err) goto finish;
+ 
+ 	err = -ENOMEM;
+@@ -1064,7 +1065,8 @@ exp_export(struct nfsctl_export *nxp)
+ 	if (!new.ex_pathname)
+ 		goto finish;
+ 	new.ex_client = clp;
+-	new.ex_path = nd.path;
++	new.ex_path.mnt = nd.mnt;
++	new.ex_path.dentry = nd.dentry;
+ 	new.ex_flags = nxp->ex_flags;
+ 	new.ex_anon_uid = nxp->ex_anon_uid;
+ 	new.ex_anon_gid = nxp->ex_anon_gid;
+@@ -1090,7 +1092,7 @@ finish:
+ 		exp_put(exp);
+ 	if (fsid_key && !IS_ERR(fsid_key))
+ 		cache_put(&fsid_key->h, &svc_expkey_cache);
+-	path_put(&nd.path);
++	backport_path_put(&nd);
+ out_put_clp:
+ 	auth_domain_put(clp);
+ out_unlock:
+@@ -1143,8 +1145,8 @@ exp_unexport(struct nfsctl_export *nxp)
+ 		goto out_domain;
+ 
+ 	err = -EINVAL;
+-	exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
+-	path_put(&nd.path);
++	exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
++	backport_path_put(&nd);
+ 	if (IS_ERR(exp))
+ 		goto out_domain;
+ 
+@@ -1180,12 +1182,12 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
+ 		printk("nfsd: exp_rootfh path not found %s", path);
+ 		return err;
+ 	}
+-	inode = nd.path.dentry->d_inode;
++	inode = nd.dentry->d_inode;
+ 
+ 	dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
+-		 path, nd.path.dentry, clp->name,
++		 path, nd.dentry, clp->name,
+ 		 inode->i_sb->s_id, inode->i_ino);
+-	exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
++	exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
+ 	if (IS_ERR(exp)) {
+ 		err = PTR_ERR(exp);
+ 		goto out;
+@@ -1195,7 +1197,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
+ 	 * fh must be initialized before calling fh_compose
+ 	 */
+ 	fh_init(&fh, maxsize);
+-	if (fh_compose(&fh, exp, nd.path.dentry, NULL))
++	if (fh_compose(&fh, exp, nd.dentry, NULL))
+ 		err = -EINVAL;
+ 	else
+ 		err = 0;
+@@ -1203,7 +1205,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
+ 	fh_put(&fh);
+ 	exp_put(exp);
+ out:
+-	path_put(&nd.path);
++	backport_path_put(&nd);
+ 	return err;
+ }
+ 
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index 145b3c8..ad22c29 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -121,9 +121,9 @@ out_no_tfm:
+ static void
+ nfsd4_sync_rec_dir(void)
+ {
+-	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
+-	nfsd_sync_dir(rec_dir.path.dentry);
+-	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
++	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
++	nfsd_sync_dir(rec_dir.dentry);
++	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+ }
+ 
+ int
+@@ -143,9 +143,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
+ 	nfs4_save_user(&uid, &gid);
+ 
+ 	/* lock the parent */
+-	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
++	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+ 
+-	dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1);
++	dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
+ 	if (IS_ERR(dentry)) {
+ 		status = PTR_ERR(dentry);
+ 		goto out_unlock;
+@@ -155,15 +155,15 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
+ 		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
+ 		goto out_put;
+ 	}
+-	status = mnt_want_write(rec_dir.path.mnt);
++	status = mnt_want_write(rec_dir.mnt);
+ 	if (status)
+ 		goto out_put;
+-	status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
+-	mnt_drop_write(rec_dir.path.mnt);
++	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
++	mnt_drop_write(rec_dir.mnt);
+ out_put:
+ 	dput(dentry);
+ out_unlock:
+-	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
++	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+ 	if (status == 0) {
+ 		clp->cl_firststate = 1;
+ 		nfsd4_sync_rec_dir();
+@@ -226,7 +226,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
+ 
+ 	nfs4_save_user(&uid, &gid);
+ 
+-	filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY);
++	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
+ 	status = PTR_ERR(filp);
+ 	if (IS_ERR(filp))
+ 		goto out;
+@@ -291,9 +291,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
+ 
+ 	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
+ 
+-	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
+-	dentry = lookup_one_len(name, rec_dir.path.dentry, namlen);
+-	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
++	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
++	dentry = lookup_one_len(name, rec_dir.dentry, namlen);
++	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+ 	if (IS_ERR(dentry)) {
+ 		status = PTR_ERR(dentry);
+ 		return status;
+@@ -302,7 +302,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
+ 	if (!dentry->d_inode)
+ 		goto out;
+ 
+-	status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry);
++	status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
+ out:
+ 	dput(dentry);
+ 	return status;
+@@ -318,7 +318,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
+ 	if (!rec_dir_init || !clp->cl_firststate)
+ 		return;
+ 
+-	status = mnt_want_write(rec_dir.path.mnt);
++	status = mnt_want_write(rec_dir.mnt);
+ 	if (status)
+ 		goto out;
+ 	clp->cl_firststate = 0;
+@@ -327,7 +327,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
+ 	nfs4_reset_user(uid, gid);
+ 	if (status == 0)
+ 		nfsd4_sync_rec_dir();
+-	mnt_drop_write(rec_dir.path.mnt);
++	mnt_drop_write(rec_dir.mnt);
+ out:
+ 	if (status)
+ 		printk("NFSD: Failed to remove expired client state directory"
+@@ -357,17 +357,17 @@ nfsd4_recdir_purge_old(void) {
+ 
+ 	if (!rec_dir_init)
+ 		return;
+-	status = mnt_want_write(rec_dir.path.mnt);
++	status = mnt_want_write(rec_dir.mnt);
+ 	if (status)
+ 		goto out;
+-	status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old);
++	status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
+ 	if (status == 0)
+ 		nfsd4_sync_rec_dir();
+-	mnt_drop_write(rec_dir.path.mnt);
++	mnt_drop_write(rec_dir.mnt);
+ out:
+ 	if (status)
+ 		printk("nfsd4: failed to purge old clients from recovery"
+-			" directory %s\n", rec_dir.path.dentry->d_name.name);
++			" directory %s\n", rec_dir.dentry->d_name.name);
+ }
+ 
+ static int
+@@ -387,10 +387,10 @@ int
+ nfsd4_recdir_load(void) {
+ 	int status;
+ 
+-	status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir);
++	status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
+ 	if (status)
+ 		printk("nfsd4: failed loading clients from recovery"
+-			" directory %s\n", rec_dir.path.dentry->d_name.name);
++			" directory %s\n", rec_dir.dentry->d_name.name);
+ 	return status;
+ }
+ 
+@@ -429,5 +429,5 @@ nfsd4_shutdown_recdir(void)
+ 	if (!rec_dir_init)
+ 		return;
+ 	rec_dir_init = 0;
+-	path_put(&rec_dir.path);
++	backport_path_put(&rec_dir);
+ }
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 1578d7a..1c6df07 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1576,7 +1576,7 @@ static __be32
+ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
+ {
+ 	struct file *filp = stp->st_vfs_file;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	unsigned int share_access, new_writer;
+ 	__be32 status;
+ 
+@@ -1923,7 +1923,7 @@ search_close_lru(u32 st_id, int flags)
+ static inline int
+ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
+ {
+-	return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode;
++	return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_dentry->d_inode;
+ }
+ 
+ static int
+@@ -2838,7 +2838,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 	 * only the dentry:inode set.
+ 	 */
+ 	memset(&file, 0, sizeof (struct file));
+-	file.f_path.dentry = cstate->current_fh.fh_dentry;
++	file.f_dentry = cstate->current_fh.fh_dentry;
+ 
+ 	status = nfs_ok;
+ 	error = vfs_test_lock(&file, &file_lock);
+@@ -2934,7 +2934,7 @@ static int
+ check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
+ {
+ 	struct file_lock **flpp;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	int status = 0;
+ 
+ 	lock_kernel();
+@@ -3294,11 +3294,11 @@ nfs4_reset_recoverydir(char *recdir)
+ 	if (status)
+ 		return status;
+ 	status = -ENOTDIR;
+-	if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) {
++	if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
+ 		nfs4_set_recdir(recdir);
+ 		status = 0;
+ 	}
+-	path_put(&nd.path);
++	backport_path_put(&nd);
+ 	return status;
+ }
+ 
+diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
+index c53e65f..fc2871b 100644
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -121,7 +121,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
+ 
+ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
+ {
+-	ino_t ino =  file->f_path.dentry->d_inode->i_ino;
++	ino_t ino = file->f_dentry->d_inode->i_ino;
+ 	char *data;
+ 	ssize_t rv;
+ 
+@@ -360,9 +360,9 @@ static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
+ 	if (error)
+ 		return error;
+ 
+-	error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
++	error = nlmsvc_unlock_all_by_sb(nd.mnt->mnt_sb);
+ 
+-	path_put(&nd.path);
++	backport_path_put(&nd);
+ 	return error;
+ }
+ 
+diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
+index 80292ff..47eb160 100644
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -574,3 +574,5 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
+ 	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
+ 	return 1;
+ }
++
++MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 18060be..becacce 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -23,7 +23,6 @@
+ #include <linux/file.h>
+ #include <linux/mount.h>
+ #include <linux/major.h>
+-#include <linux/splice.h>
+ #include <linux/proc_fs.h>
+ #include <linux/stat.h>
+ #include <linux/fcntl.h>
+@@ -766,10 +765,10 @@ static int
+ nfsd_sync(struct file *filp)
+ {
+         int err;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
+-	dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
++	struct inode *inode = filp->f_dentry->d_inode;
++	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
+ 	mutex_lock(&inode->i_mutex);
+-	err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
++	err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
+ 	mutex_unlock(&inode->i_mutex);
+ 
+ 	return err;
+@@ -828,53 +827,39 @@ found:
+ 	return ra;
+ }
+ 
+-/*
+- * Grab and keep cached pages associated with a file in the svc_rqst
+- * so that they can be passed to the network sendmsg/sendpage routines
+- * directly. They will be released after the sending has completed.
+- */
+ static int
+-nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+-		  struct splice_desc *sd)
++nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset , unsigned long size)
+ {
+-	struct svc_rqst *rqstp = sd->u.data;
++	unsigned long count = desc->count;
++	struct svc_rqst *rqstp = desc->arg.data;
+ 	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
+-	struct page *page = buf->page;
+-	size_t size;
+-	int ret;
+-
+-	ret = buf->ops->confirm(pipe, buf);
+-	if (unlikely(ret))
+-		return ret;
+ 
+-	size = sd->len;
++	if (size > count)
++		size = count;
+ 
+ 	if (rqstp->rq_res.page_len == 0) {
+ 		get_page(page);
+-		put_page(*pp);
+-		*pp = page;
+-		rqstp->rq_resused++;
+-		rqstp->rq_res.page_base = buf->offset;
++		if (*pp)
++			put_page(*pp);
++		rqstp->rq_respages[rqstp->rq_resused++] = page;
++		rqstp->rq_res.page_base = offset;
+ 		rqstp->rq_res.page_len = size;
+-	} else if (page != pp[-1]) {
++	} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) {
+ 		get_page(page);
+ 		if (*pp)
+ 			put_page(*pp);
+ 		*pp = page;
+-		rqstp->rq_resused++;
++		rqstp->rq_respages[rqstp->rq_resused++] = page;
+ 		rqstp->rq_res.page_len += size;
+-	} else
++	} else {
+ 		rqstp->rq_res.page_len += size;
++	}
+ 
++	desc->count = count - size;
++	desc->written += size;
+ 	return size;
+ }
+ 
+-static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
+-				    struct splice_desc *sd)
+-{
+-	return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
+-}
+-
+ static inline int svc_msnfs(struct svc_fh *ffhp)
+ {
+ #ifdef MSNFS
+@@ -895,7 +880,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	int		host_err;
+ 
+ 	err = nfserr_perm;
+-	inode = file->f_path.dentry->d_inode;
++	inode = file->f_dentry->d_inode;
+ 
+ 	if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
+ 		goto out;
+@@ -906,16 +891,9 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	if (ra && ra->p_set)
+ 		file->f_ra = ra->p_ra;
+ 
+-	if (file->f_op->splice_read && rqstp->rq_splice_ok) {
+-		struct splice_desc sd = {
+-			.len		= 0,
+-			.total_len	= *count,
+-			.pos		= offset,
+-			.u.data		= rqstp,
+-		};
+-
++	if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
+ 		rqstp->rq_resused = 1;
+-		host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
++		host_err = file->f_op->sendfile(file, &offset, *count, nfsd_read_actor, rqstp);
+ 	} else {
+ 		oldfs = get_fs();
+ 		set_fs(KERNEL_DS);
+@@ -937,7 +915,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 		nfsdstats.io_read += host_err;
+ 		*count = host_err;
+ 		err = 0;
+-		fsnotify_access(file->f_path.dentry);
++		fsnotify_access(file->f_dentry);
+ 	} else 
+ 		err = nfserrno(host_err);
+ out:
+@@ -971,11 +949,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	err = nfserr_perm;
+ 
+ 	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+-		(!lock_may_write(file->f_path.dentry->d_inode, offset, cnt)))
++		(!lock_may_write(file->f_dentry->d_inode, offset, cnt)))
+ 		goto out;
+ #endif
+ 
+-	dentry = file->f_path.dentry;
++	dentry = file->f_dentry;
+ 	inode = dentry->d_inode;
+ 	exp   = fhp->fh_export;
+ 
+@@ -1004,7 +982,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	set_fs(oldfs);
+ 	if (host_err >= 0) {
+ 		nfsdstats.io_write += cnt;
+-		fsnotify_modify(file->f_path.dentry);
++		fsnotify_modify(file->f_dentry);
+ 	}
+ 
+ 	/* clear setuid/setgid flag after write */
+diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
+index 27e772c..d932fb1 100644
+--- a/include/linux/exportfs.h
++++ b/include/linux/exportfs.h
+@@ -89,85 +89,9 @@ struct fid {
+ 	};
+ };
+ 
+-/**
+- * struct export_operations - for nfsd to communicate with file systems
+- * @encode_fh:      encode a file handle fragment from a dentry
+- * @fh_to_dentry:   find the implied object and get a dentry for it
+- * @fh_to_parent:   find the implied object's parent and get a dentry for it
+- * @get_name:       find the name for a given inode in a given directory
+- * @get_parent:     find the parent of a given directory
+- *
+- * See Documentation/filesystems/Exporting for details on how to use
+- * this interface correctly.
+- *
+- * encode_fh:
+- *    @encode_fh should store in the file handle fragment @fh (using at most
+- *    @max_len bytes) information that can be used by @decode_fh to recover the
+- *    file refered to by the &struct dentry @de.  If the @connectable flag is
+- *    set, the encode_fh() should store sufficient information so that a good
+- *    attempt can be made to find not only the file but also it's place in the
+- *    filesystem.   This typically means storing a reference to de->d_parent in
+- *    the filehandle fragment.  encode_fh() should return the number of bytes
+- *    stored or a negative error code such as %-ENOSPC
+- *
+- * fh_to_dentry:
+- *    @fh_to_dentry is given a &struct super_block (@sb) and a file handle
+- *    fragment (@fh, @fh_len). It should return a &struct dentry which refers
+- *    to the same file that the file handle fragment refers to.  If it cannot,
+- *    it should return a %NULL pointer if the file was found but no acceptable
+- *    &dentries were available, or an %ERR_PTR error code indicating why it
+- *    couldn't be found (e.g. %ENOENT or %ENOMEM).  Any suitable dentry can be
+- *    returned including, if necessary, a new dentry created with d_alloc_root.
+- *    The caller can then find any other extant dentries by following the
+- *    d_alias links.
+- *
+- * fh_to_parent:
+- *    Same as @fh_to_dentry, except that it returns a pointer to the parent
+- *    dentry if it was encoded into the filehandle fragment by @encode_fh.
+- *
+- * get_name:
+- *    @get_name should find a name for the given @child in the given @parent
+- *    directory.  The name should be stored in the @name (with the
+- *    understanding that it is already pointing to a a %NAME_MAX+1 sized
+- *    buffer.   get_name() should return %0 on success, a negative error code
+- *    or error.  @get_name will be called without @parent->i_mutex held.
+- *
+- * get_parent:
+- *    @get_parent should find the parent directory for the given @child which
+- *    is also a directory.  In the event that it cannot be found, or storage
+- *    space cannot be allocated, a %ERR_PTR should be returned.
+- *
+- * Locking rules:
+- *    get_parent is called with child->d_inode->i_mutex down
+- *    get_name is not (which is possibly inconsistent)
+- */
+-
+-struct export_operations {
+-	int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
+-			int connectable);
+-	struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
+-			int fh_len, int fh_type);
+-	struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+-			int fh_len, int fh_type);
+-	int (*get_name)(struct dentry *parent, char *name,
+-			struct dentry *child);
+-	struct dentry * (*get_parent)(struct dentry *child);
+-};
+-
+ extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
+ 	int *max_len, int connectable);
+ extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ 	int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
+ 	void *context);
+-
+-/*
+- * Generic helpers for filesystems.
+- */
+-extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
+-	struct fid *fid, int fh_len, int fh_type,
+-	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+-extern struct dentry *generic_fh_to_parent(struct super_block *sb,
+-	struct fid *fid, int fh_len, int fh_type,
+-	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+-
+ #endif /* LINUX_EXPORTFS_H */
+diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
+index dbb87ab..9236e80 100644
+--- a/include/linux/lockd/lockd.h
++++ b/include/linux/lockd/lockd.h
+@@ -230,7 +230,7 @@ int           nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
+ 
+ static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
+ {
+-	return file->f_file->f_path.dentry->d_inode;
++	return file->f_file->f_dentry->d_inode;
+ }
+ 
+ /*
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+index 78a5922..e59d828 100644
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -9,6 +9,7 @@
+ #ifndef _LINUX_NFS_FS_H
+ #define _LINUX_NFS_FS_H
+ 
++#include <linux/path.h>
+ #include <linux/magic.h>
+ 
+ /* Default timeout values */
+@@ -331,7 +332,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
+ extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
+ extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
+ extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+-extern int nfs_permission(struct inode *, int);
++extern int nfs_permission(struct inode *, int, struct nameidata *);
+ extern int nfs_open(struct inode *, struct file *);
+ extern int nfs_release(struct inode *, struct file *);
+ extern int nfs_attribute_timeout(struct inode *inode);
+@@ -358,9 +359,9 @@ static inline void nfs_fattr_init(struct nfs_fattr *fattr)
+ /*
+  * linux/fs/nfs/file.c
+  */
+-extern const struct inode_operations nfs_file_inode_operations;
++extern struct inode_operations nfs_file_inode_operations;
+ #ifdef CONFIG_NFS_V3
+-extern const struct inode_operations nfs3_file_inode_operations;
++extern struct inode_operations nfs3_file_inode_operations;
+ #endif /* CONFIG_NFS_V3 */
+ extern const struct file_operations nfs_file_operations;
+ extern const struct address_space_operations nfs_file_aops;
+@@ -408,9 +409,9 @@ extern ssize_t nfs_file_direct_write(struct kiocb *iocb,
+ /*
+  * linux/fs/nfs/dir.c
+  */
+-extern const struct inode_operations nfs_dir_inode_operations;
++extern struct inode_operations nfs_dir_inode_operations;
+ #ifdef CONFIG_NFS_V3
+-extern const struct inode_operations nfs3_dir_inode_operations;
++extern struct inode_operations nfs3_dir_inode_operations;
+ #endif /* CONFIG_NFS_V3 */
+ extern const struct file_operations nfs_dir_operations;
+ extern struct dentry_operations nfs_dentry_operations;
+@@ -423,7 +424,7 @@ extern void nfs_access_zap_cache(struct inode *inode);
+ /*
+  * linux/fs/nfs/symlink.c
+  */
+-extern const struct inode_operations nfs_symlink_inode_operations;
++extern struct inode_operations nfs_symlink_inode_operations;
+ 
+ /*
+  * linux/fs/nfs/sysctl.c
+@@ -439,8 +440,8 @@ extern void nfs_unregister_sysctl(void);
+ /*
+  * linux/fs/nfs/namespace.c
+  */
+-extern const struct inode_operations nfs_mountpoint_inode_operations;
+-extern const struct inode_operations nfs_referral_inode_operations;
++extern struct inode_operations nfs_mountpoint_inode_operations;
++extern struct inode_operations nfs_referral_inode_operations;
+ extern int nfs_mountpoint_expiry_timeout;
+ extern void nfs_release_automount_timer(void);
+ 
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+index 8c77c11..d9007dc 100644
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -782,8 +782,8 @@ struct nfs_access_entry;
+ struct nfs_rpc_ops {
+ 	u32	version;		/* Protocol version */
+ 	struct dentry_operations *dentry_ops;
+-	const struct inode_operations *dir_inode_ops;
+-	const struct inode_operations *file_inode_ops;
++	struct inode_operations *dir_inode_ops;
++	struct inode_operations *file_inode_ops;
+ 
+ 	int	(*getroot) (struct nfs_server *, struct nfs_fh *,
+ 			    struct nfs_fsinfo *);
+diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
+index 5431512..3753e4b 100644
+--- a/include/linux/nfsd/export.h
++++ b/include/linux/nfsd/export.h
+@@ -15,6 +15,7 @@
+ # include <linux/types.h>
+ # include <linux/in.h>
+ #endif
++#include <linux/path.h>
+ 
+ /*
+  * Important limits for the exports stuff.
+diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
+deleted file mode 100644
+index 8e41202..0000000
+--- a/include/linux/pipe_fs_i.h
++++ /dev/null
+@@ -1,151 +0,0 @@
+-#ifndef _LINUX_PIPE_FS_I_H
+-#define _LINUX_PIPE_FS_I_H
+-
+-#define PIPEFS_MAGIC 0x50495045
+-
+-#define PIPE_BUFFERS (16)
+-
+-#define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */
+-#define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */
+-#define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */
+-
+-/**
+- *	struct pipe_buffer - a linux kernel pipe buffer
+- *	@page: the page containing the data for the pipe buffer
+- *	@offset: offset of data inside the @page
+- *	@len: length of data inside the @page
+- *	@ops: operations associated with this buffer. See @pipe_buf_operations.
+- *	@flags: pipe buffer flags. See above.
+- *	@private: private data owned by the ops.
+- **/
+-struct pipe_buffer {
+-	struct page *page;
+-	unsigned int offset, len;
+-	const struct pipe_buf_operations *ops;
+-	unsigned int flags;
+-	unsigned long private;
+-};
+-
+-/**
+- *	struct pipe_inode_info - a linux kernel pipe
+- *	@wait: reader/writer wait point in case of empty/full pipe
+- *	@nrbufs: the number of non-empty pipe buffers in this pipe
+- *	@curbuf: the current pipe buffer entry
+- *	@tmp_page: cached released page
+- *	@readers: number of current readers of this pipe
+- *	@writers: number of current writers of this pipe
+- *	@waiting_writers: number of writers blocked waiting for room
+- *	@r_counter: reader counter
+- *	@w_counter: writer counter
+- *	@fasync_readers: reader side fasync
+- *	@fasync_writers: writer side fasync
+- *	@inode: inode this pipe is attached to
+- *	@bufs: the circular array of pipe buffers
+- **/
+-struct pipe_inode_info {
+-	wait_queue_head_t wait;
+-	unsigned int nrbufs, curbuf;
+-	struct page *tmp_page;
+-	unsigned int readers;
+-	unsigned int writers;
+-	unsigned int waiting_writers;
+-	unsigned int r_counter;
+-	unsigned int w_counter;
+-	struct fasync_struct *fasync_readers;
+-	struct fasync_struct *fasync_writers;
+-	struct inode *inode;
+-	struct pipe_buffer bufs[PIPE_BUFFERS];
+-};
+-
+-/*
+- * Note on the nesting of these functions:
+- *
+- * ->confirm()
+- *	->steal()
+- *	...
+- *	->map()
+- *	...
+- *	->unmap()
+- *
+- * That is, ->map() must be called on a confirmed buffer,
+- * same goes for ->steal(). See below for the meaning of each
+- * operation. Also see kerneldoc in fs/pipe.c for the pipe
+- * and generic variants of these hooks.
+- */
+-struct pipe_buf_operations {
+-	/*
+-	 * This is set to 1, if the generic pipe read/write may coalesce
+-	 * data into an existing buffer. If this is set to 0, a new pipe
+-	 * page segment is always used for new data.
+-	 */
+-	int can_merge;
+-
+-	/*
+-	 * ->map() returns a virtual address mapping of the pipe buffer.
+-	 * The last integer flag reflects whether this should be an atomic
+-	 * mapping or not. The atomic map is faster, however you can't take
+-	 * page faults before calling ->unmap() again. So if you need to eg
+-	 * access user data through copy_to/from_user(), then you must get
+-	 * a non-atomic map. ->map() uses the KM_USER0 atomic slot for
+-	 * atomic maps, so you can't map more than one pipe_buffer at once
+-	 * and you have to be careful if mapping another page as source
+-	 * or destination for a copy (IOW, it has to use something else
+-	 * than KM_USER0).
+-	 */
+-	void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
+-
+-	/*
+-	 * Undoes ->map(), finishes the virtual mapping of the pipe buffer.
+-	 */
+-	void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
+-
+-	/*
+-	 * ->confirm() verifies that the data in the pipe buffer is there
+-	 * and that the contents are good. If the pages in the pipe belong
+-	 * to a file system, we may need to wait for IO completion in this
+-	 * hook. Returns 0 for good, or a negative error value in case of
+-	 * error.
+-	 */
+-	int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *);
+-
+-	/*
+-	 * When the contents of this pipe buffer has been completely
+-	 * consumed by a reader, ->release() is called.
+-	 */
+-	void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
+-
+-	/*
+-	 * Attempt to take ownership of the pipe buffer and its contents.
+-	 * ->steal() returns 0 for success, in which case the contents
+-	 * of the pipe (the buf->page) is locked and now completely owned
+-	 * by the caller. The page may then be transferred to a different
+-	 * mapping, the most often used case is insertion into different
+-	 * file address space cache.
+-	 */
+-	int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
+-
+-	/*
+-	 * Get a reference to the pipe buffer.
+-	 */
+-	void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
+-};
+-
+-/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
+-   memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
+-#define PIPE_SIZE		PAGE_SIZE
+-
+-/* Drop the inode semaphore and wait for a pipe event, atomically */
+-void pipe_wait(struct pipe_inode_info *pipe);
+-
+-struct pipe_inode_info * alloc_pipe_info(struct inode * inode);
+-void free_pipe_info(struct inode * inode);
+-void __free_pipe_info(struct pipe_inode_info *);
+-
+-/* Generic pipe buffer ops functions */
+-void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
+-void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
+-void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
+-int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
+-int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
+-
+-#endif
+diff --git a/include/linux/splice.h b/include/linux/splice.h
+deleted file mode 100644
+index 528dcb9..0000000
+--- a/include/linux/splice.h
++++ /dev/null
+@@ -1,74 +0,0 @@
+-/*
+- * Function declerations and data structures related to the splice
+- * implementation.
+- *
+- * Copyright (C) 2007 Jens Axboe <jens.axboe at oracle.com>
+- *
+- */
+-#ifndef SPLICE_H
+-#define SPLICE_H
+-
+-#include <linux/pipe_fs_i.h>
+-
+-/*
+- * splice is tied to pipes as a transport (at least for now), so we'll just
+- * add the splice flags here.
+- */
+-#define SPLICE_F_MOVE	(0x01)	/* move pages instead of copying */
+-#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
+-				 /* we may still block on the fd we splice */
+-				 /* from/to, of course */
+-#define SPLICE_F_MORE	(0x04)	/* expect more data */
+-#define SPLICE_F_GIFT	(0x08)	/* pages passed in are a gift */
+-
+-/*
+- * Passed to the actors
+- */
+-struct splice_desc {
+-	unsigned int len, total_len;	/* current and remaining length */
+-	unsigned int flags;		/* splice flags */
+-	/*
+-	 * actor() private data
+-	 */
+-	union {
+-		void __user *userptr;	/* memory to write to */
+-		struct file *file;	/* file to read/write */
+-		void *data;		/* cookie */
+-	} u;
+-	loff_t pos;			/* file position */
+-};
+-
+-struct partial_page {
+-	unsigned int offset;
+-	unsigned int len;
+-	unsigned long private;
+-};
+-
+-/*
+- * Passed to splice_to_pipe
+- */
+-struct splice_pipe_desc {
+-	struct page **pages;		/* page map */
+-	struct partial_page *partial;	/* pages[] may not be contig */
+-	int nr_pages;			/* number of pages in map */
+-	unsigned int flags;		/* splice flags */
+-	const struct pipe_buf_operations *ops;/* ops associated with output pipe */
+-	void (*spd_release)(struct splice_pipe_desc *, unsigned int);
+-};
+-
+-typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
+-			   struct splice_desc *);
+-typedef int (splice_direct_actor)(struct pipe_inode_info *,
+-				  struct splice_desc *);
+-
+-extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
+-				loff_t *, size_t, unsigned int,
+-				splice_actor *);
+-extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
+-				  struct splice_desc *, splice_actor *);
+-extern ssize_t splice_to_pipe(struct pipe_inode_info *,
+-			      struct splice_pipe_desc *);
+-extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
+-				      splice_direct_actor *);
+-
+-#endif
+diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
+index 10709cb..9bbadbd 100644
+--- a/include/linux/sunrpc/debug.h
++++ b/include/linux/sunrpc/debug.h
+@@ -88,6 +88,7 @@ enum {
+ 	CTL_SLOTTABLE_TCP,
+ 	CTL_MIN_RESVPORT,
+ 	CTL_MAX_RESVPORT,
++	CTL_TRANSPORT,
+ };
+ 
+ #endif /* _LINUX_SUNRPC_DEBUG_H_ */
+diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index dc69068..3a0f48f 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -255,7 +255,7 @@ struct svc_rqst {
+ 						 * determine what device number
+ 						 * to report (real or virtual)
+ 						 */
+-	int			rq_splice_ok;   /* turned off in gss privacy
++	int			rq_sendfile_ok;   /* turned off in gss privacy
+ 						 * to prevent encrypting page
+ 						 * cache pages */
+ 	wait_queue_head_t	rq_wait;	/* synchronization */
+diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
+index 6bfea9e..f0a110d 100644
+--- a/net/sunrpc/auth.c
++++ b/net/sunrpc/auth.c
+@@ -566,19 +566,16 @@ rpcauth_uptodatecred(struct rpc_task *task)
+ 		test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
+ }
+ 
+-static struct shrinker rpc_cred_shrinker = {
+-	.shrink = rpcauth_cache_shrinker,
+-	.seeks = DEFAULT_SEEKS,
+-};
++static struct shrinker *rpc_cred_shrinker;
+ 
+ void __init rpcauth_init_module(void)
+ {
+ 	rpc_init_authunix();
+ 	rpc_init_generic_auth();
+-	register_shrinker(&rpc_cred_shrinker);
++	rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker);
+ }
+ 
+ void __exit rpcauth_remove_module(void)
+ {
+-	unregister_shrinker(&rpc_cred_shrinker);
++	remove_shrinker(rpc_cred_shrinker);
+ }
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 853a414..71ba862 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -481,7 +481,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ 	const void *p, *end;
+ 	void *buf;
+ 	struct gss_upcall_msg *gss_msg;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct gss_cl_ctx *ctx;
+ 	uid_t uid;
+ 	ssize_t err = -EFBIG;
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 81ae3d6..acfb1d1 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -859,7 +859,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
+ 	u32 priv_len, maj_stat;
+ 	int pad, saved_len, remaining_len, offset;
+ 
+-	rqstp->rq_splice_ok = 0;
++	rqstp->rq_sendfile_ok = 0;
+ 
+ 	priv_len = svc_getnl(&buf->head[0]);
+ 	if (rqstp->rq_deferred) {
+diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
+index c996671..58e606e 100644
+--- a/net/sunrpc/cache.c
++++ b/net/sunrpc/cache.c
+@@ -696,7 +696,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
+ {
+ 	struct cache_reader *rp = filp->private_data;
+ 	struct cache_request *rq;
+-	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
+ 	int err;
+ 
+ 	if (count == 0)
+@@ -773,7 +773,7 @@ cache_write(struct file *filp, const char __user *buf, size_t count,
+ 	    loff_t *ppos)
+ {
+ 	int err;
+-	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
+ 
+ 	if (count == 0)
+ 		return 0;
+@@ -804,7 +804,7 @@ cache_poll(struct file *filp, poll_table *wait)
+ 	unsigned int mask;
+ 	struct cache_reader *rp = filp->private_data;
+ 	struct cache_queue *cq;
+-	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
+ 
+ 	poll_wait(filp, &queue_wait, wait);
+ 
+@@ -1239,7 +1239,7 @@ static int c_show(struct seq_file *m, void *p)
+ 	return cd->cache_show(m, cd, cp);
+ }
+ 
+-static const struct seq_operations cache_content_op = {
++static struct seq_operations cache_content_op = {
+ 	.start	= c_start,
+ 	.next	= c_next,
+ 	.stop	= c_stop,
+@@ -1269,7 +1269,7 @@ static const struct file_operations content_file_operations = {
+ static ssize_t read_flush(struct file *file, char __user *buf,
+ 			    size_t count, loff_t *ppos)
+ {
+-	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data;
+ 	char tbuf[20];
+ 	unsigned long p = *ppos;
+ 	size_t len;
+@@ -1290,7 +1290,7 @@ static ssize_t read_flush(struct file *file, char __user *buf,
+ static ssize_t write_flush(struct file * file, const char __user * buf,
+ 			     size_t count, loff_t *ppos)
+ {
+-	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data;
+ 	char tbuf[20];
+ 	char *ep;
+ 	long flushtime;
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 76739e9..11bfb52 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -213,10 +213,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
+ 	}
+ 
+ 	/* save the nodename */
+-	clnt->cl_nodelen = strlen(utsname()->nodename);
++	clnt->cl_nodelen = strlen(system_utsname.nodename);
+ 	if (clnt->cl_nodelen > UNX_MAXNODENAME)
+ 		clnt->cl_nodelen = UNX_MAXNODENAME;
+-	memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
++	memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
+ 	rpc_register_client(clnt);
+ 	return clnt;
+ 
+diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
+index 23a2b8f..003a6ec 100644
+--- a/net/sunrpc/rpc_pipe.c
++++ b/net/sunrpc/rpc_pipe.c
+@@ -26,6 +26,7 @@
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/workqueue.h>
+ #include <linux/sunrpc/rpc_pipe_fs.h>
++#include <linux/path.h>
+ 
+ static struct vfsmount *rpc_mount __read_mostly;
+ static int rpc_mount_count;
+@@ -224,7 +225,7 @@ out:
+ static ssize_t
+ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct rpc_inode *rpci = RPC_I(inode);
+ 	struct rpc_pipe_msg *msg;
+ 	int res = 0;
+@@ -267,7 +268,7 @@ out_unlock:
+ static ssize_t
+ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct rpc_inode *rpci = RPC_I(inode);
+ 	int res;
+ 
+@@ -285,7 +286,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
+ 	struct rpc_inode *rpci;
+ 	unsigned int mask = 0;
+ 
+-	rpci = RPC_I(filp->f_path.dentry->d_inode);
++	rpci = RPC_I(filp->f_dentry->d_inode);
+ 	poll_wait(filp, &rpci->waitq, wait);
+ 
+ 	mask = POLLOUT | POLLWRNORM;
+@@ -300,7 +301,7 @@ static int
+ rpc_pipe_ioctl(struct inode *ino, struct file *filp,
+ 		unsigned int cmd, unsigned long arg)
+ {
+-	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
++	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+ 	int len;
+ 
+ 	switch (cmd) {
+@@ -495,7 +496,7 @@ rpc_lookup_parent(char *path, struct nameidata *nd)
+ static void
+ rpc_release_path(struct nameidata *nd)
+ {
+-	path_put(&nd->path);
++	backport_path_put(nd);
+ 	rpc_put_mount();
+ }
+ 
+@@ -668,7 +669,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
+ 
+ 	if ((error = rpc_lookup_parent(path, nd)) != 0)
+ 		return ERR_PTR(error);
+-	dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len,
++	dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len,
+ 				   1);
+ 	if (IS_ERR(dentry))
+ 		rpc_release_path(nd);
+@@ -696,7 +697,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
+ 	dentry = rpc_lookup_negative(path, &nd);
+ 	if (IS_ERR(dentry))
+ 		return dentry;
+-	dir = nd.path.dentry->d_inode;
++	dir = nd.dentry->d_inode;
+ 	if ((error = __rpc_mkdir(dir, dentry)) != 0)
+ 		goto err_dput;
+ 	RPC_I(dentry->d_inode)->private = rpc_client;
+@@ -897,7 +898,7 @@ static struct file_system_type rpc_pipe_fs_type = {
+ };
+ 
+ static void
+-init_once(void *foo)
++init_once(void *foo, struct kmem_cache *cachep, unsigned long temp)
+ {
+ 	struct rpc_inode *rpci = (struct rpc_inode *) foo;
+ 
+diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
+index 24db2b4..6f9e46c 100644
+--- a/net/sunrpc/rpcb_clnt.c
++++ b/net/sunrpc/rpcb_clnt.c
+@@ -117,18 +117,6 @@ static void rpcb_map_release(void *data)
+ 	kfree(map);
+ }
+ 
+-static const struct sockaddr_in rpcb_inaddr_loopback = {
+-	.sin_family		= AF_INET,
+-	.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
+-	.sin_port		= htons(RPCBIND_PORT),
+-};
+-
+-static const struct sockaddr_in6 rpcb_in6addr_loopback = {
+-	.sin6_family		= AF_INET6,
+-	.sin6_addr		= IN6ADDR_LOOPBACK_INIT,
+-	.sin6_port		= htons(RPCBIND_PORT),
+-};
+-
+ static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
+ 					  size_t addrlen, u32 version)
+ {
+@@ -249,6 +237,12 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
+ 		.rpc_resp	= okay,
+ 	};
+ 
++	struct sockaddr_in rpcb_inaddr_loopback = {
++		.sin_family		= AF_INET,
++		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
++		.sin_port		= htons(RPCBIND_PORT),
++	};
++
+ 	dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
+ 			"rpcbind\n", (port ? "" : "un"),
+ 			prog, vers, prot, port);
+@@ -272,6 +266,12 @@ static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
+ 	unsigned short port = ntohs(address_to_register->sin_port);
+ 	char buf[32];
+ 
++	struct sockaddr_in rpcb_inaddr_loopback = {
++		.sin_family		= AF_INET,
++		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
++		.sin_port		= htons(RPCBIND_PORT),
++	};
++
+ 	/* Construct AF_INET universal address */
+ 	snprintf(buf, sizeof(buf),
+ 			NIPQUAD_FMT".%u.%u",
+@@ -303,6 +303,12 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
+ 	unsigned short port = ntohs(address_to_register->sin6_port);
+ 	char buf[64];
+ 
++	struct sockaddr_in6 rpcb_in6addr_loopback = {
++		.sin6_family		= AF_INET6,
++		.sin6_addr		= IN6ADDR_LOOPBACK_INIT,
++		.sin6_port		= htons(RPCBIND_PORT),
++	};
++
+ 	/* Construct AF_INET6 universal address */
+ 	snprintf(buf, sizeof(buf),
+ 			NIP6_FMT".%u.%u",
+diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
+index 50b049c..5053a5f 100644
+--- a/net/sunrpc/stats.c
++++ b/net/sunrpc/stats.c
+@@ -264,7 +264,7 @@ rpc_proc_init(void)
+ 	dprintk("RPC:       registering /proc/net/rpc\n");
+ 	if (!proc_net_rpc) {
+ 		struct proc_dir_entry *ent;
+-		ent = proc_mkdir("rpc", init_net.proc_net);
++		ent = proc_mkdir("rpc", proc_net);
+ 		if (ent) {
+ 			ent->owner = THIS_MODULE;
+ 			proc_net_rpc = ent;
+@@ -278,7 +278,7 @@ rpc_proc_exit(void)
+ 	dprintk("RPC:       unregistering /proc/net/rpc\n");
+ 	if (proc_net_rpc) {
+ 		proc_net_rpc = NULL;
+-		remove_proc_entry("rpc", init_net.proc_net);
++		remove_proc_entry("rpc", proc_net);
+ 	}
+ }
+ 
+diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
+index 5a32cb7..e0e87c6 100644
+--- a/net/sunrpc/svc.c
++++ b/net/sunrpc/svc.c
+@@ -174,7 +174,7 @@ fail:
+ static int
+ svc_pool_map_init_percpu(struct svc_pool_map *m)
+ {
+-	unsigned int maxpools = nr_cpu_ids;
++	unsigned int maxpools = highest_possible_processor_id() + 1;
+ 	unsigned int pidx = 0;
+ 	unsigned int cpu;
+ 	int err;
+@@ -202,7 +202,7 @@ svc_pool_map_init_percpu(struct svc_pool_map *m)
+ static int
+ svc_pool_map_init_pernode(struct svc_pool_map *m)
+ {
+-	unsigned int maxpools = nr_node_ids;
++	unsigned int maxpools = highest_possible_processor_id() + 1;
+ 	unsigned int pidx = 0;
+ 	unsigned int node;
+ 	int err;
+@@ -310,13 +310,12 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx)
+ 	switch (m->mode) {
+ 	case SVC_POOL_PERCPU:
+ 	{
+-		set_cpus_allowed_ptr(task, &cpumask_of_cpu(node));
++		set_cpus_allowed(task, cpumask_of_cpu(node));
+ 		break;
+ 	}
+ 	case SVC_POOL_PERNODE:
+ 	{
+-		node_to_cpumask_ptr(nodecpumask, node);
+-		set_cpus_allowed_ptr(task, nodecpumask);
++		set_cpus_allowed(task, node_to_cpumask(node));
+ 		break;
+ 	}
+ 	}
+@@ -831,7 +830,7 @@ svc_process(struct svc_rqst *rqstp)
+ 	rqstp->rq_res.tail[0].iov_base = NULL;
+ 	rqstp->rq_res.tail[0].iov_len = 0;
+ 	/* Will be turned off only in gss privacy case: */
+-	rqstp->rq_splice_ok = 1;
++	rqstp->rq_sendfile_ok = 1;
+ 
+ 	/* Setup reply header */
+ 	rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
+diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
+index f24800f..b30d725 100644
+--- a/net/sunrpc/svcauth_unix.c
++++ b/net/sunrpc/svcauth_unix.c
+@@ -678,7 +678,7 @@ int
+ svcauth_unix_set_client(struct svc_rqst *rqstp)
+ {
+ 	struct sockaddr_in *sin;
+-	struct sockaddr_in6 *sin6, sin6_storage;
++	struct sockaddr_in6 *sin6 = NULL, sin6_storage;
+ 	struct ip_map *ipm;
+ 
+ 	switch (rqstp->rq_addr.ss_family) {
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index 3e65719..cbb47a6 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -472,12 +472,16 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
+ 	if (len < 0)
+ 		return len;
+ 	rqstp->rq_addrlen = len;
+-	if (skb->tstamp.tv64 == 0) {
+-		skb->tstamp = ktime_get_real();
++	if (skb->tstamp.off_sec == 0) {
++		struct timeval tv;
++
++		tv.tv_sec = xtime.tv_sec;
++		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
++		skb_set_timestamp(skb, &tv);
+ 		/* Don't enable netstamp, sunrpc doesn't
+ 		   need that much accuracy */
+ 	}
+-	svsk->sk_sk->sk_stamp = skb->tstamp;
++	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+ 	set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
+ 
+ 	/*
+diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
+index 5231f7a..1482e34 100644
+--- a/net/sunrpc/sysctl.c
++++ b/net/sunrpc/sysctl.c
+@@ -135,6 +135,7 @@ done:
+ 
+ static ctl_table debug_table[] = {
+ 	{
++		.ctl_name	= CTL_RPCDEBUG, 
+ 		.procname	= "rpc_debug",
+ 		.data		= &rpc_debug,
+ 		.maxlen		= sizeof(int),
+@@ -142,6 +143,7 @@ static ctl_table debug_table[] = {
+ 		.proc_handler	= &proc_dodebug
+ 	},
+ 	{
++		.ctl_name	= CTL_NFSDEBUG,
+ 		.procname	= "nfs_debug",
+ 		.data		= &nfs_debug,
+ 		.maxlen		= sizeof(int),
+@@ -149,6 +151,7 @@ static ctl_table debug_table[] = {
+ 		.proc_handler	= &proc_dodebug
+ 	},
+ 	{
++		.ctl_name	= CTL_NFSDDEBUG,
+ 		.procname	= "nfsd_debug",
+ 		.data		= &nfsd_debug,
+ 		.maxlen		= sizeof(int),
+@@ -156,6 +159,7 @@ static ctl_table debug_table[] = {
+ 		.proc_handler	= &proc_dodebug
+ 	},
+ 	{
++		.ctl_name	= CTL_NLMDEBUG,
+ 		.procname	= "nlm_debug",
+ 		.data		= &nlm_debug,
+ 		.maxlen		= sizeof(int),
+@@ -163,6 +167,7 @@ static ctl_table debug_table[] = {
+ 		.proc_handler	= &proc_dodebug
+ 	},
+ 	{
++		.ctl_name	= CTL_TRANSPORT,
+ 		.procname	= "transports",
+ 		.maxlen		= 256,
+ 		.mode		= 0444,
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+index 6fb493c..761ad29 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+@@ -247,10 +247,6 @@ static void rq_comp_handler(struct ib_cq *cq, void *cq_context)
+ 	struct svcxprt_rdma *xprt = cq_context;
+ 	unsigned long flags;
+ 
+-	/* Guard against unconditional flush call for destroyed QP */
+-	if (atomic_read(&xprt->sc_xprt.xpt_ref.refcount)==0)
+-		return;
+-
+ 	/*
+ 	 * Set the bit regardless of whether or not it's on the list
+ 	 * because it may be on the list already due to an SQ
+@@ -411,10 +407,6 @@ static void sq_comp_handler(struct ib_cq *cq, void *cq_context)
+ 	struct svcxprt_rdma *xprt = cq_context;
+ 	unsigned long flags;
+ 
+-	/* Guard against unconditional flush call for destroyed QP */
+-	if (atomic_read(&xprt->sc_xprt.xpt_ref.refcount)==0)
+-		return;
+-
+ 	/*
+ 	 * Set the bit regardless of whether or not it's on the list
+ 	 * because it may be on the list already due to an RQ
+@@ -1116,9 +1108,6 @@ static void __svc_rdma_free(struct work_struct *work)
+ 		container_of(work, struct svcxprt_rdma, sc_work);
+ 	dprintk("svcrdma: svc_rdma_free(%p)\n", rdma);
+ 
+-	/* We should only be called from kref_put */
+-	BUG_ON(atomic_read(&rdma->sc_xprt.xpt_ref.refcount) != 0);
+-
+ 	/*
+ 	 * Destroy queued, but not processed read completions. Note
+ 	 * that this cleanup has to be done before destroying the
+diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
+index 8710117..ce94fa4 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma.c
++++ b/net/sunrpc/xprtrdma/svc_rdma.c
+@@ -116,6 +116,7 @@ static int read_reset_stat(ctl_table *table, int write,
+ static struct ctl_table_header *svcrdma_table_header;
+ static ctl_table svcrdma_parm_table[] = {
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "max_requests",
+ 		.data		= &svcrdma_max_requests,
+ 		.maxlen		= sizeof(unsigned int),
+@@ -126,6 +127,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.extra2		= &max_max_requests
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "max_req_size",
+ 		.data		= &svcrdma_max_req_size,
+ 		.maxlen		= sizeof(unsigned int),
+@@ -136,6 +138,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.extra2		= &max_max_inline
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "max_outbound_read_requests",
+ 		.data		= &svcrdma_ord,
+ 		.maxlen		= sizeof(unsigned int),
+@@ -147,6 +150,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 	},
+ 
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_read",
+ 		.data		= &rdma_stat_read,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -154,6 +158,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_recv",
+ 		.data		= &rdma_stat_recv,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -161,6 +166,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_write",
+ 		.data		= &rdma_stat_write,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -168,6 +174,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_sq_starve",
+ 		.data		= &rdma_stat_sq_starve,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -175,6 +182,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_rq_starve",
+ 		.data		= &rdma_stat_rq_starve,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -182,6 +190,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_rq_poll",
+ 		.data		= &rdma_stat_rq_poll,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -189,6 +198,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_rq_prod",
+ 		.data		= &rdma_stat_rq_prod,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -196,6 +206,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_sq_poll",
+ 		.data		= &rdma_stat_sq_poll,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -203,6 +214,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 		.proc_handler	= &read_reset_stat,
+ 	},
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "rdma_stat_sq_prod",
+ 		.data		= &rdma_stat_sq_prod,
+ 		.maxlen		= sizeof(atomic_t),
+@@ -216,6 +228,7 @@ static ctl_table svcrdma_parm_table[] = {
+ 
+ static ctl_table svcrdma_table[] = {
+ 	{
++		.ctl_name	= CTL_UNNUMBERED,
+ 		.procname	= "svc_rdma",
+ 		.mode		= 0555,
+ 		.child		= svcrdma_parm_table
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0080_revert_to_2_6_28.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0080_revert_to_2_6_28.patch
new file mode 100644
index 0000000..59385b0
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0080_revert_to_2_6_28.patch
@@ -0,0 +1,92 @@
+diff --git a/drivers/infiniband/ulp/sdp/sdp_main.c b/drivers/infiniband/ulp/sdp/sdp_main.c
+index 7a38c47..51801e0 100644
+--- a/drivers/infiniband/ulp/sdp/sdp_main.c
++++ b/drivers/infiniband/ulp/sdp/sdp_main.c
+@@ -580,7 +580,7 @@ adjudge_to_death:
+ 		/* TODO: tcp_fin_time to get timeout */
+ 		sdp_dbg(sk, "%s: entering time wait refcnt %d\n", __func__,
+ 			atomic_read(&sk->sk_refcnt));
+-		percpu_counter_inc(sk->sk_prot->orphan_count);
++		atomic_inc(sk->sk_prot->orphan_count);
+ 	}
+ 
+ 	/* TODO: limit number of orphaned sockets.
+@@ -861,7 +861,7 @@ void sdp_cancel_dreq_wait_timeout(struct sdp_sock *ssk)
+ 		sock_put(&ssk->isk.sk, SOCK_REF_DREQ_TO);
+ 	}
+ 
+-	percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
++	atomic_dec(ssk->isk.sk.sk_prot->orphan_count);
+ }
+ 
+ void sdp_destroy_work(struct work_struct *work)
+@@ -902,7 +902,7 @@ void sdp_dreq_wait_timeout_work(struct work_struct *work)
+ 	sdp_sk(sk)->dreq_wait_timeout = 0;
+ 
+ 	if (sk->sk_state == TCP_FIN_WAIT1)
+-		percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
++		atomic_dec(ssk->isk.sk.sk_prot->orphan_count);
+ 
+ 	sdp_exch_state(sk, TCPF_LAST_ACK | TCPF_FIN_WAIT1, TCP_TIME_WAIT);
+ 
+@@ -2162,9 +2162,9 @@ void sdp_urg(struct sdp_sock *ssk, struct sk_buff *skb)
+ 		sk->sk_data_ready(sk, 0);
+ }
+ 
+-static struct percpu_counter *sockets_allocated;
++static atomic_t sockets_allocated;
+ static atomic_t memory_allocated;
+-static struct percpu_counter *orphan_count;
++static atomic_t orphan_count;
+ static int memory_pressure;
+ struct proto sdp_proto = {
+         .close       = sdp_close,
+@@ -2182,8 +2182,10 @@ struct proto sdp_proto = {
+         .get_port    = sdp_get_port,
+ 	/* Wish we had this: .listen   = sdp_listen */
+ 	.enter_memory_pressure = sdp_enter_memory_pressure,
++	.sockets_allocated = &sockets_allocated,
+ 	.memory_allocated = &memory_allocated,
+ 	.memory_pressure = &memory_pressure,
++	.orphan_count = &orphan_count,
+         .sysctl_mem             = sysctl_tcp_mem,
+         .sysctl_wmem            = sysctl_tcp_wmem,
+         .sysctl_rmem            = sysctl_tcp_rmem,
+@@ -2538,15 +2540,6 @@ static int __init sdp_init(void)
+ 	spin_lock_init(&sock_list_lock);
+ 	spin_lock_init(&sdp_large_sockets_lock);
+ 
+-	sockets_allocated = kmalloc(sizeof(*sockets_allocated), GFP_KERNEL);
+-	orphan_count = kmalloc(sizeof(*orphan_count), GFP_KERNEL);
+-	percpu_counter_init(sockets_allocated, 0);
+-	percpu_counter_init(orphan_count, 0);
+-
+-	sdp_proto.sockets_allocated = sockets_allocated;
+-	sdp_proto.orphan_count = orphan_count;
+-
+-
+ 	sdp_workqueue = create_singlethread_workqueue("sdp");
+ 	if (!sdp_workqueue) {
+ 		return -ENOMEM;
+@@ -2581,9 +2574,9 @@ static void __exit sdp_exit(void)
+ 	sock_unregister(PF_INET_SDP);
+ 	proto_unregister(&sdp_proto);
+ 
+-	if (percpu_counter_read_positive(orphan_count))
+-		printk(KERN_WARNING "%s: orphan_count %lld\n", __func__,
+-		       percpu_counter_read_positive(orphan_count));
++	if (atomic_read(&orphan_count))
++		printk(KERN_WARNING "%s: orphan_count %d\n", __func__,
++		       atomic_read(&orphan_count));
+ 	destroy_workqueue(sdp_workqueue);
+ 	flush_scheduled_work();
+ 
+@@ -2596,8 +2589,6 @@ static void __exit sdp_exit(void)
+ 	sdp_proc_unregister();
+ 
+ 	ib_unregister_client(&sdp_client);
+-	kfree(orphan_count);
+-	kfree(sockets_allocated);
+ }
+ 
+ module_init(sdp_init);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0090_revert_to_2_6_24.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0090_revert_to_2_6_24.patch
new file mode 100644
index 0000000..893db9b
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0090_revert_to_2_6_24.patch
@@ -0,0 +1,242 @@
+---
+ drivers/infiniband/ulp/sdp/sdp.h       |   26 --------------------------
+ drivers/infiniband/ulp/sdp/sdp_bcopy.c |   24 ++++++++++++------------
+ drivers/infiniband/ulp/sdp/sdp_cma.c   |    2 --
+ drivers/infiniband/ulp/sdp/sdp_main.c  |   19 +++++++++----------
+ 4 files changed, 21 insertions(+), 50 deletions(-)
+
+Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp.h
+===================================================================
+--- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp.h
++++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp.h
+@@ -317,30 +317,4 @@
+ void sdp_start_keepalive_timer(struct sock *sk);
+ void sdp_bzcopy_write_space(struct sdp_sock *ssk);
+ 
+-static inline struct sk_buff *sdp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
+-{
+-	struct sk_buff *skb;
+-
+-	/* The TCP header must be at least 32-bit aligned.  */
+-	size = ALIGN(size, 4);
+-
+-	skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
+-	if (skb) {
+-		if (sk_wmem_schedule(sk, skb->truesize)) {
+-			/*
+-			 * Make sure that we have exactly size bytes
+-			 * available to the caller, no more, no less.
+-			 */
+-			skb_reserve(skb, skb_tailroom(skb) - size);
+-			return skb;
+-		}
+-		__kfree_skb(skb);
+-	} else {
+-		sk->sk_prot->enter_memory_pressure(sk);
+-		sk_stream_moderate_sndbuf(sk);
+-	}
+-	return NULL;
+-}
+-
+-
+ #endif
+Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_bcopy.c
+===================================================================
+--- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_bcopy.c
++++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_bcopy.c
+@@ -139,7 +139,7 @@
+ 	}
+ 
+ 
+-	sk_mem_reclaim(sk);
++	sk_stream_mem_reclaim(sk);
+ 
+ 	if (!sock_flag(sk, SOCK_DEAD)) {
+ 		sk->sk_state_change(sk);
+@@ -190,7 +190,7 @@
+ 	struct ib_send_wr *bad_wr;
+ 
+ 	h->mid = mid;
+-	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG))
++	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_URG))
+ 		h->flags = SDP_OOB_PRES | SDP_OOB_PEND;
+ 	else
+ 		h->flags = 0;
+@@ -234,7 +234,7 @@
+ 	ssk->tx_wr.num_sge = frags + 1;
+ 	ssk->tx_wr.opcode = IB_WR_SEND;
+ 	ssk->tx_wr.send_flags = IB_SEND_SIGNALED;
+-	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG))
++	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_URG))
+ 		ssk->tx_wr.send_flags |= IB_SEND_SOLICITED;
+ 	rc = ib_post_send(ssk->qp, &ssk->tx_wr, &bad_wr);
+ 	++ssk->tx_head;
+@@ -304,11 +304,11 @@
+ 	/* TODO: allocate from cache */
+ 
+ 	if (unlikely(ssk->isk.sk.sk_allocation)) {
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
+ 					  ssk->isk.sk.sk_allocation);
+ 		gfp_page = ssk->isk.sk.sk_allocation | __GFP_HIGHMEM;
+ 	} else {
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
+ 					  GFP_KERNEL);
+ 		gfp_page = GFP_HIGHUSER;
+ 	}
+@@ -476,7 +476,7 @@
+ 	if (likely(ssk->bufs > 1) &&
+ 	    likely(ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE)) {
+ 		struct sk_buff *skb;
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk,
+ 					  sizeof(struct sdp_bsdh),
+ 					  GFP_KERNEL);
+ 		if (!skb)
+@@ -514,7 +514,7 @@
+ 	    ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE) {
+ 		struct sdp_chrecvbuf *resp_size;
+ 		ssk->recv_request = 0;
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk,
+ 					  sizeof(struct sdp_bsdh) +
+ 					  sizeof(*resp_size),
+ 					  gfp_page);
+@@ -539,7 +539,7 @@
+ 	    ssk->tx_head > ssk->sent_request_head + SDP_RESIZE_WAIT &&
+ 	    ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE) {
+ 		struct sdp_chrecvbuf *req_size;
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk,
+ 					  sizeof(struct sdp_bsdh) +
+ 					  sizeof(*req_size),
+ 					  gfp_page);
+@@ -561,7 +561,7 @@
+ 	    likely(ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE) &&
+ 	    likely((1 << ssk->isk.sk.sk_state) &
+ 		    (TCPF_ESTABLISHED | TCPF_FIN_WAIT1))) {
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk,
+ 					  sizeof(struct sdp_bsdh),
+ 					  GFP_KERNEL);
+ 		/* FIXME */
+@@ -573,7 +573,7 @@
+ 		!ssk->isk.sk.sk_send_head &&
+ 		ssk->bufs > (ssk->remote_credits >= ssk->rx_head - ssk->rx_tail)) {
+ 		ssk->sdp_disconnect = 0;
+-		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
++		skb = sk_stream_alloc_skb(&ssk->isk.sk,
+ 					  sizeof(struct sdp_bsdh),
+ 					  gfp_page);
+ 		/* FIXME */
+@@ -778,7 +778,7 @@
+ 	}
+ 
+ out:
+-	sk_wmem_free_skb(&ssk->isk.sk, skb);
++	sk_stream_free_skb(&ssk->isk.sk, skb);
+ 
+ 	return 0;
+ }
+@@ -864,7 +864,7 @@
+ 
+ 	sdp_poll_cq(ssk, cq);
+ 	release_sock(sk);
+-	sk_mem_reclaim(sk);
++	sk_stream_mem_reclaim(sk);
+ 	lock_sock(sk);
+ 	cq = ssk->cq;
+ 	if (unlikely(!cq))
+Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_cma.c
+===================================================================
+--- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_cma.c
++++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_cma.c
+@@ -161,8 +161,6 @@
+ 		goto err_cq;
+ 	}
+ 
+-	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+-
+         qp_init_attr.send_cq = qp_init_attr.recv_cq = cq;
+ 
+ 	rc = rdma_create_qp(id, pd, &qp_init_attr);
+Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
+===================================================================
+--- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_main.c
++++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
+@@ -509,7 +509,7 @@
+ 		__kfree_skb(skb);
+ 	}
+ 
+-	sk_mem_reclaim(sk);
++	sk_stream_mem_reclaim(sk);
+ 
+ 	/* As outlined in draft-ietf-tcpimpl-prob-03.txt, section
+ 	 * 3.10, we send a RST here because data was lost.  To
+@@ -1200,7 +1200,7 @@
+ {
+ 	if (unlikely(flags & MSG_OOB)) {
+ 		struct sk_buff *skb = sk->sk_write_queue.prev;
+-		TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_URG;
++		TCP_SKB_CB(skb)->flags |= TCPCB_URG;
+ 	}
+ }
+ 
+@@ -1217,8 +1217,7 @@
+ {
+         skb_header_release(skb);
+         __skb_queue_tail(&sk->sk_write_queue, skb);
+-	sk->sk_wmem_queued += skb->truesize;
+-        sk_mem_charge(sk, skb->truesize);
++	sk_charge_skb(sk, skb);
+         if (!sk->sk_send_head)
+                 sk->sk_send_head = skb;
+         if (ssk->nonagle & TCP_NAGLE_PUSH)
+@@ -1382,7 +1381,7 @@
+ 		if (copy > PAGE_SIZE - off)
+ 			copy = PAGE_SIZE - off;
+ 
+-		if (!sk_wmem_schedule(sk, copy))
++		if (!sk_stream_wmem_schedule(sk, copy))
+ 			return SDP_DO_WAIT_MEM;
+ 
+ 		if (!page) {
+@@ -1454,7 +1453,7 @@
+ 		if (left <= this_page)
+ 			this_page = left;
+ 
+-		if (!sk_wmem_schedule(sk, copy))
++		if (!sk_stream_wmem_schedule(sk, copy))
+ 			return SDP_DO_WAIT_MEM;
+ 
+ 		skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
+@@ -1662,8 +1661,8 @@
+ 						goto wait_for_sndbuf;
+ 				}
+ 
+-				skb = sdp_stream_alloc_skb(sk, select_size(sk, ssk),
+-							   sk->sk_allocation);
++				skb = sk_stream_alloc_pskb(sk, select_size(sk, ssk),
++							   0, sk->sk_allocation);
+ 				if (!skb)
+ 					goto wait_for_memory;
+ 
+@@ -1687,7 +1686,7 @@
+ 
+ 			/* OOB data byte should be the last byte of
+ 			   the data payload */
+-			if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG) &&
++			if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_URG) &&
+ 			    !(flags & MSG_OOB)) {
+ 				sdp_mark_push(ssk, skb);
+ 				goto new_segment;
+@@ -1763,7 +1762,7 @@
+ 		if (sk->sk_send_head == skb)
+ 			sk->sk_send_head = NULL;
+ 		__skb_unlink(skb, &sk->sk_write_queue);
+-		sk_wmem_free_skb(sk, skb);
++		sk_stream_free_skb(sk, skb);
+ 	}
+ 
+ do_error:
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0100_revert_to_2_6_23.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0100_revert_to_2_6_23.patch
new file mode 100644
index 0000000..0d22e37
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0100_revert_to_2_6_23.patch
@@ -0,0 +1,54 @@
+---
+ drivers/infiniband/ulp/sdp/sdp_main.c |   12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
+===================================================================
+--- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_main.c
++++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
+@@ -2158,16 +2158,13 @@
+ 	.sendpage   = sock_no_sendpage,
+ };
+ 
+-static int sdp_create_socket(struct net *net, struct socket *sock, int protocol)
++static int sdp_create_socket(struct socket *sock, int protocol)
+ {
+ 	struct sock *sk;
+ 	int rc;
+ 
+ 	sdp_dbg(NULL, "%s: type %d protocol %d\n", __func__, sock->type, protocol);
+ 
+-	if (net != &init_net)
+-		return -EAFNOSUPPORT;
+-
+ 	if (sock->type != SOCK_STREAM) {
+ 		sdp_warn(NULL, "SDP: unsupported type %d.\n", sock->type);
+ 		return -ESOCKTNOSUPPORT;
+@@ -2179,7 +2176,7 @@
+ 		return -EPROTONOSUPPORT;
+ 	}
+ 
+-	sk = sk_alloc(net, PF_INET_SDP, GFP_KERNEL, &sdp_proto);
++	sk = sk_alloc(PF_INET_SDP, GFP_KERNEL, &sdp_proto, 1);
+ 	if (!sk) {
+ 		sdp_warn(NULL, "SDP: failed to allocate socket.\n");
+ 		return -ENOMEM;
+@@ -2363,8 +2360,7 @@
+ 	sdp_seq_afinfo.seq_fops->llseek        = seq_lseek;
+ 	sdp_seq_afinfo.seq_fops->release       = seq_release_private;
+ 
+-	p = proc_net_fops_create(&init_net, sdp_seq_afinfo.name, S_IRUGO,
+-				 sdp_seq_afinfo.seq_fops);
++ 	p = proc_net_fops_create(sdp_seq_afinfo.name, S_IRUGO, sdp_seq_afinfo.seq_fops);
+ 	if (p)
+ 		p->data = &sdp_seq_afinfo;
+ 	else
+@@ -2375,7 +2371,7 @@
+ 
+ static void sdp_proc_unregister(void)
+ {
+-	proc_net_remove(&init_net, sdp_seq_afinfo.name);
++	proc_net_remove(sdp_seq_afinfo.name);
+ 	memset(sdp_seq_afinfo.seq_fops, 0, sizeof(*sdp_seq_afinfo.seq_fops));
+ }
+ 
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0120_revert_2_6_27_to_2_6_24.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0120_revert_2_6_27_to_2_6_24.patch
new file mode 100644
index 0000000..bc538c3
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/sdp_0120_revert_2_6_27_to_2_6_24.patch
@@ -0,0 +1,51 @@
+---
+ drivers/infiniband/ulp/sdp/sdp_cma.c  |    1 +
+ drivers/infiniband/ulp/sdp/sdp_main.c |    8 ++++----
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/sdp/sdp_cma.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/sdp/sdp_cma.c
++++ ofed_kernel/drivers/infiniband/ulp/sdp/sdp_cma.c
+@@ -31,6 +31,7 @@
+  *
+  * $Id$
+  */
++#include <asm/semaphore.h>
+ #include <linux/device.h>
+ #include <linux/in.h>
+ #include <linux/err.h>
+Index: ofed_kernel/drivers/infiniband/ulp/sdp/sdp_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/sdp/sdp_main.c
++++ ofed_kernel/drivers/infiniband/ulp/sdp/sdp_main.c
+@@ -523,7 +523,7 @@ static void sdp_close(struct sock *sk, l
+ 	if (data_was_unread ||
+ 		(sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) {
+ 		/* Unread data was tossed, zap the connection. */
+-		NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
++		NET_INC_STATS_USER(LINUX_MIB_TCPABORTONCLOSE);
+ 		sdp_exch_state(sk, TCPF_CLOSE_WAIT | TCPF_ESTABLISHED,
+ 			       TCP_TIME_WAIT);
+ 
+@@ -1845,7 +1845,7 @@ static int sdp_recvmsg(struct kiocb *ioc
+ 			if (offset < skb->len)
+ 				goto found_ok_skb;
+ 
+-			WARN_ON(!(flags & MSG_PEEK));
++			BUG_TRAP(flags & MSG_PEEK);
+ 			skb = skb->next;
+ 		} while (skb != (struct sk_buff *)&sk->sk_receive_queue);
+ 
+@@ -2082,9 +2082,9 @@ static unsigned int sdp_poll(struct file
+ 	return mask;
+ }
+ 
+-static void sdp_enter_memory_pressure(struct sock *sk)
++static void sdp_enter_memory_pressure(void)
+ {
+-	sdp_dbg(sk, "%s\n", __func__);
++	sdp_dbg(NULL, "%s\n", __func__);
+ }
+ 
+ void sdp_urg(struct sdp_sock *ssk, struct sk_buff *skb)
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/srp_0100_revert_role_to_2_6_23.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_0100_revert_role_to_2_6_23.patch
new file mode 100644
index 0000000..6e18ae8
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_0100_revert_role_to_2_6_23.patch
@@ -0,0 +1,30 @@
+commit aebd5e476ecc8ceb53577b20f2a352ff4ceffd8d
+Author: FUJITA Tomonori <tomof at acm.org>
+Date:   Wed Jul 11 15:08:15 2007 +0900
+
+    [SCSI] transport_srp: add rport roles attribute
+    
+    This adds a 'roles' attribute to rport like transport_fc. The role can
+    be initiator or target. That is, the initiator driver creates target
+    remote ports and the target driver creates initiator remote ports.
+    
+    Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
+    Signed-off-by: Mike Christie <michaelc at cs.wisc.edu>
+    Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
+
+---
+ drivers/infiniband/ulp/srp/ib_srp.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
++++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -1741,7 +1741,6 @@ static int srp_add_target(struct srp_hos
+ 
+ 	memcpy(ids.port_id, &target->id_ext, 8);
+ 	memcpy(ids.port_id + 8, &target->ioc_guid, 8);
+-	ids.roles = SRP_RPORT_ROLE_TARGET;
+ 	rport = srp_rport_add(target->scsi_host, &ids);
+ 	if (IS_ERR(rport)) {
+ 		scsi_remove_host(target->scsi_host);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/srp_0200_revert_srp_transport_to_2.6.23.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_0200_revert_srp_transport_to_2.6.23.patch
new file mode 100644
index 0000000..924dc9c
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_0200_revert_srp_transport_to_2.6.23.patch
@@ -0,0 +1,146 @@
+commit 3236822b1c9b67ad10745d965515b528818f1120
+Author: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
+Date:   Wed Jun 27 16:33:12 2007 +0900
+
+    [SCSI] ib_srp: convert to use the srp transport class
+    
+    This converts ib_srp to use the srp transport class.
+    
+    I don't have ib hardware so I've not tested this patch.
+    
+    Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
+    Cc: Roland Dreier <rolandd at cisco.com>
+    Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
+
+---
+ drivers/infiniband/ulp/srp/Kconfig  |    1 -
+ drivers/infiniband/ulp/srp/ib_srp.c |   28 ----------------------------
+ 2 files changed, 29 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/srp/Kconfig
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/Kconfig
++++ ofed_kernel/drivers/infiniband/ulp/srp/Kconfig
+@@ -1,7 +1,6 @@
+ config INFINIBAND_SRP
+ 	tristate "InfiniBand SCSI RDMA Protocol"
+ 	depends on SCSI
+-	select SCSI_SRP_ATTRS
+ 	---help---
+ 	  Support for the SCSI RDMA Protocol over InfiniBand.  This
+ 	  allows you to access storage devices that speak SRP over
+Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
++++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -45,7 +45,6 @@
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_dbg.h>
+ #include <scsi/srp.h>
+-#include <scsi/scsi_transport_srp.h>
+ 
+ #include "ib_srp.h"
+ 
+@@ -90,8 +89,6 @@ static void srp_remove_one(struct ib_dev
+ static void srp_completion(struct ib_cq *cq, void *target_ptr);
+ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
+ 
+-static struct scsi_transport_template *ib_srp_transport_template;
+-
+ static struct ib_client srp_client = {
+ 	.name   = "srp",
+ 	.add    = srp_add_one,
+@@ -447,7 +444,6 @@ static void srp_remove_work(struct work_
+ 	list_del(&target->list);
+ 	spin_unlock(&target->srp_host->target_lock);
+ 
+-	srp_remove_host(target->scsi_host);
+ 	scsi_remove_host(target->scsi_host);
+ 	ib_destroy_cm_id(target->cm_id);
+ 	srp_free_target_ib(target);
+@@ -1730,23 +1726,12 @@ static struct scsi_host_template srp_tem
+ 
+ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
+ {
+-	struct srp_rport_identifiers ids;
+-	struct srp_rport *rport;
+-
+ 	sprintf(target->target_name, "SRP.T10:%016llX",
+ 		 (unsigned long long) be64_to_cpu(target->id_ext));
+ 
+ 	if (scsi_add_host(target->scsi_host, host->srp_dev->dev->dma_device))
+ 		return -ENODEV;
+ 
+-	memcpy(ids.port_id, &target->id_ext, 8);
+-	memcpy(ids.port_id + 8, &target->ioc_guid, 8);
+-	rport = srp_rport_add(target->scsi_host, &ids);
+-	if (IS_ERR(rport)) {
+-		scsi_remove_host(target->scsi_host);
+-		return PTR_ERR(rport);
+-	}
+-
+ 	spin_lock(&host->target_lock);
+ 	list_add_tail(&target->list, &host->target_list);
+ 	spin_unlock(&host->target_lock);
+@@ -1973,7 +1958,6 @@ static ssize_t srp_create_target(struct 
+ 	if (!target_host)
+ 		return -ENOMEM;
+ 
+-	target_host->transportt = ib_srp_transport_template;
+ 	target_host->max_lun     = SRP_MAX_LUN;
+ 	target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
+ 
+@@ -2307,7 +2291,6 @@ static void srp_remove_one(struct ib_dev
+ 
+ 		list_for_each_entry_safe(target, tmp_target,
+ 					 &host->target_list, list) {
+-			srp_remove_host(target->scsi_host);
+ 			scsi_remove_host(target->scsi_host);
+ 			srp_disconnect_target(target);
+ 			ib_destroy_cm_id(target->cm_id);
+@@ -2326,9 +2309,6 @@ static void srp_remove_one(struct ib_dev
+ 	kfree(srp_dev);
+ }
+ 
+-static struct srp_function_template ib_srp_transport_functions = {
+-};
+-
+ static int __init srp_init_module(void)
+ {
+ 	int ret;
+@@ -2338,11 +2318,6 @@ static int __init srp_init_module(void)
+ 		srp_sg_tablesize = 255;
+ 	}
+ 
+-	ib_srp_transport_template =
+-		srp_attach_transport(&ib_srp_transport_functions);
+-	if (!ib_srp_transport_template)
+-		return -ENOMEM;
+-
+ 	srp_template.sg_tablesize = srp_sg_tablesize;
+ 	srp_max_iu_len = (sizeof (struct srp_cmd) +
+ 			  sizeof (struct srp_indirect_buf) +
+@@ -2354,7 +2329,6 @@ static int __init srp_init_module(void)
+ 	ret = class_register(&srp_class);
+ 	if (ret) {
+ 		printk(KERN_ERR PFX "couldn't register class infiniband_srp\n");
+-		srp_release_transport(ib_srp_transport_template);
+ 		return ret;
+ 	}
+ 
+@@ -2363,7 +2337,6 @@ static int __init srp_init_module(void)
+ 	ret = ib_register_client(&srp_client);
+ 	if (ret) {
+ 		printk(KERN_ERR PFX "couldn't register IB client\n");
+-		srp_release_transport(ib_srp_transport_template);
+ 		ib_sa_unregister_client(&srp_sa_client);
+ 		class_unregister(&srp_class);
+ 		return ret;
+@@ -2377,7 +2350,6 @@ static void __exit srp_cleanup_module(vo
+ 	ib_unregister_client(&srp_client);
+ 	ib_sa_unregister_client(&srp_sa_client);
+ 	class_unregister(&srp_class);
+-	srp_release_transport(ib_srp_transport_template);
+ }
+ 
+ module_init(srp_init_module);
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/srp_class_device_if.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_class_device_if.patch
new file mode 100644
index 0000000..5634d8e
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_class_device_if.patch
@@ -0,0 +1,333 @@
+---
+ drivers/infiniband/ulp/srp/ib_srp.c |  154 ++++++++++++++++--------------------
+ drivers/infiniband/ulp/srp/ib_srp.h |    2 
+ 2 files changed, 72 insertions(+), 84 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
++++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -1517,10 +1517,9 @@ static int srp_reset_host(struct scsi_cm
+ 	return ret;
+ }
+ 
+-static ssize_t show_id_ext(struct device *dev, struct device_attribute *attr,
+-			   char *buf)
++static ssize_t show_id_ext(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1530,10 +1529,9 @@ static ssize_t show_id_ext(struct device
+ 		       (unsigned long long) be64_to_cpu(target->id_ext));
+ }
+ 
+-static ssize_t show_ioc_guid(struct device *dev, struct device_attribute *attr,
+-			     char *buf)
++static ssize_t show_ioc_guid(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1543,10 +1541,9 @@ static ssize_t show_ioc_guid(struct devi
+ 		       (unsigned long long) be64_to_cpu(target->ioc_guid));
+ }
+ 
+-static ssize_t show_service_id(struct device *dev,
+-			       struct device_attribute *attr, char *buf)
++static ssize_t show_service_id(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1556,10 +1553,9 @@ static ssize_t show_service_id(struct de
+ 		       (unsigned long long) be64_to_cpu(target->service_id));
+ }
+ 
+-static ssize_t show_pkey(struct device *dev, struct device_attribute *attr,
+-			 char *buf)
++static ssize_t show_pkey(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1568,10 +1564,9 @@ static ssize_t show_pkey(struct device *
+ 	return sprintf(buf, "0x%04x\n", be16_to_cpu(target->path.pkey));
+ }
+ 
+-static ssize_t show_dgid(struct device *dev, struct device_attribute *attr,
+-			 char *buf)
++static ssize_t show_dgid(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1588,10 +1583,9 @@ static ssize_t show_dgid(struct device *
+ 		       be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
+ }
+ 
+-static ssize_t show_orig_dgid(struct device *dev,
+-			      struct device_attribute *attr, char *buf)
++static ssize_t show_orig_dgid(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1608,10 +1602,9 @@ static ssize_t show_orig_dgid(struct dev
+ 		       be16_to_cpu(target->orig_dgid[7]));
+ }
+ 
+-static ssize_t show_zero_req_lim(struct device *dev,
+-				 struct device_attribute *attr, char *buf)
++static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	if (target->state == SRP_TARGET_DEAD ||
+ 	    target->state == SRP_TARGET_REMOVED)
+@@ -1620,27 +1613,24 @@ static ssize_t show_zero_req_lim(struct 
+ 	return sprintf(buf, "%d\n", target->zero_req_lim);
+ }
+ 
+-static ssize_t show_local_ib_port(struct device *dev,
+-				  struct device_attribute *attr, char *buf)
++static ssize_t show_local_ib_port(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	return sprintf(buf, "%d\n", target->srp_host->port);
+ }
+ 
+-static ssize_t show_local_ib_device(struct device *dev,
+-				    struct device_attribute *attr, char *buf)
++static ssize_t show_local_ib_device(struct class_device *cdev, char *buf)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name);
+ }
+ 
+-static ssize_t srp_target_oofabric(struct device *dev,
+-				   struct device_attribute *attr, const char *buf,
+-				   size_t count)
++static ssize_t srp_target_oofabric(struct class_device *cdev,
++ 				   const char *buf, size_t count)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	shost_printk(KERN_DEBUG, target->scsi_host, PFX
+ 		     "Get async_event out-of-fabric at state=%d qp_err=%d\n",
+@@ -1657,11 +1647,10 @@ static ssize_t srp_target_oofabric(struc
+ 	return count;
+ }
+ 
+-static ssize_t srp_target_infabric(struct device *dev,
+-				   struct device_attribute *attr, const char *buf,
+-				   size_t count)
++static ssize_t srp_target_infabric(struct class_device *cdev,
++ 				   const char *buf, size_t count)
+ {
+-	struct srp_target_port *target = host_to_target(class_to_shost(dev));
++ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+ 
+ 	shost_printk(KERN_DEBUG, target->scsi_host, PFX
+ 		     "Get async_event in-fabric at state=%d qp_err=%d\n",
+@@ -1681,30 +1670,30 @@ static ssize_t srp_target_infabric(struc
+ 	return count;
+ }
+ 
+-static DEVICE_ATTR(id_ext,	    S_IRUGO, show_id_ext,	   NULL);
+-static DEVICE_ATTR(ioc_guid,	    S_IRUGO, show_ioc_guid,	   NULL);
+-static DEVICE_ATTR(service_id,	    S_IRUGO, show_service_id,	   NULL);
+-static DEVICE_ATTR(pkey,	    S_IRUGO, show_pkey,		   NULL);
+-static DEVICE_ATTR(dgid,	    S_IRUGO, show_dgid,		   NULL);
+-static DEVICE_ATTR(orig_dgid,	    S_IRUGO, show_orig_dgid,	   NULL);
+-static DEVICE_ATTR(zero_req_lim,    S_IRUGO, show_zero_req_lim,	   NULL);
+-static DEVICE_ATTR(local_ib_port,   S_IRUGO, show_local_ib_port,   NULL);
+-static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
+-static DEVICE_ATTR(target_oofabric, S_IWUSR, NULL,  srp_target_oofabric);
+-static DEVICE_ATTR(target_infabric, S_IWUSR, NULL,  srp_target_infabric);
+-
+-static struct device_attribute *srp_host_attrs[] = {
+-	&dev_attr_id_ext,
+-	&dev_attr_ioc_guid,
+-	&dev_attr_service_id,
+-	&dev_attr_pkey,
+-	&dev_attr_dgid,
+-	&dev_attr_orig_dgid,
+-	&dev_attr_zero_req_lim,
+-	&dev_attr_local_ib_port,
+-	&dev_attr_local_ib_device,
+-	&dev_attr_target_oofabric,
+-	&dev_attr_target_infabric,
++static CLASS_DEVICE_ATTR(id_ext,	  S_IRUGO, show_id_ext,		 NULL);
++static CLASS_DEVICE_ATTR(ioc_guid,	  S_IRUGO, show_ioc_guid,	 NULL);
++static CLASS_DEVICE_ATTR(service_id,	  S_IRUGO, show_service_id,	 NULL);
++static CLASS_DEVICE_ATTR(pkey,		  S_IRUGO, show_pkey,		 NULL);
++static CLASS_DEVICE_ATTR(dgid,		  S_IRUGO, show_dgid,		 NULL);
++static CLASS_DEVICE_ATTR(orig_dgid,	  S_IRUGO, show_orig_dgid,	 NULL);
++static CLASS_DEVICE_ATTR(zero_req_lim,	  S_IRUGO, show_zero_req_lim,	 NULL);
++static CLASS_DEVICE_ATTR(local_ib_port,   S_IRUGO, show_local_ib_port,	 NULL);
++static CLASS_DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
++static CLASS_DEVICE_ATTR(target_oofabric, S_IWUSR, NULL,  srp_target_oofabric);
++static CLASS_DEVICE_ATTR(target_infabric, S_IWUSR, NULL,  srp_target_infabric);
++
++static struct class_device_attribute *srp_host_attrs[] = {
++	&class_device_attr_id_ext,
++	&class_device_attr_ioc_guid,
++	&class_device_attr_service_id,
++	&class_device_attr_pkey,
++	&class_device_attr_dgid,
++	&class_device_attr_orig_dgid,
++	&class_device_attr_zero_req_lim,
++	&class_device_attr_local_ib_port,
++	&class_device_attr_local_ib_device,
++ 	&class_device_attr_target_oofabric,
++ 	&class_device_attr_target_infabric,
+ 	NULL
+ };
+ 
+@@ -1744,17 +1733,17 @@ static int srp_add_target(struct srp_hos
+ 	return 0;
+ }
+ 
+-static void srp_release_dev(struct device *dev)
++static void srp_release_class_dev(struct class_device *class_dev)
+ {
+ 	struct srp_host *host =
+-		container_of(dev, struct srp_host, dev);
++		container_of(class_dev, struct srp_host, class_dev);
+ 
+ 	complete(&host->released);
+ }
+ 
+ static struct class srp_class = {
+ 	.name    = "infiniband_srp",
+-	.dev_release = srp_release_dev
++	.release = srp_release_class_dev
+ };
+ 
+ /*
+@@ -1942,12 +1931,11 @@ out:
+ 	return ret;
+ }
+ 
+-static ssize_t srp_create_target(struct device *dev,
+-				 struct device_attribute *attr,
++static ssize_t srp_create_target(struct class_device *class_dev,
+ 				 const char *buf, size_t count)
+ {
+ 	struct srp_host *host =
+-		container_of(dev, struct srp_host, dev);
++		container_of(class_dev, struct srp_host, class_dev);
+ 	struct Scsi_Host *target_host;
+ 	struct srp_target_port *target;
+ 	int ret;
+@@ -2033,27 +2021,27 @@ err:
+ 	return ret;
+ }
+ 
+-static DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);
++static CLASS_DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);
+ 
+-static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
+-			  char *buf)
++static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+ {
+-	struct srp_host *host = container_of(dev, struct srp_host, dev);
++	struct srp_host *host =
++		container_of(class_dev, struct srp_host, class_dev);
+ 
+ 	return sprintf(buf, "%s\n", host->srp_dev->dev->name);
+ }
+ 
+-static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
++static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+ 
+-static ssize_t show_port(struct device *dev, struct device_attribute *attr,
+-			 char *buf)
++static ssize_t show_port(struct class_device *class_dev, char *buf)
+ {
+-	struct srp_host *host = container_of(dev, struct srp_host, dev);
++	struct srp_host *host =
++		container_of(class_dev, struct srp_host, class_dev);
+ 
+ 	return sprintf(buf, "%d\n", host->port);
+ }
+ 
+-static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
++static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+ 
+ static struct srp_host *srp_add_port(struct srp_device *device, u8 port)
+ {
+@@ -2069,24 +2057,24 @@ static struct srp_host *srp_add_port(str
+ 	host->srp_dev = device;
+ 	host->port = port;
+ 
+-	host->dev.class = &srp_class;
+-	host->dev.parent = device->dev->dma_device;
+-	snprintf(host->dev.bus_id, BUS_ID_SIZE, "srp-%s-%d",
++ 	host->class_dev.class = &srp_class;
++ 	host->class_dev.dev   = device->dev->dma_device;
++ 	snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",
+ 		 device->dev->name, port);
+ 
+-	if (device_register(&host->dev))
++ 	if (class_device_register(&host->class_dev))
+ 		goto free_host;
+-	if (device_create_file(&host->dev, &dev_attr_add_target))
++ 	if (class_device_create_file(&host->class_dev, &class_device_attr_add_target))
+ 		goto err_class;
+-	if (device_create_file(&host->dev, &dev_attr_ibdev))
++ 	if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev))
+ 		goto err_class;
+-	if (device_create_file(&host->dev, &dev_attr_port))
++ 	if (class_device_create_file(&host->class_dev, &class_device_attr_port))
+ 		goto err_class;
+ 
+ 	return host;
+ 
+ err_class:
+-	device_unregister(&host->dev);
++ 	class_device_unregister(&host->class_dev);
+ 
+ free_host:
+ 	kfree(host);
+@@ -2263,7 +2251,7 @@ static void srp_remove_one(struct ib_dev
+ 	ib_unregister_event_handler(&srp_dev->event_handler);
+ 
+ 	list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) {
+-		device_unregister(&host->dev);
++		class_device_unregister(&host->class_dev);
+ 		/*
+ 		 * Wait for the sysfs entry to go away, so that no new
+ 		 * target ports can be created.
+Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.h
++++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
+@@ -98,7 +98,7 @@ struct srp_device {
+ struct srp_host {
+ 	struct srp_device      *srp_dev;
+ 	u8			port;
+-	struct device		dev;
++	struct class_device	class_dev;
+ 	struct list_head	target_list;
+ 	spinlock_t		target_lock;
+ 	struct completion	released;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/srp_cmd_to_2_6_22.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_cmd_to_2_6_22.patch
new file mode 100644
index 0000000..7af01c7
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/srp_cmd_to_2_6_22.patch
@@ -0,0 +1,79 @@
+---
+ drivers/infiniband/ulp/srp/ib_srp.c |   33 +++++++++++++++++++++++++++++----
+ drivers/infiniband/ulp/srp/ib_srp.h |    5 +++++
+ 2 files changed, 34 insertions(+), 4 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
++++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -510,6 +510,9 @@ static void srp_unmap_data(struct scsi_c
+ 			   struct srp_target_port *target,
+ 			   struct srp_request *req)
+ {
++	struct scatterlist *scat;
++	int nents;
++
+ 	if (!scsi_sglist(scmnd) ||
+ 	    (scmnd->sc_data_direction != DMA_TO_DEVICE &&
+ 	     scmnd->sc_data_direction != DMA_FROM_DEVICE))
+@@ -520,8 +523,20 @@ static void srp_unmap_data(struct scsi_c
+ 		req->fmr = NULL;
+ 	}
+ 
+-	ib_dma_unmap_sg(target->srp_host->srp_dev->dev, scsi_sglist(scmnd),
+-			scsi_sg_count(scmnd), scmnd->sc_data_direction);
++	/*
++	 * This handling of non-SG commands can be killed when the
++	 * SCSI midlayer no longer generates non-SG commands.
++	 */
++	if (likely(scsi_sg_count(scmnd))) {
++		nents = scsi_sg_count(scmnd);
++		scat  = scsi_sglist(scmnd);
++	} else {
++		nents = 1;
++		scat  = &req->fake_sg;
++	}
++
++	ib_dma_unmap_sg(target->srp_host->srp_dev->dev, scat, nents,
++			scmnd->sc_data_direction);
+ }
+ 
+ static void srp_remove_req(struct srp_target_port *target, struct srp_request *req)
+@@ -721,8 +736,18 @@ static int srp_map_data(struct scsi_cmnd
+ 		return -EINVAL;
+ 	}
+ 
+-	nents = scsi_sg_count(scmnd);
+-	scat  = scsi_sglist(scmnd);
++	/*
++	 * This handling of non-SG commands can be killed when the
++	 * SCSI midlayer no longer generates non-SG commands.
++	 */
++	if (likely(scsi_sg_count(scmnd))) {
++		nents = scsi_sg_count(scmnd);
++		scat  = scsi_sglist(scmnd);
++	} else {
++		nents = 1;
++		scat  = &req->fake_sg;
++		sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen);
++	}
+ 
+ 	dev = target->srp_host->srp_dev;
+ 	ibdev = dev->dev;
+Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.h
++++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
+@@ -111,6 +111,11 @@ struct srp_request {
+ 	struct srp_iu	       *cmd;
+ 	struct srp_iu	       *tsk_mgmt;
+ 	struct ib_pool_fmr     *fmr;
++	/*
++	 * Fake scatterlist used when scsi_sg_count(scmnd)==0.  Can be killed
++	 * when the SCSI midlayer no longer generates non-SG commands.
++	 */
++	struct scatterlist	fake_sg;
+ 	struct completion	done;
+ 	short			index;
+ 	u8			cmd_done;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/srpt_class_dev.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/srpt_class_dev.patch
new file mode 100644
index 0000000..c6187cf
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/srpt_class_dev.patch
@@ -0,0 +1,121 @@
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c |   42 ++++++++++++++++------------------
+ drivers/infiniband/ulp/srpt/ib_srpt.h |    2 -
+ 2 files changed, 21 insertions(+), 23 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -2297,20 +2297,19 @@ struct scst_tgt_template srpt_template =
+ 	.task_mgmt_fn_done = srpt_tsk_mgmt_done
+ };
+ 
+-static void srpt_release_class_dev(struct device *dev)
++static void srpt_release_class_dev(struct class_device *class_dev)
+ {
+ }
+ 
+ static struct class srpt_class = {
+ 	.name = "infiniband_srpt",
+-	.dev_release = srpt_release_class_dev
++	.release = srpt_release_class_dev
+ };
+ 
+-static ssize_t show_login_info(struct device *dev,
+-			       struct device_attribute *attr, char *buf)
++static ssize_t show_login_info(struct class_device *class_dev, char *buf)
+ {
+ 	struct srpt_device *sdev =
+-		container_of(dev, struct srpt_device, dev);
++		container_of(class_dev, struct srpt_device, class_dev);
+ 	struct srpt_port *sport;
+ 	int i;
+ 	int len = 0;
+@@ -2338,16 +2337,15 @@ static ssize_t show_login_info(struct de
+ 	return len;
+ }
+ 
+-static DEVICE_ATTR(login_info, S_IRUGO, show_login_info, NULL);
++static CLASS_DEVICE_ATTR(login_info, S_IRUGO, show_login_info, NULL);
+ 
+-static ssize_t show_mem_info(struct device *dev, struct device_attribute *attr,
+-			     char *buf)
++static ssize_t show_mem_info(struct class_device *class_dev, char *buf)
+ {
+ 	return sprintf(buf, "mem_avail= %d mem_elements= %d mem_size= %d\n",
+ 		       mem_avail, mem_elements, mem_size);
+ }
+ 
+-static DEVICE_ATTR(mem_info, S_IRUGO, show_mem_info, NULL);
++static CLASS_DEVICE_ATTR(mem_info, S_IRUGO, show_mem_info, NULL);
+ 
+ static void srpt_add_one(struct ib_device *device)
+ {
+@@ -2362,23 +2360,23 @@ static void srpt_add_one(struct ib_devic
+ 	sdev->device = device;
+ 	init_completion(&sdev->scst_released);
+ 
+-	sdev->dev.class = &srpt_class;
+-	sdev->dev.parent = device->dma_device;
+-	snprintf(sdev->dev.bus_id, BUS_ID_SIZE, "srpt-%s", device->name);
++	sdev->class_dev.class = &srpt_class;
++	sdev->class_dev.dev = device->dma_device;
++	snprintf(sdev->class_dev.class_id, BUS_ID_SIZE, "srpt-%s", device->name);
+ 
+-	if (device_register(&sdev->dev))
++	if (class_device_register(&sdev->class_dev))
+ 		goto free_dev;
+-	if (device_create_file(&sdev->dev, &dev_attr_login_info))
+-		goto err_dev;
+-	if (device_create_file(&sdev->dev, &dev_attr_mem_info))
+-		goto err_dev;
++	if (class_device_create_file(&sdev->class_dev, &class_device_attr_login_info))
++		goto err_class;
++	if (class_device_create_file(&sdev->class_dev, &class_device_attr_mem_info))
++		goto err_class;
+ 
+ 	if (ib_query_device(device, &sdev->dev_attr))
+-		goto err_dev;
++		goto err_class;
+ 
+ 	sdev->pd = ib_alloc_pd(device);
+ 	if (IS_ERR(sdev->pd))
+-		goto err_dev;
++		goto err_class;
+ 
+ 	sdev->mr = ib_get_dma_mr(sdev->pd, IB_ACCESS_LOCAL_WRITE);
+ 	if (IS_ERR(sdev->mr))
+@@ -2450,8 +2448,8 @@ static void srpt_add_one(struct ib_devic
+ 	ib_dereg_mr(sdev->mr);
+       err_pd:
+ 	ib_dealloc_pd(sdev->pd);
+-      err_dev:
+-	device_unregister(&sdev->dev);
++      err_class:
++	class_device_unregister(&sdev->class_dev);
+       free_dev:
+ 	kfree(sdev);
+ }
+@@ -2472,7 +2470,7 @@ static void srpt_remove_one(struct ib_de
+ 	ib_destroy_srq(sdev->srq);
+ 	ib_dereg_mr(sdev->mr);
+ 	ib_dealloc_pd(sdev->pd);
+-	device_unregister(&sdev->dev);
++	class_device_unregister(&sdev->class_dev);
+ 
+ 	for (i = 0; i < SRPT_SRQ_SIZE; ++i)
+ 		srpt_free_ioctx(sdev, sdev->ioctx_ring[i]);
+Index: ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.h
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -171,7 +171,7 @@ struct srpt_device {
+ 	struct srpt_port port[2];
+ 	struct ib_event_handler event_handler;
+ 	struct completion scst_released;
+-	struct device dev;
++	struct class_device class_dev;
+ 
+ 	struct scst_tgt *scst_tgt;
+ };
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/uverbs_main_1_to_2_6_24.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/uverbs_main_1_to_2_6_24.patch
new file mode 100644
index 0000000..cf5446d
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/uverbs_main_1_to_2_6_24.patch
@@ -0,0 +1,39 @@
+---
+ drivers/infiniband/core/uverbs_main.c |   19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
++++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
+@@ -553,18 +553,23 @@ struct file *ib_uverbs_alloc_event_file(
+ 		goto err;
+ 	}
+ 
+-	/*
+-	 * fops_get() can't fail here, because we're coming from a
+-	 * system call on a uverbs file, which will already have a
+-	 * module reference.
+-	 */
+-	filp = alloc_file(uverbs_event_mnt, dget(uverbs_event_mnt->mnt_root),
+-			  FMODE_READ, fops_get(&uverbs_event_fops));
++	filp = get_empty_filp();
+ 	if (!filp) {
+ 		ret = -ENFILE;
+ 		goto err_fd;
+ 	}
+ 
++	/*
++	 * fops_get() can't fail here, because we're coming from a
++	 * system call on a uverbs file, which will already have a
++	 * module reference.
++	 */
++	filp->f_op 	   = fops_get(&uverbs_event_fops);
++	filp->f_path.mnt 	   = mntget(uverbs_event_mnt);
++	filp->f_path.dentry 	   = dget(uverbs_event_mnt->mnt_root);
++	filp->f_mapping    = filp->f_path.dentry->d_inode->i_mapping;
++	filp->f_flags      = O_RDONLY;
++	filp->f_mode       = FMODE_READ;
+ 	filp->private_data = ev_file;
+ 
+ 	return filp;
diff --git a/kernel_patches/attic/backport/2.6.18-EL5.1/uverbs_main_2_to_2_6_19.patch b/kernel_patches/attic/backport/2.6.18-EL5.1/uverbs_main_2_to_2_6_19.patch
new file mode 100644
index 0000000..11ae95b
--- /dev/null
+++ b/kernel_patches/attic/backport/2.6.18-EL5.1/uverbs_main_2_to_2_6_19.patch
@@ -0,0 +1,70 @@
+---
+ drivers/infiniband/core/uverbs_main.c        |    6 +++---
+ drivers/infiniband/hw/ipath/ipath_file_ops.c |    4 ++--
+ drivers/infiniband/hw/ipath/ipath_fs.c       |    6 +++---
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
++++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
+@@ -565,9 +565,9 @@ struct file *ib_uverbs_alloc_event_file(
+ 	 * module reference.
+ 	 */
+ 	filp->f_op 	   = fops_get(&uverbs_event_fops);
+-	filp->f_path.mnt 	   = mntget(uverbs_event_mnt);
+-	filp->f_path.dentry 	   = dget(uverbs_event_mnt->mnt_root);
+-	filp->f_mapping    = filp->f_path.dentry->d_inode->i_mapping;
++	filp->f_vfsmnt 	   = mntget(uverbs_event_mnt);
++	filp->f_dentry 	   = dget(uverbs_event_mnt->mnt_root);
++	filp->f_mapping    = filp->f_dentry->d_inode->i_mapping;
+ 	filp->f_flags      = O_RDONLY;
+ 	filp->f_mode       = FMODE_READ;
+ 	filp->private_data = ev_file;
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
+@@ -1868,9 +1868,9 @@ static int ipath_assign_port(struct file
+ 		goto done_chk_sdma;
+ 	}
+ 
+-	i_minor = iminor(fp->f_path.dentry->d_inode) - IPATH_USER_MINOR_BASE;
++	i_minor = iminor(fp->f_dentry->d_inode) - IPATH_USER_MINOR_BASE;
+ 	ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n",
+-		   (long)fp->f_path.dentry->d_inode->i_rdev, i_minor);
++		   (long)fp->f_dentry->d_inode->i_rdev, i_minor);
+ 
+ 	if (i_minor)
+ 		ret = find_free_port(i_minor - 1, fp, uinfo);
+Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_fs.c
+===================================================================
+--- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_fs.c
++++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_fs.c
+@@ -113,7 +113,7 @@ static ssize_t atomic_counters_read(stru
+ 	struct infinipath_counters counters;
+ 	struct ipath_devdata *dd;
+ 
+-	dd = file->f_path.dentry->d_inode->i_private;
++	dd = file->f_dentry->d_inode->i_private;
+ 	dd->ipath_f_read_counters(dd, &counters);
+ 
+ 	return simple_read_from_buffer(buf, count, ppos, &counters,
+@@ -153,7 +153,7 @@ static ssize_t flash_read(struct file *f
+ 		goto bail;
+ 	}
+ 
+-	dd = file->f_path.dentry->d_inode->i_private;
++	dd = file->f_dentry->d_inode->i_private;
+ 	if (ipath_eeprom_read(dd, pos, tmp, count)) {
+ 		ipath_dev_err(dd, "failed to read from flash\n");
+ 		ret = -ENXIO;
+@@ -206,7 +206,7 @@ static ssize_t flash_write(struct file *
+ 		goto bail_tmp;
+ 	}
+ 
+-	dd = file->f_path.dentry->d_inode->i_private;
++	dd = file->f_dentry->d_inode->i_private;
+ 	if (ipath_eeprom_write(dd, pos, tmp, count)) {
+ 		ret = -ENXIO;
+ 		ipath_dev_err(dd, "failed to write to flash\n");
diff --git a/kernel_patches/backport/2.6.18-EL5.1/2_misc_device_to_2_6_19.patch b/kernel_patches/backport/2.6.18-EL5.1/2_misc_device_to_2_6_19.patch
deleted file mode 100644
index 4785803..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/2_misc_device_to_2_6_19.patch
+++ /dev/null
@@ -1,56 +0,0 @@
->Post a replacement to 2_misc_device_to_2_6_19.patch, we'll test.
-
-I did not test this patch, but you can try replacing the contents of
-the 2_misc_device_to_2_6_19.patch with the changes below.  (It's
-possible that this may lead to some conflict further down in the patch
-chain...)  The function prototype for show_abi_version changed between
-2.6.20 to 2.6.19; this was the missing piece in the original backport
-patch.  I would have expected a build warning for this.
-
-Signed-off-by: Sean Hefty <sean.hefty at intel.com>
-
----
----
- drivers/infiniband/core/ucma.c |   12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/ucma.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/ucma.c
-+++ ofed_kernel/drivers/infiniband/core/ucma.c
-@@ -1207,13 +1207,11 @@ static struct miscdevice ucma_misc = {
- 	.fops	= &ucma_fops,
- };
- 
--static ssize_t show_abi_version(struct device *dev,
--				struct device_attribute *attr,
--				char *buf)
-+static ssize_t show_abi_version(struct class_device *class_dev, char *buf)
- {
- 	return sprintf(buf, "%d\n", RDMA_USER_CM_ABI_VERSION);
- }
--static DEVICE_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
-+static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
- 
- static int __init ucma_init(void)
- {
-@@ -1223,7 +1221,8 @@ static int __init ucma_init(void)
- 	if (ret)
- 		return ret;
- 
--	ret = device_create_file(ucma_misc.this_device, &dev_attr_abi_version);
-+	ret = class_device_create_file(ucma_misc.class,
-+				       &class_device_attr_abi_version);
- 	if (ret) {
- 		printk(KERN_ERR "rdma_ucm: couldn't create abi_version attr\n");
- 		goto err;
-@@ -1236,7 +1235,8 @@ err:
- 
- static void __exit ucma_cleanup(void)
- {
--	device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
-+	class_device_remove_file(ucma_misc.class,
-+				 &class_device_attr_abi_version);
- 	misc_deregister(&ucma_misc);
- 	idr_destroy(&ctx_idr);
- }
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cma_to_2_6_23.patch b/kernel_patches/backport/2.6.18-EL5.1/cma_to_2_6_23.patch
deleted file mode 100644
index 82f24b3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cma_to_2_6_23.patch
+++ /dev/null
@@ -1,23 +0,0 @@
----
- drivers/infiniband/core/cma.c |    5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/cma.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/cma.c
-+++ ofed_kernel/drivers/infiniband/core/cma.c
-@@ -2835,13 +2835,10 @@ static int cma_netdev_callback(struct no
- 	struct rdma_id_private *id_priv;
- 	int ret = NOTIFY_DONE;
- 
--	if (dev_net(ndev) != &init_net)
--		return NOTIFY_DONE;
--
- 	if (event != NETDEV_BONDING_FAILOVER)
- 		return NOTIFY_DONE;
- 
--	if (!(ndev->flags & IFF_MASTER) || !(ndev->priv_flags & IFF_BONDING))
-+	if (!(ndev->flags & IFF_MASTER))
- 		return NOTIFY_DONE;
- 
- 	mutex_lock(&lock);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_0_sysfs_to_2_6_25.patch b/kernel_patches/backport/2.6.18-EL5.1/core_0_sysfs_to_2_6_25.patch
deleted file mode 100644
index 504cf73..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_0_sysfs_to_2_6_25.patch
+++ /dev/null
@@ -1,81 +0,0 @@
----
- drivers/infiniband/core/cm.c          |    4 ++--
- drivers/infiniband/core/user_mad.c    |   14 ++++++++------
- drivers/infiniband/core/uverbs_main.c |   11 +++++------
- 3 files changed, 15 insertions(+), 14 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/cm.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/cm.c
-+++ ofed_kernel/drivers/infiniband/core/cm.c
-@@ -3738,8 +3738,8 @@ static void cm_add_one(struct ib_device 
- 	cm_dev->ib_device = ib_device;
- 	cm_get_ack_delay(cm_dev);
- 
--	cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
--					       MKDEV(0, 0), NULL,
-+	cm_dev->device = device_create(&cm_class, &ib_device->dev,
-+					       MKDEV(0, 0),
- 					       "%s", ib_device->name);
- 	if (!cm_dev->device) {
- 		kfree(cm_dev);
-Index: ofed_kernel/drivers/infiniband/core/user_mad.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/user_mad.c
-+++ ofed_kernel/drivers/infiniband/core/user_mad.c
-@@ -1016,9 +1016,8 @@ static int ib_umad_init_port(struct ib_d
- 	if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
- 		goto err_cdev;
- 
--	port->dev = device_create_drvdata(umad_class, device->dma_device,
--					  port->cdev->dev, port,
--					  "umad%d", port->dev_num);
-+	port->dev = device_create(umad_class, device->dma_device,
-+				  port->cdev->dev, "umad%d", port->dev_num);
- 	if (IS_ERR(port->dev))
- 		goto err_cdev;
- 
-@@ -1036,12 +1035,15 @@ static int ib_umad_init_port(struct ib_d
- 	if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
- 		goto err_sm_cdev;
- 
--	port->sm_dev = device_create_drvdata(umad_class, device->dma_device,
--					     port->sm_cdev->dev, port,
--					     "issm%d", port->dev_num);
-+	port->sm_dev = device_create(umad_class, device->dma_device,
-+				     port->sm_cdev->dev,
-+				     "issm%d", port->dev_num);
- 	if (IS_ERR(port->sm_dev))
- 		goto err_sm_cdev;
- 
-+	dev_set_drvdata(port->dev,    port);
-+	dev_set_drvdata(port->sm_dev, port);
-+
- 	if (device_create_file(port->sm_dev, &dev_attr_ibdev))
- 		goto err_sm_dev;
- 	if (device_create_file(port->sm_dev, &dev_attr_port))
-Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
-+++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
-@@ -802,15 +802,14 @@ static void ib_uverbs_add_one(struct ib_
- 	if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
- 		goto err_cdev;
- 
--	uverbs_dev->dev = device_create_drvdata(uverbs_class,
--						device->dma_device,
--						uverbs_dev->cdev->dev,
--						uverbs_dev,
--						"uverbs%d",
--						uverbs_dev->devnum);
-+	uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
-+					uverbs_dev->cdev->dev,
-+					"uverbs%d", uverbs_dev->devnum);
- 	if (IS_ERR(uverbs_dev->dev))
- 		goto err_cdev;
- 
-+	dev_set_drvdata(uverbs_dev->dev, uverbs_dev);
-+
- 	if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev))
- 		goto err_class;
- 	if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_1_kobject_backport.patch b/kernel_patches/backport/2.6.18-EL5.1/core_1_kobject_backport.patch
deleted file mode 100644
index b96dcf6..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_1_kobject_backport.patch
+++ /dev/null
@@ -1,191 +0,0 @@
----
- drivers/infiniband/core/Makefile           |    4 
- drivers/infiniband/core/kobject_backport.c |  160 +++++++++++++++++++++++++++++
- 2 files changed, 162 insertions(+), 2 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/Makefile
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/Makefile
-+++ ofed_kernel/drivers/infiniband/core/Makefile
-@@ -8,14 +8,14 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) +=	
- 					$(user_access-y)
- 
- ib_core-y :=			packer.o ud_header.o verbs.o sysfs.o \
--				device.o fmr_pool.o cache.o
-+				device.o fmr_pool.o cache.o kobject_backport.o
- ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
- 
- ib_mad-y :=			mad.o smi.o agent.o mad_rmpp.o
- 
- ib_sa-y :=			sa_query.o multicast.o notice.o local_sa.o
- 
--ib_cm-y :=			cm.o
-+ib_cm-y :=			cm.o kobject_backport.o
- 
- iw_cm-y :=			iwcm.o
- 
-Index: ofed_kernel/drivers/infiniband/core/kobject_backport.c
-===================================================================
---- /dev/null
-+++ ofed_kernel/drivers/infiniband/core/kobject_backport.c
-@@ -0,0 +1,160 @@
-+#include <linux/slab.h>
-+#include <linux/kobject.h>
-+
-+struct kobj_attribute {
-+	struct attribute attr;
-+	ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
-+			char *buf);
-+	ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
-+			 const char *buf, size_t count);
-+};
-+
-+/* default kobject attribute operations */
-+static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
-+			      char *buf)
-+{
-+	struct kobj_attribute *kattr;
-+	ssize_t ret = -EIO;
-+
-+	kattr = container_of(attr, struct kobj_attribute, attr);
-+	if (kattr->show)
-+		ret = kattr->show(kobj, kattr, buf);
-+	return ret;
-+}
-+
-+static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
-+			       const char *buf, size_t count)
-+{
-+	struct kobj_attribute *kattr;
-+	ssize_t ret = -EIO;
-+
-+	kattr = container_of(attr, struct kobj_attribute, attr);
-+	if (kattr->store)
-+		ret = kattr->store(kobj, kattr, buf, count);
-+	return ret;
-+}
-+
-+static struct sysfs_ops kobj_sysfs_ops = {
-+	.show   = kobj_attr_show,
-+	.store  = kobj_attr_store,
-+};
-+
-+static void dynamic_kobj_release(struct kobject *kobj)
-+{
-+	pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__);
-+	kfree(kobj);
-+}
-+
-+static struct kobj_type dynamic_kobj_ktype = {
-+	.release        = dynamic_kobj_release,
-+	.sysfs_ops      = &kobj_sysfs_ops,
-+};
-+
-+/**
-+ * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs
-+ *
-+ * @name: the name for the kset
-+ * @parent: the parent kobject of this kobject, if any.
-+ *
-+ * This function creates a kobject structure dynamically and registers it
-+ * with sysfs.  When you are finished with this structure, call
-+ * kobject_put() and the structure will be dynamically freed when
-+ * it is no longer being used.
-+ *
-+ * If the kobject was not able to be created, NULL will be returned.
-+ */
-+struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
-+{
-+	struct kobject *kobj;
-+	int retval;
-+
-+	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
-+	if (!kobj)
-+		return NULL;
-+
-+	kobject_init(kobj);
-+	kobj->ktype = &dynamic_kobj_ktype;
-+	kobj->parent = parent;
-+
-+	retval = kobject_set_name(kobj, "%s", name);
-+	if (retval) {
-+		printk(KERN_WARNING "%s: kobject_set_name error: %d\n",
-+			__FUNCTION__, retval);
-+		goto err;
-+	}
-+
-+	retval = kobject_add(kobj);
-+	if (retval) {
-+		printk(KERN_WARNING "%s: kobject_add error: %d\n",
-+			__FUNCTION__, retval);
-+		goto err;
-+	}
-+
-+	return kobj;
-+
-+err:
-+	kobject_put(kobj);
-+	return NULL;
-+}
-+
-+/**
-+ * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy
-+ * @kobj: pointer to the kobject to initialize
-+ * @ktype: pointer to the ktype for this kobject.
-+ * @parent: pointer to the parent of this kobject.
-+ * @fmt: the name of the kobject.
-+ *
-+ * This function combines the call to kobject_init() and
-+ * kobject_add().  The same type of error handling after a call to
-+ * kobject_add() and kobject lifetime rules are the same here.
-+ */
-+int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
-+                         struct kobject *parent, const char *fmt, ...)
-+{
-+	int retval;
-+	int limit;
-+	int need;
-+	va_list args;
-+	char *name;
-+
-+	/* find out how big a buffer we need */
-+	name = kmalloc(1024, GFP_KERNEL);
-+	if (!name) {
-+		retval = -ENOMEM;
-+		goto out;
-+	}
-+	va_start(args, fmt);
-+	need = vsnprintf(name, 1024, fmt, args);
-+	va_end(args);
-+	kfree(name);
-+
-+	/* Allocate the new space and copy the string in */
-+	limit = need + 1;
-+	name = kmalloc(limit, GFP_KERNEL);
-+	if (!name) {
-+		retval = -ENOMEM;
-+		goto out;
-+	}
-+
-+	va_start(args, fmt);
-+	need = vsnprintf(name, limit, fmt, args);
-+	va_end(args);
-+
-+	kobject_init(kobj);
-+
-+	kobj->ktype = ktype;
-+	kobj->parent = parent;
-+
-+	retval = kobject_set_name(kobj, name);
-+	kfree(name);
-+	if (retval)
-+		goto out;
-+
-+	retval = kobject_add(kobj);
-+	if (retval)
-+		goto out;
-+
-+out:
-+	return retval;
-+}
-+
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_2_kobject_unregister_to_2_6_24.patch b/kernel_patches/backport/2.6.18-EL5.1/core_2_kobject_unregister_to_2_6_24.patch
deleted file mode 100644
index 1239f4b..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_2_kobject_unregister_to_2_6_24.patch
+++ /dev/null
@@ -1,64 +0,0 @@
----
- drivers/infiniband/core/cm.c    |    8 ++++----
- drivers/infiniband/core/sysfs.c |    8 +++++---
- 2 files changed, 9 insertions(+), 7 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/cm.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/cm.c
-+++ ofed_kernel/drivers/infiniband/core/cm.c
-@@ -3696,8 +3696,8 @@ static int cm_create_port_fs(struct cm_p
- 
- error:
- 	while (i--)
--		kobject_put(&port->counter_group[i].obj);
--	kobject_put(&port->port_obj);
-+		kobject_unregister(&port->counter_group[i].obj);
-+	kobject_unregister(&port->port_obj);
- 	return ret;
- 
- }
-@@ -3707,9 +3707,9 @@ static void cm_remove_port_fs(struct cm_
- 	int i;
- 
- 	for (i = 0; i < CM_COUNTER_GROUPS; i++)
--		kobject_put(&port->counter_group[i].obj);
-+		kobject_unregister(&port->counter_group[i].obj);
- 
--	kobject_put(&port->port_obj);
-+	kobject_unregister(&port->port_obj);
- }
- 
- static void cm_add_one(struct ib_device *ib_device)
-Index: ofed_kernel/drivers/infiniband/core/sysfs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/sysfs.c
-+++ ofed_kernel/drivers/infiniband/core/sysfs.c
-@@ -838,11 +838,11 @@ err_put:
- 			sysfs_remove_group(p, &pma_group);
- 			sysfs_remove_group(p, &port->pkey_group);
- 			sysfs_remove_group(p, &port->gid_group);
--			kobject_put(p);
-+			kobject_unregister(p);
- 		}
- 	}
- 
--	kobject_put(&class_dev->kobj);
-+	kobject_unregister(&class_dev->kobj);
- 
- err_unregister:
- 	device_unregister(class_dev);
-@@ -862,10 +862,12 @@ void ib_device_unregister_sysfs(struct i
- 		sysfs_remove_group(p, &pma_group);
- 		sysfs_remove_group(p, &port->pkey_group);
- 		sysfs_remove_group(p, &port->gid_group);
--		kobject_put(p);
-+		kobject_unregister(p);
- 	}
- 
- 	kobject_put(device->ports_parent);
-+	/* WA for memory leak */
-+	kfree(device->ports_parent);
- 	device_unregister(&device->dev);
- }
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_2_z010_sysfs_to_2.6.18.patch b/kernel_patches/backport/2.6.18-EL5.1/core_2_z010_sysfs_to_2.6.18.patch
deleted file mode 100644
index 5d1d562..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_2_z010_sysfs_to_2.6.18.patch
+++ /dev/null
@@ -1,32 +0,0 @@
---- a/drivers/infiniband/core/device.c	2009-02-24 14:00:50.387541000 +0200
-+++ b/drivers/infiniband/core/device.c	2009-02-24 14:00:54.891362000 +0200
-@@ -199,7 +199,7 @@ void ib_dealloc_device(struct ib_device 
- 
- 	BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
- 
--	kobject_put(&device->dev.kobj);
-+	ib_device_unregister_sysfs(device);
- }
- EXPORT_SYMBOL(ib_dealloc_device);
- 
-@@ -356,8 +356,6 @@ void ib_unregister_device(struct ib_devi
- 
- 	mutex_unlock(&device_mutex);
- 
--	ib_device_unregister_sysfs(device);
--
- 	spin_lock_irqsave(&device->client_data_lock, flags);
- 	list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
- 		kfree(context);
---- a/drivers/infiniband/core/sysfs.c	2009-02-24 13:58:42.509754000 +0200
-+++ b/drivers/infiniband/core/sysfs.c	2009-02-24 14:00:54.894368000 +0200
-@@ -863,9 +863,6 @@ void ib_device_unregister_sysfs(struct i
- 	struct kobject *p, *t;
- 	struct ib_port *port;
- 
--	/* Hold kobject until ib_dealloc_device() */
--	kobject_get(&device->dev.kobj);
--
- 	list_for_each_entry_safe(p, t, &device->port_list, entry) {
- 		list_del(&p->entry);
- 		port = container_of(p, struct ib_port, kobj);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_3_sysfs_to_2_6_18.patch b/kernel_patches/backport/2.6.18-EL5.1/core_3_sysfs_to_2_6_18.patch
deleted file mode 100644
index c65a40a..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_3_sysfs_to_2_6_18.patch
+++ /dev/null
@@ -1,761 +0,0 @@
----
- drivers/infiniband/core/cm.c          |    2 
- drivers/infiniband/core/sysfs.c       |  172 ++++++++++++++++------------------
- drivers/infiniband/core/ucm.c         |   62 ++++++------
- drivers/infiniband/core/user_mad.c    |  109 ++++++++++-----------
- drivers/infiniband/core/uverbs.h      |    4 
- drivers/infiniband/core/uverbs_main.c |   51 ++++------
- include/rdma/ib_verbs.h               |    2 
- 7 files changed, 199 insertions(+), 203 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/cm.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/cm.c
-+++ ofed_kernel/drivers/infiniband/core/cm.c
-@@ -3738,7 +3738,7 @@ static void cm_add_one(struct ib_device 
- 	cm_dev->ib_device = ib_device;
- 	cm_get_ack_delay(cm_dev);
- 
--	cm_dev->device = device_create(&cm_class, &ib_device->dev,
-+	cm_dev->device = device_create(&cm_class, ib_device->class_dev.dev,
- 					       MKDEV(0, 0),
- 					       "%s", ib_device->name);
- 	if (!cm_dev->device) {
-Index: ofed_kernel/drivers/infiniband/core/sysfs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/sysfs.c
-+++ ofed_kernel/drivers/infiniband/core/sysfs.c
-@@ -425,25 +425,28 @@ static struct kobj_type port_type = {
- 	.default_attrs = port_default_attrs
- };
- 
--static void ib_device_release(struct device *device)
-+static void ib_device_release(struct class_device *cdev)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 
- 	kfree(dev);
- }
- 
--static int ib_device_uevent(struct device *device,
--			    struct kobj_uevent_env *env)
-+static int ib_device_uevent(struct class_device *cdev, char **envp,
-+			    int num_envp, char *buf, int size)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
-+	int i = 0, len = 0;
- 
--	if (add_uevent_var(env, "NAME=%s", dev->name))
-+	if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
-+			   "NAME=%s", dev->name))
- 		return -ENOMEM;
- 
- 	/*
- 	 * It would be nice to pass the node GUID with the event...
- 	 */
- 
-+	envp[i] = NULL;
- 	return 0;
- }
- 
-@@ -565,10 +568,9 @@ err_put:
- 	return ret;
- }
- 
--static ssize_t show_node_type(struct device *device,
--			      struct device_attribute *attr, char *buf)
-+static ssize_t show_node_type(struct class_device *cdev, char *buf)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 
- 	if (!ibdev_is_alive(dev))
- 		return -ENODEV;
-@@ -582,10 +584,9 @@ static ssize_t show_node_type(struct dev
- 	}
- }
- 
--static ssize_t show_sys_image_guid(struct device *device,
--				   struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 	struct ib_device_attr attr;
- 	ssize_t ret;
- 
-@@ -603,10 +604,9 @@ static ssize_t show_sys_image_guid(struc
- 		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
- }
- 
--static ssize_t show_node_guid(struct device *device,
--			      struct device_attribute *attr, char *buf)
-+static ssize_t show_node_guid(struct class_device *cdev, char *buf)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 
- 	if (!ibdev_is_alive(dev))
- 		return -ENODEV;
-@@ -618,19 +618,17 @@ static ssize_t show_node_guid(struct dev
- 		       be16_to_cpu(((__be16 *) &dev->node_guid)[3]));
- }
- 
--static ssize_t show_node_desc(struct device *device,
--			      struct device_attribute *attr, char *buf)
-+static ssize_t show_node_desc(struct class_device *cdev, char *buf)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 
- 	return sprintf(buf, "%.64s\n", dev->node_desc);
- }
- 
--static ssize_t set_node_desc(struct device *device,
--			     struct device_attribute *attr,
--			     const char *buf, size_t count)
-+static ssize_t set_node_desc(struct class_device *cdev, const char *buf,
-+			      size_t count)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 	struct ib_device_modify desc = {};
- 	int ret;
- 
-@@ -645,30 +643,30 @@ static ssize_t set_node_desc(struct devi
- 	return count;
- }
- 
--static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
--static DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
--static DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
--static DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc);
--
--static struct device_attribute *ib_class_attributes[] = {
--	&dev_attr_node_type,
--	&dev_attr_sys_image_guid,
--	&dev_attr_node_guid,
--	&dev_attr_node_desc
-+static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
-+static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
-+static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
-+static CLASS_DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc);
-+
-+static struct class_device_attribute *ib_class_attributes[] = {
-+	&class_device_attr_node_type,
-+	&class_device_attr_sys_image_guid,
-+	&class_device_attr_node_guid,
-+	&class_device_attr_node_desc
- };
- 
- static struct class ib_class = {
- 	.name    = "infiniband",
--	.dev_release = ib_device_release,
--	.dev_uevent = ib_device_uevent,
-+	.release = ib_device_release,
-+	.uevent = ib_device_uevent,
- };
- 
- /* Show a given an attribute in the statistics group */
--static ssize_t show_protocol_stat(const struct device *device,
--			    struct device_attribute *attr, char *buf,
-+static ssize_t show_protocol_stat(struct class_device *cdev,
-+			    char *buf,
- 			    unsigned offset)
- {
--	struct ib_device *dev = container_of(device, struct ib_device, dev);
-+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
- 	union rdma_protocol_stats stats;
- 	ssize_t ret;
- 
-@@ -682,14 +680,14 @@ static ssize_t show_protocol_stat(const 
- 
- /* generate a read-only iwarp statistics attribute */
- #define IW_STATS_ENTRY(name)						\
--static ssize_t show_##name(struct device *device,			\
--			   struct device_attribute *attr, char *buf)	\
-+static ssize_t show_##name(struct class_device *cdev,			\
-+			   char *buf)					\
- {									\
--	return show_protocol_stat(device, attr, buf,			\
-+	return show_protocol_stat(cdev, buf,			\
- 				  offsetof(struct iw_protocol_stats, name) / \
- 				  sizeof (u64));			\
- }									\
--static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
-+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
- 
- IW_STATS_ENTRY(ipInReceives);
- IW_STATS_ENTRY(ipInHdrErrors);
-@@ -731,44 +729,44 @@ IW_STATS_ENTRY(tcpInErrs);
- IW_STATS_ENTRY(tcpOutRsts);
- 
- static struct attribute *iw_proto_stats_attrs[] = {
--	&dev_attr_ipInReceives.attr,
--	&dev_attr_ipInHdrErrors.attr,
--	&dev_attr_ipInTooBigErrors.attr,
--	&dev_attr_ipInNoRoutes.attr,
--	&dev_attr_ipInAddrErrors.attr,
--	&dev_attr_ipInUnknownProtos.attr,
--	&dev_attr_ipInTruncatedPkts.attr,
--	&dev_attr_ipInDiscards.attr,
--	&dev_attr_ipInDelivers.attr,
--	&dev_attr_ipOutForwDatagrams.attr,
--	&dev_attr_ipOutRequests.attr,
--	&dev_attr_ipOutDiscards.attr,
--	&dev_attr_ipOutNoRoutes.attr,
--	&dev_attr_ipReasmTimeout.attr,
--	&dev_attr_ipReasmReqds.attr,
--	&dev_attr_ipReasmOKs.attr,
--	&dev_attr_ipReasmFails.attr,
--	&dev_attr_ipFragOKs.attr,
--	&dev_attr_ipFragFails.attr,
--	&dev_attr_ipFragCreates.attr,
--	&dev_attr_ipInMcastPkts.attr,
--	&dev_attr_ipOutMcastPkts.attr,
--	&dev_attr_ipInBcastPkts.attr,
--	&dev_attr_ipOutBcastPkts.attr,
--	&dev_attr_tcpRtoAlgorithm.attr,
--	&dev_attr_tcpRtoMin.attr,
--	&dev_attr_tcpRtoMax.attr,
--	&dev_attr_tcpMaxConn.attr,
--	&dev_attr_tcpActiveOpens.attr,
--	&dev_attr_tcpPassiveOpens.attr,
--	&dev_attr_tcpAttemptFails.attr,
--	&dev_attr_tcpEstabResets.attr,
--	&dev_attr_tcpCurrEstab.attr,
--	&dev_attr_tcpInSegs.attr,
--	&dev_attr_tcpOutSegs.attr,
--	&dev_attr_tcpRetransSegs.attr,
--	&dev_attr_tcpInErrs.attr,
--	&dev_attr_tcpOutRsts.attr,
-+	&class_device_attr_ipInReceives.attr,
-+	&class_device_attr_ipInHdrErrors.attr,
-+	&class_device_attr_ipInTooBigErrors.attr,
-+	&class_device_attr_ipInNoRoutes.attr,
-+	&class_device_attr_ipInAddrErrors.attr,
-+	&class_device_attr_ipInUnknownProtos.attr,
-+	&class_device_attr_ipInTruncatedPkts.attr,
-+	&class_device_attr_ipInDiscards.attr,
-+	&class_device_attr_ipInDelivers.attr,
-+	&class_device_attr_ipOutForwDatagrams.attr,
-+	&class_device_attr_ipOutRequests.attr,
-+	&class_device_attr_ipOutDiscards.attr,
-+	&class_device_attr_ipOutNoRoutes.attr,
-+	&class_device_attr_ipReasmTimeout.attr,
-+	&class_device_attr_ipReasmReqds.attr,
-+	&class_device_attr_ipReasmOKs.attr,
-+	&class_device_attr_ipReasmFails.attr,
-+	&class_device_attr_ipFragOKs.attr,
-+	&class_device_attr_ipFragFails.attr,
-+	&class_device_attr_ipFragCreates.attr,
-+	&class_device_attr_ipInMcastPkts.attr,
-+	&class_device_attr_ipOutMcastPkts.attr,
-+	&class_device_attr_ipInBcastPkts.attr,
-+	&class_device_attr_ipOutBcastPkts.attr,
-+	&class_device_attr_tcpRtoAlgorithm.attr,
-+	&class_device_attr_tcpRtoMin.attr,
-+	&class_device_attr_tcpRtoMax.attr,
-+	&class_device_attr_tcpMaxConn.attr,
-+	&class_device_attr_tcpActiveOpens.attr,
-+	&class_device_attr_tcpPassiveOpens.attr,
-+	&class_device_attr_tcpAttemptFails.attr,
-+	&class_device_attr_tcpEstabResets.attr,
-+	&class_device_attr_tcpCurrEstab.attr,
-+	&class_device_attr_tcpInSegs.attr,
-+	&class_device_attr_tcpOutSegs.attr,
-+	&class_device_attr_tcpRetransSegs.attr,
-+	&class_device_attr_tcpInErrs.attr,
-+	&class_device_attr_tcpOutRsts.attr,
- 	NULL
- };
- 
-@@ -779,23 +777,23 @@ static struct attribute_group iw_stats_g
- 
- int ib_device_register_sysfs(struct ib_device *device)
- {
--	struct device *class_dev = &device->dev;
-+	struct class_device *class_dev = &device->class_dev;
- 	int ret;
- 	int i;
- 
- 	class_dev->class      = &ib_class;
--	class_dev->driver_data = device;
--	class_dev->parent     = device->dma_device;
--	strlcpy(class_dev->bus_id, device->name, BUS_ID_SIZE);
-+	class_dev->class_data = device;
-+	class_dev->dev	      = device->dma_device;
-+	strlcpy(class_dev->class_id, device->name, BUS_ID_SIZE);
- 
- 	INIT_LIST_HEAD(&device->port_list);
- 
--	ret = device_register(class_dev);
-+	ret = class_device_register(class_dev);
- 	if (ret)
- 		goto err;
- 
- 	for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) {
--		ret = device_create_file(class_dev, ib_class_attributes[i]);
-+		ret = class_device_create_file(class_dev, ib_class_attributes[i]);
- 		if (ret)
- 			goto err_unregister;
- 	}
-@@ -845,7 +843,7 @@ err_put:
- 	kobject_unregister(&class_dev->kobj);
- 
- err_unregister:
--	device_unregister(class_dev);
-+	class_device_unregister(class_dev);
- 
- err:
- 	return ret;
-@@ -868,7 +866,7 @@ void ib_device_unregister_sysfs(struct i
- 	kobject_put(device->ports_parent);
- 	/* WA for memory leak */
- 	kfree(device->ports_parent);
--	device_unregister(&device->dev);
-+	class_device_unregister(&device->class_dev);
- }
- 
- int ib_sysfs_setup(void)
-Index: ofed_kernel/drivers/infiniband/core/ucm.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/ucm.c
-+++ ofed_kernel/drivers/infiniband/core/ucm.c
-@@ -56,8 +56,8 @@ MODULE_LICENSE("Dual BSD/GPL");
- 
- struct ib_ucm_device {
- 	int			devnum;
--	struct cdev		cdev;
--	struct device		dev;
-+	struct cdev		dev;
-+	struct class_device	class_dev;
- 	struct ib_device	*ib_dev;
- };
- 
-@@ -1177,7 +1177,7 @@ static int ib_ucm_open(struct inode *ino
- 
- 	filp->private_data = file;
- 	file->filp = filp;
--	file->device = container_of(inode->i_cdev, struct ib_ucm_device, cdev);
-+	file->device = container_of(inode->i_cdev, struct ib_ucm_device, dev);
- 
- 	return 0;
- }
-@@ -1208,14 +1208,14 @@ static int ib_ucm_close(struct inode *in
- 	return 0;
- }
- 
--static void ib_ucm_release_dev(struct device *dev)
-+static void ucm_release_class_dev(struct class_device *class_dev)
- {
--	struct ib_ucm_device *ucm_dev;
-+	struct ib_ucm_device *dev;
- 
--	ucm_dev = container_of(dev, struct ib_ucm_device, dev);
--	cdev_del(&ucm_dev->cdev);
--	clear_bit(ucm_dev->devnum, dev_map);
--	kfree(ucm_dev);
-+	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
-+	cdev_del(&dev->dev);
-+	clear_bit(dev->devnum, dev_map);
-+	kfree(dev);
- }
- 
- static const struct file_operations ucm_fops = {
-@@ -1226,15 +1226,14 @@ static const struct file_operations ucm_
- 	.poll    = ib_ucm_poll,
- };
- 
--static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
- {
--	struct ib_ucm_device *ucm_dev;
-+	struct ib_ucm_device *dev;
- 
--	ucm_dev = container_of(dev, struct ib_ucm_device, dev);
--	return sprintf(buf, "%s\n", ucm_dev->ib_dev->name);
-+	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
-+	return sprintf(buf, "%s\n", dev->ib_dev->name);
- }
--static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
-+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
- 
- static void ib_ucm_add_one(struct ib_device *device)
- {
-@@ -1256,31 +1255,32 @@ static void ib_ucm_add_one(struct ib_dev
- 
- 	set_bit(ucm_dev->devnum, dev_map);
- 
--	cdev_init(&ucm_dev->cdev, &ucm_fops);
--	ucm_dev->cdev.owner = THIS_MODULE;
--	kobject_set_name(&ucm_dev->cdev.kobj, "ucm%d", ucm_dev->devnum);
--	if (cdev_add(&ucm_dev->cdev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
-+	cdev_init(&ucm_dev->dev, &ucm_fops);
-+	ucm_dev->dev.owner = THIS_MODULE;
-+	kobject_set_name(&ucm_dev->dev.kobj, "ucm%d", ucm_dev->devnum);
-+	if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))
- 		goto err;
- 
--	ucm_dev->dev.class = &cm_class;
--	ucm_dev->dev.parent = device->dma_device;
--	ucm_dev->dev.devt = ucm_dev->cdev.dev;
--	ucm_dev->dev.release = ib_ucm_release_dev;
--	snprintf(ucm_dev->dev.bus_id, BUS_ID_SIZE, "ucm%d",
-+	ucm_dev->class_dev.class = &cm_class;
-+	ucm_dev->class_dev.dev = device->dma_device;
-+	ucm_dev->class_dev.devt = ucm_dev->dev.dev;
-+	ucm_dev->class_dev.release = ucm_release_class_dev;
-+	snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
- 		 ucm_dev->devnum);
--	if (device_register(&ucm_dev->dev))
-+	if (class_device_register(&ucm_dev->class_dev))
- 		goto err_cdev;
- 
--	if (device_create_file(&ucm_dev->dev, &dev_attr_ibdev))
--		goto err_dev;
-+	if (class_device_create_file(&ucm_dev->class_dev,
-+				     &class_device_attr_ibdev))
-+		goto err_class;
- 
- 	ib_set_client_data(device, &ucm_client, ucm_dev);
- 	return;
- 
--err_dev:
--	device_unregister(&ucm_dev->dev);
-+err_class:
-+	class_device_unregister(&ucm_dev->class_dev);
- err_cdev:
--	cdev_del(&ucm_dev->cdev);
-+	cdev_del(&ucm_dev->dev);
- 	clear_bit(ucm_dev->devnum, dev_map);
- err:
- 	kfree(ucm_dev);
-@@ -1294,7 +1294,7 @@ static void ib_ucm_remove_one(struct ib_
- 	if (!ucm_dev)
- 		return;
- 
--	device_unregister(&ucm_dev->dev);
-+	class_device_unregister(&ucm_dev->class_dev);
- }
- 
- static ssize_t show_abi_version(struct class *class, char *buf)
-Index: ofed_kernel/drivers/infiniband/core/user_mad.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/user_mad.c
-+++ ofed_kernel/drivers/infiniband/core/user_mad.c
-@@ -86,11 +86,11 @@ enum {
-  */
- 
- struct ib_umad_port {
--	struct cdev           *cdev;
--	struct device	      *dev;
-+	struct cdev           *dev;
-+	struct class_device   *class_dev;
- 
--	struct cdev           *sm_cdev;
--	struct device	      *sm_dev;
-+	struct cdev           *sm_dev;
-+	struct class_device   *sm_class_dev;
- 	struct semaphore       sm_sem;
- 
- 	struct mutex	       file_mutex;
-@@ -959,29 +959,27 @@ static struct ib_client umad_client = {
- 	.remove = ib_umad_remove_one
- };
- 
--static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
- {
--	struct ib_umad_port *port = dev_get_drvdata(dev);
-+	struct ib_umad_port *port = class_get_devdata(class_dev);
- 
- 	if (!port)
- 		return -ENODEV;
- 
- 	return sprintf(buf, "%s\n", port->ib_dev->name);
- }
--static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
-+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
- 
--static ssize_t show_port(struct device *dev, struct device_attribute *attr,
--			 char *buf)
-+static ssize_t show_port(struct class_device *class_dev, char *buf)
- {
--	struct ib_umad_port *port = dev_get_drvdata(dev);
-+	struct ib_umad_port *port = class_get_devdata(class_dev);
- 
- 	if (!port)
- 		return -ENODEV;
- 
- 	return sprintf(buf, "%d\n", port->port_num);
- }
--static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
-+static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
- 
- static ssize_t show_abi_version(struct class *class, char *buf)
- {
-@@ -1007,47 +1005,48 @@ static int ib_umad_init_port(struct ib_d
- 	mutex_init(&port->file_mutex);
- 	INIT_LIST_HEAD(&port->file_list);
- 
--	port->cdev = cdev_alloc();
--	if (!port->cdev)
-+	port->dev = cdev_alloc();
-+	if (!port->dev)
- 		return -1;
--	port->cdev->owner = THIS_MODULE;
--	port->cdev->ops   = &umad_fops;
--	kobject_set_name(&port->cdev->kobj, "umad%d", port->dev_num);
--	if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
-+	port->dev->owner = THIS_MODULE;
-+	port->dev->ops   = &umad_fops;
-+	kobject_set_name(&port->dev->kobj, "umad%d", port->dev_num);
-+	if (cdev_add(port->dev, base_dev + port->dev_num, 1))
- 		goto err_cdev;
- 
--	port->dev = device_create(umad_class, device->dma_device,
--				  port->cdev->dev, "umad%d", port->dev_num);
--	if (IS_ERR(port->dev))
-+	port->class_dev = class_device_create(umad_class, NULL, port->dev->dev,
-+					      device->dma_device,
-+					      "umad%d", port->dev_num);
-+	if (IS_ERR(port->class_dev))
- 		goto err_cdev;
- 
--	if (device_create_file(port->dev, &dev_attr_ibdev))
--		goto err_dev;
--	if (device_create_file(port->dev, &dev_attr_port))
--		goto err_dev;
--
--	port->sm_cdev = cdev_alloc();
--	if (!port->sm_cdev)
--		goto err_dev;
--	port->sm_cdev->owner = THIS_MODULE;
--	port->sm_cdev->ops   = &umad_sm_fops;
--	kobject_set_name(&port->sm_cdev->kobj, "issm%d", port->dev_num);
--	if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
-+	if (class_device_create_file(port->class_dev, &class_device_attr_ibdev))
-+		goto err_class;
-+	if (class_device_create_file(port->class_dev, &class_device_attr_port))
-+		goto err_class;
-+
-+	port->sm_dev = cdev_alloc();
-+	if (!port->sm_dev)
-+		goto err_class;
-+	port->sm_dev->owner = THIS_MODULE;
-+	port->sm_dev->ops   = &umad_sm_fops;
-+	kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
-+	if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
- 		goto err_sm_cdev;
- 
--	port->sm_dev = device_create(umad_class, device->dma_device,
--				     port->sm_cdev->dev,
--				     "issm%d", port->dev_num);
--	if (IS_ERR(port->sm_dev))
-+	port->sm_class_dev = class_device_create(umad_class, NULL, port->sm_dev->dev,
-+						 device->dma_device,
-+						 "issm%d", port->dev_num);
-+	if (IS_ERR(port->sm_class_dev))
- 		goto err_sm_cdev;
- 
--	dev_set_drvdata(port->dev,    port);
--	dev_set_drvdata(port->sm_dev, port);
-+	class_set_devdata(port->class_dev,    port);
-+	class_set_devdata(port->sm_class_dev, port);
- 
--	if (device_create_file(port->sm_dev, &dev_attr_ibdev))
--		goto err_sm_dev;
--	if (device_create_file(port->sm_dev, &dev_attr_port))
--		goto err_sm_dev;
-+	if (class_device_create_file(port->sm_class_dev, &class_device_attr_ibdev))
-+		goto err_sm_class;
-+	if (class_device_create_file(port->sm_class_dev, &class_device_attr_port))
-+		goto err_sm_class;
- 
- 	spin_lock(&port_lock);
- 	umad_port[port->dev_num] = port;
-@@ -1055,17 +1054,17 @@ static int ib_umad_init_port(struct ib_d
- 
- 	return 0;
- 
--err_sm_dev:
--	device_destroy(umad_class, port->sm_cdev->dev);
-+err_sm_class:
-+	class_device_destroy(umad_class, port->sm_dev->dev);
- 
- err_sm_cdev:
--	cdev_del(port->sm_cdev);
-+	cdev_del(port->sm_dev);
- 
--err_dev:
--	device_destroy(umad_class, port->cdev->dev);
-+err_class:
-+	class_device_destroy(umad_class, port->dev->dev);
- 
- err_cdev:
--	cdev_del(port->cdev);
-+	cdev_del(port->dev);
- 	clear_bit(port->dev_num, dev_map);
- 
- 	return -1;
-@@ -1077,14 +1076,14 @@ static void ib_umad_kill_port(struct ib_
- 	int already_dead;
- 	int id;
- 
--	dev_set_drvdata(port->dev,    NULL);
--	dev_set_drvdata(port->sm_dev, NULL);
-+	class_set_devdata(port->class_dev,    NULL);
-+	class_set_devdata(port->sm_class_dev, NULL);
- 
--	device_destroy(umad_class, port->cdev->dev);
--	device_destroy(umad_class, port->sm_cdev->dev);
-+	class_device_destroy(umad_class, port->dev->dev);
-+	class_device_destroy(umad_class, port->sm_dev->dev);
- 
--	cdev_del(port->cdev);
--	cdev_del(port->sm_cdev);
-+	cdev_del(port->dev);
-+	cdev_del(port->sm_dev);
- 
- 	spin_lock(&port_lock);
- 	umad_port[port->dev_num] = NULL;
-Index: ofed_kernel/drivers/infiniband/core/uverbs.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/uverbs.h
-+++ ofed_kernel/drivers/infiniband/core/uverbs.h
-@@ -71,8 +71,8 @@ struct ib_uverbs_device {
- 	struct kref				ref;
- 	struct completion			comp;
- 	int					devnum;
--	struct cdev			       *cdev;
--	struct device			       *dev;
-+	struct cdev			       *dev;
-+	struct class_device		       *class_dev;
- 	struct ib_device		       *ib_dev;
- 	int					num_comp_vectors;
- };
-Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
-+++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
-@@ -737,29 +737,27 @@ static struct ib_client uverbs_client = 
- 	.remove = ib_uverbs_remove_one
- };
- 
--static ssize_t show_ibdev(struct device *device, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
- {
--	struct ib_uverbs_device *dev = dev_get_drvdata(device);
-+	struct ib_uverbs_device *dev = class_get_devdata(class_dev);
- 
- 	if (!dev)
- 		return -ENODEV;
- 
- 	return sprintf(buf, "%s\n", dev->ib_dev->name);
- }
--static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
-+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
- 
--static ssize_t show_dev_abi_version(struct device *device,
--				    struct device_attribute *attr, char *buf)
-+static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf)
- {
--	struct ib_uverbs_device *dev = dev_get_drvdata(device);
-+	struct ib_uverbs_device *dev = class_get_devdata(class_dev);
- 
- 	if (!dev)
- 		return -ENODEV;
- 
- 	return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver);
- }
--static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
-+static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
- 
- static ssize_t show_abi_version(struct class *class, char *buf)
- {
-@@ -793,26 +791,27 @@ static void ib_uverbs_add_one(struct ib_
- 	uverbs_dev->ib_dev           = device;
- 	uverbs_dev->num_comp_vectors = device->num_comp_vectors;
- 
--	uverbs_dev->cdev = cdev_alloc();
--	if (!uverbs_dev->cdev)
-+	uverbs_dev->dev = cdev_alloc();
-+	if (!uverbs_dev->dev)
- 		goto err;
--	uverbs_dev->cdev->owner = THIS_MODULE;
--	uverbs_dev->cdev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
--	kobject_set_name(&uverbs_dev->cdev->kobj, "uverbs%d", uverbs_dev->devnum);
--	if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
-+	uverbs_dev->dev->owner = THIS_MODULE;
-+	uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
-+	kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum);
-+	if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
- 		goto err_cdev;
- 
--	uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
--					uverbs_dev->cdev->dev,
--					"uverbs%d", uverbs_dev->devnum);
--	if (IS_ERR(uverbs_dev->dev))
-+	uverbs_dev->class_dev = class_device_create(uverbs_class, NULL,
-+						    uverbs_dev->dev->dev,
-+						    device->dma_device,
-+						    "uverbs%d", uverbs_dev->devnum);
-+	if (IS_ERR(uverbs_dev->class_dev))
- 		goto err_cdev;
- 
--	dev_set_drvdata(uverbs_dev->dev, uverbs_dev);
-+	class_set_devdata(uverbs_dev->class_dev, uverbs_dev);
- 
--	if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev))
-+	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev))
- 		goto err_class;
--	if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
-+	if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version))
- 		goto err_class;
- 
- 	spin_lock(&map_lock);
-@@ -824,10 +823,10 @@ static void ib_uverbs_add_one(struct ib_
- 	return;
- 
- err_class:
--	device_destroy(uverbs_class, uverbs_dev->cdev->dev);
-+	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
- 
- err_cdev:
--	cdev_del(uverbs_dev->cdev);
-+	cdev_del(uverbs_dev->dev);
- 	clear_bit(uverbs_dev->devnum, dev_map);
- 
- err:
-@@ -844,9 +843,9 @@ static void ib_uverbs_remove_one(struct 
- 	if (!uverbs_dev)
- 		return;
- 
--	dev_set_drvdata(uverbs_dev->dev, NULL);
--	device_destroy(uverbs_class, uverbs_dev->cdev->dev);
--	cdev_del(uverbs_dev->cdev);
-+	class_set_devdata(uverbs_dev->class_dev, NULL);
-+	class_device_destroy(uverbs_class, uverbs_dev->dev->dev);
-+	cdev_del(uverbs_dev->dev);
- 
- 	spin_lock(&map_lock);
- 	dev_table[uverbs_dev->devnum] = NULL;
-Index: ofed_kernel/include/rdma/ib_verbs.h
-===================================================================
---- ofed_kernel.orig/include/rdma/ib_verbs.h
-+++ ofed_kernel/include/rdma/ib_verbs.h
-@@ -1196,7 +1196,7 @@ struct ib_device {
- 	struct ib_dma_mapping_ops   *dma_ops;
- 
- 	struct module               *owner;
--	struct device                dev;
-+	struct class_device          class_dev;
- 	struct kobject               *ports_parent;
- 	struct list_head             port_list;
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_undo_weak_ordering.patch b/kernel_patches/backport/2.6.18-EL5.1/core_undo_weak_ordering.patch
deleted file mode 100644
index 7277c55..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_undo_weak_ordering.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 91f5e350089e023d485e42e6f30a7fcf28ea394c Mon Sep 17 00:00:00 2001
-From: Eli Cohen <eli at mellanox.co.il>
-Date: Tue, 28 Oct 2008 10:19:24 +0200
-Subject: [PATCH] Revert "ib_core: Use weak ordering for data registered memory"
-
-This reverts commit 4beb8b521a750990346adf47f549c7db5fd50893.
-
-Doing this for backports since the original patch requires API
-available in kernel 2.6.27 and newer.
-
-Signed-off-by: Eli Cohen <eli at mellanox.co.il>
----
- drivers/infiniband/core/umem.c |   12 ++----------
- include/rdma/ib_umem.h         |    2 --
- 2 files changed, 2 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
-index da5e247..6f7c096 100644
---- a/drivers/infiniband/core/umem.c
-+++ b/drivers/infiniband/core/umem.c
-@@ -40,10 +40,6 @@
- 
- #include "uverbs.h"
- 
--static int allow_weak_ordering;
--module_param(allow_weak_ordering, bool, 0444);
--MODULE_PARM_DESC(allow_weak_ordering,  "Allow weak ordering for data registered memory");
--
- #define IB_UMEM_MAX_PAGE_CHUNK						\
- 	((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) /	\
- 	 ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] -	\
-@@ -55,8 +51,8 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
- 	int i;
- 
- 	list_for_each_entry_safe(chunk, tmp, &umem->chunk_list, list) {
--		ib_dma_unmap_sg_attrs(dev, chunk->page_list,
--				      chunk->nents, DMA_BIDIRECTIONAL, &chunk->attrs);
-+		ib_dma_unmap_sg(dev, chunk->page_list,
-+				chunk->nents, DMA_BIDIRECTIONAL);
- 		for (i = 0; i < chunk->nents; ++i) {
- 			struct page *page = sg_page(&chunk->page_list[i]);
- 
-@@ -95,9 +91,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
- 
- 	if (dmasync)
- 		dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
--	else if (allow_weak_ordering)
--		dma_set_attr(DMA_ATTR_WEAK_ORDERING, &attrs);
--
- 
- 	if (!can_do_mlock())
- 		return ERR_PTR(-EPERM);
-@@ -176,7 +169,6 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
- 				goto out;
- 			}
- 
--			chunk->attrs = attrs;
- 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
- 			sg_init_table(chunk->page_list, chunk->nents);
- 			for (i = 0; i < chunk->nents; ++i) {
-diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
-index 90f3712..9ee0d2e 100644
---- a/include/rdma/ib_umem.h
-+++ b/include/rdma/ib_umem.h
-@@ -36,7 +36,6 @@
- #include <linux/list.h>
- #include <linux/scatterlist.h>
- #include <linux/workqueue.h>
--#include <linux/dma-attrs.h>
- 
- struct ib_ucontext;
- 
-@@ -57,7 +56,6 @@ struct ib_umem_chunk {
- 	struct list_head	list;
- 	int                     nents;
- 	int                     nmap;
--	struct dma_attrs	attrs;
- 	struct scatterlist      page_list[0];
- };
- 
--- 
-1.6.0.2
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/core_z0010_sysfs_race.patch b/kernel_patches/backport/2.6.18-EL5.1/core_z0010_sysfs_race.patch
deleted file mode 100644
index 73367e5..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/core_z0010_sysfs_race.patch
+++ /dev/null
@@ -1,496 +0,0 @@
-ib_core: avoid race condition between sysfs access and low-level module unload. (V2)
-
-In newer kernels, although a low-level module will not be unloaded (code)
-while its sysfs interface is being accessed, it is possible for the module to
-free all its resources (data) during such access.  This almost always causes
-a kernel Oops.
-
-To avoid this, we protect the device reg_state with a mutex, and perform
-all sysfs operations (show, store) atomically within this mutex.
-
-V2: fix thinko bug in sysfs_state_show changes(found by Ralph Campbell).
-
-Signed-off-by: Jack Morgenstein <jackm at dev.mellanox.co.il>
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
-Index: ofed_kernel/drivers/infiniband/core/device.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/device.c	2009-02-22 15:36:34.531430000 +0200
-+++ ofed_kernel/drivers/infiniband/core/device.c	2009-02-22 15:38:28.650322000 +0200
-@@ -178,9 +178,14 @@ static int end_port(struct ib_device *de
-  */
- struct ib_device *ib_alloc_device(size_t size)
- {
-+	struct ib_device *ibdev;
-+
- 	BUG_ON(size < sizeof (struct ib_device));
- 
--	return kzalloc(size, GFP_KERNEL);
-+	ibdev = kzalloc(size, GFP_KERNEL);
-+	if (ibdev)
-+		mutex_init(&ibdev->sysfs_mutex);
-+	return ibdev;
- }
- EXPORT_SYMBOL(ib_alloc_device);
- 
-@@ -313,9 +318,10 @@ int ib_register_device(struct ib_device 
- 		goto out;
- 	}
- 
-+	mutex_lock(&device->sysfs_mutex);
- 	list_add_tail(&device->core_list, &device_list);
--
- 	device->reg_state = IB_DEV_REGISTERED;
-+	mutex_unlock(&device->sysfs_mutex);
- 
- 	{
- 		struct ib_client *client;
-@@ -361,7 +367,9 @@ void ib_unregister_device(struct ib_devi
- 		kfree(context);
- 	spin_unlock_irqrestore(&device->client_data_lock, flags);
- 
-+	mutex_lock(&device->sysfs_mutex);
- 	device->reg_state = IB_DEV_UNREGISTERED;
-+	mutex_unlock(&device->sysfs_mutex);
- }
- EXPORT_SYMBOL(ib_unregister_device);
- 
-Index: ofed_kernel/drivers/infiniband/core/sysfs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/sysfs.c	2009-02-22 15:36:35.914354000 +0200
-+++ ofed_kernel/drivers/infiniband/core/sysfs.c	2009-02-22 16:12:37.485629000 +0200
-@@ -94,7 +94,7 @@ static ssize_t state_show(struct ib_port
- 			  char *buf)
- {
- 	struct ib_port_attr attr;
--	ssize_t ret;
-+	ssize_t ret = -ENODEV;
- 
- 	static const char *state_name[] = {
- 		[IB_PORT_NOP]		= "NOP",
-@@ -105,26 +105,33 @@ static ssize_t state_show(struct ib_port
- 		[IB_PORT_ACTIVE_DEFER]	= "ACTIVE_DEFER"
- 	};
- 
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
--
--	return sprintf(buf, "%d: %s\n", attr.state,
--		       attr.state >= 0 && attr.state < ARRAY_SIZE(state_name) ?
--		       state_name[attr.state] : "UNKNOWN");
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "%d: %s\n", attr.state,
-+				      attr.state >= 0 &&
-+				      attr.state < ARRAY_SIZE(state_name) ?
-+				      state_name[attr.state] : "UNKNOWN");
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t lid_show(struct ib_port *p, struct port_attribute *unused,
- 			char *buf)
- {
- 	struct ib_port_attr attr;
--	ssize_t ret;
-+	ssize_t ret = -ENODEV;
- 
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
--
--	return sprintf(buf, "0x%x\n", attr.lid);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "0x%x\n", attr.lid);
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t lid_mask_count_show(struct ib_port *p,
-@@ -132,52 +139,64 @@ static ssize_t lid_mask_count_show(struc
- 				   char *buf)
- {
- 	struct ib_port_attr attr;
--	ssize_t ret;
--
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
-+	ssize_t ret = -ENODEV;
- 
--	return sprintf(buf, "%d\n", attr.lmc);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "%d\n", attr.lmc);
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t sm_lid_show(struct ib_port *p, struct port_attribute *unused,
- 			   char *buf)
- {
- 	struct ib_port_attr attr;
--	ssize_t ret;
--
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
-+	ssize_t ret = -ENODEV;
- 
--	return sprintf(buf, "0x%x\n", attr.sm_lid);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "0x%x\n", attr.sm_lid);
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t sm_sl_show(struct ib_port *p, struct port_attribute *unused,
- 			  char *buf)
- {
- 	struct ib_port_attr attr;
--	ssize_t ret;
--
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
-+	ssize_t ret = -ENODEV;
- 
--	return sprintf(buf, "%d\n", attr.sm_sl);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "%d\n", attr.sm_sl);
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t cap_mask_show(struct ib_port *p, struct port_attribute *unused,
- 			     char *buf)
- {
- 	struct ib_port_attr attr;
--	ssize_t ret;
--
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
-+	ssize_t ret = -ENODEV;
- 
--	return sprintf(buf, "0x%08x\n", attr.port_cap_flags);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "0x%08x\n", attr.port_cap_flags);
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
-@@ -186,24 +205,33 @@ static ssize_t rate_show(struct ib_port 
- 	struct ib_port_attr attr;
- 	char *speed = "";
- 	int rate;
--	ssize_t ret;
-+	ssize_t ret = -ENODEV;
- 
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
--
--	switch (attr.active_speed) {
--	case 2: speed = " DDR"; break;
--	case 4: speed = " QDR"; break;
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret) {
-+			switch (attr.active_speed) {
-+			case 2: speed = " DDR"; break;
-+			case 4: speed = " QDR"; break;
-+			}
-+
-+			rate = 25 * ib_width_enum_to_int(attr.active_width) *
-+				attr.active_speed;
-+			if (rate < 0) {
-+				ret = -EINVAL;
-+				goto out;
-+			}
-+
-+			ret = sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
-+				      rate / 10, rate % 10 ? ".5" : "",
-+				      ib_width_enum_to_int(attr.active_width),
-+				      speed);
-+		}
- 	}
--
--	rate = 25 * ib_width_enum_to_int(attr.active_width) * attr.active_speed;
--	if (rate < 0)
--		return -EINVAL;
--
--	return sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
--		       rate / 10, rate % 10 ? ".5" : "",
--		       ib_width_enum_to_int(attr.active_width), speed);
-+out:
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
-@@ -211,22 +239,42 @@ static ssize_t phys_state_show(struct ib
- {
- 	struct ib_port_attr attr;
- 
--	ssize_t ret;
--
--	ret = ib_query_port(p->ibdev, p->port_num, &attr);
--	if (ret)
--		return ret;
-+	ssize_t ret = -ENODEV;
- 
--	switch (attr.phys_state) {
--	case 1:  return sprintf(buf, "1: Sleep\n");
--	case 2:  return sprintf(buf, "2: Polling\n");
--	case 3:  return sprintf(buf, "3: Disabled\n");
--	case 4:  return sprintf(buf, "4: PortConfigurationTraining\n");
--	case 5:  return sprintf(buf, "5: LinkUp\n");
--	case 6:  return sprintf(buf, "6: LinkErrorRecovery\n");
--	case 7:  return sprintf(buf, "7: Phy Test\n");
--	default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_port(p->ibdev, p->port_num, &attr);
-+		if (!ret) {
-+			switch (attr.phys_state) {
-+			case 1:
-+				ret = sprintf(buf, "1: Sleep\n");
-+				break;
-+			case 2:
-+				ret = sprintf(buf, "2: Polling\n");
-+				break;
-+			case 3:
-+				ret = sprintf(buf, "3: Disabled\n");
-+				break;
-+			case 4:
-+				ret = sprintf(buf, "4: PortConfigurationTraining\n");
-+				break;
-+			case 5:
-+				ret = sprintf(buf, "5: LinkUp\n");
-+				break;
-+			case 6:
-+				ret = sprintf(buf, "6: LinkErrorRecovery\n");
-+				break;
-+			case 7:
-+				ret = sprintf(buf, "7: Phy Test\n");
-+				break;
-+			default:
-+				ret = sprintf(buf, "%d: <unknown>\n", attr.phys_state);
-+				break;
-+			}
-+		}
- 	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static PORT_ATTR_RO(state);
-@@ -256,21 +304,24 @@ static ssize_t show_port_gid(struct ib_p
- 	struct port_table_attribute *tab_attr =
- 		container_of(attr, struct port_table_attribute, attr);
- 	union ib_gid gid;
--	ssize_t ret;
-+	ssize_t ret = -ENODEV;
- 
--	ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid);
--	if (ret)
--		return ret;
--
--	return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
--		       be16_to_cpu(((__be16 *) gid.raw)[0]),
--		       be16_to_cpu(((__be16 *) gid.raw)[1]),
--		       be16_to_cpu(((__be16 *) gid.raw)[2]),
--		       be16_to_cpu(((__be16 *) gid.raw)[3]),
--		       be16_to_cpu(((__be16 *) gid.raw)[4]),
--		       be16_to_cpu(((__be16 *) gid.raw)[5]),
--		       be16_to_cpu(((__be16 *) gid.raw)[6]),
--		       be16_to_cpu(((__be16 *) gid.raw)[7]));
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid);
-+		if (!ret)
-+			ret = sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
-+				      be16_to_cpu(((__be16 *) gid.raw)[0]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[1]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[2]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[3]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[4]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[5]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[6]),
-+				      be16_to_cpu(((__be16 *) gid.raw)[7]));
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
-@@ -279,13 +330,16 @@ static ssize_t show_port_pkey(struct ib_
- 	struct port_table_attribute *tab_attr =
- 		container_of(attr, struct port_table_attribute, attr);
- 	u16 pkey;
--	ssize_t ret;
--
--	ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
--	if (ret)
--		return ret;
-+	ssize_t ret = -ENODEV;
- 
--	return sprintf(buf, "0x%04x\n", pkey);
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (ibdev_is_alive(p->ibdev)) {
-+		ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
-+		if (!ret)
-+			ret = sprintf(buf, "0x%04x\n", pkey);
-+	}
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
-+	return ret;
- }
- 
- #define PORT_PMA_ATTR(_name, _counter, _width, _offset)			\
-@@ -308,6 +346,12 @@ static ssize_t show_pma_counter(struct i
- 	if (!p->ibdev->process_mad)
- 		return sprintf(buf, "N/A (no PMA)\n");
- 
-+	mutex_lock(&p->ibdev->sysfs_mutex);
-+	if (!ibdev_is_alive(p->ibdev)) {
-+		ret = -ENODEV;
-+		goto out;
-+	}
-+
- 	in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
- 	out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
- 	if (!in_mad || !out_mad) {
-@@ -354,7 +414,7 @@ static ssize_t show_pma_counter(struct i
- out:
- 	kfree(in_mad);
- 	kfree(out_mad);
--
-+	mutex_unlock(&p->ibdev->sysfs_mutex);
- 	return ret;
- }
- 
-@@ -594,20 +654,20 @@ static ssize_t show_sys_image_guid(struc
- {
- 	struct ib_device *dev = container_of(device, struct ib_device, dev);
- 	struct ib_device_attr attr;
--	ssize_t ret;
--
--	if (!ibdev_is_alive(dev))
--		return -ENODEV;
-+	ssize_t ret = -ENODEV;
- 
--	ret = ib_query_device(dev, &attr);
--	if (ret)
--		return ret;
--
--	return sprintf(buf, "%04x:%04x:%04x:%04x\n",
--		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
--		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
--		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
--		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
-+	mutex_lock(&dev->sysfs_mutex);
-+	if (ibdev_is_alive(dev)) {
-+		ret = ib_query_device(dev, &attr);
-+		if (!ret)
-+			ret = sprintf(buf, "%04x:%04x:%04x:%04x\n",
-+				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
-+				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
-+				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
-+				      be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
-+	}
-+	mutex_unlock(&dev->sysfs_mutex);
-+	return ret;
- }
- 
- static ssize_t show_node_guid(struct device *device,
-@@ -639,17 +699,20 @@ static ssize_t set_node_desc(struct devi
- {
- 	struct ib_device *dev = container_of(device, struct ib_device, dev);
- 	struct ib_device_modify desc = {};
--	int ret;
-+	int ret = -ENODEV;
- 
- 	if (!dev->modify_device)
- 		return -EIO;
- 
- 	memcpy(desc.node_desc, buf, min_t(int, count, 64));
--	ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
--	if (ret)
--		return ret;
--
--	return count;
-+	mutex_lock(&dev->sysfs_mutex);
-+	if (ibdev_is_alive(dev)) {
-+		ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
-+		if (!ret)
-+			ret = count;
-+	}
-+	mutex_unlock(&dev->sysfs_mutex);
-+	return ret;
- }
- 
- static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
-@@ -677,14 +740,18 @@ static ssize_t show_protocol_stat(const 
- {
- 	struct ib_device *dev = container_of(device, struct ib_device, dev);
- 	union rdma_protocol_stats stats;
--	ssize_t ret;
-+	ssize_t ret = -ENODEV;
- 
--	ret = dev->get_protocol_stats(dev, &stats);
--	if (ret)
--		return ret;
--
--	return sprintf(buf, "%llu\n",
--		       (unsigned long long) ((u64 *) &stats)[offset]);
-+	mutex_lock(&dev->sysfs_mutex);
-+	if (ibdev_is_alive(dev)) {
-+		ret = dev->get_protocol_stats(dev, &stats);
-+		if (!ret)
-+			ret = sprintf(buf, "%llu\n",
-+				      (unsigned long long)
-+				      ((u64 *) &stats)[offset]);
-+	}
-+	mutex_unlock(&dev->sysfs_mutex);
-+	return ret;
- }
- 
- /* generate a read-only iwarp statistics attribute */
-Index: ofed_kernel/include/rdma/ib_verbs.h
-===================================================================
---- ofed_kernel.orig/include/rdma/ib_verbs.h	2009-02-22 15:36:40.252210000 +0200
-+++ ofed_kernel/include/rdma/ib_verbs.h	2009-02-22 15:38:28.678322000 +0200
-@@ -1205,6 +1205,7 @@ struct ib_device {
- 		IB_DEV_REGISTERED,
- 		IB_DEV_UNREGISTERED
- 	}                            reg_state;
-+	struct mutex		     sysfs_mutex;
- 
- 	u64			     uverbs_cmd_mask;
- 	int			     uverbs_abi_ver;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0002_undo_250.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0002_undo_250.patch
deleted file mode 100644
index 9605fb7..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0002_undo_250.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
-index d5e9bf7..dc2c79d 100644
---- a/drivers/net/cxgb3/common.h
-+++ b/drivers/net/cxgb3/common.h
-@@ -726,7 +726,6 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index);
- void early_hw_init(struct adapter *adapter, const struct adapter_info *ai);
- int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
- 		    int reset);
--int t3_replay_prep_adapter(struct adapter *adapter);
- void t3_led_ready(struct adapter *adapter);
- void t3_fatal_err(struct adapter *adapter);
- void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
-diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
-index 8de820e..48fbda6 100644
---- a/drivers/net/cxgb3/cxgb3_main.c
-+++ b/drivers/net/cxgb3/cxgb3_main.c
-@@ -2485,6 +2485,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
- 	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
- 		offload_close(&adapter->tdev);
- 
-+	/* Free sge resources */
-+	t3_free_sge_resources(adapter);
-+
- 	adapter->flags &= ~FULL_INIT_DONE;
- 
- 	pci_disable_device(pdev);
-@@ -2509,12 +2512,8 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
- 		goto err;
- 	}
- 	pci_set_master(pdev);
--	pci_restore_state(pdev);
--
--	/* Free sge resources */
--	t3_free_sge_resources(adapter);
- 
--	if (t3_replay_prep_adapter(adapter))
-+	if (t3_prep_adapter(adapter, adapter->params.info, 1))
- 		goto err;
- 
- 	return PCI_ERS_RESULT_RECOVERED;
-@@ -2666,7 +2665,6 @@ static int __devinit init_one(struct pci_dev *pdev,
- 	}
- 
- 	pci_set_master(pdev);
--	pci_save_state(pdev);
- 
- 	mmio_start = pci_resource_start(pdev, 0);
- 	mmio_len = pci_resource_len(pdev, 0);
-diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
-index a035d5c..086cd02 100644
---- a/drivers/net/cxgb3/regs.h
-+++ b/drivers/net/cxgb3/regs.h
-@@ -444,14 +444,6 @@
- 
- #define A_PCIE_CFG 0x88
- 
--#define S_ENABLELINKDWNDRST    21
--#define V_ENABLELINKDWNDRST(x) ((x) << S_ENABLELINKDWNDRST)
--#define F_ENABLELINKDWNDRST    V_ENABLELINKDWNDRST(1U)
--
--#define S_ENABLELINKDOWNRST    20
--#define V_ENABLELINKDOWNRST(x) ((x) << S_ENABLELINKDOWNRST)
--#define F_ENABLELINKDOWNRST    V_ENABLELINKDOWNRST(1U)
--
- #define S_PCIE_CLIDECEN    16
- #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN)
- #define F_PCIE_CLIDECEN    V_PCIE_CLIDECEN(1U)
-diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
-index 1b0861d..912f816 100644
---- a/drivers/net/cxgb3/sge.c
-+++ b/drivers/net/cxgb3/sge.c
-@@ -563,33 +563,6 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
- }
- 
- /**
-- *	t3_reset_qset - reset a sge qset
-- *	@q: the queue set
-- *
-- *	Reset the qset structure.
-- *	the NAPI structure is preserved in the event of
-- *	the qset's reincarnation, for example during EEH recovery.
-- */
--static void t3_reset_qset(struct sge_qset *q)
--{
--	if (q->adap &&
--	    !(q->adap->flags & NAPI_INIT)) {
--		memset(q, 0, sizeof(*q));
--		return;
--	}
--
--	q->adap = NULL;
--	memset(&q->rspq, 0, sizeof(q->rspq));
--	memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
--	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
--	q->txq_stopped = 0;
--	memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
--	kfree(q->lro_frag_tbl);
--	q->lro_nfrags = q->lro_frag_len = 0;
--}
--
--
--/**
-  *	free_qset - free the resources of an SGE queue set
-  *	@adapter: the adapter owning the queue set
-  *	@q: the queue set
-@@ -645,7 +618,7 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
- 				  q->rspq.desc, q->rspq.phys_addr);
- 	}
- 
--	t3_reset_qset(q);
-+	memset(q, 0, sizeof(*q));
- }
- 
- /**
-diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
-index bf5c076..533fc74 100644
---- a/drivers/net/cxgb3/t3_hw.c
-+++ b/drivers/net/cxgb3/t3_hw.c
-@@ -3303,7 +3303,6 @@ static void config_pcie(struct adapter *adap)
- 
- 	t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
- 	t3_set_reg_field(adap, A_PCIE_CFG, 0,
--			 F_ENABLELINKDWNDRST | F_ENABLELINKDOWNRST |
- 			 F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
- }
- 
-@@ -3706,31 +3705,3 @@ void t3_led_ready(struct adapter *adapter)
- 			 F_GPIO0_OUT_VAL);
- }
- 
--int t3_replay_prep_adapter(struct adapter *adapter)
--{
--	const struct adapter_info *ai = adapter->params.info;
--	unsigned int i, j = -1;
--	int ret;
--
--	early_hw_init(adapter, ai);
--	ret = init_parity(adapter);
--	if (ret)
--		return ret;
--
--	for_each_port(adapter, i) {
--		const struct port_type_info *pti;
--		struct port_info *p = adap2pinfo(adapter, i);
--
--		while (!adapter->params.vpd.port_type[++j])
--			;
--
--		pti = &port_types[adapter->params.vpd.port_type[j]];
--		ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
--		if (ret)
--			return ret;
--		p->phy.ops->power_down(&p->phy, 1);
--	}
--
--return 0;
--}
--
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0004_undo_240.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0004_undo_240.patch
deleted file mode 100644
index 62df290..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0004_undo_240.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-commit 48c4b6dbb7e246957e13302668acf7c77e4f8b3a
-Author: Divy Le Ray <divy at chelsio.com>
-Date:   Tue May 6 19:25:56 2008 -0700
-
-    cxgb3 - fix port up/down error path
-    
-    Fix faiures path when ports are stopped and restarted
-    in EEH recovery.
-    
-    Signed-off-by: Divy Le Ray <divy at chelsio.com>
-    Signed-off-by: Jeff Garzik <jgarzik at redhat.com>
-
----
- drivers/net/cxgb3/adapter.h    |    1 -
- drivers/net/cxgb3/cxgb3_main.c |   32 +++++++++++++++-----------------
- 2 files changed, 15 insertions(+), 18 deletions(-)
-
-Index: ofed_kernel/drivers/net/cxgb3/adapter.h
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/adapter.h
-+++ ofed_kernel/drivers/net/cxgb3/adapter.h
-@@ -72,7 +72,6 @@ enum {				/* adapter flags */
- 	USING_MSIX = (1 << 2),
- 	QUEUES_BOUND = (1 << 3),
- 	TP_PARITY_INIT = (1 << 4),
--	NAPI_INIT = (1 << 5),
- };
- 
- struct fl_pg_chunk {
-Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
-+++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-@@ -421,13 +421,6 @@ static void init_napi(struct adapter *ad
- 			netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
- 				       64);
- 	}
--
--	/*
--	 * netif_napi_add() can be called only once per napi_struct because it
--	 * adds each new napi_struct to a list.  Be careful not to call it a
--	 * second time, e.g., during EEH recovery, by making a note of it.
--	 */
--	adap->flags |= NAPI_INIT;
- }
- 
- /*
-@@ -903,8 +896,7 @@ static int cxgb_up(struct adapter *adap)
- 			goto out;
- 
- 		setup_rss(adap);
--		if (!(adap->flags & NAPI_INIT))
--			init_napi(adap);
-+		init_napi(adap);
- 		adap->flags |= FULL_INIT_DONE;
- 	}
- 
-@@ -1007,7 +999,7 @@ static int offload_open(struct net_devic
- 		return 0;
- 
- 	if (!adap_up && (err = cxgb_up(adapter)) < 0)
--		goto out;
-+		return err;
- 
- 	t3_tp_set_offload_mode(adapter, 1);
- 	tdev->lldev = adapter->port[0];
-@@ -1069,8 +1061,10 @@ static int cxgb_open(struct net_device *
- 	int other_ports = adapter->open_device_map & PORT_MASK;
- 	int err;
- 
--	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
-+	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
-+		quiesce_rx(adapter);
- 		return err;
-+	}
- 
- 	set_bit(pi->port_id, &adapter->open_device_map);
- 	if (is_offload(adapter) && !ofld_disable) {
-@@ -2456,7 +2450,7 @@ static pci_ers_result_t t3_io_error_dete
- 
- 	pci_disable_device(pdev);
- 
--	/* Request a slot reset. */
-+	/* Request a slot slot reset. */
- 	return PCI_ERS_RESULT_NEED_RESET;
- }
- 
-@@ -2473,16 +2467,13 @@ static pci_ers_result_t t3_io_slot_reset
- 	if (pci_enable_device(pdev)) {
- 		dev_err(&pdev->dev,
- 			"Cannot re-enable PCI device after reset.\n");
--		goto err;
-+		return PCI_ERS_RESULT_DISCONNECT;
- 	}
- 	pci_set_master(pdev);
- 
--	if (t3_prep_adapter(adapter, adapter->params.info, 1))
--		goto err;
-+	t3_prep_adapter(adapter, adapter->params.info, 1);
- 
- 	return PCI_ERS_RESULT_RECOVERED;
--err:
--	return PCI_ERS_RESULT_DISCONNECT;
- }
- 
- /**
-@@ -2511,6 +2502,13 @@ static void t3_io_resume(struct pci_dev 
- 			netif_device_attach(netdev);
- 		}
- 	}
-+
-+	if (is_offload(adapter)) {
-+		__set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
-+		if (offload_open(adapter->port[0]))
-+			printk(KERN_WARNING
-+			       "Could not bring back offload capabilities\n");
-+	}
- }
- 
- static struct pci_error_handlers t3_err_handler = {
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0008_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0008_pci_dma_mapping_error_to_2_6_26.patch
deleted file mode 100644
index bcf69aa..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0008_pci_dma_mapping_error_to_2_6_26.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- drivers/net/cxgb3/sge.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: ofed_kernel/drivers/net/cxgb3/sge.c
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/sge.c
-+++ ofed_kernel/drivers/net/cxgb3/sge.c
-@@ -386,7 +386,7 @@ static inline int add_one_rx_buf(void *v
- 	dma_addr_t mapping;
- 
- 	mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE);
--	if (unlikely(pci_dma_mapping_error(pdev, mapping)))
-+	if (unlikely(pci_dma_mapping_error(mapping)))
- 		return -ENOMEM;
- 
- 	pci_unmap_addr_set(sd, dma_addr, mapping);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0010_napi.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0010_napi.patch
deleted file mode 100644
index df3eaed..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0010_napi.patch
+++ /dev/null
@@ -1,610 +0,0 @@
-diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
-index 3b33ecb..21dad82 100644
---- a/drivers/net/cxgb3/adapter.h
-+++ b/drivers/net/cxgb3/adapter.h
-@@ -48,12 +48,10 @@
- 
- struct vlan_group;
- struct adapter;
--struct sge_qset;
- 
- struct port_info {
- 	struct adapter *adapter;
- 	struct vlan_group *vlan_grp;
--	struct sge_qset *qs;
- 	u8 port_id;
- 	u8 rx_csum_offload;
- 	u8 nqsets;
-@@ -183,8 +181,6 @@ enum {				/* per port SGE statistics */
- #define T3_MAX_LRO_MAX_PKTS 64
- 
- struct sge_qset {		/* an SGE queue set */
--	struct adapter *adap;
--	struct napi_struct napi;
- 	struct sge_rspq rspq;
- 	struct sge_fl fl[SGE_RXQ_PER_SET];
- 	struct sge_txq txq[SGE_TXQ_PER_SET];
-@@ -195,7 +191,7 @@ struct sge_qset {		/* an SGE queue set */
- 	int lro_enabled;
- 	int lro_frag_len;
- 	void *lro_va;
--	struct net_device *netdev;
-+	struct net_device *netdev;	/* associated net device */
- 	unsigned long txq_stopped;	/* which Tx queues are stopped */
- 	struct timer_list tx_reclaim_timer;	/* reclaims TX buffers */
- 	unsigned long port_stats[SGE_PSTAT_MAX];
-@@ -240,6 +236,12 @@ struct adapter {
- 	struct delayed_work adap_check_task;
- 	struct work_struct ext_intr_handler_task;
- 
-+	/*
-+	 * Dummy netdevices are needed when using multiple receive queues with
-+	 * NAPI as each netdevice can service only one queue.
-+	 */
-+	struct net_device *dummy_netdev[SGE_QSETS - 1];
-+
- 	struct dentry *debugfs_root;
- 
- 	struct mutex mdio_lock;
-@@ -266,6 +268,12 @@ static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
- 	return netdev_priv(adap->port[idx]);
- }
- 
-+/*
-+ * We use the spare atalk_ptr to map a net device to its SGE queue set.
-+ * This is a macro so it can be used as l-value.
-+ */
-+#define dev2qset(netdev) ((netdev)->atalk_ptr)
-+
- #define OFFLOAD_DEVMAP_BIT 15
- 
- #define tdev2adap(d) container_of(d, struct adapter, tdev)
-@@ -292,7 +300,7 @@ int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
- void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p);
- int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
- 		      int irq_vec_idx, const struct qset_params *p,
--		      int ntxq, struct net_device *dev);
-+		      int ntxq, struct net_device *netdev);
- int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
- 		unsigned char *data);
- irqreturn_t t3_sge_intr_msix(int irq, void *cookie);
-diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
-index 0f4c694..342d441 100644
---- a/drivers/net/cxgb3/cxgb3_main.c
-+++ b/drivers/net/cxgb3/cxgb3_main.c
-@@ -435,17 +435,49 @@ static void setup_rss(struct adapter *adap)
- 		      V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map);
- }
- 
--static void init_napi(struct adapter *adap)
-+/*
-+ * If we have multiple receive queues per port serviced by NAPI we need one
-+ * netdevice per queue as NAPI operates on netdevices.  We already have one
-+ * netdevice, namely the one associated with the interface, so we use dummy
-+ * ones for any additional queues.  Note that these netdevices exist purely
-+ * so that NAPI has something to work with, they do not represent network
-+ * ports and are not registered.
-+ */
-+static int init_dummy_netdevs(struct adapter *adap)
- {
--	int i;
-+	int i, j, dummy_idx = 0;
-+	struct net_device *nd;
-+
-+	for_each_port(adap, i) {
-+		struct net_device *dev = adap->port[i];
-+		const struct port_info *pi = netdev_priv(dev);
-+
-+		for (j = 0; j < pi->nqsets - 1; j++) {
-+			if (!adap->dummy_netdev[dummy_idx]) {
-+				struct port_info *p;
-+
-+				nd = alloc_netdev(sizeof(*p), "", ether_setup);
-+				if (!nd)
-+					goto free_all;
- 
--	for (i = 0; i < SGE_QSETS; i++) {
--		struct sge_qset *qs = &adap->sge.qs[i];
-+				p = netdev_priv(nd);
-+				p->adapter = adap;
-+				nd->weight = 64;
-+				set_bit(__LINK_STATE_START, &nd->state);
-+				adap->dummy_netdev[dummy_idx] = nd;
-+			}
-+			strcpy(adap->dummy_netdev[dummy_idx]->name, dev->name);
-+			dummy_idx++;
-+		}
-+	}
-+	return 0;
- 
--		if (qs->adap)
--			netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
--				       64);
-+free_all:
-+	while (--dummy_idx >= 0) {
-+		free_netdev(adap->dummy_netdev[dummy_idx]);
-+		adap->dummy_netdev[dummy_idx] = NULL;
- 	}
-+	return -ENOMEM;
- }
- 
- /*
-@@ -456,18 +488,20 @@ static void init_napi(struct adapter *adap)
- static void quiesce_rx(struct adapter *adap)
- {
- 	int i;
-+	struct net_device *dev;
- 
--	for (i = 0; i < SGE_QSETS; i++)
--		if (adap->sge.qs[i].adap)
--			napi_disable(&adap->sge.qs[i].napi);
--}
-+	for_each_port(adap, i) {
-+		dev = adap->port[i];
-+		while (test_bit(__LINK_STATE_RX_SCHED, &dev->state))
-+			msleep(1);
-+	}
- 
--static void enable_all_napi(struct adapter *adap)
--{
--	int i;
--	for (i = 0; i < SGE_QSETS; i++)
--		if (adap->sge.qs[i].adap)
--			napi_enable(&adap->sge.qs[i].napi);
-+	for (i = 0; i < ARRAY_SIZE(adap->dummy_netdev); i++) {
-+		dev = adap->dummy_netdev[i];
-+		if (dev)
-+			while (test_bit(__LINK_STATE_RX_SCHED, &dev->state))
-+				msleep(1);
-+	}
- }
- 
- /**
-@@ -480,7 +514,7 @@ static void enable_all_napi(struct adapter *adap)
-  */
- static int setup_sge_qsets(struct adapter *adap)
- {
--	int i, j, err, irq_idx = 0, qset_idx = 0;
-+	int i, j, err, irq_idx = 0, qset_idx = 0, dummy_dev_idx = 0;
- 	unsigned int ntxq = SGE_TXQ_PER_SET;
- 
- 	if (adap->params.rev > 0 && !(adap->flags & USING_MSI))
-@@ -488,14 +522,15 @@ static int setup_sge_qsets(struct adapter *adap)
- 
- 	for_each_port(adap, i) {
- 		struct net_device *dev = adap->port[i];
--		struct port_info *pi = netdev_priv(dev);
-+		const struct port_info *pi = netdev_priv(dev);
- 
--		pi->qs = &adap->sge.qs[pi->first_qset];
- 		for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
- 			err = t3_sge_alloc_qset(adap, qset_idx, 1,
- 				(adap->flags & USING_MSIX) ? qset_idx + 1 :
- 							     irq_idx,
--				&adap->params.sge.qset[qset_idx], ntxq, dev);
-+				&adap->params.sge.qset[qset_idx], ntxq,
-+				j == 0 ? dev :
-+					 adap-> dummy_netdev[dummy_dev_idx++]);
- 			if (err) {
- 				t3_free_sge_resources(adap);
- 				return err;
-@@ -909,6 +944,10 @@ static int cxgb_up(struct adapter *adap)
- 				goto out;
- 		}
- 
-+ 		err = init_dummy_netdevs(adap);
-+ 		if (err)
-+ 			goto out;
-+
- 		err = t3_init_hw(adap, 0);
- 		if (err)
- 			goto out;
-@@ -921,7 +960,6 @@ static int cxgb_up(struct adapter *adap)
- 			goto out;
- 
- 		setup_rss(adap);
--		init_napi(adap);
- 		adap->flags |= FULL_INIT_DONE;
- 	}
- 
-@@ -949,7 +987,6 @@ static int cxgb_up(struct adapter *adap)
- 				      adap->name, adap)))
- 		goto irq_err;
- 
--	enable_all_napi(adap);
- 	t3_sge_start(adap);
- 	t3_intr_enable(adap);
- 
-@@ -1086,10 +1123,8 @@ static int cxgb_open(struct net_device *dev)
- 	int other_ports = adapter->open_device_map & PORT_MASK;
- 	int err;
- 
--	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
--		quiesce_rx(adapter);
-+	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
- 		return err;
--	}
- 
- 	set_bit(pi->port_id, &adapter->open_device_map);
- 	if (is_offload(adapter) && !ofld_disable) {
-@@ -2736,6 +2771,7 @@ static int __devinit init_one(struct pci_dev *pdev,
- #ifdef CONFIG_NET_POLL_CONTROLLER
- 		netdev->poll_controller = cxgb_netpoll;
- #endif
-+		netdev->weight = 64;
- 
- 		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
- 	}
-@@ -2836,6 +2872,12 @@ static void __devexit remove_one(struct pci_dev *pdev)
- 		t3_free_sge_resources(adapter);
- 		cxgb_disable_msi(adapter);
- 
-+		for (i = 0; i < ARRAY_SIZE(adapter->dummy_netdev); i++)
-+			if (adapter->dummy_netdev[i]) {
-+				free_netdev(adapter->dummy_netdev[i]);
-+				adapter->dummy_netdev[i] = NULL;
-+			}
-+
- 		for_each_port(adapter, i)
- 			if (adapter->port[i])
- 				free_netdev(adapter->port[i]);
-diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
-index f6bc6fe..3bbf626 100644
---- a/drivers/net/cxgb3/sge.c
-+++ b/drivers/net/cxgb3/sge.c
-@@ -618,6 +618,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
- 				  q->rspq.desc, q->rspq.phys_addr);
- 	}
- 
-+	if (q->netdev)
-+		q->netdev->atalk_ptr = NULL;
-+
- 	memset(q, 0, sizeof(*q));
- }
- 
-@@ -1116,7 +1119,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
- 	unsigned int ndesc, pidx, credits, gen, compl;
- 	const struct port_info *pi = netdev_priv(dev);
- 	struct adapter *adap = pi->adapter;
--	struct sge_qset *qs = pi->qs;
-+	struct sge_qset *qs = dev2qset(dev);
- 	struct sge_txq *q = &qs->txq[TXQ_ETH];
- 
- 	/*
-@@ -1365,12 +1368,13 @@ static void restart_ctrlq(unsigned long data)
- 	struct sk_buff *skb;
- 	struct sge_qset *qs = (struct sge_qset *)data;
- 	struct sge_txq *q = &qs->txq[TXQ_CTRL];
-+	const struct port_info *pi = netdev_priv(qs->netdev);
-+	struct adapter *adap = pi->adapter;
- 
- 	spin_lock(&q->lock);
-       again:reclaim_completed_tx_imm(q);
- 
--	while (q->in_use < q->size &&
--	       (skb = __skb_dequeue(&q->sendq)) != NULL) {
-+	while (q->in_use < q->size && (skb = __skb_dequeue(&q->sendq)) != NULL) {
- 
- 		write_imm(&q->desc[q->pidx], skb, skb->len, q->gen);
- 
-@@ -1393,7 +1397,7 @@ static void restart_ctrlq(unsigned long data)
- 
- 	spin_unlock(&q->lock);
- 	wmb();
--	t3_write_reg(qs->adap, A_SG_KDOORBELL,
-+	t3_write_reg(adap, A_SG_KDOORBELL,
- 		     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
- }
- 
-@@ -1683,7 +1687,8 @@ static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb)
- 	else {
- 		struct sge_qset *qs = rspq_to_qset(q);
- 
--		napi_schedule(&qs->napi);
-+		if (__netif_rx_schedule_prep(qs->netdev))
-+			__netif_rx_schedule(qs->netdev);
- 		q->rx_head = skb;
- 	}
- 	q->rx_tail = skb;
-@@ -1719,30 +1724,34 @@ static inline void deliver_partial_bundle(struct t3cdev *tdev,
-  *	receive handler.  Batches need to be of modest size as we do prefetches
-  *	on the packets in each.
-  */
--static int ofld_poll(struct napi_struct *napi, int budget)
-+static int ofld_poll(struct net_device *dev, int *budget)
- {
--	struct sge_qset *qs = container_of(napi, struct sge_qset, napi);
-+	const struct port_info *pi = netdev_priv(dev);
-+	struct adapter *adapter = pi->adapter;
-+	struct sge_qset *qs = dev2qset(dev);
- 	struct sge_rspq *q = &qs->rspq;
--	struct adapter *adapter = qs->adap;
--	int work_done = 0;
-+	int work_done, limit = min(*budget, dev->quota), avail = limit;
- 
--	while (work_done < budget) {
-+	while (avail) {
- 		struct sk_buff *head, *tail, *skbs[RX_BUNDLE_SIZE];
- 		int ngathered;
- 
- 		spin_lock_irq(&q->lock);
- 		head = q->rx_head;
- 		if (!head) {
--			napi_complete(napi);
-+			work_done = limit - avail;
-+			*budget -= work_done;
-+			dev->quota -= work_done;
-+			__netif_rx_complete(dev);
- 			spin_unlock_irq(&q->lock);
--			return work_done;
-+			return 0;
- 		}
- 
- 		tail = q->rx_tail;
- 		q->rx_head = q->rx_tail = NULL;
- 		spin_unlock_irq(&q->lock);
- 
--		for (ngathered = 0; work_done < budget && head; work_done++) {
-+		for (ngathered = 0; avail && head; avail--) {
- 			prefetch(head->data);
- 			skbs[ngathered] = head;
- 			head = head->next;
-@@ -1764,8 +1773,10 @@ static int ofld_poll(struct napi_struct *napi, int budget)
- 		}
- 		deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered);
- 	}
--
--	return work_done;
-+	work_done = limit - avail;
-+	*budget -= work_done;
-+	dev->quota -= work_done;
-+	return 1;
- }
- 
- /**
-@@ -2325,47 +2336,50 @@ static inline int is_pure_response(const struct rsp_desc *r)
- 
- /**
-  *	napi_rx_handler - the NAPI handler for Rx processing
-- *	@napi: the napi instance
-+ *	@dev: the net device
-  *	@budget: how many packets we can process in this round
-  *
-  *	Handler for new data events when using NAPI.
-  */
--static int napi_rx_handler(struct napi_struct *napi, int budget)
-+static int napi_rx_handler(struct net_device *dev, int *budget)
- {
--	struct sge_qset *qs = container_of(napi, struct sge_qset, napi);
--	struct adapter *adap = qs->adap;
--	int work_done = process_responses(adap, qs, budget);
-+	const struct port_info *pi = netdev_priv(dev);
-+	struct adapter *adap = pi->adapter;
-+	struct sge_qset *qs = dev2qset(dev);
-+	int effective_budget = min(*budget, dev->quota);
- 
--	if (likely(work_done < budget)) {
--		napi_complete(napi);
-+	int work_done = process_responses(adap, qs, effective_budget);
-+	*budget -= work_done;
-+	dev->quota -= work_done;
- 
--		/*
--		 * Because we don't atomically flush the following
--		 * write it is possible that in very rare cases it can
--		 * reach the device in a way that races with a new
--		 * response being written plus an error interrupt
--		 * causing the NAPI interrupt handler below to return
--		 * unhandled status to the OS.  To protect against
--		 * this would require flushing the write and doing
--		 * both the write and the flush with interrupts off.
--		 * Way too expensive and unjustifiable given the
--		 * rarity of the race.
--		 *
--		 * The race cannot happen at all with MSI-X.
--		 */
--		t3_write_reg(adap, A_SG_GTS, V_RSPQ(qs->rspq.cntxt_id) |
--			     V_NEWTIMER(qs->rspq.next_holdoff) |
--			     V_NEWINDEX(qs->rspq.cidx));
--	}
--	return work_done;
-+	if (work_done >= effective_budget)
-+		return 1;
-+
-+	netif_rx_complete(dev);
-+
-+	/*
-+	 * Because we don't atomically flush the following write it is
-+	 * possible that in very rare cases it can reach the device in a way
-+	 * that races with a new response being written plus an error interrupt
-+	 * causing the NAPI interrupt handler below to return unhandled status
-+	 * to the OS.  To protect against this would require flushing the write
-+	 * and doing both the write and the flush with interrupts off.  Way too
-+	 * expensive and unjustifiable given the rarity of the race.
-+	 *
-+	 * The race cannot happen at all with MSI-X.
-+	 */
-+	t3_write_reg(adap, A_SG_GTS, V_RSPQ(qs->rspq.cntxt_id) |
-+		     V_NEWTIMER(qs->rspq.next_holdoff) |
-+		     V_NEWINDEX(qs->rspq.cidx));
-+	return 0;
- }
- 
- /*
-  * Returns true if the device is already scheduled for polling.
-  */
--static inline int napi_is_scheduled(struct napi_struct *napi)
-+static inline int napi_is_scheduled(struct net_device *dev)
- {
--	return test_bit(NAPI_STATE_SCHED, &napi->state);
-+	return test_bit(__LINK_STATE_RX_SCHED, &dev->state);
- }
- 
- /**
-@@ -2448,7 +2462,8 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
- 			     V_NEWTIMER(q->holdoff_tmr) | V_NEWINDEX(q->cidx));
- 		return 0;
- 	}
--	napi_schedule(&qs->napi);
-+	if (likely(__netif_rx_schedule_prep(qs->netdev)))
-+		__netif_rx_schedule(qs->netdev);
- 	return 1;
- }
- 
-@@ -2459,7 +2474,8 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q)
- irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
- {
- 	struct sge_qset *qs = cookie;
--	struct adapter *adap = qs->adap;
-+	const struct port_info *pi = netdev_priv(qs->netdev);
-+	struct adapter *adap = pi->adapter;
- 	struct sge_rspq *q = &qs->rspq;
- 
- 	spin_lock(&q->lock);
-@@ -2478,11 +2494,13 @@ irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
- static irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
- {
- 	struct sge_qset *qs = cookie;
-+	const struct port_info *pi = netdev_priv(qs->netdev);
-+	struct adapter *adap = pi->adapter;
- 	struct sge_rspq *q = &qs->rspq;
- 
- 	spin_lock(&q->lock);
- 
--	if (handle_responses(qs->adap, q) < 0)
-+	if (handle_responses(adap, q) < 0)
- 		q->unhandled_irqs++;
- 	spin_unlock(&q->lock);
- 	return IRQ_HANDLED;
-@@ -2525,13 +2543,11 @@ static irqreturn_t t3_intr_msi(int irq, void *cookie)
- 	return IRQ_HANDLED;
- }
- 
--static int rspq_check_napi(struct sge_qset *qs)
-+static int rspq_check_napi(struct net_device *dev, struct sge_rspq *q)
- {
--	struct sge_rspq *q = &qs->rspq;
--
--	if (!napi_is_scheduled(&qs->napi) &&
--	    is_new_response(&q->desc[q->cidx], q)) {
--		napi_schedule(&qs->napi);
-+	if (!napi_is_scheduled(dev) && is_new_response(&q->desc[q->cidx], q)) {
-+		if (likely(__netif_rx_schedule_prep(dev)))
-+			__netif_rx_schedule(dev);
- 		return 1;
- 	}
- 	return 0;
-@@ -2552,9 +2568,10 @@ static irqreturn_t t3_intr_msi_napi(int irq, void *cookie)
- 
- 	spin_lock(&q->lock);
- 
--	new_packets = rspq_check_napi(&adap->sge.qs[0]);
-+	new_packets = rspq_check_napi(adap->sge.qs[0].netdev, q);
- 	if (adap->params.nports == 2)
--		new_packets += rspq_check_napi(&adap->sge.qs[1]);
-+		new_packets += rspq_check_napi(adap->sge.qs[1].netdev,
-+					       &adap->sge.qs[1].rspq);
- 	if (!new_packets && t3_slow_intr_handler(adap) == 0)
- 		q->unhandled_irqs++;
- 
-@@ -2657,9 +2674,9 @@ static irqreturn_t t3b_intr(int irq, void *cookie)
- static irqreturn_t t3b_intr_napi(int irq, void *cookie)
- {
- 	u32 map;
-+	struct net_device *dev;
- 	struct adapter *adap = cookie;
--	struct sge_qset *qs0 = &adap->sge.qs[0];
--	struct sge_rspq *q0 = &qs0->rspq;
-+	struct sge_rspq *q0 = &adap->sge.qs[0].rspq;
- 
- 	t3_write_reg(adap, A_PL_CLI, 0);
- 	map = t3_read_reg(adap, A_SG_DATA_INTR);
-@@ -2672,11 +2689,18 @@ static irqreturn_t t3b_intr_napi(int irq, void *cookie)
- 	if (unlikely(map & F_ERRINTR))
- 		t3_slow_intr_handler(adap);
- 
--	if (likely(map & 1))
--		napi_schedule(&qs0->napi);
-+	if (likely(map & 1)) {
-+		dev = adap->sge.qs[0].netdev;
- 
--	if (map & 2)
--		napi_schedule(&adap->sge.qs[1].napi);
-+		if (likely(__netif_rx_schedule_prep(dev)))
-+			__netif_rx_schedule(dev);
-+	}
-+	if (map & 2) {
-+		dev = adap->sge.qs[1].netdev;
-+
-+		if (likely(__netif_rx_schedule_prep(dev)))
-+			__netif_rx_schedule(dev);
-+	}
- 
- 	spin_unlock(&q0->lock);
- 	return IRQ_HANDLED;
-@@ -2775,7 +2799,8 @@ static void sge_timer_cb(unsigned long data)
- {
- 	spinlock_t *lock;
- 	struct sge_qset *qs = (struct sge_qset *)data;
--	struct adapter *adap = qs->adap;
-+	const struct port_info *pi = netdev_priv(qs->netdev);
-+	struct adapter *adap = pi->adapter;
- 
- 	if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
- 		reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
-@@ -2786,9 +2811,9 @@ static void sge_timer_cb(unsigned long data)
- 		spin_unlock(&qs->txq[TXQ_OFLD].lock);
- 	}
- 	lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock :
--					    &adap->sge.qs[0].rspq.lock;
-+	    &adap->sge.qs[0].rspq.lock;
- 	if (spin_trylock_irq(lock)) {
--		if (!napi_is_scheduled(&qs->napi)) {
-+		if (!napi_is_scheduled(qs->netdev)) {
- 			u32 status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
- 
- 			if (qs->fl[0].credits < qs->fl[0].size)
-@@ -2822,9 +2847,12 @@ static void sge_timer_cb(unsigned long data)
-  */
- void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p)
- {
-+	if (!qs->netdev)
-+		return;
-+
- 	qs->rspq.holdoff_tmr = max(p->coalesce_usecs * 10, 1U);/* can't be 0 */
- 	qs->rspq.polling = p->polling;
--	qs->napi.poll = p->polling ? napi_rx_handler : ofld_poll;
-+	qs->netdev->poll = p->polling ? napi_rx_handler : ofld_poll;
- }
- 
- /**
-@@ -2844,7 +2872,7 @@ void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p)
-  */
- int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
- 		      int irq_vec_idx, const struct qset_params *p,
--		      int ntxq, struct net_device *dev)
-+		      int ntxq, struct net_device *netdev)
- {
- 	int i, avail, ret = -ENOMEM;
- 	struct sge_qset *q = &adapter->sge.qs[id];
-@@ -2978,11 +3006,17 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
- 	}
- 
- 	spin_unlock_irq(&adapter->sge.reg_lock);
--
--	q->adap = adapter;
--	q->netdev = dev;
-+	q->netdev = netdev;
- 	t3_update_qset_coalesce(q, p);
- 
-+ 	/*
-+ 	 * We use atalk_ptr as a backpointer to a qset.  In case a device is
-+ 	 * associated with multiple queue sets only the first one sets
-+ 	 * atalk_ptr.
-+ 	 */
-+ 	if (netdev->atalk_ptr == NULL)
-+ 		netdev->atalk_ptr = q;
-+
- 	init_lro_mgr(q, lro_mgr);
- 
- 	avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0020_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0020_sysfs.patch
deleted file mode 100644
index d5ddedb..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0020_sysfs.patch
+++ /dev/null
@@ -1,202 +0,0 @@
----
- drivers/net/cxgb3/cxgb3_main.c |   78 +++++++++++++++++++----------------------
- 1 file changed, 38 insertions(+), 40 deletions(-)
-
-Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
-+++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-@@ -76,6 +76,8 @@ enum {
- 
- #define EEPROM_MAGIC 0x38E2F10C
- 
-+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-+
- #define CH_DEVICE(devid, idx) \
- 	{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, idx }
- 
-@@ -516,7 +518,7 @@ static int setup_sge_qsets(struct adapte
- 	return 0;
- }
- 
--static ssize_t attr_show(struct device *d, char *buf,
-+static ssize_t attr_show(struct class_device *d, char *buf,
- 			 ssize_t(*format) (struct net_device *, char *))
- {
- 	ssize_t len;
-@@ -528,7 +530,7 @@ static ssize_t attr_show(struct device *
- 	return len;
- }
- 
--static ssize_t attr_store(struct device *d,
-+static ssize_t attr_store(struct class_device *d,
- 			  const char *buf, size_t len,
- 			  ssize_t(*set) (struct net_device *, unsigned int),
- 			  unsigned int min_val, unsigned int max_val)
-@@ -559,10 +561,9 @@ static ssize_t format_##name(struct net_
- 	struct adapter *adap = pi->adapter; \
- 	return sprintf(buf, "%u\n", val_expr); \
- } \
--static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
--			   char *buf) \
-+static ssize_t show_##name(struct class_device *cd, char *buf) \
- { \
--	return attr_show(d, buf, format_##name); \
-+	return attr_show(cd, buf, format_##name); \
- }
- 
- static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
-@@ -582,10 +583,10 @@ static ssize_t set_nfilters(struct net_d
- 	return 0;
- }
- 
--static ssize_t store_nfilters(struct device *d, struct device_attribute *attr,
--			      const char *buf, size_t len)
-+static ssize_t store_nfilters(struct class_device *cd, const char *buf,
-+			      size_t len)
- {
--	return attr_store(d, buf, len, set_nfilters, 0, ~0);
-+	return attr_store(cd, buf, len, set_nfilters, 0, ~0);
- }
- 
- static ssize_t set_nservers(struct net_device *dev, unsigned int val)
-@@ -602,35 +603,34 @@ static ssize_t set_nservers(struct net_d
- 	return 0;
- }
- 
--static ssize_t store_nservers(struct device *d, struct device_attribute *attr,
--			      const char *buf, size_t len)
-+static ssize_t store_nservers(struct class_device *cd, const char *buf,
-+			      size_t len)
- {
--	return attr_store(d, buf, len, set_nservers, 0, ~0);
-+	return attr_store(cd, buf, len, set_nservers, 0, ~0);
- }
- 
- #define CXGB3_ATTR_R(name, val_expr) \
- CXGB3_SHOW(name, val_expr) \
--static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
-+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
- 
- #define CXGB3_ATTR_RW(name, val_expr, store_method) \
- CXGB3_SHOW(name, val_expr) \
--static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method)
-+static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method)
- 
- CXGB3_ATTR_R(cam_size, t3_mc5_size(&adap->mc5));
- CXGB3_ATTR_RW(nfilters, adap->params.mc5.nfilters, store_nfilters);
- CXGB3_ATTR_RW(nservers, adap->params.mc5.nservers, store_nservers);
- 
- static struct attribute *cxgb3_attrs[] = {
--	&dev_attr_cam_size.attr,
--	&dev_attr_nfilters.attr,
--	&dev_attr_nservers.attr,
-+	&class_device_attr_cam_size.attr,
-+	&class_device_attr_nfilters.attr,
-+	&class_device_attr_nservers.attr,
- 	NULL
- };
- 
- static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs };
- 
--static ssize_t tm_attr_show(struct device *d,
--			    char *buf, int sched)
-+static ssize_t tm_attr_show(struct class_device *d, char *buf, int sched)
- {
- 	struct port_info *pi = netdev_priv(to_net_dev(d));
- 	struct adapter *adap = pi->adapter;
-@@ -655,8 +655,8 @@ static ssize_t tm_attr_show(struct devic
- 	return len;
- }
- 
--static ssize_t tm_attr_store(struct device *d,
--			     const char *buf, size_t len, int sched)
-+static ssize_t tm_attr_store(struct class_device *d, const char *buf,
-+			     size_t len, int sched)
- {
- 	struct port_info *pi = netdev_priv(to_net_dev(d));
- 	struct adapter *adap = pi->adapter;
-@@ -680,17 +680,15 @@ static ssize_t tm_attr_store(struct devi
- }
- 
- #define TM_ATTR(name, sched) \
--static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
--			   char *buf) \
-+static ssize_t show_##name(struct class_device *cd, char *buf) \
- { \
--	return tm_attr_show(d, buf, sched); \
-+	return tm_attr_show(cd, buf, sched); \
- } \
--static ssize_t store_##name(struct device *d, struct device_attribute *attr, \
--			    const char *buf, size_t len) \
-+static ssize_t store_##name(struct class_device *cd, const char *buf, size_t len) \
- { \
--	return tm_attr_store(d, buf, len, sched); \
-+	return tm_attr_store(cd, buf, len, sched); \
- } \
--static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
-+static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
- 
- TM_ATTR(sched0, 0);
- TM_ATTR(sched1, 1);
-@@ -702,14 +700,14 @@ TM_ATTR(sched6, 6);
- TM_ATTR(sched7, 7);
- 
- static struct attribute *offload_attrs[] = {
--	&dev_attr_sched0.attr,
--	&dev_attr_sched1.attr,
--	&dev_attr_sched2.attr,
--	&dev_attr_sched3.attr,
--	&dev_attr_sched4.attr,
--	&dev_attr_sched5.attr,
--	&dev_attr_sched6.attr,
--	&dev_attr_sched7.attr,
-+	&class_device_attr_sched0.attr,
-+	&class_device_attr_sched1.attr,
-+	&class_device_attr_sched2.attr,
-+	&class_device_attr_sched3.attr,
-+	&class_device_attr_sched4.attr,
-+	&class_device_attr_sched5.attr,
-+	&class_device_attr_sched6.attr,
-+	&class_device_attr_sched7.attr,
- 	NULL
- };
- 
-@@ -1051,8 +1049,8 @@ static int offload_open(struct net_devic
- 		     adapter->port[0]->mtu : 0xffff);
- 	init_smt(adapter);
- 
--	if (sysfs_create_group(&tdev->lldev->dev.kobj, &offload_attr_group))
--		dev_dbg(&dev->dev, "cannot create sysfs group\n");
-+ 	if (sysfs_create_group(&tdev->lldev->class_dev.kobj, &offload_attr_group))
-+		dev_dbg(&adapter->pdev->dev, "cannot create sysfs group\n");
- 
- 	/* Call back all registered clients */
- 	cxgb3_add_clients(tdev);
-@@ -1077,7 +1075,7 @@ static int offload_close(struct t3cdev *
- 	/* Call back all registered clients */
- 	cxgb3_remove_clients(tdev);
- 
--	sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
-+	sysfs_remove_group(&tdev->lldev->class_dev.kobj, &offload_attr_group);
- 
- 	tdev->lldev = NULL;
- 	cxgb3_set_dummy_ops(tdev);
-@@ -2788,7 +2786,7 @@ static int __devinit init_one(struct pci
- 	else if (msi > 0 && pci_enable_msi(pdev) == 0)
- 		adapter->flags |= USING_MSI;
- 
--	err = sysfs_create_group(&adapter->port[0]->dev.kobj,
-+	err = sysfs_create_group(&adapter->port[0]->class_dev.kobj,
- 				 &cxgb3_attr_group);
- 
- 	print_port_info(adapter, ai);
-@@ -2819,7 +2817,7 @@ static void __devexit remove_one(struct 
- 		int i;
- 
- 		t3_sge_stop(adapter);
--		sysfs_remove_group(&adapter->port[0]->dev.kobj,
-+		sysfs_remove_group(&adapter->port[0]->class_dev.kobj,
- 				   &cxgb3_attr_group);
- 
- 		if (is_offload(adapter)) {
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0030_sset.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0030_sset.patch
deleted file mode 100644
index 3f1b40e..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0030_sset.patch
+++ /dev/null
@@ -1,34 +0,0 @@
----
- drivers/net/cxgb3/cxgb3_main.c |   11 +++--------
- 1 file changed, 3 insertions(+), 8 deletions(-)
-
-Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
-+++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-@@ -1249,14 +1249,9 @@ static char stats_strings[][ETH_GSTRING_
- 
- };
- 
--static int get_sset_count(struct net_device *dev, int sset)
-+static int get_stats_count(struct net_device *dev)
- {
--	switch (sset) {
--	case ETH_SS_STATS:
--		return ARRAY_SIZE(stats_strings);
--	default:
--		return -EOPNOTSUPP;
--	}
-+	return ARRAY_SIZE(stats_strings);
- }
- 
- #define T3_REGMAP_SIZE (3 * 1024)
-@@ -1774,7 +1769,7 @@ static const struct ethtool_ops cxgb_eth
- 	.get_strings = get_strings,
- 	.phys_id = cxgb3_phys_id,
- 	.nway_reset = restart_autoneg,
--	.get_sset_count = get_sset_count,
-+	.get_stats_count = get_stats_count,
- 	.get_ethtool_stats = get_stats,
- 	.get_regs_len = get_regs_len,
- 	.get_regs = get_regs,
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0100_remove_lro.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0100_remove_lro.patch
deleted file mode 100644
index 6cd1123..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0100_remove_lro.patch
+++ /dev/null
@@ -1,491 +0,0 @@
----
- drivers/net/cxgb3/adapter.h     |   14 --
- drivers/net/cxgb3/common.h      |    1 
- drivers/net/cxgb3/cxgb3_ioctl.h |    1 
- drivers/net/cxgb3/cxgb3_main.c  |   19 ---
- drivers/net/cxgb3/sge.c         |  230 ++--------------------------------------
- drivers/net/cxgb3/t3_cpl.h      |   11 -
- 6 files changed, 12 insertions(+), 264 deletions(-)
-
-Index: ofed_kernel/drivers/net/cxgb3/adapter.h
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/adapter.h
-+++ ofed_kernel/drivers/net/cxgb3/adapter.h
-@@ -42,7 +42,6 @@
- #include <linux/cache.h>
- #include <linux/mutex.h>
- #include <linux/bitops.h>
--#include <linux/inet_lro.h>
- #include "t3cdev.h"
- #include <asm/io.h>
- 
-@@ -171,27 +170,14 @@ enum {				/* per port SGE statistics */
- 	SGE_PSTAT_TX_CSUM,	/* # of TX checksum offloads */
- 	SGE_PSTAT_VLANEX,	/* # of VLAN tag extractions */
- 	SGE_PSTAT_VLANINS,	/* # of VLAN tag insertions */
--	SGE_PSTAT_LRO_AGGR,	/* # of page chunks added to LRO sessions */
--	SGE_PSTAT_LRO_FLUSHED,	/* # of flushed LRO sessions */
--	SGE_PSTAT_LRO_NO_DESC,	/* # of overflown LRO sessions */
- 
- 	SGE_PSTAT_MAX		/* must be last */
- };
- 
--#define T3_MAX_LRO_SES 8
--#define T3_MAX_LRO_MAX_PKTS 64
--
- struct sge_qset {		/* an SGE queue set */
- 	struct sge_rspq rspq;
- 	struct sge_fl fl[SGE_RXQ_PER_SET];
- 	struct sge_txq txq[SGE_TXQ_PER_SET];
--	struct net_lro_mgr lro_mgr;
--	struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
--	struct skb_frag_struct *lro_frag_tbl;
--	int lro_nfrags;
--	int lro_enabled;
--	int lro_frag_len;
--	void *lro_va;
- 	struct net_device *netdev;	/* associated net device */
- 	unsigned long txq_stopped;	/* which Tx queues are stopped */
- 	struct timer_list tx_reclaim_timer;	/* reclaims TX buffers */
-Index: ofed_kernel/drivers/net/cxgb3/common.h
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/common.h
-+++ ofed_kernel/drivers/net/cxgb3/common.h
-@@ -351,7 +351,6 @@ struct tp_params {
- 
- struct qset_params {		/* SGE queue set parameters */
- 	unsigned int polling;	/* polling/interrupt service for rspq */
--	unsigned int lro;	/* large receive offload */
- 	unsigned int coalesce_usecs;	/* irq coalescing timer */
- 	unsigned int rspq_size;	/* # of entries in response queue */
- 	unsigned int fl_size;	/* # of entries in regular free list */
-Index: ofed_kernel/drivers/net/cxgb3/cxgb3_ioctl.h
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_ioctl.h
-+++ ofed_kernel/drivers/net/cxgb3/cxgb3_ioctl.h
-@@ -90,7 +90,6 @@ struct ch_qset_params {
- 	int32_t fl_size[2];
- 	int32_t intr_lat;
- 	int32_t polling;
--	int32_t lro;
- 	int32_t cong_thres;
- };
- 
-Index: ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/cxgb3_main.c
-+++ ofed_kernel/drivers/net/cxgb3/cxgb3_main.c
-@@ -1239,9 +1239,6 @@ static char stats_strings[][ETH_GSTRING_
- 	"VLANinsertions     ",
- 	"TxCsumOffload      ",
- 	"RxCsumGood         ",
--	"LroAggregated      ",
--	"LroFlushed         ",
--	"LroNoDesc          ",
- 	"RxDrops            ",
- 
- 	"CheckTXEnToggled   ",
-@@ -1365,9 +1362,6 @@ static void get_stats(struct net_device 
- 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
- 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
- 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
--	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
--	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
--	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
- 	*data++ = s->rx_cong_drops;
- 
- 	*data++ = s->num_toggled;
-@@ -1586,13 +1580,6 @@ static int set_rx_csum(struct net_device
- 	struct port_info *p = netdev_priv(dev);
- 
- 	p->rx_csum_offload = data;
--	if (!data) {
--		struct adapter *adap = p->adapter;
--		int i;
--
--		for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
--			adap->sge.qs[i].lro_enabled = 0;
--	}
- 	return 0;
- }
- 
-@@ -1865,11 +1852,6 @@ static int cxgb_extension_ioctl(struct n
- 				}
- 			}
- 		}
--		if (t.lro >= 0) {
--			struct sge_qset *qs = &adapter->sge.qs[t.qset_idx];
--			q->lro = t.lro;
--			qs->lro_enabled = t.lro;
--		}
- 		break;
- 	}
- 	case CHELSIO_GET_QSET_PARAMS:{
-@@ -1889,7 +1871,6 @@ static int cxgb_extension_ioctl(struct n
- 		t.fl_size[0] = q->fl_size;
- 		t.fl_size[1] = q->jumbo_size;
- 		t.polling = q->polling;
--		t.lro = q->lro;
- 		t.intr_lat = q->coalesce_usecs;
- 		t.cong_thres = q->cong_thres;
- 
-Index: ofed_kernel/drivers/net/cxgb3/sge.c
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/sge.c
-+++ ofed_kernel/drivers/net/cxgb3/sge.c
-@@ -774,7 +774,7 @@ recycle:
- 		goto recycle;
- 
- 	if (!skb)
--		newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
-+		newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
- 	if (unlikely(!newskb)) {
- 		if (!drop_thres)
- 			return NULL;
-@@ -1854,10 +1854,9 @@ static void restart_tx(struct sge_qset *
-  *	if it was immediate data in a response.
-  */
- static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
--		   struct sk_buff *skb, int pad, int lro)
-+		   struct sk_buff *skb, int pad)
- {
- 	struct cpl_rx_pkt *p = (struct cpl_rx_pkt *)(skb->data + pad);
--	struct sge_qset *qs = rspq_to_qset(rq);
- 	struct port_info *pi;
- 
- 	skb_pull(skb, sizeof(*p) + pad);
-@@ -1874,202 +1873,18 @@ static void rx_eth(struct adapter *adap,
- 	if (unlikely(p->vlan_valid)) {
- 		struct vlan_group *grp = pi->vlan_grp;
- 
--		qs->port_stats[SGE_PSTAT_VLANEX]++;
-+		rspq_to_qset(rq)->port_stats[SGE_PSTAT_VLANEX]++;
- 		if (likely(grp))
--			if (lro)
--				lro_vlan_hwaccel_receive_skb(&qs->lro_mgr, skb,
--							     grp,
--							     ntohs(p->vlan),
--							     p);
--			else
--				__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
--					  	  rq->polling);
-+			__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
-+					  rq->polling);
- 		else
- 			dev_kfree_skb_any(skb);
--	} else if (rq->polling) {
--		if (lro)
--			lro_receive_skb(&qs->lro_mgr, skb, p);
--		else
--			netif_receive_skb(skb);
--	} else
-+	} else if (rq->polling)
-+		netif_receive_skb(skb);
-+	else
- 		netif_rx(skb);
- }
- 
--static inline int is_eth_tcp(u32 rss)
--{
--	return G_HASHTYPE(ntohl(rss)) == RSS_HASH_4_TUPLE;
--}
--
--/**
-- *	lro_frame_ok - check if an ingress packet is eligible for LRO
-- *	@p: the CPL header of the packet
-- *
-- *	Returns true if a received packet is eligible for LRO.
-- *	The following conditions must be true:
-- *	- packet is TCP/IP Ethernet II (checked elsewhere)
-- *	- not an IP fragment
-- *	- no IP options
-- *	- TCP/IP checksums are correct
-- *	- the packet is for this host
-- */
--static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
--{
--	const struct ethhdr *eh = (struct ethhdr *)(p + 1);
--	const struct iphdr *ih = (struct iphdr *)(eh + 1);
--
--	return (*((u8 *)p + 1) & 0x90) == 0x10 && p->csum == htons(0xffff) &&
--		eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
--}
--
--#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
--                       TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
--		                       TCP_FLAG_SYN | TCP_FLAG_FIN)
--#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
--                     (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
--
--/**
-- *	lro_segment_ok - check if a TCP segment is eligible for LRO
-- *	@tcph: the TCP header of the packet
-- *
-- *	Returns true if a TCP packet is eligible for LRO.  This requires that
-- *	the packet have only the ACK flag set and no TCP options besides
-- *	time stamps.
-- */
--static inline int lro_segment_ok(const struct tcphdr *tcph)
--{
--	int optlen;
--
--	if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
--		return 0;
--
--	optlen = (tcph->doff << 2) - sizeof(*tcph);
--	if (optlen) {
--		const u32 *opt = (const u32 *)(tcph + 1);
--
--		if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
--		    *opt != htonl(TSTAMP_WORD) || !opt[2])
--			return 0;
--	}
--	return 1;
--}
--
--static int t3_get_lro_header(void **eh,  void **iph, void **tcph,
--			     u64 *hdr_flags, void *priv)
--{
--	const struct cpl_rx_pkt *cpl = priv;
--
--	if (!lro_frame_ok(cpl))
--		return -1;
--
--	*eh = (struct ethhdr *)(cpl + 1);
--	*iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
--	*tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
--
--	 if (!lro_segment_ok(*tcph))
--		return -1;
--
--	*hdr_flags = LRO_IPV4 | LRO_TCP;
--	return 0;
--}
--
--static int t3_get_skb_header(struct sk_buff *skb,
--			      void **iph, void **tcph, u64 *hdr_flags,
--			      void *priv)
--{
--	void *eh;
--
--	return t3_get_lro_header(&eh, iph, tcph, hdr_flags, priv);
--}
--
--static int t3_get_frag_header(struct skb_frag_struct *frag, void **eh,
--			      void **iph, void **tcph, u64 *hdr_flags,
--			      void *priv)
--{
--	return t3_get_lro_header(eh, iph, tcph, hdr_flags, priv);
--}
--
--/**
-- *	lro_add_page - add a page chunk to an LRO session
-- *	@adap: the adapter
-- *	@qs: the associated queue set
-- *	@fl: the free list containing the page chunk to add
-- *	@len: packet length
-- *	@complete: Indicates the last fragment of a frame
-- *
-- *	Add a received packet contained in a page chunk to an existing LRO
-- *	session.
-- */
--static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
--			 struct sge_fl *fl, int len, int complete)
--{
--	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
--	struct cpl_rx_pkt *cpl;
--	struct skb_frag_struct *rx_frag = qs->lro_frag_tbl;
--	int nr_frags = qs->lro_nfrags, frag_len = qs->lro_frag_len;
--	int offset = 0;
--
--	if (!nr_frags) {
--		offset = 2 + sizeof(struct cpl_rx_pkt);
--		qs->lro_va = cpl = sd->pg_chunk.va + 2;
--	}
--
--	fl->credits--;
--
--	len -= offset;
--	pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
--			 fl->buf_size, PCI_DMA_FROMDEVICE);
--
--	rx_frag += nr_frags;
--	rx_frag->page = sd->pg_chunk.page;
--	rx_frag->page_offset = sd->pg_chunk.offset + offset;
--	rx_frag->size = len;
--	frag_len += len;
--	qs->lro_nfrags++;
--	qs->lro_frag_len = frag_len;
--
--	if (!complete)
--		return;
--
--	qs->lro_nfrags = qs->lro_frag_len = 0;
--	cpl = qs->lro_va;
--
--	if (unlikely(cpl->vlan_valid)) {
--		struct net_device *dev = qs->netdev;
--		struct port_info *pi = netdev_priv(dev);
--		struct vlan_group *grp = pi->vlan_grp;
--
--		if (likely(grp != NULL)) {
--			lro_vlan_hwaccel_receive_frags(&qs->lro_mgr,
--						       qs->lro_frag_tbl,
--						       frag_len, frag_len,
--						       grp, ntohs(cpl->vlan),
--						       cpl, 0);
--			return;
--		}
--	}
--	lro_receive_frags(&qs->lro_mgr, qs->lro_frag_tbl,
--			  frag_len, frag_len, cpl, 0);
--}
--
--/**
-- *	init_lro_mgr - initialize a LRO manager object
-- *	@lro_mgr: the LRO manager object
-- */
--static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
--{
--	lro_mgr->dev = qs->netdev;
--	lro_mgr->features = LRO_F_NAPI;
--	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
--	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
--	lro_mgr->max_desc = T3_MAX_LRO_SES;
--	lro_mgr->lro_arr = qs->lro_desc;
--	lro_mgr->get_frag_header = t3_get_frag_header;
--	lro_mgr->get_skb_header = t3_get_skb_header;
--	lro_mgr->max_aggr = T3_MAX_LRO_MAX_PKTS;
--	if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
--		lro_mgr->max_aggr = MAX_SKB_FRAGS;
--}
--
- /**
-  *	handle_rsp_cntrl_info - handles control information in a response
-  *	@qs: the queue set corresponding to the response
-@@ -2198,7 +2013,7 @@ static int process_responses(struct adap
- 	q->next_holdoff = q->holdoff_tmr;
- 
- 	while (likely(budget_left && is_new_response(r, q))) {
--		int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
-+		int packet_complete, eth, ethpad = 2;
- 		struct sk_buff *skb = NULL;
- 		u32 len, flags = ntohl(r->flags);
- 		__be32 rss_hi = *(const __be32 *)r,
-@@ -2230,9 +2045,6 @@ no_mem:
- 		} else if ((len = ntohl(r->len_cq)) != 0) {
- 			struct sge_fl *fl;
- 
--			if (eth)
--				lro = qs->lro_enabled && is_eth_tcp(rss_hi);
--
- 			fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
- 			if (fl->use_pages) {
- 				void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
-@@ -2242,12 +2054,6 @@ no_mem:
- 				prefetch(addr + L1_CACHE_BYTES);
- #endif
- 				__refill_fl(adap, fl);
--				if (lro > 0) {
--					lro_add_page(adap, qs, fl,
--						     G_RSPD_LEN(len),
--						     flags & F_RSPD_EOP);
--					 goto next_fl;
--				}
- 
- 				skb = get_packet_pg(adap, fl, q,
- 						    G_RSPD_LEN(len),
-@@ -2263,7 +2069,7 @@ no_mem:
- 				q->rx_drops++;
- 			} else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT))
- 				__skb_pull(skb, 2);
--next_fl:
-+
- 			if (++fl->cidx == fl->size)
- 				fl->cidx = 0;
- 		} else
-@@ -2293,7 +2099,7 @@ next_fl:
- 
- 		if (skb != NULL && packet_complete) {
- 			if (eth)
--				rx_eth(adap, q, skb, ethpad, lro);
-+				rx_eth(adap, q, skb, ethpad);
- 			else {
- 				q->offload_pkts++;
- 				/* Preserve the RSS info in csum & priority */
-@@ -2305,17 +2111,12 @@ next_fl:
- 			}
- 
- 			if (flags & F_RSPD_EOP)
--				clear_rspq_bufstate(q);
-+				clear_rspq_bufstate(q);
- 		}
- 		--budget_left;
- 	}
- 
- 	deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);
--	lro_flush_all(&qs->lro_mgr);
--	qs->port_stats[SGE_PSTAT_LRO_AGGR] = qs->lro_mgr.stats.aggregated;
--	qs->port_stats[SGE_PSTAT_LRO_FLUSHED] = qs->lro_mgr.stats.flushed;
--	qs->port_stats[SGE_PSTAT_LRO_NO_DESC] = qs->lro_mgr.stats.no_desc;
--
- 	if (sleeping)
- 		check_ring_db(adap, qs, sleeping);
- 
-@@ -2876,7 +2677,6 @@ int t3_sge_alloc_qset(struct adapter *ad
- {
- 	int i, avail, ret = -ENOMEM;
- 	struct sge_qset *q = &adapter->sge.qs[id];
--	struct net_lro_mgr *lro_mgr = &q->lro_mgr;
- 
- 	init_qset_cntxt(q, id);
- 	init_timer(&q->tx_reclaim_timer);
-@@ -2957,10 +2757,6 @@ int t3_sge_alloc_qset(struct adapter *ad
- 	q->fl[0].order = FL0_PG_ORDER;
- 	q->fl[1].order = FL1_PG_ORDER;
- 
--	q->lro_frag_tbl = kcalloc(MAX_FRAME_SIZE / FL1_PG_CHUNK_SIZE + 1,
--				  sizeof(struct skb_frag_struct),
--				  GFP_KERNEL);
--	q->lro_nfrags = q->lro_frag_len = 0;
- 	spin_lock_irq(&adapter->sge.reg_lock);
- 
- 	/* FL threshold comparison uses < */
-@@ -3017,8 +2813,6 @@ int t3_sge_alloc_qset(struct adapter *ad
-  	if (netdev->atalk_ptr == NULL)
-  		netdev->atalk_ptr = q;
- 
--	init_lro_mgr(q, lro_mgr);
--
- 	avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
- 			  GFP_KERNEL | __GFP_COMP);
- 	if (!avail) {
-Index: ofed_kernel/drivers/net/cxgb3/t3_cpl.h
-===================================================================
---- ofed_kernel.orig/drivers/net/cxgb3/t3_cpl.h
-+++ ofed_kernel/drivers/net/cxgb3/t3_cpl.h
-@@ -174,13 +174,6 @@ enum {				/* TCP congestion control algo
- 	CONG_ALG_HIGHSPEED
- };
- 
--enum {			/* RSS hash type */
--	RSS_HASH_NONE = 0,
--	RSS_HASH_2_TUPLE = 1,
--	RSS_HASH_4_TUPLE = 2,
--	RSS_HASH_TCPV6 = 3
--};
--
- union opcode_tid {
- 	__be32 opcode_tid;
- 	__u8 opcode;
-@@ -194,10 +187,6 @@ union opcode_tid {
- #define S_QNUM 0
- #define G_QNUM(x) (((x) >> S_QNUM) & 0xFFFF)
- 
--#define S_HASHTYPE 22
--#define M_HASHTYPE 0x3
--#define G_HASHTYPE(x) (((x) >> S_HASHTYPE) & M_HASHTYPE)
--
- /* tid is assumed to be 24-bits */
- #define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid))
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0110_provider_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0110_provider_sysfs.patch
deleted file mode 100644
index cafd90e..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/cxgb3_0110_provider_sysfs.patch
+++ /dev/null
@@ -1,120 +0,0 @@
----
- drivers/infiniband/hw/cxgb3/iwch_provider.c |   63 +++++++++++++---------------
- 1 file changed, 30 insertions(+), 33 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_provider.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/cxgb3/iwch_provider.c
-+++ ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_provider.c
-@@ -1178,46 +1178,43 @@ static int iwch_query_port(struct ib_dev
- 	return 0;
- }
- 
--static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_rev(struct class_device *cdev, char *buf)
- {
--	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
--						 ibdev.dev);
--	PDBG("%s dev 0x%p\n", __func__, dev);
-+	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
-+						 ibdev.class_dev);
-+	PDBG("%s dev 0x%p\n", __func__, cdev);
- 	return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type);
- }
- 
--static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf)
-+static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
- {
--	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
--						 ibdev.dev);
-+	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
-+						 ibdev.class_dev);
- 	struct ethtool_drvinfo info;
- 	struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
- 
--	PDBG("%s dev 0x%p\n", __func__, dev);
-+	PDBG("%s dev 0x%p\n", __func__, cdev);
- 	lldev->ethtool_ops->get_drvinfo(lldev, &info);
- 	return sprintf(buf, "%s\n", info.fw_version);
- }
- 
--static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_hca(struct class_device *cdev, char *buf)
- {
--	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
--						 ibdev.dev);
-+	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
-+						 ibdev.class_dev);
- 	struct ethtool_drvinfo info;
- 	struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
- 
--	PDBG("%s dev 0x%p\n", __func__, dev);
-+	PDBG("%s dev 0x%p\n", __func__, cdev);
- 	lldev->ethtool_ops->get_drvinfo(lldev, &info);
- 	return sprintf(buf, "%s\n", info.driver);
- }
- 
--static ssize_t show_board(struct device *dev, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_board(struct class_device *cdev, char *buf)
- {
--	struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
--						 ibdev.dev);
--	PDBG("%s dev 0x%p\n", __func__, dev);
-+	struct iwch_dev *iwch_dev = container_of(cdev, struct iwch_dev,
-+						 ibdev.class_dev);
-+	PDBG("%s dev 0x%p\n", __func__, cdev);
- 	return sprintf(buf, "%x.%x\n", iwch_dev->rdev.rnic_info.pdev->vendor,
- 		       iwch_dev->rdev.rnic_info.pdev->device);
- }
-@@ -1281,16 +1278,16 @@ static int iwch_get_mib(struct ib_device
- 	return 0;
- }
- 
--static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
--static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
--static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
--static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
--
--static struct device_attribute *iwch_class_attributes[] = {
--	&dev_attr_hw_rev,
--	&dev_attr_fw_ver,
--	&dev_attr_hca_type,
--	&dev_attr_board_id,
-+static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
-+static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
-+static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
-+static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
-+
-+static struct class_device_attribute *iwch_class_attributes[] = {
-+	&class_device_attr_hw_rev,
-+	&class_device_attr_fw_ver,
-+	&class_device_attr_hca_type,
-+	&class_device_attr_board_id,
- };
- 
- int iwch_register_device(struct iwch_dev *dev)
-@@ -1389,8 +1386,8 @@ int iwch_register_device(struct iwch_dev
- 		goto bail1;
- 
- 	for (i = 0; i < ARRAY_SIZE(iwch_class_attributes); ++i) {
--		ret = device_create_file(&dev->ibdev.dev,
--					 iwch_class_attributes[i]);
-+		ret = class_device_create_file(&dev->ibdev.class_dev,
-+						iwch_class_attributes[i]);
- 		if (ret) {
- 			goto bail2;
- 		}
-@@ -1408,8 +1405,8 @@ void iwch_unregister_device(struct iwch_
- 
- 	PDBG("%s iwch_dev %p\n", __func__, dev);
- 	for (i = 0; i < ARRAY_SIZE(iwch_class_attributes); ++i)
--		device_remove_file(&dev->ibdev.dev,
--				   iwch_class_attributes[i]);
-+		class_device_remove_file(&dev->ibdev.class_dev,
-+					iwch_class_attributes[i]);
- 	ib_unregister_device(&dev->ibdev);
- 	return;
- }
diff --git a/kernel_patches/backport/2.6.18-EL5.1/dma_mapping_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/dma_mapping_to_2_6_26.patch
deleted file mode 100644
index 3159b92..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/dma_mapping_to_2_6_26.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- include/rdma/ib_verbs.h |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: ofed_kernel/include/rdma/ib_verbs.h
-===================================================================
---- ofed_kernel.orig/include/rdma/ib_verbs.h
-+++ ofed_kernel/include/rdma/ib_verbs.h
-@@ -1682,7 +1682,7 @@ static inline int ib_dma_mapping_error(s
- {
- 	if (dev->dma_ops)
- 		return dev->dma_ops->mapping_error(dev, dma_addr);
--	return dma_mapping_error(dev->dma_device, dma_addr);
-+	return dma_mapping_error(dma_addr);
- }
- 
- /**
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ehca-00-revert_inhibit_dmem.patch b/kernel_patches/backport/2.6.18-EL5.1/ehca-00-revert_inhibit_dmem.patch
deleted file mode 100644
index 3b153ec..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ehca-00-revert_inhibit_dmem.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 8e110a2fff1f110a9211f240acc12b8310e5cbd3 Mon Sep 17 00:00:00 2001
-From: Stefan Roscher <ossrosch at linux.vnet.ibm.com>
-Date: Wed, 22 Oct 2008 15:54:38 -0700
-Subject: [PATCH] IB/ehca: Reject dynamic memory add/remove when ehca adapter is present
-
-Since the ehca device driver does not support dynamic memory add and
-remove operations, the driver must explicitly reject such requests in
-order to prevent unpredictable behaviors related to existing memory
-regions that cover all of memory being used by InfiniBand protocols in
-the kernel.
-
-The solution (for now at least) is to add a memory notifier to the
-ehca device driver and if a request for dynamic memory add or remove
-comes in, ehca will always reject it.  The user can add or remove
-memory by hot-removing the ehca adapter, performing the memory
-operation, and then hot-adding the ehca adapter back.
-
-Signed-off-by: Stefan Roscher <stefan.roscher at de.ibm.com>
-Signed-off-by: Roland Dreier <rolandd at cisco.com>
----
- drivers/infiniband/hw/ehca/ehca_main.c |   47 --------------------------------
- 1 files changed, 0 insertions(+), 47 deletions(-)
-
-diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
-index bec7e02..086959a 100644
---- a/drivers/infiniband/hw/ehca/ehca_main.c
-+++ b/drivers/infiniband/hw/ehca/ehca_main.c
-@@ -44,8 +44,6 @@
- #include <linux/slab.h>
- #endif
- 
--#include <linux/notifier.h>
--#include <linux/memory.h>
- #include "ehca_classes.h"
- #include "ehca_iverbs.h"
- #include "ehca_mrmw.h"
-@@ -971,40 +969,6 @@ void ehca_poll_eqs(unsigned long data)
- 	spin_unlock(&shca_list_lock);
- }
- 
--static int ehca_mem_notifier(struct notifier_block *nb,
--			     unsigned long action, void *data)
--{
--	static unsigned long ehca_dmem_warn_time;
--
--	switch (action) {
--	case MEM_CANCEL_OFFLINE:
--	case MEM_CANCEL_ONLINE:
--	case MEM_ONLINE:
--	case MEM_OFFLINE:
--		return NOTIFY_OK;
--	case MEM_GOING_ONLINE:
--	case MEM_GOING_OFFLINE:
--		/* only ok if no hca is attached to the lpar */
--		spin_lock(&shca_list_lock);
--		if (list_empty(&shca_list)) {
--			spin_unlock(&shca_list_lock);
--			return NOTIFY_OK;
--		} else {
--			spin_unlock(&shca_list_lock);
--			if (printk_timed_ratelimit(&ehca_dmem_warn_time,
--						   30 * 1000))
--				ehca_gen_err("DMEM operations are not allowed"
--					     "in conjunction with eHCA");
--			return NOTIFY_BAD;
--		}
--	}
--	return NOTIFY_OK;
--}
--
--static struct notifier_block ehca_mem_nb = {
--	.notifier_call = ehca_mem_notifier,
--};
--
- static int __init ehca_module_init(void)
- {
- 	int ret;
-@@ -1032,12 +996,6 @@ static int __init ehca_module_init(void)
- 		goto module_init2;
- 	}
- 
--	ret = register_memory_notifier(&ehca_mem_nb);
--	if (ret) {
--		ehca_gen_err("Failed registering memory add/remove notifier");
--		goto module_init3;
--	}
--
- 	if (ehca_poll_all_eqs != 1) {
- 		ehca_gen_err("WARNING!!!");
- 		ehca_gen_err("It is possible to lose interrupts.");
-@@ -1050,9 +1008,6 @@ static int __init ehca_module_init(void)
- 
- 	return 0;
- 
--module_init3:
--	ibmebus_unregister_driver(&ehca_driver);
--
- module_init2:
- 	ehca_destroy_slab_caches();
- 
-@@ -1068,8 +1023,6 @@ static void __exit ehca_module_exit(void)
- 
- 	ibmebus_unregister_driver(&ehca_driver);
- 
--	unregister_memory_notifier(&ehca_mem_nb);
--
- 	ehca_destroy_slab_caches();
- 
- 	ehca_destroy_comp_pool();
--- 
-1.5.5
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ehca-01-ibmebus_loc_code.patch b/kernel_patches/backport/2.6.18-EL5.1/ehca-01-ibmebus_loc_code.patch
deleted file mode 100644
index c486733..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ehca-01-ibmebus_loc_code.patch
+++ /dev/null
@@ -1,191 +0,0 @@
----
- drivers/infiniband/hw/ehca/ehca_classes.h |    2 -
- drivers/infiniband/hw/ehca/ehca_eq.c      |    6 +--
- drivers/infiniband/hw/ehca/ehca_main.c    |   49 ++++++++++++++----------------
- 3 files changed, 27 insertions(+), 30 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_classes.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_classes.h
-+++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_classes.h
-@@ -112,7 +112,7 @@ struct ehca_sport {
- 
- struct ehca_shca {
- 	struct ib_device ib_device;
--	struct of_device *ofdev;
-+	struct ibmebus_dev *ibmebus_dev;
- 	u8 num_ports;
- 	int hw_level;
- 	struct list_head shca_list;
-Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_eq.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_eq.c
-+++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_eq.c
-@@ -122,7 +122,7 @@ int ehca_create_eq(struct ehca_shca *shc
- 
- 	/* register interrupt handlers and initialize work queues */
- 	if (type == EHCA_EQ) {
--		ret = ibmebus_request_irq(eq->ist, ehca_interrupt_eq,
-+		ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq,
- 					  IRQF_DISABLED, "ehca_eq",
- 					  (void *)shca);
- 		if (ret < 0)
-@@ -130,7 +130,7 @@ int ehca_create_eq(struct ehca_shca *shc
- 
- 		tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
- 	} else if (type == EHCA_NEQ) {
--		ret = ibmebus_request_irq(eq->ist, ehca_interrupt_neq,
-+		ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq,
- 					  IRQF_DISABLED, "ehca_neq",
- 					  (void *)shca);
- 		if (ret < 0)
-@@ -170,7 +170,7 @@ int ehca_destroy_eq(struct ehca_shca *sh
- 	u64 h_ret;
- 
- 	spin_lock_irqsave(&eq->spinlock, flags);
--	ibmebus_free_irq(eq->ist, (void *)shca);
-+	ibmebus_free_irq(NULL, eq->ist, (void *)shca);
- 
- 	h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
- 
-Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_main.c
-+++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_main.c
-@@ -289,8 +289,8 @@ static int ehca_sense_attributes(struct 
- 	};
- 
- 	ehca_gen_dbg("Probing adapter %s...",
--		     shca->ofdev->node->full_name);
--	loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL);
-+		     shca->ibmebus_dev->ofdev.node->full_name);
-+	loc_code = of_get_property(shca->ibmebus_dev->ofdev.node, "ibm,loc-code", NULL);
- 	if (loc_code)
- 		ehca_gen_dbg(" ... location lode=%s", loc_code);
- 
-@@ -458,7 +458,7 @@ static int ehca_init_device(struct ehca_
- 	shca->ib_device.node_type           = RDMA_NODE_IB_CA;
- 	shca->ib_device.phys_port_cnt       = shca->num_ports;
- 	shca->ib_device.num_comp_vectors    = 1;
--	shca->ib_device.dma_device          = &shca->ofdev->dev;
-+	shca->ib_device.dma_device          = &shca->ibmebus_dev->ofdev.dev;
- 	shca->ib_device.query_device        = ehca_query_device;
- 	shca->ib_device.query_port          = ehca_query_port;
- 	shca->ib_device.query_gid           = ehca_query_gid;
-@@ -619,11 +619,6 @@ static struct attribute_group ehca_drv_a
- 	.attrs = ehca_drv_attrs
- };
- 
--static struct attribute_group *ehca_drv_attr_groups[] = {
--	&ehca_drv_attr_grp,
--	NULL,
--};
--
- #define EHCA_RESOURCE_ATTR(name)                                           \
- static ssize_t  ehca_show_##name(struct device *dev,                       \
- 				 struct device_attribute *attr,            \
-@@ -707,7 +702,7 @@ static struct attribute_group ehca_dev_a
- 	.attrs = ehca_dev_attrs
- };
- 
--static int __devinit ehca_probe(struct of_device *dev,
-+static int __devinit ehca_probe(struct ibmebus_dev *dev,
- 				const struct of_device_id *id)
- {
- 	struct ehca_shca *shca;
-@@ -715,16 +710,16 @@ static int __devinit ehca_probe(struct o
- 	struct ib_pd *ibpd;
- 	int ret, i, eq_size;
- 
--	handle = of_get_property(dev->node, "ibm,hca-handle", NULL);
-+	handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
- 	if (!handle) {
- 		ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
--			     dev->node->full_name);
-+			     dev->ofdev.node->full_name);
- 		return -ENODEV;
- 	}
- 
- 	if (!(*handle)) {
- 		ehca_gen_err("Wrong eHCA handle for adapter: %s.",
--			     dev->node->full_name);
-+			     dev->ofdev.node->full_name);
- 		return -ENODEV;
- 	}
- 
-@@ -739,9 +734,9 @@ static int __devinit ehca_probe(struct o
- 	for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
- 		spin_lock_init(&shca->sport[i].mod_sqp_lock);
- 
--	shca->ofdev = dev;
-+	shca->ibmebus_dev = dev;
- 	shca->ipz_hca_handle.handle = *handle;
--	dev->dev.driver_data = shca;
-+	dev->ofdev.dev.driver_data = shca;
- 
- 	ret = ehca_sense_attributes(shca);
- 	if (ret < 0) {
-@@ -818,7 +813,7 @@ static int __devinit ehca_probe(struct o
- 		}
- 	}
- 
--	ret = sysfs_create_group(&dev->dev.kobj, &ehca_dev_attr_grp);
-+	ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
- 	if (ret) /* only complain; we can live without attributes */
- 		ehca_err(&shca->ib_device,
- 			 "Cannot create device attributes  ret=%d", ret);
-@@ -868,12 +863,12 @@ probe1:
- 	return -EINVAL;
- }
- 
--static int __devexit ehca_remove(struct of_device *dev)
-+static int __devexit ehca_remove(struct ibmebus_dev *dev)
- {
--	struct ehca_shca *shca = dev->dev.driver_data;
-+	struct ehca_shca *shca = dev->ofdev.dev.driver_data;
- 	int ret;
- 
--	sysfs_remove_group(&dev->dev.kobj, &ehca_dev_attr_grp);
-+	sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
- 
- 	if (ehca_open_aqp1 == 1) {
- 		int i;
-@@ -925,14 +920,11 @@ static struct of_device_id ehca_device_t
- };
- MODULE_DEVICE_TABLE(of, ehca_device_table);
- 
--static struct of_platform_driver ehca_driver = {
--	.name        = "ehca",
--	.match_table = ehca_device_table,
--	.probe       = ehca_probe,
--	.remove      = ehca_remove,
--	.driver	     = {
--		.groups = ehca_drv_attr_groups,
--	},
-+static struct ibmebus_driver ehca_driver = {
-+	.name     = "ehca",
-+	.id_table = ehca_device_table,
-+	.probe    = ehca_probe,
-+	.remove   = ehca_remove,
- };
- 
- void ehca_poll_eqs(unsigned long data)
-@@ -991,6 +983,10 @@ static int __init ehca_module_init(void)
- 		goto module_init2;
- 	}
- 
-+	ret = sysfs_create_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp);
-+	if (ret) /* only complain; we can live without attributes */
-+		ehca_gen_err("Cannot create driver attributes  ret=%d", ret);
-+
- 	if (ehca_poll_all_eqs != 1) {
- 		ehca_gen_err("WARNING!!!");
- 		ehca_gen_err("It is possible to lose interrupts.");
-@@ -1016,6 +1012,7 @@ static void __exit ehca_module_exit(void
- 	if (ehca_poll_all_eqs == 1)
- 		del_timer_sync(&poll_eqs_timer);
- 
-+	sysfs_remove_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp);
- 	ibmebus_unregister_driver(&ehca_driver);
- 
- 	ehca_destroy_slab_caches();
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ehca_02_revert_interface_change.patch b/kernel_patches/backport/2.6.18-EL5.1/ehca_02_revert_interface_change.patch
deleted file mode 100644
index 5cbbabd..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ehca_02_revert_interface_change.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 7ef1f7881a8f660654e7d1567213638b37adbbb5 Mon Sep 17 00:00:00 2001
-From: Stefan Roscher <stefan.roscher at de.ibm.com>
-Date: Wed, 6 Aug 2008 16:27:25 +0200
-Subject: [PATCH] Revert "infiniband: use performance variant for_each_cpu_mask_nr"
-
-This reverts commit 5d7bfd0c4d463d288422032c9903d0452dee141d.
----
- drivers/infiniband/hw/ehca/ehca_irq.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ehca/ehca_irq.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ehca/ehca_irq.c
-+++ ofed_kernel/drivers/infiniband/hw/ehca/ehca_irq.c
-@@ -650,8 +650,8 @@ static inline int find_next_online_cpu(s
- 		ehca_dmp(&cpu_online_map, sizeof(cpumask_t), "");
- 
- 	spin_lock_irqsave(&pool->last_cpu_lock, flags);
--	cpu = next_cpu_nr(pool->last_cpu, cpu_online_map);
--	if (cpu >= nr_cpu_ids)
-+	cpu = next_cpu(pool->last_cpu, cpu_online_map);
-+	if (cpu == NR_CPUS)
- 		cpu = first_cpu(cpu_online_map);
- 	pool->last_cpu = cpu;
- 	spin_unlock_irqrestore(&pool->last_cpu_lock, flags);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0005_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0005_pci_dma_mapping_error_to_2_6_26.patch
deleted file mode 100644
index 9d336a7..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0005_pci_dma_mapping_error_to_2_6_26.patch
+++ /dev/null
@@ -1,58 +0,0 @@
----
- drivers/infiniband/hw/ipath/ipath_sdma.c      |    2 +-
- drivers/infiniband/hw/ipath/ipath_user_sdma.c |    6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
-Index: ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_sdma.c
-===================================================================
---- ofa_kernel-1.4.orig/drivers/infiniband/hw/ipath/ipath_sdma.c	2009-01-25 21:37:35.000000000 -0800
-+++ ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_sdma.c	2009-01-25 21:41:22.000000000 -0800
-@@ -698,7 +698,7 @@ retry:
- 
- 	addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr,
- 			      tx->map_len, DMA_TO_DEVICE);
--	if (dma_mapping_error(&dd->pcidev->dev, addr))
-+	if (dma_mapping_error(addr))
- 		goto ioerr;
- 
- 	dwoffset = tx->map_len >> 2;
-@@ -739,7 +739,7 @@ retry:
- 		dw = (len + 3) >> 2;
- 		addr = dma_map_single(&dd->pcidev->dev, sge->vaddr, dw << 2,
- 				      DMA_TO_DEVICE);
--		if (dma_mapping_error(&dd->pcidev->dev, addr))
-+		if (dma_mapping_error(addr))
- 			goto unmap;
- 		make_sdma_desc(dd, sdmadesc, (u64) addr, dw, dwoffset);
- 		/* SDmaUseLargeBuf has to be set in every descriptor */
-Index: ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_user_sdma.c
-===================================================================
---- ofa_kernel-1.4.orig/drivers/infiniband/hw/ipath/ipath_user_sdma.c	2009-01-25 21:37:18.000000000 -0800
-+++ ofa_kernel-1.4/drivers/infiniband/hw/ipath/ipath_user_sdma.c	2009-01-25 21:37:54.000000000 -0800
-@@ -206,7 +206,7 @@ static int ipath_user_sdma_coalesce(cons
- 
- 	dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len,
- 				DMA_TO_DEVICE);
--	if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) {
-+	if (dma_mapping_error(dma_addr)) {
- 		ret = -ENOMEM;
- 		goto free_unmap;
- 	}
-@@ -301,7 +301,7 @@ static int ipath_user_sdma_pin_pages(con
- 				     pages[j], 0, flen, DMA_TO_DEVICE);
- 		unsigned long fofs = addr & ~PAGE_MASK;
- 
--		if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) {
-+		if (dma_mapping_error(dma_addr)) {
- 			ret = -ENOMEM;
- 			goto done;
- 		}
-@@ -508,7 +508,7 @@ static int ipath_user_sdma_queue_pkts(co
- 		if (page) {
- 			dma_addr = dma_map_page(&dd->pcidev->dev,
- 						page, 0, len, DMA_TO_DEVICE);
--			if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) {
-+			if (dma_mapping_error(dma_addr)) {
- 				ret = -ENOMEM;
- 				goto free_pbc;
- 			}
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0010_revert_pid.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0010_revert_pid.patch
deleted file mode 100644
index 58d1019..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0010_revert_pid.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-Signed-off-by: Dave Olson <dave.olson at qlogic.com>
----
-
-diff -upr ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_driver.c ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_driver.c
---- ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_driver.c	2008-10-28 12:27:04.000000000 -0700
-+++ ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_driver.c	2008-10-28 12:31:40.000000000 -0700
-@@ -2622,7 +2622,7 @@ int ipath_reset_device(int unit)
- 				ipath_dbg("unit %u port %d is in use "
- 					  "(PID %u cmd %s), can't reset\n",
- 					  unit, i,
--					  pid_nr(dd->ipath_pd[i]->port_pid),
-+					  dd->ipath_pd[i]->port_pid,
- 					  dd->ipath_pd[i]->port_comm);
- 				ret = -EBUSY;
- 				goto bail;
-@@ -2661,7 +2661,7 @@ bail:
- static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
- {
- 	int i, sub, any = 0;
--	struct pid *pid;
-+	pid_t pid;
- 	unsigned long flags;
- 	
- 	if (!dd->ipath_pd)
-@@ -2669,7 +2669,8 @@ static int ipath_signal_procs(struct ipa
- 
- 	spin_lock_irqsave(&dd->ipath_uctxt_lock, flags);
- 	for (i = 1; i < dd->ipath_cfgports; i++) {
--		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt)
-+		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt ||
-+		    !dd->ipath_pd[i]->port_pid)
- 			continue;
- 		pid = dd->ipath_pd[i]->port_pid;
- 		if (!pid)
-@@ -2677,8 +2678,8 @@ static int ipath_signal_procs(struct ipa
- 
- 		dev_info(&dd->pcidev->dev, "context %d in use "
- 			  "(PID %u), sending signal %d\n",
--			  i, pid_nr(pid), sig);
--		kill_pid(pid, sig, 1);
-+			  i, pid, sig);
-+		kill_proc(pid, sig, 1);
- 		any++;
- 		for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) {
- 			pid = dd->ipath_pd[i]->port_subpid[sub];
-@@ -2686,8 +2687,8 @@ static int ipath_signal_procs(struct ipa
- 				continue;
- 			dev_info(&dd->pcidev->dev, "sub-context "
- 				"%d:%d in use (PID %u), sending "
--				"signal %d\n", i, sub, pid_nr(pid), sig);
--			kill_pid(pid, sig, 1);
-+				"signal %d\n", i, sub, pid, sig);
-+			kill_proc(pid, sig, 1);
- 			any++;
- 		}
- 	}
-diff -upr ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_file_ops.c ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_file_ops.c
---- ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_file_ops.c	2008-10-28 12:27:04.000000000 -0700
-+++ ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_file_ops.c	2008-10-28 12:46:09.000000000 -0700
-@@ -556,7 +556,7 @@ static int ipath_tid_free(struct ipath_p
- 			p = dd->ipath_pageshadow[porttid + tid];
- 			dd->ipath_pageshadow[porttid + tid] = NULL;
- 			ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
--				   pid_nr(pd->port_pid), tid);
-+				   pd->port_pid, tid);
- 			dd->ipath_f_put_tid(dd, &tidbase[tid],
- 					    RCVHQ_RCV_TYPE_EXPECTED,
- 					    dd->ipath_tidinvalid);
-@@ -1610,7 +1610,7 @@ static int try_alloc_port(struct ipath_d
- 			   port);
- 		pd->port_cnt = 1;
- 		port_fp(fp) = pd;
--		pd->port_pid = get_pid(task_pid(current));
-+		pd->port_pid = current->pid;
- 		strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
- 		ipath_stats.sps_ports++;
- 		ret = 0;
-@@ -1794,15 +1794,14 @@ static int find_shared_port(struct file 
- 			}
- 			port_fp(fp) = pd;
- 			subport_fp(fp) = pd->port_cnt++;
--			pd->port_subpid[subport_fp(fp)] =
--				get_pid(task_pid(current));
-+			pd->port_subpid[subport_fp(fp)] = current->pid;
- 			tidcursor_fp(fp) = 0;
- 			pd->active_slaves |= 1 << subport_fp(fp);
- 			ipath_cdbg(PROC,
- 				   "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
- 				   current->comm, current->pid,
- 				   subport_fp(fp),
--				   pd->port_comm, pid_nr(pd->port_pid),
-+				   pd->port_comm, pd->port_pid,
- 				   dd->ipath_unit, pd->port_port);
- 			ret = 1;
- 			goto done;
-@@ -2043,7 +2042,7 @@ static int ipath_close(struct inode *in,
- 	struct ipath_devdata *dd;
- 	unsigned long flags;
- 	unsigned port;
--	struct pid *pid;
-+	pid_t pid;
- 
- 	ipath_cdbg(VERBOSE, "close on dev %lx, private data %p\n",
- 		   (long)in->i_rdev, fp->private_data);
-@@ -2071,8 +2070,7 @@ static int ipath_close(struct inode *in,
- 		 * the slave(s) don't wait for receive data forever.
- 		 */
- 		pd->active_slaves &= ~(1 << fd->subport);
--		put_pid(pd->port_subpid[fd->subport]);
--		pd->port_subpid[fd->subport] = NULL;
-+		pd->port_subpid[fd->subport] = 0;
- 		mutex_unlock(&ipath_mutex);
- 		goto bail;
- 	}
-@@ -2139,11 +2137,10 @@ static int ipath_close(struct inode *in,
- 			unlock_expected_tids(pd);
- 		ipath_stats.sps_ports--;
- 		ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
--			   pd->port_comm, pid_nr(pid),
-+			   pd->port_comm, pid,
- 			   dd->ipath_unit, port);
- 	}
- 
--	put_pid(pid);
- 	mutex_unlock(&ipath_mutex);
- 	ipath_free_pddata(dd, pd); /* after releasing the mutex */
- 
-diff -upr ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_kernel.h ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_kernel.h
---- ofed_kernel-fixes-orig/drivers/infiniband/hw/ipath/ipath_kernel.h	2008-10-28 12:27:04.000000000 -0700
-+++ ofed_kernel-fixes/drivers/infiniband/hw/ipath/ipath_kernel.h	2008-10-28 12:29:17.000000000 -0700
-@@ -159,8 +159,8 @@ struct ipath_portdata {
- 	/* saved total number of polled urgent packets for poll edge trigger */
- 	u32 port_urgent_poll;
- 	/* pid of process using this port */
--	struct pid *port_pid;
--	struct pid *port_subpid[INFINIPATH_MAX_SUBPORT];
-+	pid_t port_pid;
-+	pid_t port_subpid[INFINIPATH_MAX_SUBPORT];
- 	/* same size as task_struct .comm[] */
- 	char port_comm[16];
- 	/* pkeys set by this use of this port */
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0020_class_dev_to_device.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0020_class_dev_to_device.patch
deleted file mode 100644
index bc9d4a1..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0020_class_dev_to_device.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-BACKPORT - revert struct class_dev to device
-
-This patch reverts commit f4e91eb4a81559da87a3843758a641b5cc590b65 in 2.6.26.
-
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
----
- drivers/infiniband/hw/ipath/ipath_diag.c     |   10 +++---
- drivers/infiniband/hw/ipath/ipath_file_ops.c |   44 +++++++++++++--------------
- drivers/infiniband/hw/ipath/ipath_kernel.h   |    8 ++--
- 3 files changed, 31 insertions(+), 31 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_diag.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_diag.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_diag.c
-@@ -79,7 +79,7 @@ static const struct file_operations diag
- 
- static atomic_t diagpkt_count = ATOMIC_INIT(0);
- static struct cdev *diagpkt_cdev;
--static struct device *diagpkt_dev;
-+static struct class_device *diagpkt_class_dev;
- 
- int ipath_diag_add(struct ipath_devdata *dd)
- {
-@@ -89,7 +89,7 @@ int ipath_diag_add(struct ipath_devdata 
- 	if (atomic_inc_return(&diagpkt_count) == 1) {
- 		ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR,
- 				      "ipath_diagpkt", &diagpkt_file_ops,
--				      &diagpkt_cdev, &diagpkt_dev);
-+				      &diagpkt_cdev, &diagpkt_class_dev);
- 
- 		if (ret) {
- 			ipath_dev_err(dd, "Couldn't create ipath_diagpkt "
-@@ -102,7 +102,7 @@ int ipath_diag_add(struct ipath_devdata 
- 
- 	ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
- 			      &diag_file_ops, &dd->diag_cdev,
--			      &dd->diag_dev);
-+			      &dd->diag_class_dev);
- 	if (ret)
- 		ipath_dev_err(dd, "Couldn't create %s device: %d",
- 			      name, ret);
-@@ -114,9 +114,9 @@ done:
- void ipath_diag_remove(struct ipath_devdata *dd)
- {
- 	if (atomic_dec_and_test(&diagpkt_count))
--		ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_dev);
-+		ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
- 
--	ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_dev);
-+	ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev);
- }
- 
- /**
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-@@ -2424,11 +2424,11 @@ static ssize_t ipath_writev(struct kiocb
- static struct class *ipath_class;
- 
- static int init_cdev(int minor, char *name, const struct file_operations *fops,
--		     struct cdev **cdevp, struct device **devp)
-+		     struct cdev **cdevp, struct class_device **class_devp)
- {
- 	const dev_t dev = MKDEV(IPATH_MAJOR, minor);
- 	struct cdev *cdev = NULL;
--	struct device *device = NULL;
-+	struct class_device *class_dev = NULL;
- 	int ret;
- 
- 	cdev = cdev_alloc();
-@@ -2452,12 +2452,12 @@ static int init_cdev(int minor, char *na
- 		goto err_cdev;
- 	}
- 
--	device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
-+	class_dev = class_device_create(ipath_class, NULL, dev, NULL, name);
- 
--	if (IS_ERR(device)) {
--		ret = PTR_ERR(device);
-+	if (IS_ERR(class_dev)) {
-+		ret = PTR_ERR(class_dev);
- 		printk(KERN_ERR IPATH_DRV_NAME ": Could not create "
--		       "device for minor %d, %s (err %d)\n",
-+		       "class_dev for minor %d, %s (err %d)\n",
- 		       minor, name, -ret);
- 		goto err_cdev;
- 	}
-@@ -2471,29 +2471,29 @@ err_cdev:
- done:
- 	if (ret >= 0) {
- 		*cdevp = cdev;
--		*devp = device;
-+		*class_devp = class_dev;
- 	} else {
- 		*cdevp = NULL;
--		*devp = NULL;
-+		*class_devp = NULL;
- 	}
- 
- 	return ret;
- }
- 
- int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
--		    struct cdev **cdevp, struct device **devp)
-+		    struct cdev **cdevp, struct class_device **class_devp)
- {
--	return init_cdev(minor, name, fops, cdevp, devp);
-+	return init_cdev(minor, name, fops, cdevp, class_devp);
- }
- 
- static void cleanup_cdev(struct cdev **cdevp,
--			 struct device **devp)
-+			 struct class_device **class_devp)
- {
--	struct device *dev = *devp;
-+	struct class_device *class_dev = *class_devp;
- 
--	if (dev) {
--		device_unregister(dev);
--		*devp = NULL;
-+	if (class_dev) {
-+		class_device_unregister(class_dev);
-+		*class_devp = NULL;
- 	}
- 
- 	if (*cdevp) {
-@@ -2503,13 +2503,13 @@ static void cleanup_cdev(struct cdev **c
- }
- 
- void ipath_cdev_cleanup(struct cdev **cdevp,
--			struct device **devp)
-+			struct class_device **class_devp)
- {
--	cleanup_cdev(cdevp, devp);
-+	cleanup_cdev(cdevp, class_devp);
- }
- 
- static struct cdev *wildcard_cdev;
--static struct device *wildcard_dev;
-+static struct class_device *wildcard_class_dev;
- 
- static const dev_t dev = MKDEV(IPATH_MAJOR, 0);
- 
-@@ -2566,7 +2566,7 @@ int ipath_user_add(struct ipath_devdata 
- 			goto bail;
- 		}
- 		ret = init_cdev(0, "ipath", &ipath_file_ops, &wildcard_cdev,
--				&wildcard_dev);
-+				&wildcard_class_dev);
- 		if (ret < 0) {
- 			ipath_dev_err(dd, "Could not create wildcard "
- 				      "minor: error %d\n", -ret);
-@@ -2579,7 +2579,7 @@ int ipath_user_add(struct ipath_devdata 
- 	snprintf(name, sizeof(name), "ipath%d", dd->ipath_unit);
- 
- 	ret = init_cdev(dd->ipath_unit + 1, name, &ipath_file_ops,
--			&dd->user_cdev, &dd->user_dev);
-+			&dd->user_cdev, &dd->user_class_dev);
- 	if (ret < 0)
- 		ipath_dev_err(dd, "Could not create user minor %d, %s\n",
- 			      dd->ipath_unit + 1, name);
-@@ -2594,13 +2594,13 @@ bail:
- 
- void ipath_user_remove(struct ipath_devdata *dd)
- {
--	cleanup_cdev(&dd->user_cdev, &dd->user_dev);
-+	cleanup_cdev(&dd->user_cdev, &dd->user_class_dev);
- 
- 	if (atomic_dec_return(&user_count) == 0) {
- 		if (atomic_read(&user_setup) == 0)
- 			goto bail;
- 
--		cleanup_cdev(&wildcard_cdev, &wildcard_dev);
-+		cleanup_cdev(&wildcard_cdev, &wildcard_class_dev);
- 		user_cleanup();
- 
- 		atomic_set(&user_setup, 0);
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_kernel.h
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
-@@ -477,8 +477,8 @@ struct ipath_devdata {
- 	struct pci_dev *pcidev;
- 	struct cdev *user_cdev;
- 	struct cdev *diag_cdev;
--	struct device *user_dev;
--	struct device *diag_dev;
-+	struct class_device *user_class_dev;
-+	struct class_device *diag_class_dev;
- 	/* timer used to prevent stats overflow, error throttling, etc. */
- 	struct timer_list ipath_stats_timer;
- 	/* timer to verify interrupts work, and fallback if possible */
-@@ -865,9 +865,9 @@ void ipath_clear_freeze(struct ipath_dev
- 
- struct file_operations;
- int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
--		    struct cdev **cdevp, struct device **devp);
-+		    struct cdev **cdevp, struct class_device **class_devp);
- void ipath_cdev_cleanup(struct cdev **cdevp,
--			struct device **devp);
-+			struct class_device **class_devp);
- 
- int ipath_diag_add(struct ipath_devdata *);
- void ipath_diag_remove(struct ipath_devdata *);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0030_revert_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0030_revert_sysfs.patch
deleted file mode 100644
index f369f4d..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0030_revert_sysfs.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-BACKPORT - revert to older code for creating sysfs driver groups
-
-This reverts commit 23b9c1ab5baf368a32b7242bf110ef1f48700d04 in 2.6.25
-    
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
----
- drivers/infiniband/hw/ipath/ipath_driver.c |   17 +++++++++++++----
- drivers/infiniband/hw/ipath/ipath_kernel.h |    3 ++-
- drivers/infiniband/hw/ipath/ipath_sysfs.c  |   19 ++++++++++++++-----
- 3 files changed, 29 insertions(+), 10 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_driver.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
-@@ -151,9 +151,6 @@ static struct pci_driver ipath_driver = 
- 	.probe = ipath_init_one,
- 	.remove = __devexit_p(ipath_remove_one),
- 	.id_table = ipath_pci_tbl,
--	.driver = {
--		.groups = ipath_driver_attr_groups,
--	},
- };
- 
- static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev,
-@@ -2544,15 +2541,25 @@ static int __init infinipath_init(void)
- 		goto bail_unit;
- 	}
- 
-+	ret = ipath_driver_create_group(&ipath_driver.driver);
-+	if (ret < 0) {
-+		printk(KERN_ERR IPATH_DRV_NAME ": Unable to create driver "
-+		       "sysfs entries: error %d\n", -ret);
-+		goto bail_pci;
-+	}
-+
- 	ret = ipath_init_ipathfs();
- 	if (ret < 0) {
- 		printk(KERN_ERR IPATH_DRV_NAME ": Unable to create "
- 		       "ipathfs: error %d\n", -ret);
--		goto bail_pci;
-+		goto bail_group;
- 	}
- 
- 	goto bail;
- 
-+bail_group:
-+	ipath_driver_remove_group(&ipath_driver.driver);
-+
- bail_pci:
- 	pci_unregister_driver(&ipath_driver);
- 
-@@ -2567,6 +2574,8 @@ static void __exit infinipath_cleanup(vo
- {
- 	ipath_exit_ipathfs();
- 
-+	ipath_driver_remove_group(&ipath_driver.driver);
-+
- 	ipath_cdbg(VERBOSE, "Unregistering pci driver\n");
- 	pci_unregister_driver(&ipath_driver);
- 
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_kernel.h
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_kernel.h
-@@ -1271,7 +1271,8 @@ struct device_driver;
- 
- extern const char ib_ipath_version[];
- 
--extern struct attribute_group *ipath_driver_attr_groups[];
-+int ipath_driver_create_group(struct device_driver *);
-+void ipath_driver_remove_group(struct device_driver *);
- 
- int ipath_device_create_group(struct device *, struct ipath_devdata *);
- void ipath_device_remove_group(struct device *, struct ipath_devdata *);
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_sysfs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_sysfs.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_sysfs.c
-@@ -1069,11 +1069,6 @@ static ssize_t show_tempsense(struct dev
- 	return ret;
- }
- 
--struct attribute_group *ipath_driver_attr_groups[] = {
--	&driver_attr_group,
--	NULL,
--};
--
- static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid);
- static DEVICE_ATTR(lmc, S_IWUSR | S_IRUGO, show_lmc, store_lmc);
- static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid);
-@@ -1181,6 +1176,20 @@ int ipath_expose_reset(struct device *de
- 	return ret;
- }
- 
-+int ipath_driver_create_group(struct device_driver *drv)
-+{
-+	int ret;
-+
-+	ret = sysfs_create_group(&drv->kobj, &driver_attr_group);
-+
-+	return ret;
-+}
-+
-+void ipath_driver_remove_group(struct device_driver *drv)
-+{
-+	sysfs_remove_group(&drv->kobj, &driver_attr_group);
-+}
-+
- int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd)
- {
- 	int ret;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0040_nopage_to_fault.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0040_nopage_to_fault.patch
deleted file mode 100644
index a8557d0..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0040_nopage_to_fault.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-IB/ipath - revert struct vm_operations_struct nopage to fault rename
-
-This patch reverts commit 3c8450860ba9d6279dbc969633eacf99161860d9 in 2.6.25
-
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
----
- drivers/infiniband/hw/ipath/ipath_debug.h    |    4 +--
- drivers/infiniband/hw/ipath/ipath_file_ops.c |   29 +++++++++++++++++----------
- 2 files changed, 21 insertions(+), 12 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_debug.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_debug.h
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_debug.h
-@@ -55,7 +55,7 @@
- #define __IPATH_PKTDBG      0x80	/* print packet data */
- /* print process startup (init)/exit messages */
- #define __IPATH_PROCDBG     0x100
--/* print mmap/fault stuff, not using VDBG any more */
-+/* print mmap/nopage stuff, not using VDBG any more */
- #define __IPATH_MMDBG       0x200
- #define __IPATH_ERRPKTDBG   0x400
- #define __IPATH_USER_SEND   0x1000	/* use user mode send */
-@@ -82,7 +82,7 @@
- #define __IPATH_VERBDBG   0x0	/* very verbose debug */
- #define __IPATH_PKTDBG    0x0	/* print packet data */
- #define __IPATH_PROCDBG   0x0	/* process startup (init)/exit messages */
--/* print mmap/fault stuff, not using VDBG any more */
-+/* print mmap/nopage stuff, not using VDBG any more */
- #define __IPATH_MMDBG     0x0
- #define __IPATH_EPKTDBG   0x0	/* print ethernet packet data */
- #define __IPATH_IPATHDBG  0x0	/* Ethernet (IPATH) table dump on */
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-@@ -1130,24 +1130,33 @@ bail:
- }
- 
- /*
-- * ipath_file_vma_fault - handle a VMA page fault.
-+ * ipath_file_vma_nopage - handle a VMA page fault.
-  */
--static int ipath_file_vma_fault(struct vm_area_struct *vma,
--					struct vm_fault *vmf)
-+static struct page *ipath_file_vma_nopage(struct vm_area_struct *vma,
-+					  unsigned long address, int *type)
- {
--	struct page *page;
-+	unsigned long offset = address - vma->vm_start;
-+	struct page *page = NOPAGE_SIGBUS;
-+	void *pageptr;
- 
--	page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT));
-+	/*
-+	 * Convert the vmalloc address into a struct page.
-+	 */
-+	pageptr = (void *)(offset + (vma->vm_pgoff << PAGE_SHIFT));
-+	page = vmalloc_to_page(pageptr);
- 	if (!page)
--		return VM_FAULT_SIGBUS;
--	get_page(page);
--	vmf->page = page;
-+		goto out;
- 
--	return 0;
-+	/* Increment the reference count. */
-+	get_page(page);
-+	if (type)
-+		*type = VM_FAULT_MINOR;
-+out:
-+	return page;
- }
- 
- static struct vm_operations_struct ipath_file_vm_ops = {
--	.fault = ipath_file_vma_fault,
-+	.nopage = ipath_file_vma_nopage,
- };
- 
- static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0050_aio_write.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0050_aio_write.patch
deleted file mode 100644
index 3a0b5e3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0050_aio_write.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-BACKPORT - Use writev instead of aio_write in 2.6.18 and older kernels
-
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
----
- drivers/infiniband/hw/ipath/ipath_file_ops.c |   11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-@@ -50,15 +50,15 @@ static int ipath_open(struct inode *, st
- static int ipath_close(struct inode *, struct file *);
- static ssize_t ipath_write(struct file *, const char __user *, size_t,
- 			   loff_t *);
--static ssize_t ipath_writev(struct kiocb *, const struct iovec *,
--			    unsigned long , loff_t);
-+static ssize_t ipath_writev(struct file *, const struct iovec *,
-+			    unsigned long , loff_t *);
- static unsigned int ipath_poll(struct file *, struct poll_table_struct *);
- static int ipath_mmap(struct file *, struct vm_area_struct *);
- 
- static const struct file_operations ipath_file_ops = {
- 	.owner = THIS_MODULE,
- 	.write = ipath_write,
--	.aio_write = ipath_writev,
-+	.writev = ipath_writev,
- 	.open = ipath_open,
- 	.release = ipath_close,
- 	.poll = ipath_poll,
-@@ -2416,10 +2416,9 @@ bail:
- 	return ret;
- }
- 
--static ssize_t ipath_writev(struct kiocb *iocb, const struct iovec *iov,
--			    unsigned long dim, loff_t off)
-+static ssize_t ipath_writev(struct file *filp, const struct iovec *iov,
-+			    unsigned long dim, loff_t *off)
- {
--	struct file *filp = iocb->ki_filp;
- 	struct ipath_filedata *fp = filp->private_data;
- 	struct ipath_portdata *pd = port_fp(filp);
- 	struct ipath_user_sdma_queue *pq = fp->pq;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0060_htirq.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0060_htirq.patch
deleted file mode 100644
index e2fa5a3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0060_htirq.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-BACKPORT - use old HT IRQ infrastructure on 2.6.18 and earlier
-
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
----
- drivers/infiniband/hw/ipath/Makefile        |    2 
- drivers/infiniband/hw/ipath/ipath_driver.c  |    2 
- drivers/infiniband/hw/ipath/ipath_iba6110.c |   82 ++++++++++++++++++----------
- 3 files changed, 57 insertions(+), 29 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ipath/Makefile
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/Makefile
-+++ ofed_kernel/drivers/infiniband/hw/ipath/Makefile
-@@ -34,7 +34,7 @@ ib_ipath-y := \
- 	ipath_sd7220.o \
- 	ipath_sd7220_img.o
- 
--ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
-+ib_ipath-y += ipath_iba6110.o
- ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
- 
- ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_driver.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_driver.c
-@@ -42,6 +42,8 @@
- #include "ipath_kernel.h"
- #include "ipath_verbs.h"
- 
-+#define CONFIG_HT_IRQ
-+
- static void ipath_update_pio_bufs(struct ipath_devdata *);
- 
- const char *ipath_get_unit_name(int unit)
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_iba6110.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_iba6110.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_iba6110.c
-@@ -39,7 +39,6 @@
- #include <linux/vmalloc.h>
- #include <linux/pci.h>
- #include <linux/delay.h>
--#include <linux/htirq.h>
- #include <rdma/ib_verbs.h>
- 
- #include "ipath_kernel.h"
-@@ -986,23 +985,50 @@ static int ipath_ht_intconfig(struct ipa
- 	return ret;
- }
- 
--static void ipath_ht_irq_update(struct pci_dev *dev, int irq,
--				struct ht_irq_msg *msg)
-+static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev,
-+			    int pos)
- {
--	struct ipath_devdata *dd = pci_get_drvdata(dev);
--	u64 prev_intconfig = dd->ipath_intconfig;
-+	u32 int_handler_addr_lower;
-+	u32 int_handler_addr_upper;
-+	u64 ihandler;
-+	u32 intvec;
-+
-+	/* use indirection register to get the intr handler */
-+	pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10);
-+	pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower);
-+	pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11);
-+	pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper);
-+
-+	ihandler = (u64) int_handler_addr_lower |
-+		((u64) int_handler_addr_upper << 32);
-+
-+	/*
-+	 * kernels with CONFIG_PCI_MSI set the vector in the irq field of
-+	 * struct pci_device, so we use that to program the internal
-+	 * interrupt register (not config space) with that value. The BIOS
-+	 * must still have done the basic MSI setup.
-+	 */
-+	intvec = pdev->irq;
-+	/*
-+	 * clear any vector bits there; normally not set but we'll overload
-+	 * this for some debug purposes (setting the HTC debug register
-+	 * value from software, rather than GPIOs), so it might be set on a
-+	 * driver reload.
-+	 */
-+	ihandler &= ~0xff0000;
-+	/* x86 vector goes in intrinfo[23:16] */
-+	ihandler |= intvec << 16;
-+	ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, "
-+		   "interruptconfig %llx\n", int_handler_addr_lower,
-+		   int_handler_addr_upper, intvec,
-+		   (unsigned long long) ihandler);
-+
-+	/* can't program yet, so save for interrupt setup */
-+	dd->ipath_intconfig = ihandler;
-+	dd->ipath_irq = intvec;
-+	/* keep going, so we find link control stuff also */
- 
--	dd->ipath_intconfig = msg->address_lo;
--	dd->ipath_intconfig |= ((u64) msg->address_hi) << 32;
--
--	/*
--	 * If the previous value of dd->ipath_intconfig is zero, we're
--	 * getting configured for the first time, and must not program the
--	 * intconfig register here (it will be programmed later, when the
--	 * hardware is ready).  Otherwise, we should.
--	 */
--	if (prev_intconfig)
--		ipath_ht_intconfig(dd);
-+	return ihandler != 0;
- }
- 
- /**
-@@ -1018,19 +1044,12 @@ static void ipath_ht_irq_update(struct p
- static int ipath_setup_ht_config(struct ipath_devdata *dd,
- 				 struct pci_dev *pdev)
- {
--	int pos, ret;
--
--	ret = __ht_create_irq(pdev, 0, ipath_ht_irq_update);
--	if (ret < 0) {
--		ipath_dev_err(dd, "Couldn't create interrupt handler: "
--			      "err %d\n", ret);
--		goto bail;
--	}
--	dd->ipath_irq = ret;
--	ret = 0;
-+	int pos, ret = 0;
-+	int ihandler = 0;
- 
- 	/*
--	 * Handle clearing CRC errors in linkctrl register if necessary.  We
-+	 * Read the capability info to find the interrupt info, and also
-+	 * handle clearing CRC errors in linkctrl register if necessary.  We
- 	 * do this early, before we ever enable errors or hardware errors,
- 	 * mostly to avoid causing the chip to enter freeze mode.
- 	 */
-@@ -1055,9 +1074,17 @@ static int ipath_setup_ht_config(struct 
- 		}
- 		if (!(cap_type & 0xE0))
- 			slave_or_pri_blk(dd, pdev, pos, cap_type);
-+		else if (cap_type == HT_INTR_DISC_CONFIG)
-+			ihandler = set_int_handler(dd, pdev, pos);
- 	} while ((pos = pci_find_next_capability(pdev, pos,
- 						 PCI_CAP_ID_HT)));
- 
-+	if (!ihandler) {
-+		ipath_dev_err(dd, "Couldn't find interrupt handler in "
-+			      "config space\n");
-+		ret = -ENODEV;
-+	}
-+
- 	dd->ipath_flags |= IPATH_SWAP_PIOBUFS;
- 
- bail:
-@@ -1690,7 +1717,6 @@ static int ipath_ht_get_base_info(struct
- static void ipath_ht_free_irq(struct ipath_devdata *dd)
- {
- 	free_irq(dd->ipath_irq, dd);
--	ht_destroy_irq(dd->ipath_irq);
- 	dd->ipath_irq = 0;
- 	dd->ipath_intconfig = 0;
- }
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0070_vmalloc_user-2.6.18.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0070_vmalloc_user-2.6.18.patch
deleted file mode 100644
index 4e0f1f3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0070_vmalloc_user-2.6.18.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-BACKPORT - avoid using vmalloc_user() in 2.6.18 due to bugs.
-
-Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
-
-diff -up a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
---- a/drivers/infiniband/hw/ipath/ipath_cq.c	2008-10-24 10:40:30.000000000 -0700
-+++ b/drivers/infiniband/hw/ipath/ipath_cq.c	2008-10-24 10:45:56.000000000 -0700
-@@ -230,11 +230,12 @@ struct ib_cq *ipath_create_cq(struct ib_
- 		sz += sizeof(struct ib_uverbs_wc) * (entries + 1);
- 	else
- 		sz += sizeof(struct ib_wc) * (entries + 1);
--	wc = vmalloc_user(sz);
-+	wc = vmalloc(sz);
- 	if (!wc) {
- 		ret = ERR_PTR(-ENOMEM);
- 		goto bail_cq;
- 	}
-+	memset(wc, 0, sz);
- 
- 	/*
- 	 * Return the address of the WC as the offset to mmap.
-@@ -389,11 +390,12 @@ int ipath_resize_cq(struct ib_cq *ibcq, 
- 		sz += sizeof(struct ib_uverbs_wc) * (cqe + 1);
- 	else
- 		sz += sizeof(struct ib_wc) * (cqe + 1);
--	wc = vmalloc_user(sz);
-+	wc = vmalloc(sz);
- 	if (!wc) {
- 		ret = -ENOMEM;
- 		goto bail;
- 	}
-+	memset(wc, 0, sz);
- 
- 	/* Check that we can write the offset to mmap. */
- 	if (udata && udata->outlen >= sizeof(__u64)) {
-diff -up a/drivers/infiniband/hw/ipath/ipath_mmap.c b/drivers/infiniband/hw/ipath/ipath_mmap.c
---- a/drivers/infiniband/hw/ipath/ipath_mmap.c	2008-10-24 10:40:30.000000000 -0700
-+++ b/drivers/infiniband/hw/ipath/ipath_mmap.c	2008-10-24 10:45:56.000000000 -0700
-@@ -74,9 +74,40 @@ static void ipath_vma_close(struct vm_ar
- 	kref_put(&ip->ref, ipath_release_mmap_info);
- }
- 
-+/*
-+ * ipath_vma_nopage - handle a VMA page fault.
-+ */
-+static struct page *ipath_vma_nopage(struct vm_area_struct *vma,
-+				     unsigned long address, int *type)
-+{
-+	struct ipath_mmap_info *ip = vma->vm_private_data;
-+	unsigned long offset = address - vma->vm_start;
-+	struct page *page = NOPAGE_SIGBUS;
-+	void *pageptr;
-+
-+	if (offset >= ip->size)
-+		goto out; /* out of range */
-+
-+	/*
-+	 * Convert the vmalloc address into a struct page.
-+	 */
-+	pageptr = (void *)(offset + ip->obj);
-+	page = vmalloc_to_page(pageptr);
-+	if (!page)
-+		goto out;
-+
-+	/* Increment the reference count. */
-+	get_page(page);
-+	if (type)
-+		*type = VM_FAULT_MINOR;
-+out:
-+	return page;
-+}
-+
- static struct vm_operations_struct ipath_vm_ops = {
- 	.open =     ipath_vma_open,
- 	.close =    ipath_vma_close,
-+	.nopage =   ipath_vma_nopage,
- };
- 
- /**
-@@ -111,10 +142,10 @@ int ipath_mmap(struct ib_ucontext *conte
- 		list_del_init(&ip->pending_mmaps);
- 		spin_unlock_irq(&dev->pending_lock);
- 
--		ret = remap_vmalloc_range(vma, ip->obj, 0);
--		if (ret)
--			goto done;
-+		ret = 0;
-+
- 		vma->vm_ops = &ipath_vm_ops;
-+		vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- 		vma->vm_private_data = ip;
- 		ipath_vma_open(vma);
- 		goto done;
-diff -up a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
---- a/drivers/infiniband/hw/ipath/ipath_qp.c	2008-10-24 10:40:33.000000000 -0700
-+++ b/drivers/infiniband/hw/ipath/ipath_qp.c	2008-10-24 10:47:56.000000000 -0700
-@@ -827,12 +827,14 @@ struct ib_qp *ipath_create_qp(struct ib_
- 			qp->r_rq.max_sge = init_attr->cap.max_recv_sge;
- 			sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +
- 				sizeof(struct ipath_rwqe);
--			qp->r_rq.wq = vmalloc_user(sizeof(struct ipath_rwq) +
-+			qp->r_rq.wq = vmalloc(sizeof(struct ipath_rwq) +
- 					      qp->r_rq.size * sz);
- 			if (!qp->r_rq.wq) {
- 				ret = ERR_PTR(-ENOMEM);
- 				goto bail_sg_list;
- 			}
-+			memset(qp->r_rq.wq, 0,
-+			       sizeof(struct ipath_rwq) + qp->r_rq.size * sz);
- 		}
- 
- 		/*
-diff -up a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
---- a/drivers/infiniband/hw/ipath/ipath_srq.c	2008-10-24 10:40:30.000000000 -0700
-+++ b/drivers/infiniband/hw/ipath/ipath_srq.c	2008-10-24 10:45:56.000000000 -0700
-@@ -130,11 +130,12 @@ struct ib_srq *ipath_create_srq(struct i
- 	srq->rq.max_sge = srq_init_attr->attr.max_sge;
- 	sz = sizeof(struct ib_sge) * srq->rq.max_sge +
- 		sizeof(struct ipath_rwqe);
--	srq->rq.wq = vmalloc_user(sizeof(struct ipath_rwq) + srq->rq.size * sz);
-+	srq->rq.wq = vmalloc(sizeof(struct ipath_rwq) + srq->rq.size * sz);
- 	if (!srq->rq.wq) {
- 		ret = ERR_PTR(-ENOMEM);
- 		goto bail_srq;
- 	}
-+	memset(srq->rq.wq, 0, sizeof(struct ipath_rwq) + srq->rq.size * sz);
- 
- 	/*
- 	 * Return the address of the RWQ as the offset to mmap.
-@@ -230,11 +231,12 @@ int ipath_modify_srq(struct ib_srq *ibsr
- 		sz = sizeof(struct ipath_rwqe) +
- 			srq->rq.max_sge * sizeof(struct ib_sge);
- 		size = attr->max_wr + 1;
--		wq = vmalloc_user(sizeof(struct ipath_rwq) + size * sz);
-+		wq = vmalloc(sizeof(struct ipath_rwq) + size * sz);
- 		if (!wq) {
- 			ret = -ENOMEM;
- 			goto bail;
- 		}
-+		memset(wq, 0, sizeof(struct ipath_rwq) + size * sz);
- 
- 		/* Check that we can write the offset to mmap. */
- 		if (udata && udata->inlen >= sizeof(__u64)) {
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0080_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0080_sysfs.patch
deleted file mode 100644
index 2703595..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0080_sysfs.patch
+++ /dev/null
@@ -1,85 +0,0 @@
----
- drivers/infiniband/hw/ipath/ipath_verbs.c |   39 +++++++++++++-----------------
- 1 file changed, 18 insertions(+), 21 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_verbs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_verbs.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_verbs.c
-@@ -2235,20 +2235,18 @@ void ipath_unregister_ib_device(struct i
- 	ib_dealloc_device(ibdev);
- }
- 
--static ssize_t show_rev(struct device *device, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_rev(struct class_device *cdev, char *buf)
- {
- 	struct ipath_ibdev *dev =
--		container_of(device, struct ipath_ibdev, ibdev.dev);
-+		container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
- 
- 	return sprintf(buf, "%x\n", dev->dd->ipath_pcirev);
- }
- 
--static ssize_t show_hca(struct device *device, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_hca(struct class_device *cdev, char *buf)
- {
- 	struct ipath_ibdev *dev =
--		container_of(device, struct ipath_ibdev, ibdev.dev);
-+		container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
- 	int ret;
- 
- 	ret = dev->dd->ipath_f_get_boardname(dev->dd, buf, 128);
-@@ -2261,11 +2259,10 @@ bail:
- 	return ret;
- }
- 
--static ssize_t show_stats(struct device *device, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_stats(struct class_device *cdev, char *buf)
- {
- 	struct ipath_ibdev *dev =
--		container_of(device, struct ipath_ibdev, ibdev.dev);
-+		container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
- 	int i;
- 	int len;
- 
-@@ -2300,16 +2297,16 @@ static ssize_t show_stats(struct device 
- 	return len;
- }
- 
--static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
--static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
--static DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL);
--static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
--
--static struct device_attribute *ipath_class_attributes[] = {
--	&dev_attr_hw_rev,
--	&dev_attr_hca_type,
--	&dev_attr_board_id,
--	&dev_attr_stats
-+static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
-+static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
-+static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL);
-+static CLASS_DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
-+
-+static struct class_device_attribute *ipath_class_attributes[] = {
-+	&class_device_attr_hw_rev,
-+	&class_device_attr_hca_type,
-+	&class_device_attr_board_id,
-+	&class_device_attr_stats
- };
- 
- static int ipath_verbs_register_sysfs(struct ib_device *dev)
-@@ -2318,8 +2315,8 @@ static int ipath_verbs_register_sysfs(st
- 	int ret;
- 
- 	for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i)
--		if (device_create_file(&dev->dev,
--				       ipath_class_attributes[i])) {
-+		if (class_device_create_file(&dev->class_dev,
-+					       ipath_class_attributes[i])) {
- 			ret = 1;
- 			goto bail;
- 		}
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipath_0095_pat.patch b/kernel_patches/backport/2.6.18-EL5.1/ipath_0095_pat.patch
deleted file mode 100644
index ceb9a9f..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipath_0095_pat.patch
+++ /dev/null
@@ -1,77 +0,0 @@
---- a/drivers/infiniband/hw/ipath/ipath_wc_pat.c.orig	2008-11-04 13:46:56.557658000 -0800
-+++ b/drivers/infiniband/hw/ipath/ipath_wc_pat.c	2008-11-04 13:47:50.521639000 -0800
-@@ -182,7 +182,7 @@
- 	preempt_disable();
- 	rd_old_pat(&ret);
- 	if (!ret)
--		smp_call_function(rd_old_pat, &ret, 1);
-+		smp_call_function(rd_old_pat, &ret, 1, 1);
- 	if (ret)
- 		goto out;
- 
-@@ -193,7 +193,7 @@
- 	if (ret)
- 		goto out;
- 
--	smp_call_function(wr_new_pat, &ret, 1);
-+	smp_call_function(wr_new_pat, &ret, 1, 1);
- 	BUG_ON(ret); /* have inconsistent PAT state */
- out:
- 	preempt_enable();
-@@ -207,7 +207,7 @@
- 	preempt_disable();
- 	wr_old_pat(&ret);
- 	if (!ret) {
--		smp_call_function(wr_old_pat, &ret, 1);
-+		smp_call_function(wr_old_pat, &ret, 1, 1);
- 		BUG_ON(ret); /* have inconsistent PAT state */
- 	}
- 
-diff --git a/drivers/infiniband/hw/ipath/ipath_wc_pat.c b/drivers/infiniband/hw/ipath/ipath_wc_pat.c
-index 8edf2fb..5233eac 100644
---- a/drivers/infiniband/hw/ipath/ipath_wc_pat.c
-+++ b/drivers/infiniband/hw/ipath/ipath_wc_pat.c
-@@ -217,7 +217,7 @@
- 
- int ipath_enable_wc_pat(void)
- {
--	struct cpuinfo_x86 *c = &cpu_data(0);
-+	struct cpuinfo_x86 *c = &(cpu_data)[0];
- 	int ret;
- 
- 	if (wc_enabled)
-@@ -257,6 +257,11 @@ pgprot_t pgprot_wc(pgprot_t _prot)
- 		pgprot_noncached(_prot);
- }
- 
-+void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size)
-+{
-+	return __ioremap(phys_addr, size, IPATH_WC_FLAGS);
-+}
-+
- int ipath_wc_pat_enabled(void)
- {
- 	return wc_enabled;
-@@ -272,6 +277,11 @@ pgprot_t pgprot_wc(pgprot_t _prot)
- 	return pgprot_noncached(_prot);
- }
- 
-+void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size)
-+{
-+	return ioremap_nocache(phys_addr, size);
-+}
-+
- int ipath_wc_pat_enabled(void)
- {
- 	return 0;
-diff --git a/drivers/infiniband/hw/ipath/ipath_wc_pat.h b/drivers/infiniband/hw/ipath/ipath_wc_pat.h
-index 28ba52f..1b17661 100644
---- a/drivers/infiniband/hw/ipath/ipath_wc_pat.h
-+++ b/drivers/infiniband/hw/ipath/ipath_wc_pat.h
-@@ -42,5 +42,6 @@ int ipath_enable_wc_pat(void);
- void ipath_disable_wc_pat(void);
- int ipath_wc_pat_enabled(void);
- pgprot_t pgprot_wc(pgprot_t _prot);
-+void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size);
- 
- #endif
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0100_to_2.6.21.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_0100_to_2.6.21.patch
deleted file mode 100644
index ee2706f..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0100_to_2.6.21.patch
+++ /dev/null
@@ -1,458 +0,0 @@
-Backport IPOIB to kernel 2.6.23
-
-Signed-off-by: Eli Cohen <eli at mellanox.co.il>
-
----
-
----
- drivers/infiniband/ulp/ipoib/ipoib.h           |    6 +-
- drivers/infiniband/ulp/ipoib/ipoib_cm.c        |   20 ++++-----
- drivers/infiniband/ulp/ipoib/ipoib_ib.c        |   55 +++++++++++++------------
- drivers/infiniband/ulp/ipoib/ipoib_main.c      |   34 +++++----------
- drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   10 ++--
- 5 files changed, 61 insertions(+), 64 deletions(-)
-
-Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib.h
-===================================================================
---- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2009-04-16 23:35:04.000000000 +0300
-+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib.h	2009-04-16 23:46:20.000000000 +0300
-@@ -277,8 +277,6 @@ struct ipoib_dev_priv {
- 
- 	struct net_device *dev;
- 
--	struct napi_struct napi;
--
- 	unsigned long flags;
- 
- 	struct mutex vlan_mutex;
-@@ -336,6 +334,8 @@ struct ipoib_dev_priv {
- 
- 	struct ib_event_handler event_handler;
- 
-+	struct net_device_stats stats;
-+
- 	struct net_device *parent;
- 	struct list_head child_intfs;
- 	struct list_head list;
-@@ -423,7 +423,7 @@ extern struct workqueue_struct *ipoib_wo
- 
- /* functions */
- 
--int ipoib_poll(struct napi_struct *napi, int budget);
-+int ipoib_poll(struct net_device *dev, int *budget);
- void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
- void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr);
- 
-Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-===================================================================
---- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2009-04-16 23:35:04.000000000 +0300
-+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2009-04-16 23:46:20.000000000 +0300
-@@ -593,7 +593,7 @@ void ipoib_cm_handle_rx_wc(struct net_de
- 		ipoib_dbg(priv, "cm recv error "
- 			   "(status=%d, wrid=%d vend_err %x)\n",
- 			   wc->status, wr_id, wc->vendor_err);
--		++dev->stats.rx_dropped;
-+		++priv->stats.rx_dropped;
- 		if (has_srq)
- 			goto repost;
- 		else {
-@@ -646,7 +646,7 @@ void ipoib_cm_handle_rx_wc(struct net_de
- 		 * this packet and reuse the old buffer.
- 		 */
- 		ipoib_dbg(priv, "failed to allocate receive buffer %d\n", wr_id);
--		++dev->stats.rx_dropped;
-+		++priv->stats.rx_dropped;
- 		goto repost;
- 	}
- 
-@@ -664,8 +664,8 @@ copied:
- 	skb_pull(skb, IPOIB_ENCAP_LEN);
- 
- 	dev->last_rx = jiffies;
--	++dev->stats.rx_packets;
--	dev->stats.rx_bytes += skb->len;
-+	++priv->stats.rx_packets;
-+	priv->stats.rx_bytes += skb->len;
- 
- 	skb->dev = dev;
- 	/* XXX get correct PACKET_ type here */
-@@ -714,8 +714,8 @@ void ipoib_cm_send(struct net_device *de
- 	if (unlikely(skb->len > tx->mtu)) {
- 		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
- 			   skb->len, tx->mtu);
--		++dev->stats.tx_dropped;
--		++dev->stats.tx_errors;
-+		++priv->stats.tx_dropped;
-+		++priv->stats.tx_errors;
- 		ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN);
- 		return;
- 	}
-@@ -734,7 +734,7 @@ void ipoib_cm_send(struct net_device *de
- 	tx_req->skb = skb;
- 	addr = ib_dma_map_single(priv->ca, skb->data, skb->len, DMA_TO_DEVICE);
- 	if (unlikely(ib_dma_mapping_error(priv->ca, addr))) {
--		++dev->stats.tx_errors;
-+		++priv->stats.tx_errors;
- 		dev_kfree_skb_any(skb);
- 		return;
- 	}
-@@ -744,7 +744,7 @@ void ipoib_cm_send(struct net_device *de
- 	if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
- 			       addr, skb->len))) {
- 		ipoib_warn(priv, "post_send failed\n");
--		++dev->stats.tx_errors;
-+		++priv->stats.tx_errors;
- 		ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE);
- 		dev_kfree_skb_any(skb);
- 	} else {
-@@ -781,8 +781,8 @@ void ipoib_cm_handle_tx_wc(struct net_de
- 	ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE);
- 
- 	/* FIXME: is this right? Shouldn't we only increment on success? */
--	++dev->stats.tx_packets;
--	dev->stats.tx_bytes += tx_req->skb->len;
-+	++priv->stats.tx_packets;
-+	priv->stats.tx_bytes += tx_req->skb->len;
- 
- 	dev_kfree_skb_any(tx_req->skb);
- 
-Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-===================================================================
---- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-04-16 23:43:16.000000000 +0300
-+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-04-16 23:49:04.000000000 +0300
-@@ -261,7 +261,7 @@ static void ipoib_ib_handle_rx_wc(struct
- 	 * this packet and reuse the old buffer.
- 	 */
- 	if (unlikely(!ipoib_alloc_rx_skb(dev, wr_id))) {
--		++dev->stats.rx_dropped;
-+		++priv->stats.rx_dropped;
- 		goto repost;
- 	}
- 
-@@ -278,8 +278,8 @@ static void ipoib_ib_handle_rx_wc(struct
- 	skb_pull(skb, IPOIB_ENCAP_LEN);
- 
- 	dev->last_rx = jiffies;
--	++dev->stats.rx_packets;
--	dev->stats.rx_bytes += skb->len;
-+	++priv->stats.rx_packets;
-+	priv->stats.rx_bytes += skb->len;
- 
- 	skb->dev = dev;
- 	/* XXX get correct PACKET_ type here */
-@@ -379,8 +379,8 @@ static void ipoib_ib_handle_tx_wc(struct
- 
- 	ipoib_dma_unmap_tx(priv->ca, tx_req);
- 
--	++dev->stats.tx_packets;
--	dev->stats.tx_bytes += tx_req->skb->len;
-+	++priv->stats.tx_packets;
-+	priv->stats.tx_bytes += tx_req->skb->len;
- 
- 	dev_kfree_skb_any(tx_req->skb);
- 
-@@ -408,19 +408,19 @@ static int poll_tx(struct ipoib_dev_priv
- 	return n == MAX_SEND_CQE;
- }
- 
--int ipoib_poll(struct napi_struct *napi, int budget)
-+int ipoib_poll(struct net_device *dev, int *budget)
- {
--	struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi);
--	struct net_device *dev = priv->dev;
-+	struct ipoib_dev_priv *priv = netdev_priv(dev);
-+	int max = min(*budget, dev->quota);
- 	int done;
- 	int t;
- 	int n, i;
-+	int ret;
- 
- 	done  = 0;
- 
- poll_more:
--	while (done < budget) {
--		int max = (budget - done);
-+	while (max) {
- 
- 		t = min(IPOIB_NUM_WC, max);
- 		n = ib_poll_cq(priv->recv_cq, t, priv->ibwc);
-@@ -430,6 +430,7 @@ poll_more:
- 
- 			if (wc->wr_id & IPOIB_OP_RECV) {
- 				++done;
-+				--max;
- 				if (wc->wr_id & IPOIB_OP_CM)
- 					ipoib_cm_handle_rx_wc(dev, wc);
- 				else
-@@ -442,27 +443,29 @@ poll_more:
- 			break;
- 	}
- 
--	if (done < budget) {
-+	if (max) {
- 		if (dev->features & NETIF_F_LRO)
- 			lro_flush_all(&priv->lro.lro_mgr);
- 
--		netif_rx_complete(dev, napi);
-+		netif_rx_complete(dev);
- 		if (unlikely(ib_req_notify_cq(priv->recv_cq,
- 					      IB_CQ_NEXT_COMP |
- 					      IB_CQ_REPORT_MISSED_EVENTS)) &&
--		    netif_rx_reschedule(dev, napi))
-+					      netif_rx_reschedule(dev, 0))
- 			goto poll_more;
--	}
-+		ret = 0;
-+	} else
-+		ret = 1;
-+
-+	dev->quota -= done;
-+	*budget    -= done;
- 
--	return done;
-+	return ret;
- }
- 
- void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
- {
--	struct net_device *dev = dev_ptr;
--	struct ipoib_dev_priv *priv = netdev_priv(dev);
--
--	netif_rx_schedule(dev, &priv->napi);
-+	netif_rx_schedule(dev_ptr);
- }
- 
- static void drain_tx_cq(struct net_device *dev)
-@@ -539,8 +542,8 @@ void ipoib_send(struct net_device *dev, 
- 		phead = skb->data;
- 		if (unlikely(!skb_pull(skb, hlen))) {
- 			ipoib_warn(priv, "linear data too small\n");
--			++dev->stats.tx_dropped;
--			++dev->stats.tx_errors;
-+			++priv->stats.tx_dropped;
-+			++priv->stats.tx_errors;
- 			dev_kfree_skb_any(skb);
- 			return;
- 		}
-@@ -548,8 +551,8 @@ void ipoib_send(struct net_device *dev, 
- 		if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {
- 			ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
- 				   skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);
--			++dev->stats.tx_dropped;
--			++dev->stats.tx_errors;
-+			++priv->stats.tx_dropped;
-+			++priv->stats.tx_errors;
- 			ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);
- 			return;
- 		}
-@@ -570,7 +573,7 @@ void ipoib_send(struct net_device *dev, 
- 	tx_req = &priv->tx_ring[priv->tx_head & (ipoib_sendq_size - 1)];
- 	tx_req->skb = skb;
- 	if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req))) {
--		++dev->stats.tx_errors;
-+		++priv->stats.tx_errors;
- 		dev_kfree_skb_any(skb);
- 		return;
- 	}
-@@ -590,7 +593,7 @@ void ipoib_send(struct net_device *dev, 
- 	if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
- 			       address->ah, qpn, tx_req, phead, hlen))) {
- 		ipoib_warn(priv, "post_send failed\n");
--		++dev->stats.tx_errors;
-+		++priv->stats.tx_errors;
- 		--priv->tx_outstanding;
- 		ipoib_dma_unmap_tx(priv->ca, tx_req);
- 		dev_kfree_skb_any(skb);
-@@ -708,8 +711,7 @@ int ipoib_ib_dev_open(struct net_device 
- 	priv->poll_timer.function = ipoib_ib_tx_timer_func;
- 	priv->poll_timer.data = (unsigned long)dev;
- 
--	if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
--		napi_enable(&priv->napi);
-+	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
- 
- 	return 0;
- }
-@@ -828,8 +830,8 @@ int ipoib_ib_dev_stop(struct net_device 
- 	struct ipoib_tx_buf *tx_req;
- 	int i;
- 
--	if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
--		napi_disable(&priv->napi);
-+	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
-+	netif_poll_disable(dev);
- 
- 	ipoib_cm_dev_stop(dev);
- 
-@@ -903,6 +905,7 @@ timeout:
- 
- 	ipoib_ah_dev_cleanup(dev);
- 
-+	netif_poll_enable(dev);
- 	ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP);
- 
- 	return 0;
-Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_main.c
-===================================================================
---- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-04-16 23:44:02.000000000 +0300
-+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-04-16 23:46:20.000000000 +0300
-@@ -585,7 +585,7 @@ static void neigh_add_path(struct sk_buf
- 
- 	neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
- 	if (!neigh) {
--		++dev->stats.tx_dropped;
-+		++priv->stats.tx_dropped;
- 		dev_kfree_skb_any(skb);
- 		return;
- 	}
-@@ -646,7 +646,7 @@ err_list:
- err_path:
- 	ipoib_neigh_free(dev, neigh);
- err_drop:
--	++dev->stats.tx_dropped;
-+	++priv->stats.tx_dropped;
- 	dev_kfree_skb_any(skb);
- 
- 	spin_unlock_irqrestore(&priv->lock, flags);
-@@ -697,7 +697,7 @@ static void unicast_arp_send(struct sk_b
- 			} else
- 				__path_add(dev, path);
- 		} else {
--			++dev->stats.tx_dropped;
-+			++priv->stats.tx_dropped;
- 			dev_kfree_skb_any(skb);
- 		}
- 
-@@ -716,7 +716,7 @@ static void unicast_arp_send(struct sk_b
- 		skb_push(skb, sizeof *phdr);
- 		__skb_queue_tail(&path->queue, skb);
- 	} else {
--		++dev->stats.tx_dropped;
-+		++priv->stats.tx_dropped;
- 		dev_kfree_skb_any(skb);
- 	}
- 
-@@ -773,7 +773,7 @@ static int ipoib_start_xmit(struct sk_bu
- 			__skb_queue_tail(&neigh->queue, skb);
- 			spin_unlock_irqrestore(&priv->lock, flags);
- 		} else {
--			++dev->stats.tx_dropped;
-+			++priv->stats.tx_dropped;
- 			dev_kfree_skb_any(skb);
- 		}
- 	} else {
-@@ -799,7 +799,7 @@ static int ipoib_start_xmit(struct sk_bu
- 					   IPOIB_QPN(phdr->hwaddr),
- 					   IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
- 				dev_kfree_skb_any(skb);
--				++dev->stats.tx_dropped;
-+				++priv->stats.tx_dropped;
- 				return NETDEV_TX_OK;
- 			}
- 
-@@ -825,7 +825,7 @@ static void ipoib_timeout(struct net_dev
- static int ipoib_hard_header(struct sk_buff *skb,
- 			     struct net_device *dev,
- 			     unsigned short type,
--			     const void *daddr, const void *saddr, unsigned len)
-+			     void *daddr, void *saddr, unsigned len)
- {
- 	struct ipoib_header *header;
- 
-@@ -914,9 +914,10 @@ struct ipoib_neigh *ipoib_neigh_alloc(st
- void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
- {
- 	struct sk_buff *skb;
-+	struct ipoib_dev_priv *priv = netdev_priv(dev);
- 	*to_ipoib_neigh(neigh->neighbour) = NULL;
- 	while ((skb = __skb_dequeue(&neigh->queue))) {
--		++dev->stats.tx_dropped;
-+		++priv->stats.tx_dropped;
- 		dev_kfree_skb_any(skb);
- 	}
- 	if (ipoib_cm_get(neigh))
-@@ -991,10 +992,6 @@ void ipoib_dev_cleanup(struct net_device
- 	priv->tx_ring = NULL;
- }
- 
--static const struct header_ops ipoib_header_ops = {
--	.create	= ipoib_hard_header,
--};
--
- static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
- 		       void **tcph, u64 *hdr_flags, void *priv)
- {
-@@ -1052,13 +1049,13 @@ static void ipoib_setup(struct net_devic
- 	dev->change_mtu		 = ipoib_change_mtu;
- 	dev->hard_start_xmit	 = ipoib_start_xmit;
- 	dev->tx_timeout		 = ipoib_timeout;
--	dev->header_ops		 = &ipoib_header_ops;
-+	dev->hard_header         = ipoib_hard_header;
- 	dev->set_multicast_list	 = ipoib_set_mcast_list;
- 	dev->neigh_setup	 = ipoib_neigh_setup_dev;
--
- 	ipoib_set_ethtool_ops(dev);
-+	dev->poll                = ipoib_poll;
-+	dev->weight              = 100;
- 
--	netif_napi_add(dev, &priv->napi, ipoib_poll, 100);
- 
- 	dev->watchdog_timeo	 = HZ;
- 
-Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-===================================================================
---- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2009-04-16 23:35:04.000000000 +0300
-+++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2009-04-16 23:46:20.000000000 +0300
-@@ -100,7 +100,7 @@ static void ipoib_mcast_free(struct ipoi
- 	}
- 
- 	netif_tx_lock_bh(dev);
--	dev->stats.tx_dropped += tx_dropped;
-+	priv->stats.tx_dropped += tx_dropped;
- 	netif_tx_unlock_bh(dev);
- 
- 	kfree(mcast);
-@@ -285,6 +285,7 @@ ipoib_mcast_sendonly_join_complete(int s
- {
- 	struct ipoib_mcast *mcast = multicast->context;
- 	struct net_device *dev = mcast->dev;
-+	struct ipoib_dev_priv *priv = netdev_priv(dev);
- 
- 	/* We trap for port events ourselves. */
- 	if (status == -ENETRESET)
-@@ -302,7 +303,7 @@ ipoib_mcast_sendonly_join_complete(int s
- 		/* Flush out any queued packets */
- 		netif_tx_lock_bh(dev);
- 		while (!skb_queue_empty(&mcast->pkt_queue)) {
--			++dev->stats.tx_dropped;
-+			++priv->stats.tx_dropped;
- 			dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
- 		}
- 		netif_tx_unlock_bh(dev);
-@@ -677,7 +678,7 @@ void ipoib_mcast_send(struct net_device 
- 	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)		||
- 	    !priv->broadcast					||
- 	    !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
--		++dev->stats.tx_dropped;
-+		++priv->stats.tx_dropped;
- 		dev_kfree_skb_any(skb);
- 		goto unlock;
- 	}
-@@ -692,7 +693,7 @@ void ipoib_mcast_send(struct net_device 
- 		if (!mcast) {
- 			ipoib_warn(priv, "unable to allocate memory for "
- 				   "multicast structure\n");
--			++dev->stats.tx_dropped;
-+			++priv->stats.tx_dropped;
- 			dev_kfree_skb_any(skb);
- 			goto out;
- 		}
-@@ -707,7 +708,7 @@ void ipoib_mcast_send(struct net_device 
- 		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
- 			skb_queue_tail(&mcast->pkt_queue, skb);
- 		else {
--			++dev->stats.tx_dropped;
-+			++priv->stats.tx_dropped;
- 			dev_kfree_skb_any(skb);
- 		}
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0110_restore_get_stats.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_0110_restore_get_stats.patch
deleted file mode 100644
index 1b9bae4..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0110_restore_get_stats.patch
+++ /dev/null
@@ -1,30 +0,0 @@
----
- drivers/infiniband/ulp/ipoib/ipoib_main.c |    8 ++++++++
- 1 file changed, 8 insertions(+)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-@@ -813,6 +813,13 @@ out:
- 	return NETDEV_TX_OK;
- }
- 
-+static struct net_device_stats *ipoib_get_stats(struct net_device *dev)
-+{
-+	struct ipoib_dev_priv *priv = netdev_priv(dev);
-+
-+	return &priv->stats;
-+}
-+
- static void ipoib_timeout(struct net_device *dev)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-@@ -1051,6 +1058,7 @@ static void ipoib_setup(struct net_devic
- 	dev->stop		 = ipoib_stop;
- 	dev->change_mtu		 = ipoib_change_mtu;
- 	dev->hard_start_xmit	 = ipoib_start_xmit;
-+	dev->get_stats 		 = ipoib_get_stats;
- 	dev->tx_timeout		 = ipoib_timeout;
- 	dev->hard_header         = ipoib_hard_header;
- 	dev->set_multicast_list	 = ipoib_set_mcast_list;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0500_warnings_ipoib_fs_to_2_6_19.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_0500_warnings_ipoib_fs_to_2_6_19.patch
deleted file mode 100644
index 7f45167..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0500_warnings_ipoib_fs_to_2_6_19.patch
+++ /dev/null
@@ -1,26 +0,0 @@
----
- drivers/infiniband/ulp/ipoib/ipoib_fs.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: ofa_kernel-1.4/drivers/infiniband/ulp/ipoib/ipoib_fs.c
-===================================================================
---- ofa_kernel-1.4.orig/drivers/infiniband/ulp/ipoib/ipoib_fs.c
-+++ ofa_kernel-1.4/drivers/infiniband/ulp/ipoib/ipoib_fs.c
-@@ -134,7 +134,7 @@ static int ipoib_mcg_open(struct inode *
- 	struct seq_file *seq;
- 	int ret;
- 
--	ret = seq_open(file, &ipoib_mcg_seq_ops);
-+	ret = seq_open(file, (struct seq_operations *) &ipoib_mcg_seq_ops);
- 	if (ret)
- 		return ret;
- 
-@@ -240,7 +240,7 @@ static int ipoib_path_open(struct inode 
- 	struct seq_file *seq;
- 	int ret;
- 
--	ret = seq_open(file, &ipoib_path_seq_ops);
-+	ret = seq_open(file, (struct seq_operations *) &ipoib_path_seq_ops);
- 	if (ret)
- 		return ret;
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0900_netif_lock_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_0900_netif_lock_to_2_6_26.patch
deleted file mode 100644
index c2fdd18..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_0900_netif_lock_to_2_6_26.patch
+++ /dev/null
@@ -1,26 +0,0 @@
----
- drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-@@ -777,7 +777,7 @@ void ipoib_mcast_restart_task(struct wor
- 	ipoib_mcast_stop_thread(dev, 0);
- 
- 	local_irq_save(flags);
--	netif_addr_lock(dev);
-+	netif_tx_lock(dev);
- 	spin_lock(&priv->lock);
- 
- 	/*
-@@ -854,7 +854,7 @@ void ipoib_mcast_restart_task(struct wor
- 	}
- 
- 	spin_unlock(&priv->lock);
--	netif_addr_unlock(dev);
-+	netif_tx_unlock(dev);
- 	local_irq_restore(flags);
- 
- 	/* We have to cancel outside of the spinlock */
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20.patch
deleted file mode 100644
index f7cb26d..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-Revert the following patch:
-
-commit 43cb76d91ee85f579a69d42bc8efc08bac560278
-Author: Greg Kroah-Hartman <gregkh at suse.de>
-Date:   Tue Apr 9 12:14:34 2002 -0700
-
-    Network: convert network devices to use struct device instead of class_device
-
-    This lets the network core have the ability to handle suspend/resume
-    issues, if it wants to.
-
-    Thanks to Frederik Deweerdt <frederik.deweerdt at gmail.com> for the arm
-    driver fixes.
-
-    Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
-
----
- drivers/infiniband/ulp/ipoib/ipoib_cm.c   |   13 ++++++-------
- drivers/infiniband/ulp/ipoib/ipoib_main.c |   26 ++++++++++++++------------
- drivers/infiniband/ulp/ipoib/ipoib_vlan.c |   10 ++++++----
- 3 files changed, 26 insertions(+), 23 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-@@ -47,6 +47,8 @@ MODULE_PARM_DESC(max_nonsrq_conn_qp,
- 		 "Max number of connected-mode QPs per interface "
- 		 "(applied only if shared receive queue is not available)");
- 
-+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-+
- #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA
- static int data_debug_level;
- 
-@@ -1433,9 +1435,7 @@ static void ipoib_cm_stale_task(struct w
- 	spin_unlock_irq(&priv->lock);
- }
- 
--
--static ssize_t show_mode(struct device *d, struct device_attribute *attr,
--			 char *buf)
-+static ssize_t show_mode(struct class_device *d, char *buf)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(d));
- 
-@@ -1445,8 +1445,7 @@ static ssize_t show_mode(struct device *
- 		return sprintf(buf, "datagram\n");
- }
- 
--static ssize_t set_mode(struct device *d, struct device_attribute *attr,
--			const char *buf, size_t count)
-+static ssize_t set_mode(struct class_device *d, const char *buf, size_t count)
- {
- 	struct net_device *dev = to_net_dev(d);
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-@@ -1490,11 +1489,11 @@ static ssize_t set_mode(struct device *d
- 	return -EINVAL;
- }
- 
--static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
-+static CLASS_DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
- 
- int ipoib_cm_add_mode_attr(struct net_device *dev)
- {
--	return device_create_file(&dev->dev, &dev_attr_mode);
-+	return class_device_create_file(&dev->class_dev, &class_device_attr_mode);
- }
- 
- static void ipoib_cm_create_srq(struct net_device *dev, int max_sge)
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-@@ -100,6 +100,8 @@ static struct ib_client ipoib_client = {
- 	.remove = ipoib_remove_one
- };
- 
-+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-+
- int ipoib_open(struct net_device *dev)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-@@ -1123,14 +1125,13 @@ struct ipoib_dev_priv *ipoib_intf_alloc(
- 	return netdev_priv(dev);
- }
- 
--static ssize_t show_pkey(struct device *dev,
--			 struct device_attribute *attr, char *buf)
-+static ssize_t show_pkey(struct class_device *dev, char *buf)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
- 
- 	return sprintf(buf, "0x%04x\n", priv->pkey);
- }
--static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
-+static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
- 
- static ssize_t show_umcast(struct device *dev,
- 			   struct device_attribute *attr, char *buf)
-@@ -1163,8 +1164,7 @@ int ipoib_add_umcast_attr(struct net_dev
- 	return device_create_file(&dev->dev, &dev_attr_umcast);
- }
- 
--static ssize_t create_child(struct device *dev,
--			    struct device_attribute *attr,
-+static ssize_t create_child(struct class_device *dev,
- 			    const char *buf, size_t count)
- {
- 	int pkey;
-@@ -1186,10 +1186,9 @@ static ssize_t create_child(struct devic
- 
- 	return ret ? ret : count;
- }
--static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
-+static CLASS_DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
- 
--static ssize_t delete_child(struct device *dev,
--			    struct device_attribute *attr,
-+static ssize_t delete_child(struct class_device *dev,
- 			    const char *buf, size_t count)
- {
- 	int pkey;
-@@ -1206,11 +1205,12 @@ static ssize_t delete_child(struct devic
- 	return ret ? ret : count;
- 
- }
--static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
-+static CLASS_DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
- 
- int ipoib_add_pkey_attr(struct net_device *dev)
- {
--	return device_create_file(&dev->dev, &dev_attr_pkey);
-+	return class_device_create_file(&dev->class_dev,
-+					&class_device_attr_pkey);
- }
- 
- static struct net_device *ipoib_add_port(const char *format,
-@@ -1324,9 +1324,11 @@ static struct net_device *ipoib_add_port
- 		goto sysfs_failed;
- 	if (ipoib_add_umcast_attr(priv->dev))
- 		goto sysfs_failed;
--	if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
-+	if (class_device_create_file(&priv->dev->class_dev,
-+				     &class_device_attr_create_child))
- 		goto sysfs_failed;
--	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
-+	if (class_device_create_file(&priv->dev->class_dev,
-+				     &class_device_attr_delete_child))
- 		goto sysfs_failed;
- 
- 	return priv->dev;
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
-@@ -40,15 +40,16 @@
- 
- #include "ipoib.h"
- 
--static ssize_t show_parent(struct device *d, struct device_attribute *attr,
--			   char *buf)
-+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-+
-+static ssize_t show_parent(struct class_device *d, char *buf)
- {
- 	struct net_device *dev = to_net_dev(d);
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
- 
- 	return sprintf(buf, "%s\n", priv->parent->name);
- }
--static DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
-+static CLASS_DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
- 
- int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
- {
-@@ -124,7 +125,8 @@ int ipoib_vlan_add(struct net_device *pd
- 	if (ipoib_add_umcast_attr(priv->dev))
- 		goto sysfs_failed;
- 
--	if (device_create_file(&priv->dev->dev, &dev_attr_parent))
-+	if (class_device_create_file(&priv->dev->class_dev,
-+				     &class_device_attr_parent))
- 		goto sysfs_failed;
- 
- 	list_add_tail(&priv->list, &ppriv->child_intfs);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20_umcast.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20_umcast.patch
deleted file mode 100644
index 45b6ec3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_class_device_to_2_6_20_umcast.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-This patch is the buddy of ipoib_class_device_to_2_6_20.patch, namely it handles
-the same issue in the same method for the /sys/class/net/$dev/umcast sysfs entry
-
-Hence it  needs to go to all the directories under kernel_patches/backport that 
-contain the ipoib_class_device_to_2_6_20.patch
-
----
-
-backport kernel_patches/fixes/zzz_ipoib_allow_umcast.patch to older kernels
-
-Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>
-
----
- drivers/infiniband/ulp/ipoib/ipoib_main.c |   11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-@@ -1133,16 +1133,14 @@ static ssize_t show_pkey(struct class_de
- }
- static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
- 
--static ssize_t show_umcast(struct device *dev,
--			   struct device_attribute *attr, char *buf)
-+static ssize_t show_umcast(struct class_device *dev, char *buf)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
- 
- 	return sprintf(buf, "%d\n", test_bit(IPOIB_FLAG_UMCAST, &priv->flags));
- }
- 
--static ssize_t set_umcast(struct device *dev,
--			  struct device_attribute *attr,
-+static ssize_t set_umcast(struct class_device *dev,
- 			  const char *buf, size_t count)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
-@@ -1157,11 +1155,12 @@ static ssize_t set_umcast(struct device 
- 
- 	return count;
- }
--static DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
-+static CLASS_DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
- 
- int ipoib_add_umcast_attr(struct net_device *dev)
- {
--	return device_create_file(&dev->dev, &dev_attr_umcast);
-+	return class_device_create_file(&dev->class_dev,
-+					&class_device_attr_umcast);
- }
- 
- static ssize_t create_child(struct class_device *dev,
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_lro_to_2.6.23.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_lro_to_2.6.23.patch
deleted file mode 100644
index 4e349d2..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_lro_to_2.6.23.patch
+++ /dev/null
@@ -1,659 +0,0 @@
----
- drivers/infiniband/ulp/ipoib/Makefile        |    3 
- drivers/infiniband/ulp/ipoib/inet_lro.c      |  601 +++++++++++++++++++++++++++
- drivers/infiniband/ulp/ipoib/ipoib_ethtool.c |   13 
- 3 files changed, 606 insertions(+), 11 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/Makefile
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/Makefile
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/Makefile
-@@ -5,7 +5,8 @@ ib_ipoib-y					:= ipoib_main.o \
- 						   ipoib_multicast.o \
- 						   ipoib_verbs.o \
- 						   ipoib_vlan.o \
--						   ipoib_ethtool.o
-+						   ipoib_ethtool.o \
-+						   inet_lro.o
- ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_CM)		+= ipoib_cm.o
- ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_DEBUG)	+= ipoib_fs.o
- 
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/inet_lro.c
-===================================================================
---- /dev/null
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/inet_lro.c
-@@ -0,0 +1,601 @@
-+/*
-+ *  linux/net/ipv4/inet_lro.c
-+ *
-+ *  Large Receive Offload (ipv4 / tcp)
-+ *
-+ *  (C) Copyright IBM Corp. 2007
-+ *
-+ *  Authors:
-+ *       Jan-Bernd Themann <themann at de.ibm.com>
-+ *       Christoph Raisch <raisch at de.ibm.com>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/if_vlan.h>
-+#include <linux/inet_lro.h>
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jan-Bernd Themann <themann at de.ibm.com>");
-+MODULE_DESCRIPTION("Large Receive Offload (ipv4 / tcp)");
-+
-+#define TCP_HDR_LEN(tcph) (tcph->doff << 2)
-+#define IP_HDR_LEN(iph) (iph->ihl << 2)
-+#define TCP_PAYLOAD_LENGTH(iph, tcph) \
-+	(ntohs(iph->tot_len) - IP_HDR_LEN(iph) - TCP_HDR_LEN(tcph))
-+
-+#define IPH_LEN_WO_OPTIONS 5
-+#define TCPH_LEN_WO_OPTIONS 5
-+#define TCPH_LEN_W_TIMESTAMP 8
-+
-+#define LRO_MAX_PG_HLEN 64
-+
-+#define LRO_INC_STATS(lro_mgr, attr) { lro_mgr->stats.attr++; }
-+
-+/*
-+ * Basic tcp checks whether packet is suitable for LRO
-+ */
-+
-+static int lro_tcp_ip_check(struct iphdr *iph, struct tcphdr *tcph,
-+			    int len, struct net_lro_desc *lro_desc)
-+{
-+        /* check ip header: don't aggregate padded frames */
-+	if (ntohs(iph->tot_len) != len)
-+		return -1;
-+
-+	if (TCP_PAYLOAD_LENGTH(iph, tcph) == 0)
-+		return -1;
-+
-+	if (iph->ihl != IPH_LEN_WO_OPTIONS)
-+		return -1;
-+
-+	if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack
-+	    || tcph->rst || tcph->syn || tcph->fin)
-+		return -1;
-+
-+	if (INET_ECN_is_ce(ipv4_get_dsfield(iph)))
-+		return -1;
-+
-+	if (tcph->doff != TCPH_LEN_WO_OPTIONS
-+	    && tcph->doff != TCPH_LEN_W_TIMESTAMP)
-+		return -1;
-+
-+	/* check tcp options (only timestamp allowed) */
-+	if (tcph->doff == TCPH_LEN_W_TIMESTAMP) {
-+		__be32 *topt = (__be32 *)(tcph + 1);
-+
-+		if (*topt != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
-+				   | (TCPOPT_TIMESTAMP << 8)
-+				   | TCPOLEN_TIMESTAMP))
-+			return -1;
-+
-+		/* timestamp should be in right order */
-+		topt++;
-+		if (lro_desc && after(ntohl(lro_desc->tcp_rcv_tsval),
-+				      ntohl(*topt)))
-+			return -1;
-+
-+		/* timestamp reply should not be zero */
-+		topt++;
-+		if (*topt == 0)
-+			return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+static void lro_update_tcp_ip_header(struct net_lro_desc *lro_desc)
-+{
-+	struct iphdr *iph = lro_desc->iph;
-+	struct tcphdr *tcph = lro_desc->tcph;
-+	__be32 *p;
-+	__wsum tcp_hdr_csum;
-+
-+	tcph->ack_seq = lro_desc->tcp_ack;
-+	tcph->window = lro_desc->tcp_window;
-+
-+	if (lro_desc->tcp_saw_tstamp) {
-+		p = (__be32 *)(tcph + 1);
-+		*(p+2) = lro_desc->tcp_rcv_tsecr;
-+	}
-+
-+	iph->tot_len = htons(lro_desc->ip_tot_len);
-+
-+	iph->check = 0;
-+	iph->check = ip_fast_csum((u8 *)lro_desc->iph, iph->ihl);
-+
-+	tcph->check = 0;
-+	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), 0);
-+	lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum);
-+	tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
-+					lro_desc->ip_tot_len -
-+					IP_HDR_LEN(iph), IPPROTO_TCP,
-+					lro_desc->data_csum);
-+}
-+
-+static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
-+{
-+	__wsum tcp_csum;
-+	__wsum tcp_hdr_csum;
-+	__wsum tcp_ps_hdr_csum;
-+
-+	tcp_csum = ~csum_unfold(tcph->check);
-+	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), tcp_csum);
-+
-+	tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-+					     len + TCP_HDR_LEN(tcph),
-+					     IPPROTO_TCP, 0);
-+
-+	return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum),
-+			tcp_ps_hdr_csum);
-+}
-+
-+static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb,
-+			  struct iphdr *iph, struct tcphdr *tcph,
-+			  u16 vlan_tag, struct vlan_group *vgrp)
-+{
-+	int nr_frags;
-+	__be32 *ptr;
-+	u32 tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
-+
-+	nr_frags = skb_shinfo(skb)->nr_frags;
-+	lro_desc->parent = skb;
-+	lro_desc->next_frag = &(skb_shinfo(skb)->frags[nr_frags]);
-+	lro_desc->iph = iph;
-+	lro_desc->tcph = tcph;
-+	lro_desc->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len;
-+	lro_desc->tcp_ack = tcph->ack_seq;
-+	lro_desc->tcp_window = tcph->window;
-+
-+	lro_desc->pkt_aggr_cnt = 1;
-+	lro_desc->ip_tot_len = ntohs(iph->tot_len);
-+
-+	if (tcph->doff == 8) {
-+		ptr = (__be32 *)(tcph+1);
-+		lro_desc->tcp_saw_tstamp = 1;
-+		lro_desc->tcp_rcv_tsval = *(ptr+1);
-+		lro_desc->tcp_rcv_tsecr = *(ptr+2);
-+	}
-+
-+	lro_desc->mss = tcp_data_len;
-+	lro_desc->vgrp = vgrp;
-+	lro_desc->vlan_tag = vlan_tag;
-+	lro_desc->active = 1;
-+
-+	lro_desc->data_csum = lro_tcp_data_csum(iph, tcph,
-+						tcp_data_len);
-+}
-+
-+static inline void lro_clear_desc(struct net_lro_desc *lro_desc)
-+{
-+	memset(lro_desc, 0, sizeof(struct net_lro_desc));
-+}
-+
-+static void lro_add_common(struct net_lro_desc *lro_desc, struct iphdr *iph,
-+			   struct tcphdr *tcph, int tcp_data_len)
-+{
-+	struct sk_buff *parent = lro_desc->parent;
-+	__be32 *topt;
-+
-+	lro_desc->pkt_aggr_cnt++;
-+	lro_desc->ip_tot_len += tcp_data_len;
-+	lro_desc->tcp_next_seq += tcp_data_len;
-+	lro_desc->tcp_window = tcph->window;
-+	lro_desc->tcp_ack = tcph->ack_seq;
-+
-+	/* don't update tcp_rcv_tsval, would not work with PAWS */
-+	if (lro_desc->tcp_saw_tstamp) {
-+		topt = (__be32 *) (tcph + 1);
-+		lro_desc->tcp_rcv_tsecr = *(topt + 2);
-+	}
-+
-+	lro_desc->data_csum = csum_block_add(lro_desc->data_csum,
-+					     lro_tcp_data_csum(iph, tcph,
-+							       tcp_data_len),
-+					     parent->len);
-+
-+	parent->len += tcp_data_len;
-+	parent->data_len += tcp_data_len;
-+	if (tcp_data_len > lro_desc->mss)
-+		lro_desc->mss = tcp_data_len;
-+}
-+
-+static void lro_add_packet(struct net_lro_desc *lro_desc, struct sk_buff *skb,
-+			   struct iphdr *iph, struct tcphdr *tcph)
-+{
-+	struct sk_buff *parent = lro_desc->parent;
-+	int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
-+
-+	lro_add_common(lro_desc, iph, tcph, tcp_data_len);
-+
-+	skb_pull(skb, (skb->len - tcp_data_len));
-+	parent->truesize += skb->truesize;
-+
-+	if (lro_desc->last_skb)
-+		lro_desc->last_skb->next = skb;
-+	else
-+		skb_shinfo(parent)->frag_list = skb;
-+
-+	lro_desc->last_skb = skb;
-+}
-+
-+static void lro_add_frags(struct net_lro_desc *lro_desc,
-+			  int len, int hlen, int truesize,
-+			  struct skb_frag_struct *skb_frags,
-+			  struct iphdr *iph, struct tcphdr *tcph)
-+{
-+	struct sk_buff *skb = lro_desc->parent;
-+	int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
-+
-+	lro_add_common(lro_desc, iph, tcph, tcp_data_len);
-+
-+	skb->truesize += truesize;
-+
-+	skb_frags[0].page_offset += hlen;
-+	skb_frags[0].size -= hlen;
-+
-+	while (tcp_data_len > 0) {
-+		*(lro_desc->next_frag) = *skb_frags;
-+		tcp_data_len -= skb_frags->size;
-+		lro_desc->next_frag++;
-+		skb_frags++;
-+		skb_shinfo(skb)->nr_frags++;
-+	}
-+}
-+
-+static int lro_check_tcp_conn(struct net_lro_desc *lro_desc,
-+			      struct iphdr *iph,
-+			      struct tcphdr *tcph)
-+{
-+	if ((lro_desc->iph->saddr != iph->saddr)
-+	    || (lro_desc->iph->daddr != iph->daddr)
-+	    || (lro_desc->tcph->source != tcph->source)
-+	    || (lro_desc->tcph->dest != tcph->dest))
-+		return -1;
-+	return 0;
-+}
-+
-+static struct net_lro_desc *lro_get_desc(struct net_lro_mgr *lro_mgr,
-+					 struct net_lro_desc *lro_arr,
-+					 struct iphdr *iph,
-+					 struct tcphdr *tcph)
-+{
-+	struct net_lro_desc *lro_desc = NULL;
-+	struct net_lro_desc *tmp;
-+	int max_desc = lro_mgr->max_desc;
-+	int i;
-+
-+	for (i = 0; i < max_desc; i++) {
-+		tmp = &lro_arr[i];
-+		if (tmp->active)
-+			if (!lro_check_tcp_conn(tmp, iph, tcph)) {
-+				lro_desc = tmp;
-+				goto out;
-+			}
-+	}
-+
-+	for (i = 0; i < max_desc; i++) {
-+		if (!lro_arr[i].active) {
-+			lro_desc = &lro_arr[i];
-+			goto out;
-+		}
-+	}
-+
-+	LRO_INC_STATS(lro_mgr, no_desc);
-+out:
-+	return lro_desc;
-+}
-+
-+static void lro_flush(struct net_lro_mgr *lro_mgr,
-+		      struct net_lro_desc *lro_desc)
-+{
-+	if (lro_desc->pkt_aggr_cnt > 1)
-+		lro_update_tcp_ip_header(lro_desc);
-+
-+	skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss;
-+
-+	if (lro_desc->vgrp) {
-+		if (lro_mgr->features & LRO_F_NAPI)
-+			vlan_hwaccel_receive_skb(lro_desc->parent,
-+						 lro_desc->vgrp,
-+						 lro_desc->vlan_tag);
-+		else
-+			vlan_hwaccel_rx(lro_desc->parent,
-+					lro_desc->vgrp,
-+					lro_desc->vlan_tag);
-+
-+	} else {
-+		if (lro_mgr->features & LRO_F_NAPI)
-+			netif_receive_skb(lro_desc->parent);
-+		else
-+			netif_rx(lro_desc->parent);
-+	}
-+
-+	LRO_INC_STATS(lro_mgr, flushed);
-+	lro_clear_desc(lro_desc);
-+}
-+
-+static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
-+			  struct vlan_group *vgrp, u16 vlan_tag, void *priv)
-+{
-+	struct net_lro_desc *lro_desc;
-+	struct iphdr *iph;
-+	struct tcphdr *tcph;
-+	u64 flags;
-+	int vlan_hdr_len = 0;
-+
-+	if (!lro_mgr->get_skb_header
-+	    || lro_mgr->get_skb_header(skb, (void *)&iph, (void *)&tcph,
-+				       &flags, priv))
-+		goto out;
-+
-+	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))
-+		goto out;
-+
-+	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
-+	if (!lro_desc)
-+		goto out;
-+
-+	if ((skb->protocol == htons(ETH_P_8021Q))
-+	    && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID))
-+		vlan_hdr_len = VLAN_HLEN;
-+
-+	if (!lro_desc->active) { /* start new lro session */
-+		if (lro_tcp_ip_check(iph, tcph, skb->len - vlan_hdr_len, NULL))
-+			goto out;
-+
-+		skb->ip_summed = lro_mgr->ip_summed_aggr;
-+		lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp);
-+		LRO_INC_STATS(lro_mgr, aggregated);
-+		return 0;
-+	}
-+
-+	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))
-+		goto out2;
-+
-+	if (lro_tcp_ip_check(iph, tcph, skb->len, lro_desc))
-+		goto out2;
-+
-+	lro_add_packet(lro_desc, skb, iph, tcph);
-+	LRO_INC_STATS(lro_mgr, aggregated);
-+
-+	if ((lro_desc->pkt_aggr_cnt >= lro_mgr->max_aggr) ||
-+	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
-+		lro_flush(lro_mgr, lro_desc);
-+
-+	return 0;
-+
-+out2: /* send aggregated SKBs to stack */
-+	lro_flush(lro_mgr, lro_desc);
-+
-+out:  /* Original SKB has to be posted to stack */
-+	skb->ip_summed = lro_mgr->ip_summed;
-+	return 1;
-+}
-+
-+
-+static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,
-+				   struct skb_frag_struct *frags,
-+				   int len, int true_size,
-+				   void *mac_hdr,
-+				   int hlen, __wsum sum,
-+				   u32 ip_summed)
-+{
-+	struct sk_buff *skb;
-+	struct skb_frag_struct *skb_frags;
-+	int data_len = len;
-+	int hdr_len = min(len, hlen);
-+
-+	skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad);
-+	if (!skb)
-+		return NULL;
-+
-+	skb_reserve(skb, lro_mgr->frag_align_pad);
-+	skb->len = len;
-+	skb->data_len = len - hdr_len;
-+	skb->truesize += true_size;
-+	skb->tail += hdr_len;
-+
-+	memcpy(skb->data, mac_hdr, hdr_len);
-+
-+	skb_frags = skb_shinfo(skb)->frags;
-+	while (data_len > 0) {
-+		*skb_frags = *frags;
-+		data_len -= frags->size;
-+		skb_frags++;
-+		frags++;
-+		skb_shinfo(skb)->nr_frags++;
-+	}
-+
-+	skb_shinfo(skb)->frags[0].page_offset += hdr_len;
-+	skb_shinfo(skb)->frags[0].size -= hdr_len;
-+
-+	skb->ip_summed = ip_summed;
-+	skb->csum = sum;
-+	skb->protocol = eth_type_trans(skb, lro_mgr->dev);
-+	return skb;
-+}
-+
-+static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
-+					  struct skb_frag_struct *frags,
-+					  int len, int true_size,
-+					  struct vlan_group *vgrp,
-+					  u16 vlan_tag, void *priv, __wsum sum)
-+{
-+	struct net_lro_desc *lro_desc;
-+	struct iphdr *iph;
-+	struct tcphdr *tcph;
-+	struct sk_buff *skb;
-+	u64 flags;
-+	void *mac_hdr;
-+	int mac_hdr_len;
-+	int hdr_len = LRO_MAX_PG_HLEN;
-+	int vlan_hdr_len = 0;
-+
-+	if (!lro_mgr->get_frag_header
-+	    || lro_mgr->get_frag_header(frags, (void *)&mac_hdr, (void *)&iph,
-+					(void *)&tcph, &flags, priv)) {
-+		mac_hdr = page_address(frags->page) + frags->page_offset;
-+		goto out1;
-+	}
-+
-+	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))
-+		goto out1;
-+
-+	hdr_len = (int)((void *)(tcph) + TCP_HDR_LEN(tcph) - mac_hdr);
-+	mac_hdr_len = (int)((void *)(iph) - mac_hdr);
-+
-+	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
-+	if (!lro_desc)
-+		goto out1;
-+
-+	if (!lro_desc->active) { /* start new lro session */
-+		if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, NULL))
-+			goto out1;
-+
-+		skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
-+				  hdr_len, 0, lro_mgr->ip_summed_aggr);
-+		if (!skb)
-+			goto out;
-+
-+		if ((skb->protocol == htons(ETH_P_8021Q))
-+		    && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID))
-+			vlan_hdr_len = VLAN_HLEN;
-+
-+		iph = (void *)(skb->data + vlan_hdr_len);
-+		tcph = (void *)((u8 *)skb->data + vlan_hdr_len
-+				+ IP_HDR_LEN(iph));
-+
-+		lro_init_desc(lro_desc, skb, iph, tcph, 0, NULL);
-+		LRO_INC_STATS(lro_mgr, aggregated);
-+		return NULL;
-+	}
-+
-+	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))
-+		goto out2;
-+
-+	if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, lro_desc))
-+		goto out2;
-+
-+	lro_add_frags(lro_desc, len, hdr_len, true_size, frags, iph, tcph);
-+	LRO_INC_STATS(lro_mgr, aggregated);
-+
-+	if ((skb_shinfo(lro_desc->parent)->nr_frags >= lro_mgr->max_aggr) ||
-+	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
-+		lro_flush(lro_mgr, lro_desc);
-+
-+	return NULL;
-+
-+out2: /* send aggregated packets to the stack */
-+	lro_flush(lro_mgr, lro_desc);
-+
-+out1:  /* Original packet has to be posted to the stack */
-+	skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
-+			  hdr_len, sum, lro_mgr->ip_summed);
-+out:
-+	return skb;
-+}
-+
-+void lro_receive_skb(struct net_lro_mgr *lro_mgr,
-+		     struct sk_buff *skb,
-+		     void *priv)
-+{
-+	if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) {
-+		if (lro_mgr->features & LRO_F_NAPI)
-+			netif_receive_skb(skb);
-+		else
-+			netif_rx(skb);
-+	}
-+}
-+EXPORT_SYMBOL(lro_receive_skb);
-+
-+void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
-+				  struct sk_buff *skb,
-+				  struct vlan_group *vgrp,
-+				  u16 vlan_tag,
-+				  void *priv)
-+{
-+	if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) {
-+		if (lro_mgr->features & LRO_F_NAPI)
-+			vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
-+		else
-+			vlan_hwaccel_rx(skb, vgrp, vlan_tag);
-+	}
-+}
-+EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb);
-+
-+void lro_receive_frags(struct net_lro_mgr *lro_mgr,
-+		       struct skb_frag_struct *frags,
-+		       int len, int true_size, void *priv, __wsum sum)
-+{
-+	struct sk_buff *skb;
-+
-+	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0,
-+				 priv, sum);
-+	if (!skb)
-+		return;
-+
-+	if (lro_mgr->features & LRO_F_NAPI)
-+		netif_receive_skb(skb);
-+	else
-+		netif_rx(skb);
-+}
-+EXPORT_SYMBOL(lro_receive_frags);
-+
-+void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
-+				    struct skb_frag_struct *frags,
-+				    int len, int true_size,
-+				    struct vlan_group *vgrp,
-+				    u16 vlan_tag, void *priv, __wsum sum)
-+{
-+	struct sk_buff *skb;
-+
-+	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp,
-+				 vlan_tag, priv, sum);
-+	if (!skb)
-+		return;
-+
-+	if (lro_mgr->features & LRO_F_NAPI)
-+		vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
-+	else
-+		vlan_hwaccel_rx(skb, vgrp, vlan_tag);
-+}
-+EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags);
-+
-+void lro_flush_all(struct net_lro_mgr *lro_mgr)
-+{
-+	int i;
-+	struct net_lro_desc *lro_desc = lro_mgr->lro_arr;
-+
-+	for (i = 0; i < lro_mgr->max_desc; i++) {
-+		if (lro_desc[i].active)
-+			lro_flush(lro_mgr, &lro_desc[i]);
-+	}
-+}
-+EXPORT_SYMBOL(lro_flush_all);
-+
-+void lro_flush_pkt(struct net_lro_mgr *lro_mgr,
-+		  struct iphdr *iph, struct tcphdr *tcph)
-+{
-+	struct net_lro_desc *lro_desc;
-+
-+	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
-+	if (lro_desc->active)
-+		lro_flush(lro_mgr, lro_desc);
-+}
-+EXPORT_SYMBOL(lro_flush_pkt);
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
-@@ -100,14 +100,9 @@ static void ipoib_get_strings(struct net
- 	}
- }
- 
--static int ipoib_get_sset_count(struct net_device *dev, int sset)
-+static int ipoib_get_stats_count(struct net_device *dev)
- {
--	switch (sset) {
--	case ETH_SS_STATS:
--		return ARRAY_SIZE(ipoib_stats_keys);
--	default:
--		return -EOPNOTSUPP;
--	}
-+	return ARRAY_SIZE(ipoib_stats_keys);
- }
- 
- static void ipoib_get_ethtool_stats(struct net_device *dev,
-@@ -132,10 +127,8 @@ static const struct ethtool_ops ipoib_et
- 	.get_tso		= ethtool_op_get_tso,
- 	.get_coalesce		= ipoib_get_coalesce,
- 	.set_coalesce		= ipoib_set_coalesce,
--	.get_flags		= ethtool_op_get_flags,
--	.set_flags		= ethtool_op_set_flags,
- 	.get_strings		= ipoib_get_strings,
--	.get_sset_count		= ipoib_get_sset_count,
-+	.get_stats_count 	= ipoib_get_stats_count,
- 	.get_ethtool_stats	= ipoib_get_ethtool_stats,
- };
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_mcast_set_pkey_to_2_6_24.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_mcast_set_pkey_to_2_6_24.patch
deleted file mode 100644
index 9c466cd..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_mcast_set_pkey_to_2_6_24.patch
+++ /dev/null
@@ -1,19 +0,0 @@
----
- drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    4 ++++
- 1 file changed, 4 insertions(+)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-@@ -796,6 +796,10 @@ void ipoib_mcast_restart_task(struct wor
- 
- 		memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
- 
-+		/* Add in the P_Key */
-+		mgid.raw[4] = (priv->pkey >> 8) & 0xff;
-+		mgid.raw[5] = priv->pkey & 0xff;
-+
- 		mcast = __ipoib_mcast_find(dev, &mgid);
- 		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
- 			struct ipoib_mcast *nmcast;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_skb_to_2_6_20.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_skb_to_2_6_20.patch
deleted file mode 100644
index d56793d..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_skb_to_2_6_20.patch
+++ /dev/null
@@ -1,16 +0,0 @@
----
- drivers/infiniband/ulp/ipoib/ipoib_ib.c |    1 +
- 1 file changed, 1 insertion(+)
-
-Index: ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-+++ ofed_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-@@ -35,6 +35,7 @@
- 
- #include <linux/delay.h>
- #include <linux/dma-mapping.h>
-+#include <linux/skbuff.h>
- 
- #include <rdma/ib_cache.h>
- #include <linux/ip.h>
diff --git a/kernel_patches/backport/2.6.18-EL5.1/ipoib_x_neigh_cleanup.patch b/kernel_patches/backport/2.6.18-EL5.1/ipoib_x_neigh_cleanup.patch
deleted file mode 100644
index 820fd8c..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/ipoib_x_neigh_cleanup.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-IB/ipoib: Fix neigh destructor oops
-
-For kernels 2.6.20 and older, it may happen that the pointer to
-ipoib_neigh_cleanup() is called after IPoIB has been unloades,
-causing a kernel oops. This problem has been fixed for 2.6.21 with
-the following commit: ecbb416939da77c0d107409976499724baddce7b
-
-The idea with this patch is to have a helper module which remains
-always loaded, and this modules provides the destructor for
-neighbours which calls IPoIB's destructor through a function poiner.
-When IPoIB is unloaded, the function pointer is cleared so subsequent
-calls to a neighbour destructor will be made to valid addresses but
-IPoIB's destructor won't get called.
-
-Signed-off-by: Eli Cohen <eli at mellanox.co.il>
----
-
-Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
-===================================================================
---- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2008-05-14 12:49:11.000000000 +0300
-+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c	2008-05-14 12:49:32.000000000 +0300
-@@ -49,6 +49,7 @@
- 
- #include <net/dst.h>
- #include <linux/vmalloc.h>
-+#include <linux/delay.h>
- 
- MODULE_AUTHOR("Roland Dreier");
- MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
-@@ -916,7 +917,7 @@ void ipoib_neigh_free(struct net_device 
- 
- static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
- {
--	parms->neigh_cleanup = ipoib_neigh_cleanup;
-+	parms->neigh_cleanup = ipoib_neigh_cleanup_container;
- 
- 	return 0;
- }
-@@ -1383,9 +1384,13 @@ static int __init ipoib_init_module(void
- 	ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
- #endif
- 
-+
-+	ipoib_set_cleanup_function(ipoib_neigh_cleanup);
- 	ret = ipoib_register_debugfs();
--	if (ret)
-+	if (ret) {
-+		ipoib_set_cleanup_function(NULL);
- 		return ret;
-+	}
- 
- 	/*
- 	 * We create our own workqueue mainly because we want to be
-@@ -1397,6 +1402,7 @@ static int __init ipoib_init_module(void
- 	 */
- 	ipoib_workqueue = create_singlethread_workqueue("ipoib");
- 	if (!ipoib_workqueue) {
-+		ipoib_set_cleanup_function(NULL);
- 		ret = -ENOMEM;
- 		goto err_fs;
- 	}
-@@ -1404,8 +1410,10 @@ static int __init ipoib_init_module(void
- 	ib_sa_register_client(&ipoib_sa_client);
- 
- 	ret = ib_register_client(&ipoib_client);
--	if (ret)
-+	if (ret) {
-+		ipoib_set_cleanup_function(NULL);
- 		goto err_sa;
-+	}
- 
- 	return 0;
- 
-@@ -1421,7 +1429,16 @@ err_fs:
- 
- static void __exit ipoib_cleanup_module(void)
- {
-+	int ret;
-+
- 	ib_unregister_client(&ipoib_client);
-+
-+	do {
-+		ret = ipoib_set_cleanup_function(NULL);
-+		if (ret)
-+			msleep(10);
-+	} while(ret);
-+
- 	ib_sa_unregister_client(&ipoib_sa_client);
- 	ipoib_unregister_debugfs();
- 	destroy_workqueue(ipoib_workqueue);
-Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/Makefile
-===================================================================
---- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/Makefile	2008-05-14 12:49:11.000000000 +0300
-+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/Makefile	2008-05-14 12:49:32.000000000 +0300
-@@ -1,4 +1,4 @@
--obj-$(CONFIG_INFINIBAND_IPOIB)			+= ib_ipoib.o
-+obj-$(CONFIG_INFINIBAND_IPOIB)			+= ib_ipoib.o ipoib_helper.o
- 
- ib_ipoib-y					:= ipoib_main.o \
- 						   ipoib_ib.o \
-Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h
-===================================================================
---- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2008-05-14 12:49:11.000000000 +0300
-+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h	2008-05-14 12:49:32.000000000 +0300
-@@ -554,6 +554,9 @@ int ipoib_mcast_stop_thread(struct net_d
- void ipoib_mcast_dev_down(struct net_device *dev);
- void ipoib_mcast_dev_flush(struct net_device *dev);
- 
-+int ipoib_set_cleanup_function(void (*func)(struct neighbour *n));
-+void ipoib_neigh_cleanup_container(struct neighbour *n);
-+
- #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
- struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
- int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
-Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_helper.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_helper.c	2008-05-14 12:49:32.000000000 +0300
-@@ -0,0 +1,63 @@
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <net/neighbour.h>
-+
-+MODULE_AUTHOR("Eli Cohen");
-+MODULE_DESCRIPTION("container for ipoib neighbour destructor");
-+MODULE_LICENSE("Dual BSD/GPL");
-+
-+DEFINE_SPINLOCK(spl);
-+static int busy;
-+
-+static void (*cleanup_func)(struct neighbour *n);
-+
-+static int ipoib_set_cleanup_function(void (*func)(struct neighbour *n))
-+{
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&spl, flags);
-+	if (busy) {
-+		spin_unlock_irqrestore(&spl, flags);
-+		return -EBUSY;
-+	}
-+	cleanup_func = func;
-+	spin_unlock_irqrestore(&spl, flags);
-+
-+	return 0;
-+}
-+
-+static void ipoib_neigh_cleanup_container(struct neighbour *n)
-+{
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&spl, flags);
-+	busy = 1;
-+	spin_unlock_irqrestore(&spl, flags);
-+	if (cleanup_func)
-+		cleanup_func(n);
-+
-+	spin_lock_irqsave(&spl, flags);
-+	busy = 0;
-+	spin_unlock_irqrestore(&spl, flags);
-+}
-+
-+
-+EXPORT_SYMBOL(ipoib_set_cleanup_function);
-+EXPORT_SYMBOL(ipoib_neigh_cleanup_container);
-+
-+
-+static int __init ipoib_helper_init(void)
-+{
-+	if (!try_module_get(THIS_MODULE))
-+		return -1;
-+
-+	return 0;
-+}
-+
-+
-+static void __exit ipoib_helper_cleanup(void)
-+{
-+}
-+
-+module_init(ipoib_helper_init);
-+module_exit(ipoib_helper_cleanup);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iscsi_01_sync_kernel_code_with_release_2.0-869.2.patch b/kernel_patches/backport/2.6.18-EL5.1/iscsi_01_sync_kernel_code_with_release_2.0-869.2.patch
deleted file mode 100644
index ca3c430..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iscsi_01_sync_kernel_code_with_release_2.0-869.2.patch
+++ /dev/null
@@ -1,4742 +0,0 @@
-From 89ac09ec66db75fbda1bd77918066fb2ddebac38 Mon Sep 17 00:00:00 2001
-From: Doron Shoham <dorons at voltaire.com>
-Date: Mon, 25 Aug 2008 16:16:26 +0300
-Subject: [PATCH] iscsi_01_sync_kernel_code_with_release_2.0-869.2
-
-Signed-off-by: Doron Shoham <dorons at voltaire.com>
----
- drivers/scsi/iscsi_tcp.c            |  529 ++++++-------
- drivers/scsi/iscsi_tcp.h            |    7 
- drivers/scsi/libiscsi.c             | 1455 +++++++++++++++---------------------
- drivers/scsi/scsi_transport_iscsi.c |  500 +++---------
- include/scsi/libiscsi.h             |  108 +-
- include/scsi/scsi_transport_iscsi.h |   93 +-
- 6 files changed, 1119 insertions(+), 1573 deletions(-)
-
-Index: ofed_kernel/drivers/scsi/iscsi_tcp.c
-===================================================================
---- ofed_kernel.orig/drivers/scsi/iscsi_tcp.c
-+++ ofed_kernel/drivers/scsi/iscsi_tcp.c
-@@ -64,10 +64,6 @@ MODULE_LICENSE("GPL");
- #define BUG_ON(expr)
- #endif
- 
--static struct scsi_transport_template *iscsi_tcp_scsi_transport;
--static struct scsi_host_template iscsi_sht;
--static struct iscsi_transport iscsi_tcp_transport;
--
- static unsigned int iscsi_max_lun = 512;
- module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
- 
-@@ -498,63 +494,58 @@ iscsi_tcp_data_recv_prep(struct iscsi_tc
-  * must be called with session lock
-  */
- static void
--iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
-+iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_tcp_task *tcp_task = task->dd_data;
-+	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 	struct iscsi_r2t_info *r2t;
- 
--	/* nothing to do for mgmt tasks */
--	if (!task->sc)
--		return;
--
--	/* flush task's r2t queues */
--	while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
--		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
-+	/* flush ctask's r2t queues */
-+	while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
-+		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
- 			    sizeof(void*));
--		debug_scsi("iscsi_tcp_cleanup_task pending r2t dropped\n");
-+		debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n");
- 	}
- 
--	r2t = tcp_task->r2t;
-+	r2t = tcp_ctask->r2t;
- 	if (r2t != NULL) {
--		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
-+		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
- 			    sizeof(void*));
--		tcp_task->r2t = NULL;
-+		tcp_ctask->r2t = NULL;
- 	}
- }
- 
- /**
-  * iscsi_data_rsp - SCSI Data-In Response processing
-  * @conn: iscsi connection
-- * @task: scsi command task
-+ * @ctask: scsi command task
-  **/
- static int
--iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
-+iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
- {
- 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
--	struct iscsi_tcp_task *tcp_task = task->dd_data;
-+	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 	struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
- 	struct iscsi_session *session = conn->session;
--	struct scsi_cmnd *sc = task->sc;
-+	struct scsi_cmnd *sc = ctask->sc;
- 	int datasn = be32_to_cpu(rhdr->datasn);
--	unsigned total_in_length = scsi_in(sc)->length;
- 
- 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
- 	if (tcp_conn->in.datalen == 0)
- 		return 0;
- 
--	if (tcp_task->exp_datasn != datasn) {
--		debug_tcp("%s: task->exp_datasn(%d) != rhdr->datasn(%d)\n",
--		          __func__, tcp_task->exp_datasn, datasn);
-+	if (tcp_ctask->exp_datasn != datasn) {
-+		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
-+		          __FUNCTION__, tcp_ctask->exp_datasn, datasn);
- 		return ISCSI_ERR_DATASN;
- 	}
- 
--	tcp_task->exp_datasn++;
-+	tcp_ctask->exp_datasn++;
- 
--	tcp_task->data_offset = be32_to_cpu(rhdr->offset);
--	if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) {
-+	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
-+	if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) {
- 		debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
--		          __func__, tcp_task->data_offset,
--		          tcp_conn->in.datalen, total_in_length);
-+		          __FUNCTION__, tcp_ctask->data_offset,
-+		          tcp_conn->in.datalen, scsi_bufflen(sc));
- 		return ISCSI_ERR_DATA_OFFSET;
- 	}
- 
-@@ -567,8 +558,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, 
- 
- 			if (res_count > 0 &&
- 			    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
--			     res_count <= total_in_length))
--				scsi_in(sc)->resid = res_count;
-+			     res_count <= scsi_bufflen(sc)))
-+				scsi_set_resid(sc, res_count);
- 			else
- 				sc->result = (DID_BAD_TARGET << 16) |
- 					rhdr->cmd_status;
-@@ -582,7 +573,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, 
- /**
-  * iscsi_solicit_data_init - initialize first Data-Out
-  * @conn: iscsi connection
-- * @task: scsi command task
-+ * @ctask: scsi command task
-  * @r2t: R2T info
-  *
-  * Notes:
-@@ -592,7 +583,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, 
-  *	This function is called with connection lock taken.
-  **/
- static void
--iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_task *task,
-+iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
- 			struct iscsi_r2t_info *r2t)
- {
- 	struct iscsi_data *hdr;
-@@ -603,8 +594,8 @@ iscsi_solicit_data_init(struct iscsi_con
- 	hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
- 	r2t->solicit_datasn++;
- 	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
--	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
--	hdr->itt = task->hdr->itt;
-+	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
-+	hdr->itt = ctask->hdr->itt;
- 	hdr->exp_statsn = r2t->exp_statsn;
- 	hdr->offset = cpu_to_be32(r2t->data_offset);
- 	if (r2t->data_length > conn->max_xmit_dlength) {
-@@ -624,14 +615,14 @@ iscsi_solicit_data_init(struct iscsi_con
- /**
-  * iscsi_r2t_rsp - iSCSI R2T Response processing
-  * @conn: iscsi connection
-- * @task: scsi command task
-+ * @ctask: scsi command task
-  **/
- static int
--iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
-+iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
- {
- 	struct iscsi_r2t_info *r2t;
- 	struct iscsi_session *session = conn->session;
--	struct iscsi_tcp_task *tcp_task = task->dd_data;
-+	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- 	struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
- 	int r2tsn = be32_to_cpu(rhdr->r2tsn);
-@@ -644,23 +635,23 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
- 		return ISCSI_ERR_DATALEN;
- 	}
- 
--	if (tcp_task->exp_datasn != r2tsn){
--		debug_tcp("%s: task->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
--		          __func__, tcp_task->exp_datasn, r2tsn);
-+	if (tcp_ctask->exp_datasn != r2tsn){
-+		debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
-+		          __FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
- 		return ISCSI_ERR_R2TSN;
- 	}
- 
- 	/* fill-in new R2T associated with the task */
- 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
- 
--	if (!task->sc || session->state != ISCSI_STATE_LOGGED_IN) {
-+	if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) {
- 		iscsi_conn_printk(KERN_INFO, conn,
- 				  "dropping R2T itt %d in recovery.\n",
--				  task->itt);
-+				  ctask->itt);
- 		return 0;
- 	}
- 
--	rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
-+	rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
- 	BUG_ON(!rc);
- 
- 	r2t->exp_statsn = rhdr->statsn;
-@@ -668,7 +659,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
- 	if (r2t->data_length == 0) {
- 		iscsi_conn_printk(KERN_ERR, conn,
- 				  "invalid R2T with zero data len\n");
--		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
-+		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
- 			    sizeof(void*));
- 		return ISCSI_ERR_DATALEN;
- 	}
-@@ -679,12 +670,12 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
- 			    r2t->data_length, session->max_burst);
- 
- 	r2t->data_offset = be32_to_cpu(rhdr->data_offset);
--	if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) {
-+	if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) {
- 		iscsi_conn_printk(KERN_ERR, conn,
- 				  "invalid R2T with data len %u at offset %u "
- 				  "and total length %d\n", r2t->data_length,
--				  r2t->data_offset, scsi_out(task->sc)->length);
--		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
-+				  r2t->data_offset, scsi_bufflen(ctask->sc));
-+		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
- 			    sizeof(void*));
- 		return ISCSI_ERR_DATALEN;
- 	}
-@@ -692,13 +683,13 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, s
- 	r2t->ttt = rhdr->ttt; /* no flip */
- 	r2t->solicit_datasn = 0;
- 
--	iscsi_solicit_data_init(conn, task, r2t);
-+	iscsi_solicit_data_init(conn, ctask, r2t);
- 
--	tcp_task->exp_datasn = r2tsn + 1;
--	__kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
-+	tcp_ctask->exp_datasn = r2tsn + 1;
-+	__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
- 	conn->r2t_pdus_cnt++;
- 
--	iscsi_requeue_task(task);
-+	iscsi_requeue_ctask(ctask);
- 	return 0;
- }
- 
-@@ -741,8 +732,10 @@ static int
- iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
- {
- 	int rc = 0, opcode, ahslen;
-+	struct iscsi_session *session = conn->session;
- 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
--	struct iscsi_task *task;
-+	struct iscsi_cmd_task *ctask;
-+	uint32_t itt;
- 
- 	/* verify PDU length */
- 	tcp_conn->in.datalen = ntoh24(hdr->dlength);
-@@ -760,7 +753,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
- 
- 	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
- 	/* verify itt (itt encoding: age+cid+itt) */
--	rc = iscsi_verify_itt(conn, hdr->itt);
-+	rc = iscsi_verify_itt(conn, hdr, &itt);
- 	if (rc)
- 		return rc;
- 
-@@ -769,21 +762,15 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
- 
- 	switch(opcode) {
- 	case ISCSI_OP_SCSI_DATA_IN:
-+		ctask = session->cmds[itt];
- 		spin_lock(&conn->session->lock);
--		task = iscsi_itt_to_ctask(conn, hdr->itt);
--		if (!task)
--			rc = ISCSI_ERR_BAD_ITT;
--		else
--			rc = iscsi_data_rsp(conn, task);
--		if (rc) {
--			spin_unlock(&conn->session->lock);
--			break;
--		}
--
-+		rc = iscsi_data_rsp(conn, ctask);
-+		spin_unlock(&conn->session->lock);
-+		if (rc)
-+			return rc;
- 		if (tcp_conn->in.datalen) {
--			struct iscsi_tcp_task *tcp_task = task->dd_data;
-+			struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 			struct hash_desc *rx_hash = NULL;
--			struct scsi_data_buffer *sdb = scsi_in(task->sc);
- 
- 			/*
- 			 * Setup copy of Data-In into the Scsi_Cmnd
-@@ -798,21 +785,17 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
- 
- 			debug_tcp("iscsi_tcp_begin_data_in(%p, offset=%d, "
- 				  "datalen=%d)\n", tcp_conn,
--				  tcp_task->data_offset,
-+				  tcp_ctask->data_offset,
- 				  tcp_conn->in.datalen);
--			rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
--						   sdb->table.sgl,
--						   sdb->table.nents,
--						   tcp_task->data_offset,
--						   tcp_conn->in.datalen,
--						   iscsi_tcp_process_data_in,
--						   rx_hash);
--			spin_unlock(&conn->session->lock);
--			return rc;
-+			return iscsi_segment_seek_sg(&tcp_conn->in.segment,
-+						     scsi_sglist(ctask->sc),
-+						     scsi_sg_count(ctask->sc),
-+						     tcp_ctask->data_offset,
-+						     tcp_conn->in.datalen,
-+						     iscsi_tcp_process_data_in,
-+						     rx_hash);
- 		}
--		rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
--		spin_unlock(&conn->session->lock);
--		break;
-+		/* fall through */
- 	case ISCSI_OP_SCSI_CMD_RSP:
- 		if (tcp_conn->in.datalen) {
- 			iscsi_tcp_data_recv_prep(tcp_conn);
-@@ -821,17 +804,15 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn 
- 		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
- 		break;
- 	case ISCSI_OP_R2T:
--		spin_lock(&conn->session->lock);
--		task = iscsi_itt_to_ctask(conn, hdr->itt);
--		if (!task)
--			rc = ISCSI_ERR_BAD_ITT;
--		else if (ahslen)
-+		ctask = session->cmds[itt];
-+		if (ahslen)
- 			rc = ISCSI_ERR_AHSLEN;
--		else if (task->sc->sc_data_direction == DMA_TO_DEVICE)
--			rc = iscsi_r2t_rsp(conn, task);
--		else
-+		else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
-+			spin_lock(&session->lock);
-+			rc = iscsi_r2t_rsp(conn, ctask);
-+			spin_unlock(&session->lock);
-+		} else
- 			rc = ISCSI_ERR_PROTO;
--		spin_unlock(&conn->session->lock);
- 		break;
- 	case ISCSI_OP_LOGIN_RSP:
- 	case ISCSI_OP_TEXT_RSP:
-@@ -1193,7 +1174,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_con
- {
- 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- 
--	debug_tcp("%s(%p%s)\n", __func__, tcp_conn,
-+	debug_tcp("%s(%p%s)\n", __FUNCTION__, tcp_conn,
- 			conn->hdrdgst_en? ", digest enabled" : "");
- 
- 	/* Clear the data segment - needs to be filled in by the
-@@ -1202,7 +1183,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_con
- 
- 	/* If header digest is enabled, compute the CRC and
- 	 * place the digest into the same buffer. We make
--	 * sure that both iscsi_tcp_task and mtask have
-+	 * sure that both iscsi_tcp_ctask and mtask have
- 	 * sufficient room.
- 	 */
- 	if (conn->hdrdgst_en) {
-@@ -1234,7 +1215,7 @@ iscsi_tcp_send_data_prep(struct iscsi_co
- 	struct hash_desc *tx_hash = NULL;
- 	unsigned int hdr_spec_len;
- 
--	debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __func__,
-+	debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __FUNCTION__,
- 			tcp_conn, offset, len,
- 			conn->datadgst_en? ", digest enabled" : "");
- 
-@@ -1259,7 +1240,7 @@ iscsi_tcp_send_linear_data_prepare(struc
- 	struct hash_desc *tx_hash = NULL;
- 	unsigned int hdr_spec_len;
- 
--	debug_tcp("%s(%p, datalen=%d%s)\n", __func__, tcp_conn, len,
-+	debug_tcp("%s(%p, datalen=%d%s)\n", __FUNCTION__, tcp_conn, len,
- 		  conn->datadgst_en? ", digest enabled" : "");
- 
- 	/* Make sure the datalen matches what the caller
-@@ -1277,7 +1258,7 @@ iscsi_tcp_send_linear_data_prepare(struc
- /**
-  * iscsi_solicit_data_cont - initialize next Data-Out
-  * @conn: iscsi connection
-- * @task: scsi command task
-+ * @ctask: scsi command task
-  * @r2t: R2T info
-  * @left: bytes left to transfer
-  *
-@@ -1288,7 +1269,7 @@ iscsi_tcp_send_linear_data_prepare(struc
-  *	Called under connection lock.
-  **/
- static int
--iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_task *task,
-+iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
- 			struct iscsi_r2t_info *r2t)
- {
- 	struct iscsi_data *hdr;
-@@ -1305,8 +1286,8 @@ iscsi_solicit_data_cont(struct iscsi_con
- 	hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
- 	r2t->solicit_datasn++;
- 	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
--	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
--	hdr->itt = task->hdr->itt;
-+	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
-+	hdr->itt = ctask->hdr->itt;
- 	hdr->exp_statsn = r2t->exp_statsn;
- 	new_offset = r2t->data_offset + r2t->sent;
- 	hdr->offset = cpu_to_be32(new_offset);
-@@ -1324,76 +1305,87 @@ iscsi_solicit_data_cont(struct iscsi_con
- }
- 
- /**
-- * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
-+ * iscsi_tcp_ctask - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
-  * @conn: iscsi connection
-- * @task: scsi command task
-+ * @ctask: scsi command task
-  * @sc: scsi command
-  **/
- static int
--iscsi_tcp_task_init(struct iscsi_task *task)
-+iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_tcp_task *tcp_task = task->dd_data;
--	struct iscsi_conn *conn = task->conn;
--	struct scsi_cmnd *sc = task->sc;
-+	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-+	struct iscsi_conn *conn = ctask->conn;
-+	struct scsi_cmnd *sc = ctask->sc;
- 	int err;
- 
--	if (!sc) {
--		/*
--		 * mgmt tasks do not have a scatterlist since they come
--		 * in from the iscsi interface.
--		 */
--		debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id,
--			   task->itt);
--
--		/* Prepare PDU, optionally w/ immediate data */
--		iscsi_tcp_send_hdr_prep(conn, task->hdr, sizeof(*task->hdr));
--
--		/* If we have immediate data, attach a payload */
--		if (task->data_count)
--			iscsi_tcp_send_linear_data_prepare(conn, task->data,
--							   task->data_count);
--		return 0;
--	}
--
--	BUG_ON(__kfifo_len(tcp_task->r2tqueue));
--	tcp_task->sent = 0;
--	tcp_task->exp_datasn = 0;
-+	BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
-+	tcp_ctask->sent = 0;
-+	tcp_ctask->exp_datasn = 0;
- 
- 	/* Prepare PDU, optionally w/ immediate data */
--	debug_scsi("task deq [cid %d itt 0x%x imm %d unsol %d]\n",
--		    conn->id, task->itt, task->imm_count,
--		    task->unsol_count);
--	iscsi_tcp_send_hdr_prep(conn, task->hdr, task->hdr_len);
-+	debug_scsi("ctask deq [cid %d itt 0x%x imm %d unsol %d]\n",
-+		    conn->id, ctask->itt, ctask->imm_count,
-+		    ctask->unsol_count);
-+	iscsi_tcp_send_hdr_prep(conn, ctask->hdr, ctask->hdr_len);
- 
--	if (!task->imm_count)
-+	if (!ctask->imm_count)
- 		return 0;
- 
- 	/* If we have immediate data, attach a payload */
--	err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl,
--				       scsi_out(sc)->table.nents,
--				       0, task->imm_count);
-+	err = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), scsi_sg_count(sc),
-+				       0, ctask->imm_count);
- 	if (err)
- 		return err;
--	tcp_task->sent += task->imm_count;
--	task->imm_count = 0;
-+	tcp_ctask->sent += ctask->imm_count;
-+	ctask->imm_count = 0;
-+	return 0;
-+}
-+
-+/**
-+ * iscsi_tcp_mtask_xmit - xmit management(immediate) task
-+ * @conn: iscsi connection
-+ * @mtask: task management task
-+ *
-+ * Notes:
-+ *	The function can return -EAGAIN in which case caller must
-+ *	call it again later, or recover. '0' return code means successful
-+ *	xmit.
-+ **/
-+static int
-+iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
-+{
-+	int rc;
-+
-+	/* Flush any pending data first. */
-+	rc = iscsi_tcp_flush(conn);
-+	if (rc < 0)
-+		return rc;
-+
-+	if (mtask->hdr->itt == RESERVED_ITT) {
-+		struct iscsi_session *session = conn->session;
-+
-+		spin_lock_bh(&session->lock);
-+		iscsi_free_mgmt_task(conn, mtask);
-+		spin_unlock_bh(&session->lock);
-+	}
-+
- 	return 0;
- }
- 
- /*
-- * iscsi_tcp_task_xmit - xmit normal PDU task
-- * @task: iscsi command task
-+ * iscsi_tcp_ctask_xmit - xmit normal PDU task
-+ * @conn: iscsi connection
-+ * @ctask: iscsi command task
-  *
-  * We're expected to return 0 when everything was transmitted succesfully,
-  * -EAGAIN if there's still data in the queue, or != 0 for any other kind
-  * of error.
-  */
- static int
--iscsi_tcp_task_xmit(struct iscsi_task *task)
-+iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_conn *conn = task->conn;
--	struct iscsi_tcp_task *tcp_task = task->dd_data;
--	struct scsi_cmnd *sc = task->sc;
--	struct scsi_data_buffer *sdb;
-+	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-+	struct scsi_cmnd *sc = ctask->sc;
- 	int rc = 0;
- 
- flush:
-@@ -1402,39 +1394,32 @@ flush:
- 	if (rc < 0)
- 		return rc;
- 
--	/* mgmt command */
--	if (!sc) {
--		if (task->hdr->itt == RESERVED_ITT)
--			iscsi_put_task(task);
--		return 0;
--	}
--
- 	/* Are we done already? */
- 	if (sc->sc_data_direction != DMA_TO_DEVICE)
- 		return 0;
- 
--	sdb = scsi_out(sc);
--	if (task->unsol_count != 0) {
--		struct iscsi_data *hdr = &tcp_task->unsol_dtask.hdr;
-+	if (ctask->unsol_count != 0) {
-+		struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr;
- 
- 		/* Prepare a header for the unsolicited PDU.
- 		 * The amount of data we want to send will be
--		 * in task->data_count.
-+		 * in ctask->data_count.
- 		 * FIXME: return the data count instead.
- 		 */
--		iscsi_prep_unsolicit_data_pdu(task, hdr);
-+		iscsi_prep_unsolicit_data_pdu(ctask, hdr);
- 
- 		debug_tcp("unsol dout [itt 0x%x doff %d dlen %d]\n",
--				task->itt, tcp_task->sent, task->data_count);
-+				ctask->itt, tcp_ctask->sent, ctask->data_count);
- 
- 		iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr));
--		rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
--					      sdb->table.nents, tcp_task->sent,
--					      task->data_count);
-+		rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
-+					      scsi_sg_count(sc),
-+					      tcp_ctask->sent,
-+					      ctask->data_count);
- 		if (rc)
- 			goto fail;
--		tcp_task->sent += task->data_count;
--		task->unsol_count -= task->data_count;
-+		tcp_ctask->sent += ctask->data_count;
-+		ctask->unsol_count -= ctask->data_count;
- 		goto flush;
- 	} else {
- 		struct iscsi_session *session = conn->session;
-@@ -1443,22 +1428,22 @@ flush:
- 		/* All unsolicited PDUs sent. Check for solicited PDUs.
- 		 */
- 		spin_lock_bh(&session->lock);
--		r2t = tcp_task->r2t;
-+		r2t = tcp_ctask->r2t;
- 		if (r2t != NULL) {
- 			/* Continue with this R2T? */
--			if (!iscsi_solicit_data_cont(conn, task, r2t)) {
-+			if (!iscsi_solicit_data_cont(conn, ctask, r2t)) {
- 				debug_scsi("  done with r2t %p\n", r2t);
- 
--				__kfifo_put(tcp_task->r2tpool.queue,
-+				__kfifo_put(tcp_ctask->r2tpool.queue,
- 					    (void*)&r2t, sizeof(void*));
--				tcp_task->r2t = r2t = NULL;
-+				tcp_ctask->r2t = r2t = NULL;
- 			}
- 		}
- 
- 		if (r2t == NULL) {
--			__kfifo_get(tcp_task->r2tqueue, (void*)&tcp_task->r2t,
-+			__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
- 				    sizeof(void*));
--			r2t = tcp_task->r2t;
-+			r2t = tcp_ctask->r2t;
- 		}
- 		spin_unlock_bh(&session->lock);
- 
-@@ -1469,19 +1454,19 @@ flush:
- 		}
- 
- 		debug_scsi("sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n",
--			r2t, r2t->solicit_datasn - 1, task->itt,
-+			r2t, r2t->solicit_datasn - 1, ctask->itt,
- 			r2t->data_offset + r2t->sent, r2t->data_count);
- 
- 		iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr,
- 					sizeof(struct iscsi_hdr));
- 
--		rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
--					      sdb->table.nents,
-+		rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
-+					      scsi_sg_count(sc),
- 					      r2t->data_offset + r2t->sent,
- 					      r2t->data_count);
- 		if (rc)
- 			goto fail;
--		tcp_task->sent += r2t->data_count;
-+		tcp_ctask->sent += r2t->data_count;
- 		r2t->sent += r2t->data_count;
- 		goto flush;
- 	}
-@@ -1498,7 +1483,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
- 	struct iscsi_cls_conn *cls_conn;
- 	struct iscsi_tcp_conn *tcp_conn;
- 
--	cls_conn = iscsi_conn_setup(cls_session, sizeof(*tcp_conn), conn_idx);
-+	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
- 	if (!cls_conn)
- 		return NULL;
- 	conn = cls_conn->dd_data;
-@@ -1508,14 +1493,18 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
- 	 */
- 	conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
- 
--	tcp_conn = conn->dd_data;
-+	tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL);
-+	if (!tcp_conn)
-+		goto tcp_conn_alloc_fail;
-+
-+	conn->dd_data = tcp_conn;
- 	tcp_conn->iscsi_conn = conn;
- 
- 	tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
- 						  CRYPTO_ALG_ASYNC);
- 	tcp_conn->tx_hash.flags = 0;
- 	if (IS_ERR(tcp_conn->tx_hash.tfm))
--		goto free_conn;
-+		goto free_tcp_conn;
- 
- 	tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
- 						  CRYPTO_ALG_ASYNC);
-@@ -1527,12 +1516,14 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
- 
- free_tx_tfm:
- 	crypto_free_hash(tcp_conn->tx_hash.tfm);
--free_conn:
-+free_tcp_conn:
- 	iscsi_conn_printk(KERN_ERR, conn,
- 			  "Could not create connection due to crc32c "
- 			  "loading error. Make sure the crc32c "
- 			  "module is built as a module or into the "
- 			  "kernel\n");
-+	kfree(tcp_conn);
-+tcp_conn_alloc_fail:
- 	iscsi_conn_teardown(cls_conn);
- 	return NULL;
- }
-@@ -1553,6 +1544,7 @@ iscsi_tcp_release_conn(struct iscsi_conn
- 
- 	spin_lock_bh(&session->lock);
- 	tcp_conn->sock = NULL;
-+	conn->recv_lock = NULL;
- 	spin_unlock_bh(&session->lock);
- 	sockfd_put(sock);
- }
-@@ -1564,32 +1556,20 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_
- 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- 
- 	iscsi_tcp_release_conn(conn);
-+	iscsi_conn_teardown(cls_conn);
- 
- 	if (tcp_conn->tx_hash.tfm)
- 		crypto_free_hash(tcp_conn->tx_hash.tfm);
- 	if (tcp_conn->rx_hash.tfm)
- 		crypto_free_hash(tcp_conn->rx_hash.tfm);
- 
--	iscsi_conn_teardown(cls_conn);
-+	kfree(tcp_conn);
- }
- 
- static void
- iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
- {
- 	struct iscsi_conn *conn = cls_conn->dd_data;
--	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
--
--	/* userspace may have goofed up and not bound us */
--	if (!tcp_conn->sock)
--		return;
--	/*
--	 * Make sure our recv side is stopped.
--	 * Older tools called conn stop before ep_disconnect
--	 * so IO could still be coming in.
--	 */
--	write_lock_bh(&tcp_conn->sock->sk->sk_callback_lock);
--	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
--	write_unlock_bh(&tcp_conn->sock->sk->sk_callback_lock);
- 
- 	iscsi_conn_stop(cls_conn, flag);
- 	iscsi_tcp_release_conn(conn);
-@@ -1640,8 +1620,6 @@ iscsi_tcp_conn_bind(struct iscsi_cls_ses
- 		    struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
- 		    int is_leading)
- {
--	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
--	struct iscsi_host *ihost = shost_priv(shost);
- 	struct iscsi_conn *conn = cls_conn->dd_data;
- 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- 	struct sock *sk;
-@@ -1665,8 +1643,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_ses
- 	if (err)
- 		goto free_socket;
- 
--	err = iscsi_tcp_get_addr(conn, sock, ihost->local_address,
--				&ihost->local_port, kernel_getsockname);
-+	err = iscsi_tcp_get_addr(conn, sock, conn->local_address,
-+				&conn->local_port, kernel_getsockname);
- 	if (err)
- 		goto free_socket;
- 
-@@ -1683,6 +1661,13 @@ iscsi_tcp_conn_bind(struct iscsi_cls_ses
- 	sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
- 	sk->sk_allocation = GFP_ATOMIC;
- 
-+	/* FIXME: disable Nagle's algorithm */
-+
-+	/*
-+	 * Intercept TCP callbacks for sendfile like receive
-+	 * processing.
-+	 */
-+	conn->recv_lock = &sk->sk_callback_lock;
- 	iscsi_conn_set_callbacks(conn);
- 	tcp_conn->sendpage = tcp_conn->sock->ops->sendpage;
- 	/*
-@@ -1696,6 +1681,21 @@ free_socket:
- 	return err;
- }
- 
-+/* called with host lock */
-+static void
-+iscsi_tcp_mtask_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
-+{
-+	debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
-+
-+	/* Prepare PDU, optionally w/ immediate data */
-+	iscsi_tcp_send_hdr_prep(conn, mtask->hdr, sizeof(*mtask->hdr));
-+
-+	/* If we have immediate data, attach a payload */
-+	if (mtask->data_count)
-+		iscsi_tcp_send_linear_data_prepare(conn, mtask->data,
-+						   mtask->data_count);
-+}
-+
- static int
- iscsi_r2tpool_alloc(struct iscsi_session *session)
- {
-@@ -1706,8 +1706,8 @@ iscsi_r2tpool_alloc(struct iscsi_session
- 	 * initialize per-task: R2T pool and xmit queue
- 	 */
- 	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
--	        struct iscsi_task *task = session->cmds[cmd_i];
--		struct iscsi_tcp_task *tcp_task = task->dd_data;
-+	        struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
-+		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 
- 		/*
- 		 * pre-allocated x4 as much r2ts to handle race when
-@@ -1716,16 +1716,16 @@ iscsi_r2tpool_alloc(struct iscsi_session
- 		 */
- 
- 		/* R2T pool */
--		if (iscsi_pool_init(&tcp_task->r2tpool, session->max_r2t * 4, NULL,
-+		if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, NULL,
- 				    sizeof(struct iscsi_r2t_info))) {
- 			goto r2t_alloc_fail;
- 		}
- 
- 		/* R2T xmit queue */
--		tcp_task->r2tqueue = kfifo_alloc(
-+		tcp_ctask->r2tqueue = kfifo_alloc(
- 		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
--		if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) {
--			iscsi_pool_free(&tcp_task->r2tpool);
-+		if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
-+			iscsi_pool_free(&tcp_ctask->r2tpool);
- 			goto r2t_alloc_fail;
- 		}
- 	}
-@@ -1734,11 +1734,11 @@ iscsi_r2tpool_alloc(struct iscsi_session
- 
- r2t_alloc_fail:
- 	for (i = 0; i < cmd_i; i++) {
--		struct iscsi_task *task = session->cmds[i];
--		struct iscsi_tcp_task *tcp_task = task->dd_data;
-+		struct iscsi_cmd_task *ctask = session->cmds[i];
-+		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 
--		kfifo_free(tcp_task->r2tqueue);
--		iscsi_pool_free(&tcp_task->r2tpool);
-+		kfifo_free(tcp_ctask->r2tqueue);
-+		iscsi_pool_free(&tcp_ctask->r2tpool);
- 	}
- 	return -ENOMEM;
- }
-@@ -1749,11 +1749,11 @@ iscsi_r2tpool_free(struct iscsi_session 
- 	int i;
- 
- 	for (i = 0; i < session->cmds_max; i++) {
--		struct iscsi_task *task = session->cmds[i];
--		struct iscsi_tcp_task *tcp_task = task->dd_data;
-+		struct iscsi_cmd_task *ctask = session->cmds[i];
-+		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- 
--		kfifo_free(tcp_task->r2tqueue);
--		iscsi_pool_free(&tcp_task->r2tpool);
-+		kfifo_free(tcp_ctask->r2tqueue);
-+		iscsi_pool_free(&tcp_ctask->r2tpool);
- 	}
- }
- 
-@@ -1818,6 +1818,29 @@ iscsi_tcp_conn_get_param(struct iscsi_cl
- 	return len;
- }
- 
-+static int
-+iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
-+			 char *buf)
-+{
-+        struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
-+	int len;
-+
-+	switch (param) {
-+	case ISCSI_HOST_PARAM_IPADDRESS:
-+		spin_lock_bh(&session->lock);
-+		if (!session->leadconn)
-+			len = -ENODEV;
-+		else
-+			len = sprintf(buf, "%s\n",
-+				     session->leadconn->local_address);
-+		spin_unlock_bh(&session->lock);
-+		break;
-+	default:
-+		return iscsi_host_get_param(shost, param, buf);
-+	}
-+	return len;
-+}
-+
- static void
- iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
- {
-@@ -1843,70 +1866,54 @@ iscsi_conn_get_stats(struct iscsi_cls_co
- }
- 
- static struct iscsi_cls_session *
--iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
--			 uint16_t qdepth, uint32_t initial_cmdsn,
--			 uint32_t *hostno)
-+iscsi_tcp_session_create(struct iscsi_transport *iscsit,
-+			 struct scsi_transport_template *scsit,
-+			 uint16_t cmds_max, uint16_t qdepth,
-+			 uint32_t initial_cmdsn, uint32_t *hostno)
- {
- 	struct iscsi_cls_session *cls_session;
- 	struct iscsi_session *session;
--	struct Scsi_Host *shost;
-+	uint32_t hn;
- 	int cmd_i;
- 
--	if (ep) {
--		printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep);
--		return NULL;
--	}
--
--	shost = iscsi_host_alloc(&iscsi_sht, 0, qdepth);
--	if (!shost)
--		return NULL;
--	shost->transportt = iscsi_tcp_scsi_transport;
--	shost->max_lun = iscsi_max_lun;
--	shost->max_id = 0;
--	shost->max_channel = 0;
--	shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE;
--
--	if (iscsi_host_add(shost, NULL))
--		goto free_host;
--	*hostno = shost->host_no;
--
--	cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max,
--					  sizeof(struct iscsi_tcp_task),
--					  initial_cmdsn, 0);
-+	cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
-+					 sizeof(struct iscsi_tcp_cmd_task),
-+					 sizeof(struct iscsi_tcp_mgmt_task),
-+					 initial_cmdsn, &hn);
- 	if (!cls_session)
--		goto remove_host;
--	session = cls_session->dd_data;
-+		return NULL;
-+	*hostno = hn;
- 
--	shost->can_queue = session->scsi_cmds_max;
-+	session = class_to_transport_session(cls_session);
- 	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
--		struct iscsi_task *task = session->cmds[cmd_i];
--		struct iscsi_tcp_task *tcp_task = task->dd_data;
-+		struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
-+		struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-+
-+		ctask->hdr = &tcp_ctask->hdr.cmd_hdr;
-+		ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE;
-+	}
-+
-+	for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
-+		struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
-+		struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
- 
--		task->hdr = &tcp_task->hdr.cmd_hdr;
--		task->hdr_max = sizeof(tcp_task->hdr) - ISCSI_DIGEST_SIZE;
-+		mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr;
- 	}
- 
--	if (iscsi_r2tpool_alloc(session))
--		goto remove_session;
-+	if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session)))
-+		goto r2tpool_alloc_fail;
-+
- 	return cls_session;
- 
--remove_session:
-+r2tpool_alloc_fail:
- 	iscsi_session_teardown(cls_session);
--remove_host:
--	iscsi_host_remove(shost);
--free_host:
--	iscsi_host_free(shost);
- 	return NULL;
- }
- 
- static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
- {
--	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
--
--	iscsi_r2tpool_free(cls_session->dd_data);
--
--	iscsi_host_remove(shost);
--	iscsi_host_free(shost);
-+	iscsi_r2tpool_free(class_to_transport_session(cls_session));
-+	iscsi_session_teardown(cls_session);
- }
- 
- static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
-@@ -1961,11 +1968,14 @@ static struct iscsi_transport iscsi_tcp_
- 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
- 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
- 				  ISCSI_LU_RESET_TMO |
--				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
--				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
-+				  ISCSI_PING_TMO | ISCSI_RECV_TMO,
- 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
- 				  ISCSI_HOST_INITIATOR_NAME |
- 				  ISCSI_HOST_NETDEV_NAME,
-+	.host_template		= &iscsi_sht,
-+	.conndata_size		= sizeof(struct iscsi_conn),
-+	.max_conn		= 1,
-+	.max_cmd_len		= 16,
- 	/* session management */
- 	.create_session		= iscsi_tcp_session_create,
- 	.destroy_session	= iscsi_tcp_session_destroy,
-@@ -1979,14 +1989,16 @@ static struct iscsi_transport iscsi_tcp_
- 	.start_conn		= iscsi_conn_start,
- 	.stop_conn		= iscsi_tcp_conn_stop,
- 	/* iscsi host params */
--	.get_host_param		= iscsi_host_get_param,
-+	.get_host_param		= iscsi_tcp_host_get_param,
- 	.set_host_param		= iscsi_host_set_param,
- 	/* IO */
- 	.send_pdu		= iscsi_conn_send_pdu,
- 	.get_stats		= iscsi_conn_get_stats,
--	.init_task		= iscsi_tcp_task_init,
--	.xmit_task		= iscsi_tcp_task_xmit,
--	.cleanup_task		= iscsi_tcp_cleanup_task,
-+	.init_cmd_task		= iscsi_tcp_ctask_init,
-+	.init_mgmt_task		= iscsi_tcp_mtask_init,
-+	.xmit_cmd_task		= iscsi_tcp_ctask_xmit,
-+	.xmit_mgmt_task		= iscsi_tcp_mtask_xmit,
-+	.cleanup_cmd_task	= iscsi_tcp_cleanup_ctask,
- 	/* recovery */
- 	.session_recovery_timedout = iscsi_session_recovery_timedout,
- };
-@@ -1999,10 +2011,9 @@ iscsi_tcp_init(void)
- 		       iscsi_max_lun);
- 		return -EINVAL;
- 	}
-+	iscsi_tcp_transport.max_lun = iscsi_max_lun;
- 
--	iscsi_tcp_scsi_transport = iscsi_register_transport(
--							&iscsi_tcp_transport);
--	if (!iscsi_tcp_scsi_transport)
-+	if (!iscsi_register_transport(&iscsi_tcp_transport))
- 		return -ENODEV;
- 
- 	return 0;
-Index: ofed_kernel/drivers/scsi/iscsi_tcp.h
-===================================================================
---- ofed_kernel.orig/drivers/scsi/iscsi_tcp.h
-+++ ofed_kernel/drivers/scsi/iscsi_tcp.h
-@@ -103,6 +103,11 @@ struct iscsi_data_task {
- 	char			hdrext[ISCSI_DIGEST_SIZE];/* Header-Digest */
- };
- 
-+struct iscsi_tcp_mgmt_task {
-+	struct iscsi_hdr	hdr;
-+	char			hdrext[ISCSI_DIGEST_SIZE]; /* Header-Digest */
-+};
-+
- struct iscsi_r2t_info {
- 	__be32			ttt;		/* copied from R2T */
- 	__be32			exp_statsn;	/* copied from R2T */
-@@ -114,7 +119,7 @@ struct iscsi_r2t_info {
- 	struct iscsi_data_task	dtask;		/* Data-Out header buf */
- };
- 
--struct iscsi_tcp_task {
-+struct iscsi_tcp_cmd_task {
- 	struct iscsi_hdr_buff {
- 		struct iscsi_cmd	cmd_hdr;
- 		char			hdrextbuf[ISCSI_MAX_AHS_SIZE +
-Index: ofed_kernel/drivers/scsi/libiscsi.c
-===================================================================
---- ofed_kernel.orig/drivers/scsi/libiscsi.c
-+++ ofed_kernel/drivers/scsi/libiscsi.c
-@@ -38,6 +38,14 @@
- #include <scsi/scsi_transport_iscsi.h>
- #include <scsi/libiscsi.h>
- 
-+struct iscsi_session *
-+class_to_transport_session(struct iscsi_cls_session *cls_session)
-+{
-+	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-+	return iscsi_hostdata(shost->hostdata);
-+}
-+EXPORT_SYMBOL_GPL(class_to_transport_session);
-+
- /* Serial Number Arithmetic, 32 bits, less than, RFC1982 */
- #define SNA32_CHECK 2147483648UL
- 
-@@ -79,170 +87,91 @@ iscsi_update_cmdsn(struct iscsi_session 
- 		 * xmit thread
- 		 */
- 		if (!list_empty(&session->leadconn->xmitqueue) ||
--		    !list_empty(&session->leadconn->mgmtqueue)) {
--			if (!(session->tt->caps & CAP_DATA_PATH_OFFLOAD))
--				scsi_queue_work(session->host,
--						&session->leadconn->xmitwork);
--		}
-+		    !list_empty(&session->leadconn->mgmtqueue))
-+			scsi_queue_work(session->host,
-+					&session->leadconn->xmitwork);
- 	}
- }
- EXPORT_SYMBOL_GPL(iscsi_update_cmdsn);
- 
--void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *task,
-+void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask,
- 				   struct iscsi_data *hdr)
- {
--	struct iscsi_conn *conn = task->conn;
-+	struct iscsi_conn *conn = ctask->conn;
- 
- 	memset(hdr, 0, sizeof(struct iscsi_data));
- 	hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
--	hdr->datasn = cpu_to_be32(task->unsol_datasn);
--	task->unsol_datasn++;
-+	hdr->datasn = cpu_to_be32(ctask->unsol_datasn);
-+	ctask->unsol_datasn++;
- 	hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
--	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
-+	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
- 
--	hdr->itt = task->hdr->itt;
-+	hdr->itt = ctask->hdr->itt;
- 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
--	hdr->offset = cpu_to_be32(task->unsol_offset);
-+	hdr->offset = cpu_to_be32(ctask->unsol_offset);
- 
--	if (task->unsol_count > conn->max_xmit_dlength) {
-+	if (ctask->unsol_count > conn->max_xmit_dlength) {
- 		hton24(hdr->dlength, conn->max_xmit_dlength);
--		task->data_count = conn->max_xmit_dlength;
--		task->unsol_offset += task->data_count;
-+		ctask->data_count = conn->max_xmit_dlength;
-+		ctask->unsol_offset += ctask->data_count;
- 		hdr->flags = 0;
- 	} else {
--		hton24(hdr->dlength, task->unsol_count);
--		task->data_count = task->unsol_count;
-+		hton24(hdr->dlength, ctask->unsol_count);
-+		ctask->data_count = ctask->unsol_count;
- 		hdr->flags = ISCSI_FLAG_CMD_FINAL;
- 	}
- }
- EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu);
- 
--static int iscsi_add_hdr(struct iscsi_task *task, unsigned len)
-+static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len)
- {
--	unsigned exp_len = task->hdr_len + len;
-+	unsigned exp_len = ctask->hdr_len + len;
- 
--	if (exp_len > task->hdr_max) {
-+	if (exp_len > ctask->hdr_max) {
- 		WARN_ON(1);
- 		return -EINVAL;
- 	}
- 
- 	WARN_ON(len & (ISCSI_PAD_LEN - 1)); /* caller must pad the AHS */
--	task->hdr_len = exp_len;
--	return 0;
--}
--
--/*
-- * make an extended cdb AHS
-- */
--static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
--{
--	struct scsi_cmnd *cmd = task->sc;
--	unsigned rlen, pad_len;
--	unsigned short ahslength;
--	struct iscsi_ecdb_ahdr *ecdb_ahdr;
--	int rc;
--
--	ecdb_ahdr = iscsi_next_hdr(task);
--	rlen = cmd->cmd_len - ISCSI_CDB_SIZE;
--
--	BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb));
--	ahslength = rlen + sizeof(ecdb_ahdr->reserved);
--
--	pad_len = iscsi_padding(rlen);
--
--	rc = iscsi_add_hdr(task, sizeof(ecdb_ahdr->ahslength) +
--	                   sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len);
--	if (rc)
--		return rc;
--
--	if (pad_len)
--		memset(&ecdb_ahdr->ecdb[rlen], 0, pad_len);
--
--	ecdb_ahdr->ahslength = cpu_to_be16(ahslength);
--	ecdb_ahdr->ahstype = ISCSI_AHSTYPE_CDB;
--	ecdb_ahdr->reserved = 0;
--	memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen);
--
--	debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d "
--		   "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n",
--		   cmd->cmd_len, rlen, pad_len, ahslength, task->hdr_len);
--
--	return 0;
--}
--
--static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
--{
--	struct scsi_cmnd *sc = task->sc;
--	struct iscsi_rlength_ahdr *rlen_ahdr;
--	int rc;
--
--	rlen_ahdr = iscsi_next_hdr(task);
--	rc = iscsi_add_hdr(task, sizeof(*rlen_ahdr));
--	if (rc)
--		return rc;
--
--	rlen_ahdr->ahslength =
--		cpu_to_be16(sizeof(rlen_ahdr->read_length) +
--						  sizeof(rlen_ahdr->reserved));
--	rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
--	rlen_ahdr->reserved = 0;
--	rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
--
--	debug_scsi("bidi-in rlen_ahdr->read_length(%d) "
--		   "rlen_ahdr->ahslength(%d)\n",
--		   be32_to_cpu(rlen_ahdr->read_length),
--		   be16_to_cpu(rlen_ahdr->ahslength));
-+	ctask->hdr_len = exp_len;
- 	return 0;
- }
- 
- /**
-  * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
-- * @task: iscsi task
-+ * @ctask: iscsi cmd task
-  *
-  * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set
-  * fields like dlength or final based on how much data it sends
-  */
--static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
-+static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_conn *conn = task->conn;
-+	struct iscsi_conn *conn = ctask->conn;
- 	struct iscsi_session *session = conn->session;
--	struct iscsi_cmd *hdr = task->hdr;
--	struct scsi_cmnd *sc = task->sc;
--	unsigned hdrlength, cmd_len;
-+	struct iscsi_cmd *hdr = ctask->hdr;
-+	struct scsi_cmnd *sc = ctask->sc;
-+	unsigned hdrlength;
- 	int rc;
- 
--	task->hdr_len = 0;
--	rc = iscsi_add_hdr(task, sizeof(*hdr));
-+	ctask->hdr_len = 0;
-+	rc = iscsi_add_hdr(ctask, sizeof(*hdr));
- 	if (rc)
- 		return rc;
- 	hdr->opcode = ISCSI_OP_SCSI_CMD;
- 	hdr->flags = ISCSI_ATTR_SIMPLE;
- 	int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
--	hdr->itt = build_itt(task->itt, session->age);
-+	hdr->itt = build_itt(ctask->itt, session->age);
-+	hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
- 	hdr->cmdsn = cpu_to_be32(session->cmdsn);
- 	session->cmdsn++;
- 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
--	cmd_len = sc->cmd_len;
--	if (cmd_len < ISCSI_CDB_SIZE)
--		memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len);
--	else if (cmd_len > ISCSI_CDB_SIZE) {
--		rc = iscsi_prep_ecdb_ahs(task);
--		if (rc)
--			return rc;
--		cmd_len = ISCSI_CDB_SIZE;
--	}
--	memcpy(hdr->cdb, sc->cmnd, cmd_len);
-+	memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
-+	if (sc->cmd_len < MAX_COMMAND_SIZE)
-+		memset(&hdr->cdb[sc->cmd_len], 0,
-+			MAX_COMMAND_SIZE - sc->cmd_len);
- 
--	task->imm_count = 0;
--	if (scsi_bidi_cmnd(sc)) {
--		hdr->flags |= ISCSI_FLAG_CMD_READ;
--		rc = iscsi_prep_bidi_ahs(task);
--		if (rc)
--			return rc;
--	}
-+	ctask->imm_count = 0;
- 	if (sc->sc_data_direction == DMA_TO_DEVICE) {
--		unsigned out_len = scsi_out(sc)->length;
--		hdr->data_length = cpu_to_be32(out_len);
- 		hdr->flags |= ISCSI_FLAG_CMD_WRITE;
- 		/*
- 		 * Write counters:
-@@ -258,41 +187,40 @@ static int iscsi_prep_scsi_cmd_pdu(struc
- 		 *
- 		 *      pad_count       bytes to be sent as zero-padding
- 		 */
--		task->unsol_count = 0;
--		task->unsol_offset = 0;
--		task->unsol_datasn = 0;
-+		ctask->unsol_count = 0;
-+		ctask->unsol_offset = 0;
-+		ctask->unsol_datasn = 0;
- 
- 		if (session->imm_data_en) {
--			if (out_len >= session->first_burst)
--				task->imm_count = min(session->first_burst,
-+			if (scsi_bufflen(sc) >= session->first_burst)
-+				ctask->imm_count = min(session->first_burst,
- 							conn->max_xmit_dlength);
- 			else
--				task->imm_count = min(out_len,
-+				ctask->imm_count = min(scsi_bufflen(sc),
- 							conn->max_xmit_dlength);
--			hton24(hdr->dlength, task->imm_count);
-+			hton24(hdr->dlength, ctask->imm_count);
- 		} else
- 			zero_data(hdr->dlength);
- 
- 		if (!session->initial_r2t_en) {
--			task->unsol_count = min(session->first_burst, out_len)
--							     - task->imm_count;
--			task->unsol_offset = task->imm_count;
-+			ctask->unsol_count = min((session->first_burst),
-+				(scsi_bufflen(sc))) - ctask->imm_count;
-+			ctask->unsol_offset = ctask->imm_count;
- 		}
- 
--		if (!task->unsol_count)
-+		if (!ctask->unsol_count)
- 			/* No unsolicit Data-Out's */
- 			hdr->flags |= ISCSI_FLAG_CMD_FINAL;
- 	} else {
- 		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
- 		zero_data(hdr->dlength);
--		hdr->data_length = cpu_to_be32(scsi_in(sc)->length);
- 
- 		if (sc->sc_data_direction == DMA_FROM_DEVICE)
- 			hdr->flags |= ISCSI_FLAG_CMD_READ;
- 	}
- 
- 	/* calculate size of additional header segments (AHSs) */
--	hdrlength = task->hdr_len - sizeof(*hdr);
-+	hdrlength = ctask->hdr_len - sizeof(*hdr);
- 
- 	WARN_ON(hdrlength & (ISCSI_PAD_LEN-1));
- 	hdrlength /= ISCSI_PAD_LEN;
-@@ -300,180 +228,110 @@ static int iscsi_prep_scsi_cmd_pdu(struc
- 	WARN_ON(hdrlength >= 256);
- 	hdr->hlength = hdrlength & 0xFF;
- 
--	if (conn->session->tt->init_task &&
--	    conn->session->tt->init_task(task))
--		return -EIO;
--
--	task->state = ISCSI_TASK_RUNNING;
--	list_move_tail(&task->running, &conn->run_list);
-+	if (conn->session->tt->init_cmd_task(conn->ctask))
-+		return EIO;
- 
- 	conn->scsicmd_pdus_cnt++;
- 	debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d "
--		   "bidi_len %d cmdsn %d win %d]\n", scsi_bidi_cmnd(sc) ?
--		   "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ?
--		   "write" : "read", conn->id, sc, sc->cmnd[0], task->itt,
--		   scsi_bufflen(sc),
--		   scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
--		   session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
-+		"cmdsn %d win %d]\n",
-+		sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
-+		conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc),
-+		session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
- 	return 0;
- }
- 
- /**
-- * iscsi_complete_command - finish a task
-- * @task: iscsi cmd task
-+ * iscsi_complete_command - return command back to scsi-ml
-+ * @ctask: iscsi cmd task
-  *
-  * Must be called with session lock.
-- * This function returns the scsi command to scsi-ml or cleans
-- * up mgmt tasks then returns the task to the pool.
-+ * This function returns the scsi command to scsi-ml and returns
-+ * the cmd task to the pool of available cmd tasks.
-  */
--static void iscsi_complete_command(struct iscsi_task *task)
-+static void iscsi_complete_command(struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_conn *conn = task->conn;
-+	struct iscsi_conn *conn = ctask->conn;
- 	struct iscsi_session *session = conn->session;
--	struct scsi_cmnd *sc = task->sc;
--
--	list_del_init(&task->running);
--	task->state = ISCSI_TASK_COMPLETED;
--	task->sc = NULL;
--
--	if (conn->task == task)
--		conn->task = NULL;
--	/*
--	 * login task is preallocated so do not free
--	 */
--	if (conn->login_task == task)
--		return;
--
--	__kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*));
--
--	if (conn->ping_task == task)
--		conn->ping_task = NULL;
-+	struct scsi_cmnd *sc = ctask->sc;
- 
--	if (sc) {
--		task->sc = NULL;
--		/* SCSI eh reuses commands to verify us */
--		sc->SCp.ptr = NULL;
--		/*
--		 * queue command may call this to free the task, but
--		 * not have setup the sc callback
--		 */
--		if (sc->scsi_done)
--			sc->scsi_done(sc);
--	}
-+	ctask->state = ISCSI_TASK_COMPLETED;
-+	ctask->sc = NULL;
-+	/* SCSI eh reuses commands to verify us */
-+	sc->SCp.ptr = NULL;
-+	if (conn->ctask == ctask)
-+		conn->ctask = NULL;
-+	list_del_init(&ctask->running);
-+	__kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
-+	sc->scsi_done(sc);
- }
- 
--void __iscsi_get_task(struct iscsi_task *task)
-+static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask)
- {
--	atomic_inc(&task->refcount);
-+	atomic_inc(&ctask->refcount);
- }
--EXPORT_SYMBOL_GPL(__iscsi_get_task);
- 
--static void __iscsi_put_task(struct iscsi_task *task)
-+static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask)
- {
--	if (atomic_dec_and_test(&task->refcount))
--		iscsi_complete_command(task);
-+	if (atomic_dec_and_test(&ctask->refcount))
-+		iscsi_complete_command(ctask);
- }
- 
--void iscsi_put_task(struct iscsi_task *task)
--{
--	struct iscsi_session *session = task->conn->session;
--
--	spin_lock_bh(&session->lock);
--	__iscsi_put_task(task);
--	spin_unlock_bh(&session->lock);
--}
--EXPORT_SYMBOL_GPL(iscsi_put_task);
--
- /*
-  * session lock must be held
-  */
--static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task,
-+static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
- 			 int err)
- {
- 	struct scsi_cmnd *sc;
- 
--	sc = task->sc;
-+	sc = ctask->sc;
- 	if (!sc)
- 		return;
- 
--	if (task->state == ISCSI_TASK_PENDING)
-+	if (ctask->state == ISCSI_TASK_PENDING)
- 		/*
- 		 * cmd never made it to the xmit thread, so we should not count
- 		 * the cmd in the sequencing
- 		 */
- 		conn->session->queued_cmdsn--;
- 	else
--		conn->session->tt->cleanup_task(conn, task);
--	/*
--	 * Check if cleanup_task dropped the lock and the command completed,
--	 */
--	if (!task->sc)
--		return;
-+		conn->session->tt->cleanup_cmd_task(conn, ctask);
- 
- 	sc->result = err;
--	if (!scsi_bidi_cmnd(sc))
--		scsi_set_resid(sc, scsi_bufflen(sc));
--	else {
--		scsi_out(sc)->resid = scsi_out(sc)->length;
--		scsi_in(sc)->resid = scsi_in(sc)->length;
--	}
--
--	if (conn->task == task)
--		conn->task = NULL;
-+	scsi_set_resid(sc, scsi_bufflen(sc));
-+	if (conn->ctask == ctask)
-+		conn->ctask = NULL;
- 	/* release ref from queuecommand */
--	__iscsi_put_task(task);
-+	__iscsi_put_ctask(ctask);
- }
- 
--static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
--				struct iscsi_task *task)
-+/**
-+ * iscsi_free_mgmt_task - return mgmt task back to pool
-+ * @conn: iscsi connection
-+ * @mtask: mtask
-+ *
-+ * Must be called with session lock.
-+ */
-+void iscsi_free_mgmt_task(struct iscsi_conn *conn,
-+			  struct iscsi_mgmt_task *mtask)
- {
--	struct iscsi_session *session = conn->session;
--	struct iscsi_hdr *hdr = (struct iscsi_hdr *)task->hdr;
--	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
--
--	if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
--		return -ENOTCONN;
--
--	if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) &&
--	    hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
--		nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
--	/*
--	 * pre-format CmdSN for outgoing PDU.
--	 */
--	nop->cmdsn = cpu_to_be32(session->cmdsn);
--	if (hdr->itt != RESERVED_ITT) {
--		hdr->itt = build_itt(task->itt, session->age);
--		/*
--		 * TODO: We always use immediate, so we never hit this.
--		 * If we start to send tmfs or nops as non-immediate then
--		 * we should start checking the cmdsn numbers for mgmt tasks.
--		 */
--		if (conn->c_stage == ISCSI_CONN_STARTED &&
--		    !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
--			session->queued_cmdsn++;
--			session->cmdsn++;
--		}
--	}
--
--	if (session->tt->init_task)
--		session->tt->init_task(task);
--
--	if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
--		session->state = ISCSI_STATE_LOGGING_OUT;
-+	list_del_init(&mtask->running);
-+	if (conn->login_mtask == mtask)
-+		return;
- 
--	list_move_tail(&task->running, &conn->mgmt_run_list);
--	debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
--		   hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt,
--		   task->data_count);
--	return 0;
-+	if (conn->ping_mtask == mtask)
-+		conn->ping_mtask = NULL;
-+	__kfifo_put(conn->session->mgmtpool.queue,
-+		    (void*)&mtask, sizeof(void*));
- }
-+EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task);
- 
--static struct iscsi_task *
-+static struct iscsi_mgmt_task *
- __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
- 		      char *data, uint32_t data_size)
- {
- 	struct iscsi_session *session = conn->session;
--	struct iscsi_task *task;
-+	struct iscsi_mgmt_task *mtask;
- 
- 	if (session->state == ISCSI_STATE_TERMINATE)
- 		return NULL;
-@@ -483,56 +341,29 @@ __iscsi_conn_send_pdu(struct iscsi_conn 
- 		/*
- 		 * Login and Text are sent serially, in
- 		 * request-followed-by-response sequence.
--		 * Same task can be used. Same ITT must be used.
--		 * Note that login_task is preallocated at conn_create().
-+		 * Same mtask can be used. Same ITT must be used.
-+		 * Note that login_mtask is preallocated at conn_create().
- 		 */
--		task = conn->login_task;
-+		mtask = conn->login_mtask;
- 	else {
- 		BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
- 		BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
- 
--		if (!__kfifo_get(session->cmdpool.queue,
--				 (void*)&task, sizeof(void*)))
-+		if (!__kfifo_get(session->mgmtpool.queue,
-+				 (void*)&mtask, sizeof(void*)))
- 			return NULL;
--
--		if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) &&
--		     hdr->ttt == RESERVED_ITT) {
--			conn->ping_task = task;
--			conn->last_ping = jiffies;
--		}
- 	}
--	/*
--	 * released in complete pdu for task we expect a response for, and
--	 * released by the lld when it has transmitted the task for
--	 * pdus we do not expect a response for.
--	 */
--	atomic_set(&task->refcount, 1);
--	task->conn = conn;
--	task->sc = NULL;
- 
- 	if (data_size) {
--		memcpy(task->data, data, data_size);
--		task->data_count = data_size;
-+		memcpy(mtask->data, data, data_size);
-+		mtask->data_count = data_size;
- 	} else
--		task->data_count = 0;
--
--	memcpy(task->hdr, hdr, sizeof(struct iscsi_hdr));
--	INIT_LIST_HEAD(&task->running);
--	list_add_tail(&task->running, &conn->mgmtqueue);
--
--	if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) {
--		if (iscsi_prep_mgmt_task(conn, task)) {
--			__iscsi_put_task(task);
--			return NULL;
--		}
--
--		if (session->tt->xmit_task(task))
--			task = NULL;
-+		mtask->data_count = 0;
- 
--	} else
--		scsi_queue_work(conn->session->host, &conn->xmitwork);
--
--	return task;
-+	memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr));
-+	INIT_LIST_HEAD(&mtask->running);
-+	list_add_tail(&mtask->running, &conn->mgmtqueue);
-+	return mtask;
- }
- 
- int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
-@@ -546,6 +377,7 @@ int iscsi_conn_send_pdu(struct iscsi_cls
- 	if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
- 		err = -EPERM;
- 	spin_unlock_bh(&session->lock);
-+	scsi_queue_work(session->host, &conn->xmitwork);
- 	return err;
- }
- EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
-@@ -554,7 +386,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
-  * iscsi_cmd_rsp - SCSI Command Response processing
-  * @conn: iscsi connection
-  * @hdr: iscsi header
-- * @task: scsi command task
-+ * @ctask: scsi command task
-  * @data: cmd data buffer
-  * @datalen: len of buffer
-  *
-@@ -562,12 +394,12 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
-  * then completes the command and task.
-  **/
- static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
--			       struct iscsi_task *task, char *data,
-+			       struct iscsi_cmd_task *ctask, char *data,
- 			       int datalen)
- {
- 	struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)hdr;
- 	struct iscsi_session *session = conn->session;
--	struct scsi_cmnd *sc = task->sc;
-+	struct scsi_cmnd *sc = ctask->sc;
- 
- 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
- 	conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
-@@ -591,7 +423,7 @@ invalid_datalen:
- 			goto out;
- 		}
- 
--		senselen = get_unaligned_be16(data);
-+		senselen = be16_to_cpu(get_unaligned((__be16 *) data));
- 		if (datalen < senselen)
- 			goto invalid_datalen;
- 
-@@ -601,18 +433,6 @@ invalid_datalen:
- 			   min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
- 	}
- 
--	if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
--			   ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
--		int res_count = be32_to_cpu(rhdr->bi_residual_count);
--
--		if (scsi_bidi_cmnd(sc) && res_count > 0 &&
--				(rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
--				 res_count <= scsi_in(sc)->length))
--			scsi_in(sc)->resid = res_count;
--		else
--			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
--	}
--
- 	if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
- 	                   ISCSI_FLAG_CMD_OVERFLOW)) {
- 		int res_count = be32_to_cpu(rhdr->residual_count);
-@@ -620,17 +440,19 @@ invalid_datalen:
- 		if (res_count > 0 &&
- 		    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
- 		     res_count <= scsi_bufflen(sc)))
--			/* write side for bidi or uni-io set_resid */
- 			scsi_set_resid(sc, res_count);
- 		else
- 			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
--	}
-+	} else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
-+	                          ISCSI_FLAG_CMD_BIDI_OVERFLOW))
-+		sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
-+
- out:
- 	debug_scsi("done [sc %lx res %d itt 0x%x]\n",
--		   (long)sc, sc->result, task->itt);
-+		   (long)sc, sc->result, ctask->itt);
- 	conn->scsirsp_pdus_cnt++;
- 
--	__iscsi_put_task(task);
-+	__iscsi_put_ctask(ctask);
- }
- 
- static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
-@@ -655,9 +477,9 @@ static void iscsi_tmf_rsp(struct iscsi_c
- static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
- {
-         struct iscsi_nopout hdr;
--	struct iscsi_task *task;
-+	struct iscsi_mgmt_task *mtask;
- 
--	if (!rhdr && conn->ping_task)
-+	if (!rhdr && conn->ping_mtask)
- 		return;
- 
- 	memset(&hdr, 0, sizeof(struct iscsi_nopout));
-@@ -671,9 +493,18 @@ static void iscsi_send_nopout(struct isc
- 	} else
- 		hdr.ttt = RESERVED_ITT;
- 
--	task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
--	if (!task)
-+	mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
-+	if (!mtask) {
- 		iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
-+		return;
-+	}
-+
-+	/* only track our nops */
-+	if (!rhdr) {
-+		conn->ping_mtask = mtask;
-+		conn->last_ping = jiffies;
-+	}
-+	scsi_queue_work(conn->session->host, &conn->xmitwork);
- }
- 
- static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-@@ -702,31 +533,6 @@ static int iscsi_handle_reject(struct is
- }
- 
- /**
-- * iscsi_itt_to_task - look up task by itt
-- * @conn: iscsi connection
-- * @itt: itt
-- *
-- * This should be used for mgmt tasks like login and nops, or if
-- * the LDD's itt space does not include the session age.
-- *
-- * The session lock must be held.
-- */
--static struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt)
--{
--	struct iscsi_session *session = conn->session;
--	uint32_t i;
--
--	if (itt == RESERVED_ITT)
--		return NULL;
--
--	i = get_itt(itt);
--	if (i >= session->cmds_max)
--		return NULL;
--
--	return session->cmds[i];
--}
--
--/**
-  * __iscsi_complete_pdu - complete pdu
-  * @conn: iscsi conn
-  * @hdr: iscsi header
-@@ -737,28 +543,108 @@ static struct iscsi_task *iscsi_itt_to_t
-  * queuecommand or send generic. session lock must be held and verify
-  * itt must have been called.
-  */
--int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
--			 char *data, int datalen)
-+static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-+				char *data, int datalen)
- {
- 	struct iscsi_session *session = conn->session;
- 	int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0;
--	struct iscsi_task *task;
-+	struct iscsi_cmd_task *ctask;
-+	struct iscsi_mgmt_task *mtask;
- 	uint32_t itt;
- 
- 	conn->last_recv = jiffies;
--	rc = iscsi_verify_itt(conn, hdr->itt);
--	if (rc)
--		return rc;
--
- 	if (hdr->itt != RESERVED_ITT)
- 		itt = get_itt(hdr->itt);
- 	else
- 		itt = ~0U;
- 
--	debug_scsi("[op 0x%x cid %d itt 0x%x len %d]\n",
--		   opcode, conn->id, itt, datalen);
-+	if (itt < session->cmds_max) {
-+		ctask = session->cmds[itt];
-+
-+		debug_scsi("cmdrsp [op 0x%x cid %d itt 0x%x len %d]\n",
-+			   opcode, conn->id, ctask->itt, datalen);
-+
-+		switch(opcode) {
-+		case ISCSI_OP_SCSI_CMD_RSP:
-+			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-+			iscsi_scsi_cmd_rsp(conn, hdr, ctask, data,
-+					   datalen);
-+			break;
-+		case ISCSI_OP_SCSI_DATA_IN:
-+			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-+			if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
-+				conn->scsirsp_pdus_cnt++;
-+				__iscsi_put_ctask(ctask);
-+			}
-+			break;
-+		case ISCSI_OP_R2T:
-+			/* LLD handles this for now */
-+			break;
-+		default:
-+			rc = ISCSI_ERR_BAD_OPCODE;
-+			break;
-+		}
-+	} else if (itt >= ISCSI_MGMT_ITT_OFFSET &&
-+		   itt < ISCSI_MGMT_ITT_OFFSET + session->mgmtpool_max) {
-+		mtask = session->mgmt_cmds[itt - ISCSI_MGMT_ITT_OFFSET];
-+
-+		debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
-+			   opcode, conn->id, mtask->itt, datalen);
-+
-+		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
-+		switch(opcode) {
-+		case ISCSI_OP_LOGOUT_RSP:
-+			if (datalen) {
-+				rc = ISCSI_ERR_PROTO;
-+				break;
-+			}
-+			conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
-+			/* fall through */
-+		case ISCSI_OP_LOGIN_RSP:
-+		case ISCSI_OP_TEXT_RSP:
-+			/*
-+			 * login related PDU's exp_statsn is handled in
-+			 * userspace
-+			 */
-+			if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
-+				rc = ISCSI_ERR_CONN_FAILED;
-+			iscsi_free_mgmt_task(conn, mtask);
-+			break;
-+		case ISCSI_OP_SCSI_TMFUNC_RSP:
-+			if (datalen) {
-+				rc = ISCSI_ERR_PROTO;
-+				break;
-+			}
-+
-+			iscsi_tmf_rsp(conn, hdr);
-+			iscsi_free_mgmt_task(conn, mtask);
-+			break;
-+		case ISCSI_OP_NOOP_IN:
-+			if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) ||
-+			    datalen) {
-+				rc = ISCSI_ERR_PROTO;
-+				break;
-+			}
-+			conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
- 
--	if (itt == ~0U) {
-+			if (conn->ping_mtask != mtask) {
-+				/*
-+				 * If this is not in response to one of our
-+				 * nops then it must be from userspace.
-+				 */
-+				if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
-+						   datalen))
-+					rc = ISCSI_ERR_CONN_FAILED;
-+			} else
-+				mod_timer(&conn->transport_timer,
-+					  jiffies + conn->recv_timeout);
-+			iscsi_free_mgmt_task(conn, mtask);
-+			break;
-+		default:
-+			rc = ISCSI_ERR_BAD_OPCODE;
-+			break;
-+		}
-+	} else if (itt == ~0U) {
- 		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
- 
- 		switch(opcode) {
-@@ -785,104 +671,11 @@ int __iscsi_complete_pdu(struct iscsi_co
- 			rc = ISCSI_ERR_BAD_OPCODE;
- 			break;
- 		}
--		goto out;
--	}
--
--	switch(opcode) {
--	case ISCSI_OP_SCSI_CMD_RSP:
--	case ISCSI_OP_SCSI_DATA_IN:
--		task = iscsi_itt_to_ctask(conn, hdr->itt);
--		if (!task)
--			return ISCSI_ERR_BAD_ITT;
--		break;
--	case ISCSI_OP_R2T:
--		/*
--		 * LLD handles R2Ts if they need to.
--		 */
--		return 0;
--	case ISCSI_OP_LOGOUT_RSP:
--	case ISCSI_OP_LOGIN_RSP:
--	case ISCSI_OP_TEXT_RSP:
--	case ISCSI_OP_SCSI_TMFUNC_RSP:
--	case ISCSI_OP_NOOP_IN:
--		task = iscsi_itt_to_task(conn, hdr->itt);
--		if (!task)
--			return ISCSI_ERR_BAD_ITT;
--		break;
--	default:
--		return ISCSI_ERR_BAD_OPCODE;
--	}
--
--	switch(opcode) {
--	case ISCSI_OP_SCSI_CMD_RSP:
--		iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen);
--		break;
--	case ISCSI_OP_SCSI_DATA_IN:
--		if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
--			conn->scsirsp_pdus_cnt++;
--			iscsi_update_cmdsn(session,
--					   (struct iscsi_nopin*) hdr);
--			__iscsi_put_task(task);
--		}
--		break;
--	case ISCSI_OP_LOGOUT_RSP:
--		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
--		if (datalen) {
--			rc = ISCSI_ERR_PROTO;
--			break;
--		}
--		conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
--		goto recv_pdu;
--	case ISCSI_OP_LOGIN_RSP:
--	case ISCSI_OP_TEXT_RSP:
--		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
--		/*
--		 * login related PDU's exp_statsn is handled in
--		 * userspace
--		 */
--		goto recv_pdu;
--	case ISCSI_OP_SCSI_TMFUNC_RSP:
--		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
--		if (datalen) {
--			rc = ISCSI_ERR_PROTO;
--			break;
--		}
--
--		iscsi_tmf_rsp(conn, hdr);
--		__iscsi_put_task(task);
--		break;
--	case ISCSI_OP_NOOP_IN:
--		iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
--		if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) {
--			rc = ISCSI_ERR_PROTO;
--			break;
--		}
--		conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
--
--		if (conn->ping_task != task)
--			/*
--			 * If this is not in response to one of our
--			 * nops then it must be from userspace.
--			 */
--			goto recv_pdu;
--
--		mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout);
--		__iscsi_put_task(task);
--		break;
--	default:
--		rc = ISCSI_ERR_BAD_OPCODE;
--		break;
--	}
-+	} else
-+		rc = ISCSI_ERR_BAD_ITT;
- 
--out:
--	return rc;
--recv_pdu:
--	if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
--		rc = ISCSI_ERR_CONN_FAILED;
--	__iscsi_put_task(task);
- 	return rc;
- }
--EXPORT_SYMBOL_GPL(__iscsi_complete_pdu);
- 
- int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
- 		       char *data, int datalen)
-@@ -896,63 +689,51 @@ int iscsi_complete_pdu(struct iscsi_conn
- }
- EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
- 
--int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
-+/* verify itt (itt encoding: age+cid+itt) */
-+int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
-+		     uint32_t *ret_itt)
- {
- 	struct iscsi_session *session = conn->session;
--	uint32_t i;
--
--	if (itt == RESERVED_ITT)
--		return 0;
--
--	if (((__force u32)itt & ISCSI_AGE_MASK) !=
--	    (session->age << ISCSI_AGE_SHIFT)) {
--		iscsi_conn_printk(KERN_ERR, conn,
--				  "received itt %x expected session age (%x)\n",
--				  (__force u32)itt, session->age);
--		return ISCSI_ERR_BAD_ITT;
--	}
-+	struct iscsi_cmd_task *ctask;
-+	uint32_t itt;
- 
--	i = get_itt(itt);
--	if (i >= session->cmds_max) {
--		iscsi_conn_printk(KERN_ERR, conn,
--				  "received invalid itt index %u (max cmds "
--				   "%u.\n", i, session->cmds_max);
--		return ISCSI_ERR_BAD_ITT;
--	}
--	return 0;
--}
--EXPORT_SYMBOL_GPL(iscsi_verify_itt);
-+	if (hdr->itt != RESERVED_ITT) {
-+		if (((__force u32)hdr->itt & ISCSI_AGE_MASK) !=
-+		    (session->age << ISCSI_AGE_SHIFT)) {
-+			iscsi_conn_printk(KERN_ERR, conn,
-+					  "received itt %x expected session "
-+					  "age (%x)\n", (__force u32)hdr->itt,
-+					  session->age & ISCSI_AGE_MASK);
-+			return ISCSI_ERR_BAD_ITT;
-+		}
- 
--/**
-- * iscsi_itt_to_ctask - look up ctask by itt
-- * @conn: iscsi connection
-- * @itt: itt
-- *
-- * This should be used for cmd tasks.
-- *
-- * The session lock must be held.
-- */
--struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
--{
--	struct iscsi_task *task;
-+		itt = get_itt(hdr->itt);
-+	} else
-+		itt = ~0U;
- 
--	if (iscsi_verify_itt(conn, itt))
--		return NULL;
-+	if (itt < session->cmds_max) {
-+		ctask = session->cmds[itt];
- 
--	task = iscsi_itt_to_task(conn, itt);
--	if (!task || !task->sc)
--		return NULL;
-+		if (!ctask->sc) {
-+			iscsi_conn_printk(KERN_INFO, conn, "dropping ctask "
-+					  "with itt 0x%x\n", ctask->itt);
-+			/* force drop */
-+			return ISCSI_ERR_NO_SCSI_CMD;
-+		}
- 
--	if (task->sc->SCp.phase != conn->session->age) {
--		iscsi_session_printk(KERN_ERR, conn->session,
--				  "task's session age %d, expected %d\n",
--				  task->sc->SCp.phase, conn->session->age);
--		return NULL;
-+		if (ctask->sc->SCp.phase != session->age) {
-+			iscsi_conn_printk(KERN_ERR, conn,
-+					  "iscsi: ctask's session age %d, "
-+					  "expected %d\n", ctask->sc->SCp.phase,
-+					  session->age);
-+			return ISCSI_ERR_SESSION_FAILED;
-+		}
- 	}
- 
--	return task;
-+	*ret_itt = itt;
-+	return 0;
- }
--EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
-+EXPORT_SYMBOL_GPL(iscsi_verify_itt);
- 
- void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
- {
-@@ -974,6 +755,61 @@ void iscsi_conn_failure(struct iscsi_con
- }
- EXPORT_SYMBOL_GPL(iscsi_conn_failure);
- 
-+static void iscsi_prep_mtask(struct iscsi_conn *conn,
-+			     struct iscsi_mgmt_task *mtask)
-+{
-+	struct iscsi_session *session = conn->session;
-+	struct iscsi_hdr *hdr = mtask->hdr;
-+	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
-+
-+	if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) &&
-+	    hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
-+		nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
-+	/*
-+	 * pre-format CmdSN for outgoing PDU.
-+	 */
-+	nop->cmdsn = cpu_to_be32(session->cmdsn);
-+	if (hdr->itt != RESERVED_ITT) {
-+		hdr->itt = build_itt(mtask->itt, session->age);
-+		/*
-+		 * TODO: We always use immediate, so we never hit this.
-+		 * If we start to send tmfs or nops as non-immediate then
-+		 * we should start checking the cmdsn numbers for mgmt tasks.
-+		 */
-+		if (conn->c_stage == ISCSI_CONN_STARTED &&
-+		    !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
-+			session->queued_cmdsn++;
-+			session->cmdsn++;
-+		}
-+	}
-+
-+	if (session->tt->init_mgmt_task)
-+		session->tt->init_mgmt_task(conn, mtask);
-+
-+	debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
-+		   hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt,
-+		   mtask->data_count);
-+}
-+
-+static int iscsi_xmit_mtask(struct iscsi_conn *conn)
-+{
-+	struct iscsi_hdr *hdr = conn->mtask->hdr;
-+	int rc;
-+
-+	if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
-+		conn->session->state = ISCSI_STATE_LOGGING_OUT;
-+	spin_unlock_bh(&conn->session->lock);
-+
-+	rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask);
-+	spin_lock_bh(&conn->session->lock);
-+	if (rc)
-+		return rc;
-+
-+	/* done with this in-progress mtask */
-+	conn->mtask = NULL;
-+	return 0;
-+}
-+
- static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
- {
- 	struct iscsi_session *session = conn->session;
-@@ -991,38 +827,37 @@ static int iscsi_check_cmdsn_window_clos
- 	return 0;
- }
- 
--static int iscsi_xmit_task(struct iscsi_conn *conn)
-+static int iscsi_xmit_ctask(struct iscsi_conn *conn)
- {
--	struct iscsi_task *task = conn->task;
-+	struct iscsi_cmd_task *ctask = conn->ctask;
- 	int rc;
- 
--	__iscsi_get_task(task);
-+	__iscsi_get_ctask(ctask);
- 	spin_unlock_bh(&conn->session->lock);
--	rc = conn->session->tt->xmit_task(task);
-+	rc = conn->session->tt->xmit_cmd_task(conn, ctask);
- 	spin_lock_bh(&conn->session->lock);
--	__iscsi_put_task(task);
-+	__iscsi_put_ctask(ctask);
- 	if (!rc)
--		/* done with this task */
--		conn->task = NULL;
-+		/* done with this ctask */
-+		conn->ctask = NULL;
- 	return rc;
- }
- 
- /**
-- * iscsi_requeue_task - requeue task to run from session workqueue
-- * @task: task to requeue
-+ * iscsi_requeue_ctask - requeue ctask to run from session workqueue
-+ * @ctask: ctask to requeue
-  *
-- * LLDs that need to run a task from the session workqueue should call
-- * this. The session lock must be held. This should only be called
-- * by software drivers.
-+ * LLDs that need to run a ctask from the session workqueue should call
-+ * this. The session lock must be held.
-  */
--void iscsi_requeue_task(struct iscsi_task *task)
-+void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_conn *conn = task->conn;
-+	struct iscsi_conn *conn = ctask->conn;
- 
--	list_move_tail(&task->running, &conn->requeue);
-+	list_move_tail(&ctask->running, &conn->requeue);
- 	scsi_queue_work(conn->session->host, &conn->xmitwork);
- }
--EXPORT_SYMBOL_GPL(iscsi_requeue_task);
-+EXPORT_SYMBOL_GPL(iscsi_requeue_ctask);
- 
- /**
-  * iscsi_data_xmit - xmit any command into the scheduled connection
-@@ -1044,8 +879,14 @@ static int iscsi_data_xmit(struct iscsi_
- 		return -ENODATA;
- 	}
- 
--	if (conn->task) {
--		rc = iscsi_xmit_task(conn);
-+	if (conn->ctask) {
-+		rc = iscsi_xmit_ctask(conn);
-+		if (rc)
-+			goto again;
-+	}
-+
-+	if (conn->mtask) {
-+		rc = iscsi_xmit_mtask(conn);
- 	        if (rc)
- 		        goto again;
- 	}
-@@ -1057,14 +898,17 @@ static int iscsi_data_xmit(struct iscsi_
- 	 */
- check_mgmt:
- 	while (!list_empty(&conn->mgmtqueue)) {
--		conn->task = list_entry(conn->mgmtqueue.next,
--					 struct iscsi_task, running);
--		if (iscsi_prep_mgmt_task(conn, conn->task)) {
--			__iscsi_put_task(conn->task);
--			conn->task = NULL;
-+		conn->mtask = list_entry(conn->mgmtqueue.next,
-+					 struct iscsi_mgmt_task, running);
-+		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
-+			iscsi_free_mgmt_task(conn, conn->mtask);
-+			conn->mtask = NULL;
- 			continue;
- 		}
--		rc = iscsi_xmit_task(conn);
-+
-+		iscsi_prep_mtask(conn, conn->mtask);
-+		list_move_tail(conn->mgmtqueue.next, &conn->mgmt_run_list);
-+		rc = iscsi_xmit_mtask(conn);
- 		if (rc)
- 			goto again;
- 	}
-@@ -1074,21 +918,24 @@ check_mgmt:
- 		if (conn->tmf_state == TMF_QUEUED)
- 			break;
- 
--		conn->task = list_entry(conn->xmitqueue.next,
--					 struct iscsi_task, running);
-+		conn->ctask = list_entry(conn->xmitqueue.next,
-+					 struct iscsi_cmd_task, running);
- 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
--			fail_command(conn, conn->task, DID_IMM_RETRY << 16);
-+			fail_command(conn, conn->ctask, DID_IMM_RETRY << 16);
- 			continue;
- 		}
--		if (iscsi_prep_scsi_cmd_pdu(conn->task)) {
--			fail_command(conn, conn->task, DID_ABORT << 16);
-+		if (iscsi_prep_scsi_cmd_pdu(conn->ctask)) {
-+			fail_command(conn, conn->ctask, DID_ABORT << 16);
- 			continue;
- 		}
--		rc = iscsi_xmit_task(conn);
-+
-+		conn->ctask->state = ISCSI_TASK_RUNNING;
-+		list_move_tail(conn->xmitqueue.next, &conn->run_list);
-+		rc = iscsi_xmit_ctask(conn);
- 		if (rc)
- 			goto again;
- 		/*
--		 * we could continuously get new task requests so
-+		 * we could continuously get new ctask requests so
- 		 * we need to check the mgmt queue for nops that need to
- 		 * be sent to aviod starvation
- 		 */
-@@ -1106,11 +953,11 @@ check_mgmt:
- 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
- 			break;
- 
--		conn->task = list_entry(conn->requeue.next,
--					 struct iscsi_task, running);
--		conn->task->state = ISCSI_TASK_RUNNING;
-+		conn->ctask = list_entry(conn->requeue.next,
-+					 struct iscsi_cmd_task, running);
-+		conn->ctask->state = ISCSI_TASK_RUNNING;
- 		list_move_tail(conn->requeue.next, &conn->run_list);
--		rc = iscsi_xmit_task(conn);
-+		rc = iscsi_xmit_ctask(conn);
- 		if (rc)
- 			goto again;
- 		if (!list_empty(&conn->mgmtqueue))
-@@ -1154,12 +1001,11 @@ enum {
- 
- int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
- {
--	struct iscsi_cls_session *cls_session;
- 	struct Scsi_Host *host;
- 	int reason = 0;
- 	struct iscsi_session *session;
- 	struct iscsi_conn *conn;
--	struct iscsi_task *task = NULL;
-+	struct iscsi_cmd_task *ctask = NULL;
- 
- 	sc->scsi_done = done;
- 	sc->result = 0;
-@@ -1168,11 +1014,10 @@ int iscsi_queuecommand(struct scsi_cmnd 
- 	host = sc->device->host;
- 	spin_unlock(host->host_lock);
- 
--	cls_session = starget_to_session(scsi_target(sc->device));
--	session = cls_session->dd_data;
-+	session = iscsi_hostdata(host->hostdata);
- 	spin_lock(&session->lock);
- 
--	reason = iscsi_session_chkready(cls_session);
-+	reason = iscsi_session_chkready(session_to_cls(session));
- 	if (reason) {
- 		sc->result = reason;
- 		goto fault;
-@@ -1227,39 +1072,26 @@ int iscsi_queuecommand(struct scsi_cmnd 
- 		goto reject;
- 	}
- 
--	if (!__kfifo_get(session->cmdpool.queue, (void*)&task,
-+	if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
- 			 sizeof(void*))) {
- 		reason = FAILURE_OOM;
- 		goto reject;
- 	}
-+	session->queued_cmdsn++;
-+
- 	sc->SCp.phase = session->age;
--	sc->SCp.ptr = (char *)task;
-+	sc->SCp.ptr = (char *)ctask;
- 
--	atomic_set(&task->refcount, 1);
--	task->state = ISCSI_TASK_PENDING;
--	task->conn = conn;
--	task->sc = sc;
--	INIT_LIST_HEAD(&task->running);
--	list_add_tail(&task->running, &conn->xmitqueue);
--
--	if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) {
--		if (iscsi_prep_scsi_cmd_pdu(task)) {
--			sc->result = DID_ABORT << 16;
--			sc->scsi_done = NULL;
--			iscsi_complete_command(task);
--			goto fault;
--		}
--		if (session->tt->xmit_task(task)) {
--			sc->scsi_done = NULL;
--			iscsi_complete_command(task);
--			reason = FAILURE_SESSION_NOT_READY;
--			goto reject;
--		}
--	} else
--		scsi_queue_work(session->host, &conn->xmitwork);
-+	atomic_set(&ctask->refcount, 1);
-+	ctask->state = ISCSI_TASK_PENDING;
-+	ctask->conn = conn;
-+	ctask->sc = sc;
-+	INIT_LIST_HEAD(&ctask->running);
- 
--	session->queued_cmdsn++;
-+	list_add_tail(&ctask->running, &conn->xmitqueue);
- 	spin_unlock(&session->lock);
-+
-+	scsi_queue_work(host, &conn->xmitwork);
- 	spin_lock(host->host_lock);
- 	return 0;
- 
-@@ -1272,13 +1104,8 @@ reject:
- fault:
- 	spin_unlock(&session->lock);
- 	debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
--	if (!scsi_bidi_cmnd(sc))
--		scsi_set_resid(sc, scsi_bufflen(sc));
--	else {
--		scsi_out(sc)->resid = scsi_out(sc)->length;
--		scsi_in(sc)->resid = scsi_in(sc)->length;
--	}
--	done(sc);
-+	scsi_set_resid(sc, scsi_bufflen(sc));
-+	sc->scsi_done(sc);
- 	spin_lock(host->host_lock);
- 	return 0;
- }
-@@ -1295,7 +1122,7 @@ EXPORT_SYMBOL_GPL(iscsi_change_queue_dep
- 
- void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
- {
--	struct iscsi_session *session = cls_session->dd_data;
-+	struct iscsi_session *session = class_to_transport_session(cls_session);
- 
- 	spin_lock_bh(&session->lock);
- 	if (session->state != ISCSI_STATE_LOGGED_IN) {
-@@ -1309,13 +1136,9 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery
- 
- int iscsi_eh_host_reset(struct scsi_cmnd *sc)
- {
--	struct iscsi_cls_session *cls_session;
--	struct iscsi_session *session;
--	struct iscsi_conn *conn;
--
--	cls_session = starget_to_session(scsi_target(sc->device));
--	session = cls_session->dd_data;
--	conn = session->leadconn;
-+	struct Scsi_Host *host = sc->device->host;
-+	struct iscsi_session *session = iscsi_hostdata(host->hostdata);
-+	struct iscsi_conn *conn = session->leadconn;
- 
- 	mutex_lock(&session->eh_mutex);
- 	spin_lock_bh(&session->lock);
-@@ -1377,11 +1200,11 @@ static int iscsi_exec_task_mgmt_fn(struc
- 				   int timeout)
- {
- 	struct iscsi_session *session = conn->session;
--	struct iscsi_task *task;
-+	struct iscsi_mgmt_task *mtask;
- 
--	task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
-+	mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
- 				      NULL, 0);
--	if (!task) {
-+	if (!mtask) {
- 		spin_unlock_bh(&session->lock);
- 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
- 		spin_lock_bh(&session->lock);
-@@ -1397,6 +1220,7 @@ static int iscsi_exec_task_mgmt_fn(struc
- 
- 	spin_unlock_bh(&session->lock);
- 	mutex_unlock(&session->eh_mutex);
-+	scsi_queue_work(session->host, &conn->xmitwork);
- 
- 	/*
- 	 * block eh thread until:
-@@ -1415,7 +1239,7 @@ static int iscsi_exec_task_mgmt_fn(struc
- 
- 	mutex_lock(&session->eh_mutex);
- 	spin_lock_bh(&session->lock);
--	/* if the session drops it will clean up the task */
-+	/* if the session drops it will clean up the mtask */
- 	if (age != session->age ||
- 	    session->state != ISCSI_STATE_LOGGED_IN)
- 		return -ENOTCONN;
-@@ -1429,51 +1253,48 @@ static int iscsi_exec_task_mgmt_fn(struc
- static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
- 			      int error)
- {
--	struct iscsi_task *task, *tmp;
-+	struct iscsi_cmd_task *ctask, *tmp;
- 
--	if (conn->task && (conn->task->sc->device->lun == lun || lun == -1))
--		conn->task = NULL;
-+	if (conn->ctask && (conn->ctask->sc->device->lun == lun || lun == -1))
-+		conn->ctask = NULL;
- 
- 	/* flush pending */
--	list_for_each_entry_safe(task, tmp, &conn->xmitqueue, running) {
--		if (lun == task->sc->device->lun || lun == -1) {
-+	list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
-+		if (lun == ctask->sc->device->lun || lun == -1) {
- 			debug_scsi("failing pending sc %p itt 0x%x\n",
--				   task->sc, task->itt);
--			fail_command(conn, task, error << 16);
-+				   ctask->sc, ctask->itt);
-+			fail_command(conn, ctask, error << 16);
- 		}
- 	}
- 
--	list_for_each_entry_safe(task, tmp, &conn->requeue, running) {
--		if (lun == task->sc->device->lun || lun == -1) {
-+	list_for_each_entry_safe(ctask, tmp, &conn->requeue, running) {
-+		if (lun == ctask->sc->device->lun || lun == -1) {
- 			debug_scsi("failing requeued sc %p itt 0x%x\n",
--				   task->sc, task->itt);
--			fail_command(conn, task, error << 16);
-+				   ctask->sc, ctask->itt);
-+			fail_command(conn, ctask, error << 16);
- 		}
- 	}
- 
- 	/* fail all other running */
--	list_for_each_entry_safe(task, tmp, &conn->run_list, running) {
--		if (lun == task->sc->device->lun || lun == -1) {
-+	list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) {
-+		if (lun == ctask->sc->device->lun || lun == -1) {
- 			debug_scsi("failing in progress sc %p itt 0x%x\n",
--				   task->sc, task->itt);
--			fail_command(conn, task, DID_BUS_BUSY << 16);
-+				   ctask->sc, ctask->itt);
-+			fail_command(conn, ctask, DID_BUS_BUSY << 16);
- 		}
- 	}
- }
- 
--void iscsi_suspend_tx(struct iscsi_conn *conn)
-+static void iscsi_suspend_tx(struct iscsi_conn *conn)
- {
- 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
--	if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD))
--		scsi_flush_work(conn->session->host);
-+	scsi_flush_work(conn->session->host);
- }
--EXPORT_SYMBOL_GPL(iscsi_suspend_tx);
- 
- static void iscsi_start_tx(struct iscsi_conn *conn)
- {
- 	clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
--	if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD))
--		scsi_queue_work(conn->session->host, &conn->xmitwork);
-+	scsi_queue_work(conn->session->host, &conn->xmitwork);
- }
- 
- static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
-@@ -1484,7 +1305,7 @@ static enum scsi_eh_timer_return iscsi_e
- 	enum scsi_eh_timer_return rc = EH_NOT_HANDLED;
- 
- 	cls_session = starget_to_session(scsi_target(scmd->device));
--	session = cls_session->dd_data;
-+	session = class_to_transport_session(cls_session);
- 
- 	debug_scsi("scsi cmd %p timedout\n", scmd);
- 
-@@ -1522,7 +1343,7 @@ static enum scsi_eh_timer_return iscsi_e
- 			   jiffies))
- 		rc = EH_RESET_TIMER;
- 	/* if in the middle of checking the transport then give us more time */
--	if (conn->ping_task)
-+	if (conn->ping_mtask)
- 		rc = EH_RESET_TIMER;
- done:
- 	spin_unlock(&session->lock);
-@@ -1546,7 +1367,7 @@ static void iscsi_check_transport_timeou
- 
- 	recv_timeout *= HZ;
- 	last_recv = conn->last_recv;
--	if (conn->ping_task &&
-+	if (conn->ping_mtask &&
- 	    time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
- 			   jiffies)) {
- 		iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
-@@ -1572,30 +1393,27 @@ done:
- 	spin_unlock(&session->lock);
- }
- 
--static void iscsi_prep_abort_task_pdu(struct iscsi_task *task,
-+static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask,
- 				      struct iscsi_tm *hdr)
- {
- 	memset(hdr, 0, sizeof(*hdr));
- 	hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
- 	hdr->flags = ISCSI_TM_FUNC_ABORT_TASK & ISCSI_FLAG_TM_FUNC_MASK;
- 	hdr->flags |= ISCSI_FLAG_CMD_FINAL;
--	memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun));
--	hdr->rtt = task->hdr->itt;
--	hdr->refcmdsn = task->hdr->cmdsn;
-+	memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
-+	hdr->rtt = ctask->hdr->itt;
-+	hdr->refcmdsn = ctask->hdr->cmdsn;
- }
- 
- int iscsi_eh_abort(struct scsi_cmnd *sc)
- {
--	struct iscsi_cls_session *cls_session;
--	struct iscsi_session *session;
-+	struct Scsi_Host *host = sc->device->host;
-+	struct iscsi_session *session = iscsi_hostdata(host->hostdata);
- 	struct iscsi_conn *conn;
--	struct iscsi_task *task;
-+	struct iscsi_cmd_task *ctask;
- 	struct iscsi_tm *hdr;
- 	int rc, age;
- 
--	cls_session = starget_to_session(scsi_target(sc->device));
--	session = cls_session->dd_data;
--
- 	mutex_lock(&session->eh_mutex);
- 	spin_lock_bh(&session->lock);
- 	/*
-@@ -1624,17 +1442,17 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
- 	conn->eh_abort_cnt++;
- 	age = session->age;
- 
--	task = (struct iscsi_task *)sc->SCp.ptr;
--	debug_scsi("aborting [sc %p itt 0x%x]\n", sc, task->itt);
-+	ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
-+	debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
- 
--	/* task completed before time out */
--	if (!task->sc) {
-+	/* ctask completed before time out */
-+	if (!ctask->sc) {
- 		debug_scsi("sc completed while abort in progress\n");
- 		goto success;
- 	}
- 
--	if (task->state == ISCSI_TASK_PENDING) {
--		fail_command(conn, task, DID_ABORT << 16);
-+	if (ctask->state == ISCSI_TASK_PENDING) {
-+		fail_command(conn, ctask, DID_ABORT << 16);
- 		goto success;
- 	}
- 
-@@ -1644,7 +1462,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
- 	conn->tmf_state = TMF_QUEUED;
- 
- 	hdr = &conn->tmhdr;
--	iscsi_prep_abort_task_pdu(task, hdr);
-+	iscsi_prep_abort_task_pdu(ctask, hdr);
- 
- 	if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) {
- 		rc = FAILED;
-@@ -1654,20 +1472,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
- 	switch (conn->tmf_state) {
- 	case TMF_SUCCESS:
- 		spin_unlock_bh(&session->lock);
--		/*
--		 * stop tx side incase the target had sent a abort rsp but
--		 * the initiator was still writing out data.
--		 */
- 		iscsi_suspend_tx(conn);
- 		/*
--		 * we do not stop the recv side because targets have been
--		 * good and have never sent us a successful tmf response
--		 * then sent more data for the cmd.
-+		 * clean up task if aborted. grab the recv lock as a writer
- 		 */
-+		write_lock_bh(conn->recv_lock);
- 		spin_lock(&session->lock);
--		fail_command(conn, task, DID_ABORT << 16);
-+		fail_command(conn, ctask, DID_ABORT << 16);
- 		conn->tmf_state = TMF_INITIAL;
- 		spin_unlock(&session->lock);
-+		write_unlock_bh(conn->recv_lock);
- 		iscsi_start_tx(conn);
- 		goto success_unlocked;
- 	case TMF_TIMEDOUT:
-@@ -1677,7 +1491,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
- 	case TMF_NOT_FOUND:
- 		if (!sc->SCp.ptr) {
- 			conn->tmf_state = TMF_INITIAL;
--			/* task completed before tmf abort response */
-+			/* ctask completed before tmf abort response */
- 			debug_scsi("sc completed while abort in progress\n");
- 			goto success;
- 		}
-@@ -1690,7 +1504,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
- success:
- 	spin_unlock_bh(&session->lock);
- success_unlocked:
--	debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, task->itt);
-+	debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
- 	mutex_unlock(&session->eh_mutex);
- 	return SUCCESS;
- 
-@@ -1698,7 +1512,7 @@ failed:
- 	spin_unlock_bh(&session->lock);
- failed_unlocked:
- 	debug_scsi("abort failed [sc %p itt 0x%x]\n", sc,
--		    task ? task->itt : 0);
-+		    ctask ? ctask->itt : 0);
- 	mutex_unlock(&session->eh_mutex);
- 	return FAILED;
- }
-@@ -1716,15 +1530,12 @@ static void iscsi_prep_lun_reset_pdu(str
- 
- int iscsi_eh_device_reset(struct scsi_cmnd *sc)
- {
--	struct iscsi_cls_session *cls_session;
--	struct iscsi_session *session;
-+	struct Scsi_Host *host = sc->device->host;
-+	struct iscsi_session *session = iscsi_hostdata(host->hostdata);
- 	struct iscsi_conn *conn;
- 	struct iscsi_tm *hdr;
- 	int rc = FAILED;
- 
--	cls_session = starget_to_session(scsi_target(sc->device));
--	session = cls_session->dd_data;
--
- 	debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun);
- 
- 	mutex_lock(&session->eh_mutex);
-@@ -1767,11 +1578,13 @@ int iscsi_eh_device_reset(struct scsi_cm
- 	spin_unlock_bh(&session->lock);
- 
- 	iscsi_suspend_tx(conn);
--
-+	/* need to grab the recv lock then session lock */
-+	write_lock_bh(conn->recv_lock);
- 	spin_lock(&session->lock);
- 	fail_all_commands(conn, sc->device->lun, DID_ERROR);
- 	conn->tmf_state = TMF_INITIAL;
- 	spin_unlock(&session->lock);
-+	write_unlock_bh(conn->recv_lock);
- 
- 	iscsi_start_tx(conn);
- 	goto done;
-@@ -1847,203 +1660,177 @@ void iscsi_pool_free(struct iscsi_pool *
- }
- EXPORT_SYMBOL_GPL(iscsi_pool_free);
- 
--/**
-- * iscsi_host_add - add host to system
-- * @shost: scsi host
-- * @pdev: parent device
-- *
-- * This should be called by partial offload and software iscsi drivers
-- * to add a host to the system.
-- */
--int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
--{
--	if (!shost->can_queue)
--		shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
--
--	return scsi_add_host(shost, pdev);
--}
--EXPORT_SYMBOL_GPL(iscsi_host_add);
--
--/**
-- * iscsi_host_alloc - allocate a host and driver data
-- * @sht: scsi host template
-- * @dd_data_size: driver host data size
-- * @qdepth: default device queue depth
-+/*
-+ * iSCSI Session's hostdata organization:
-  *
-- * This should be called by partial offload and software iscsi drivers.
-- * To access the driver specific memory use the iscsi_host_priv() macro.
-+ *    *------------------* <== hostdata_session(host->hostdata)
-+ *    | ptr to class sess|
-+ *    |------------------| <== iscsi_hostdata(host->hostdata)
-+ *    | iscsi_session    |
-+ *    *------------------*
-  */
--struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
--				   int dd_data_size, uint16_t qdepth)
--{
--	struct Scsi_Host *shost;
- 
--	shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
--	if (!shost)
--		return NULL;
--	shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
-+#define hostdata_privsize(_sz)	(sizeof(unsigned long) + _sz + \
-+				 _sz % sizeof(unsigned long))
- 
--	if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
--		if (qdepth != 0)
--			printk(KERN_ERR "iscsi: invalid queue depth of %d. "
--			       "Queue depth must be between 1 and %d.\n",
--			       qdepth, ISCSI_MAX_CMD_PER_LUN);
--		qdepth = ISCSI_DEF_CMD_PER_LUN;
--	}
--	shost->cmd_per_lun = qdepth;
--	return shost;
--}
--EXPORT_SYMBOL_GPL(iscsi_host_alloc);
--
--/**
-- * iscsi_host_remove - remove host and sessions
-- * @shost: scsi host
-- *
-- * This will also remove any sessions attached to the host, but if userspace
-- * is managing the session at the same time this will break. TODO: add
-- * refcounting to the netlink iscsi interface so a rmmod or host hot unplug
-- * does not remove the memory from under us.
-- */
--void iscsi_host_remove(struct Scsi_Host *shost)
--{
--	iscsi_host_for_each_session(shost, iscsi_session_teardown);
--	scsi_remove_host(shost);
--}
--EXPORT_SYMBOL_GPL(iscsi_host_remove);
--
--void iscsi_host_free(struct Scsi_Host *shost)
--{
--	struct iscsi_host *ihost = shost_priv(shost);
--
--	kfree(ihost->netdev);
--	kfree(ihost->hwaddress);
--	kfree(ihost->initiatorname);
--	scsi_host_put(shost);
--}
--EXPORT_SYMBOL_GPL(iscsi_host_free);
-+#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
- 
- /**
-  * iscsi_session_setup - create iscsi cls session and host and session
-+ * @scsit: scsi transport template
-  * @iscsit: iscsi transport template
-- * @shost: scsi host
-- * @cmds_max: session can queue
-- * @cmd_task_size: LLD task private data size
-+ * @cmds_max: scsi host can queue
-+ * @qdepth: scsi host cmds per lun
-+ * @cmd_task_size: LLD ctask private data size
-+ * @mgmt_task_size: LLD mtask private data size
-  * @initial_cmdsn: initial CmdSN
-+ * @hostno: host no allocated
-  *
-  * This can be used by software iscsi_transports that allocate
-  * a session per scsi host.
-- *
-- * Callers should set cmds_max to the largest total numer (mgmt + scsi) of
-- * tasks they support. The iscsi layer reserves ISCSI_MGMT_CMDS_MAX tasks
-- * for nop handling and login/logout requests.
-- */
-+ **/
- struct iscsi_cls_session *
--iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
--		    uint16_t cmds_max, int cmd_task_size,
--		    uint32_t initial_cmdsn, unsigned int id)
-+iscsi_session_setup(struct iscsi_transport *iscsit,
-+		    struct scsi_transport_template *scsit,
-+		    uint16_t cmds_max, uint16_t qdepth,
-+		    int cmd_task_size, int mgmt_task_size,
-+		    uint32_t initial_cmdsn, uint32_t *hostno)
- {
-+	struct Scsi_Host *shost;
- 	struct iscsi_session *session;
- 	struct iscsi_cls_session *cls_session;
--	int cmd_i, scsi_cmds, total_cmds = cmds_max;
-+	int cmd_i;
- 
--	if (!total_cmds)
--		total_cmds = ISCSI_DEF_XMIT_CMDS_MAX;
--	/*
--	 * The iscsi layer needs some tasks for nop handling and tmfs,
--	 * so the cmds_max must at least be greater than ISCSI_MGMT_CMDS_MAX
--	 * + 1 command for scsi IO.
--	 */
--	if (total_cmds < ISCSI_TOTAL_CMDS_MIN) {
--		printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
--		       "must be a power of two that is at least %d.\n",
--		       total_cmds, ISCSI_TOTAL_CMDS_MIN);
--		return NULL;
--	}
--
--	if (total_cmds > ISCSI_TOTAL_CMDS_MAX) {
--		printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
--		       "must be a power of 2 less than or equal to %d.\n",
--		       cmds_max, ISCSI_TOTAL_CMDS_MAX);
--		total_cmds = ISCSI_TOTAL_CMDS_MAX;
-+	if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
-+		if (qdepth != 0)
-+			printk(KERN_ERR "iscsi: invalid queue depth of %d. "
-+			      "Queue depth must be between 1 and %d.\n",
-+			      qdepth, ISCSI_MAX_CMD_PER_LUN);
-+		qdepth = ISCSI_DEF_CMD_PER_LUN;
- 	}
- 
--	if (!is_power_of_2(total_cmds)) {
--		printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
--		       "must be a power of 2.\n", total_cmds);
--		total_cmds = rounddown_pow_of_two(total_cmds);
--		if (total_cmds < ISCSI_TOTAL_CMDS_MIN)
--			return NULL;
--		printk(KERN_INFO "iscsi: Rounding can_queue to %d.\n",
--		       total_cmds);
-+	if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET ||
-+	    cmds_max < 2) {
-+		if (cmds_max != 0)
-+			printk(KERN_ERR "iscsi: invalid can_queue of %d. "
-+			       "can_queue must be a power of 2 and between "
-+			       "2 and %d - setting to %d.\n", cmds_max,
-+			       ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX);
-+		cmds_max = ISCSI_DEF_XMIT_CMDS_MAX;
- 	}
--	scsi_cmds = total_cmds - ISCSI_MGMT_CMDS_MAX;
- 
--	cls_session = iscsi_alloc_session(shost, iscsit,
--					  sizeof(struct iscsi_session));
--	if (!cls_session)
-+	shost = scsi_host_alloc(iscsit->host_template,
-+				hostdata_privsize(sizeof(*session)));
-+	if (!shost)
- 		return NULL;
--	session = cls_session->dd_data;
--	session->cls_session = cls_session;
-+
-+	/* the iscsi layer takes one task for reserve */
-+	shost->can_queue = cmds_max - 1;
-+	shost->cmd_per_lun = qdepth;
-+	shost->max_id = 1;
-+	shost->max_channel = 0;
-+	shost->max_lun = iscsit->max_lun;
-+	shost->max_cmd_len = iscsit->max_cmd_len;
-+	shost->transportt = scsit;
-+	shost->transportt->create_work_queue = 1;
-+	shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
-+	*hostno = shost->host_no;
-+
-+	session = iscsi_hostdata(shost->hostdata);
-+	memset(session, 0, sizeof(struct iscsi_session));
- 	session->host = shost;
- 	session->state = ISCSI_STATE_FREE;
- 	session->fast_abort = 1;
- 	session->lu_reset_timeout = 15;
- 	session->abort_timeout = 10;
--	session->scsi_cmds_max = scsi_cmds;
--	session->cmds_max = total_cmds;
-+	session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
-+	session->cmds_max = cmds_max;
- 	session->queued_cmdsn = session->cmdsn = initial_cmdsn;
- 	session->exp_cmdsn = initial_cmdsn + 1;
- 	session->max_cmdsn = initial_cmdsn + 1;
- 	session->max_r2t = 1;
- 	session->tt = iscsit;
- 	mutex_init(&session->eh_mutex);
--	spin_lock_init(&session->lock);
- 
- 	/* initialize SCSI PDU commands pool */
- 	if (iscsi_pool_init(&session->cmdpool, session->cmds_max,
- 			    (void***)&session->cmds,
--			    cmd_task_size + sizeof(struct iscsi_task)))
-+			    cmd_task_size + sizeof(struct iscsi_cmd_task)))
- 		goto cmdpool_alloc_fail;
- 
- 	/* pre-format cmds pool with ITT */
- 	for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
--		struct iscsi_task *task = session->cmds[cmd_i];
-+		struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
- 
- 		if (cmd_task_size)
--			task->dd_data = &task[1];
--		task->itt = cmd_i;
--		INIT_LIST_HEAD(&task->running);
-+			ctask->dd_data = &ctask[1];
-+		ctask->itt = cmd_i;
-+		INIT_LIST_HEAD(&ctask->running);
- 	}
- 
--	if (!try_module_get(iscsit->owner))
--		goto module_get_fail;
-+	spin_lock_init(&session->lock);
- 
--	if (iscsi_add_session(cls_session, id))
-+	/* initialize immediate command pool */
-+	if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
-+			   (void***)&session->mgmt_cmds,
-+			   mgmt_task_size + sizeof(struct iscsi_mgmt_task)))
-+		goto mgmtpool_alloc_fail;
-+
-+
-+	/* pre-format immediate cmds pool with ITT */
-+	for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
-+		struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
-+
-+		if (mgmt_task_size)
-+			mtask->dd_data = &mtask[1];
-+		mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
-+		INIT_LIST_HEAD(&mtask->running);
-+	}
-+
-+	if (scsi_add_host(shost, NULL))
-+		goto add_host_fail;
-+
-+	if (!try_module_get(iscsit->owner))
- 		goto cls_session_fail;
-+
-+	cls_session = iscsi_create_session(shost, iscsit, 0);
-+	if (!cls_session)
-+		goto module_put;
-+	*(unsigned long*)shost->hostdata = (unsigned long)cls_session;
-+
- 	return cls_session;
- 
--cls_session_fail:
-+module_put:
- 	module_put(iscsit->owner);
--module_get_fail:
-+cls_session_fail:
-+	scsi_remove_host(shost);
-+add_host_fail:
-+	iscsi_pool_free(&session->mgmtpool);
-+mgmtpool_alloc_fail:
- 	iscsi_pool_free(&session->cmdpool);
- cmdpool_alloc_fail:
--	iscsi_free_session(cls_session);
-+	scsi_host_put(shost);
- 	return NULL;
- }
- EXPORT_SYMBOL_GPL(iscsi_session_setup);
- 
- /**
-  * iscsi_session_teardown - destroy session, host, and cls_session
-- * @cls_session: iscsi session
-+ * shost: scsi host
-  *
-- * The driver must have called iscsi_remove_session before
-- * calling this.
-- */
-+ * This can be used by software iscsi_transports that allocate
-+ * a session per scsi host.
-+ **/
- void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
- {
--	struct iscsi_session *session = cls_session->dd_data;
-+	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-+	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
- 	struct module *owner = cls_session->transport->owner;
- 
-+	iscsi_remove_session(cls_session);
-+	scsi_remove_host(shost);
-+
-+	iscsi_pool_free(&session->mgmtpool);
- 	iscsi_pool_free(&session->cmdpool);
- 
- 	kfree(session->password);
-@@ -2051,10 +1838,12 @@ void iscsi_session_teardown(struct iscsi
- 	kfree(session->username);
- 	kfree(session->username_in);
- 	kfree(session->targetname);
-+	kfree(session->netdev);
-+	kfree(session->hwaddress);
- 	kfree(session->initiatorname);
--	kfree(session->ifacename);
- 
--	iscsi_destroy_session(cls_session);
-+	iscsi_free_session(cls_session);
-+	scsi_host_put(shost);
- 	module_put(owner);
- }
- EXPORT_SYMBOL_GPL(iscsi_session_teardown);
-@@ -2062,26 +1851,22 @@ EXPORT_SYMBOL_GPL(iscsi_session_teardown
- /**
-  * iscsi_conn_setup - create iscsi_cls_conn and iscsi_conn
-  * @cls_session: iscsi_cls_session
-- * @dd_size: private driver data size
-  * @conn_idx: cid
-- */
-+ **/
- struct iscsi_cls_conn *
--iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
--		 uint32_t conn_idx)
-+iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
- {
--	struct iscsi_session *session = cls_session->dd_data;
-+	struct iscsi_session *session = class_to_transport_session(cls_session);
- 	struct iscsi_conn *conn;
- 	struct iscsi_cls_conn *cls_conn;
- 	char *data;
- 
--	cls_conn = iscsi_create_conn(cls_session, sizeof(*conn) + dd_size,
--				     conn_idx);
-+	cls_conn = iscsi_create_conn(cls_session, conn_idx);
- 	if (!cls_conn)
- 		return NULL;
- 	conn = cls_conn->dd_data;
--	memset(conn, 0, sizeof(*conn) + dd_size);
-+	memset(conn, 0, sizeof(*conn));
- 
--	conn->dd_data = cls_conn->dd_data + sizeof(*conn);
- 	conn->session = session;
- 	conn->cls_conn = cls_conn;
- 	conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
-@@ -2100,30 +1885,30 @@ iscsi_conn_setup(struct iscsi_cls_sessio
- 	INIT_LIST_HEAD(&conn->requeue);
- 	INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
- 
--	/* allocate login_task used for the login/text sequences */
-+	/* allocate login_mtask used for the login/text sequences */
- 	spin_lock_bh(&session->lock);
--	if (!__kfifo_get(session->cmdpool.queue,
--                         (void*)&conn->login_task,
-+	if (!__kfifo_get(session->mgmtpool.queue,
-+                         (void*)&conn->login_mtask,
- 			 sizeof(void*))) {
- 		spin_unlock_bh(&session->lock);
--		goto login_task_alloc_fail;
-+		goto login_mtask_alloc_fail;
- 	}
- 	spin_unlock_bh(&session->lock);
- 
- 	data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL);
- 	if (!data)
--		goto login_task_data_alloc_fail;
--	conn->login_task->data = conn->data = data;
-+		goto login_mtask_data_alloc_fail;
-+	conn->login_mtask->data = conn->data = data;
- 
- 	init_timer(&conn->tmf_timer);
- 	init_waitqueue_head(&conn->ehwait);
- 
- 	return cls_conn;
- 
--login_task_data_alloc_fail:
--	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
-+login_mtask_data_alloc_fail:
-+	__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
- 		    sizeof(void*));
--login_task_alloc_fail:
-+login_mtask_alloc_fail:
- 	iscsi_destroy_conn(cls_conn);
- 	return NULL;
- }
-@@ -2183,7 +1968,7 @@ void iscsi_conn_teardown(struct iscsi_cl
- 	spin_lock_bh(&session->lock);
- 	kfree(conn->data);
- 	kfree(conn->persistent_address);
--	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
-+	__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
- 		    sizeof(void*));
- 	if (session->leadconn == conn)
- 		session->leadconn = NULL;
-@@ -2255,7 +2040,7 @@ int iscsi_conn_start(struct iscsi_cls_co
- 	}
- 	spin_unlock_bh(&session->lock);
- 
--	iscsi_unblock_session(session->cls_session);
-+	iscsi_unblock_session(session_to_cls(session));
- 	wake_up(&conn->ehwait);
- 	return 0;
- }
-@@ -2264,23 +2049,21 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start);
- static void
- flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
- {
--	struct iscsi_task *task, *tmp;
-+	struct iscsi_mgmt_task *mtask, *tmp;
- 
- 	/* handle pending */
--	list_for_each_entry_safe(task, tmp, &conn->mgmtqueue, running) {
--		debug_scsi("flushing pending mgmt task itt 0x%x\n", task->itt);
--		/* release ref from prep task */
--		__iscsi_put_task(task);
-+	list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) {
-+		debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt);
-+		iscsi_free_mgmt_task(conn, mtask);
- 	}
- 
- 	/* handle running */
--	list_for_each_entry_safe(task, tmp, &conn->mgmt_run_list, running) {
--		debug_scsi("flushing running mgmt task itt 0x%x\n", task->itt);
--		/* release ref from prep task */
--		__iscsi_put_task(task);
-+	list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) {
-+		debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt);
-+		iscsi_free_mgmt_task(conn, mtask);
- 	}
- 
--	conn->task = NULL;
-+	conn->mtask = NULL;
- }
- 
- static void iscsi_start_session_recovery(struct iscsi_session *session,
-@@ -2299,6 +2082,17 @@ static void iscsi_start_session_recovery
- 	}
- 
- 	/*
-+	 * The LLD either freed/unset the lock on us, or userspace called
-+	 * stop but did not create a proper connection (connection was never
-+	 * bound or it was unbound then stop was called).
-+	 */
-+	if (!conn->recv_lock) {
-+		spin_unlock_bh(&session->lock);
-+		mutex_unlock(&session->eh_mutex);
-+		return;
-+	}
-+
-+	/*
- 	 * When this is called for the in_login state, we only want to clean
- 	 * up the login task and connection. We do not need to block and set
- 	 * the recovery state again
-@@ -2314,6 +2108,11 @@ static void iscsi_start_session_recovery
- 	spin_unlock_bh(&session->lock);
- 
- 	iscsi_suspend_tx(conn);
-+
-+	write_lock_bh(conn->recv_lock);
-+	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
-+	write_unlock_bh(conn->recv_lock);
-+
- 	/*
- 	 * for connection level recovery we should not calculate
- 	 * header digest. conn->hdr_size used for optimization
-@@ -2326,7 +2125,7 @@ static void iscsi_start_session_recovery
- 		if (session->state == ISCSI_STATE_IN_RECOVERY &&
- 		    old_stop_stage != STOP_CONN_RECOVER) {
- 			debug_scsi("blocking session\n");
--			iscsi_block_session(session->cls_session);
-+			iscsi_block_session(session_to_cls(session));
- 		}
- 	}
- 
-@@ -2361,7 +2160,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_stop);
- int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
- 		    struct iscsi_cls_conn *cls_conn, int is_leading)
- {
--	struct iscsi_session *session = cls_session->dd_data;
-+	struct iscsi_session *session = class_to_transport_session(cls_session);
- 	struct iscsi_conn *conn = cls_conn->dd_data;
- 
- 	spin_lock_bh(&session->lock);
-@@ -2500,14 +2299,6 @@ int iscsi_set_param(struct iscsi_cls_con
- 		if (!conn->persistent_address)
- 			return -ENOMEM;
- 		break;
--	case ISCSI_PARAM_IFACE_NAME:
--		if (!session->ifacename)
--			session->ifacename = kstrdup(buf, GFP_KERNEL);
--		break;
--	case ISCSI_PARAM_INITIATOR_NAME:
--		if (!session->initiatorname)
--			session->initiatorname = kstrdup(buf, GFP_KERNEL);
--		break;
- 	default:
- 		return -ENOSYS;
- 	}
-@@ -2519,7 +2310,8 @@ EXPORT_SYMBOL_GPL(iscsi_set_param);
- int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
- 			    enum iscsi_param param, char *buf)
- {
--	struct iscsi_session *session = cls_session->dd_data;
-+	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-+	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
- 	int len;
- 
- 	switch(param) {
-@@ -2574,15 +2366,6 @@ int iscsi_session_get_param(struct iscsi
- 	case ISCSI_PARAM_PASSWORD_IN:
- 		len = sprintf(buf, "%s\n", session->password_in);
- 		break;
--	case ISCSI_PARAM_IFACE_NAME:
--		len = sprintf(buf, "%s\n", session->ifacename);
--		break;
--	case ISCSI_PARAM_INITIATOR_NAME:
--		if (!session->initiatorname)
--			len = sprintf(buf, "%s\n", "unknown");
--		else
--			len = sprintf(buf, "%s\n", session->initiatorname);
--		break;
- 	default:
- 		return -ENOSYS;
- 	}
-@@ -2642,35 +2425,29 @@ EXPORT_SYMBOL_GPL(iscsi_conn_get_param);
- int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
- 			 char *buf)
- {
--	struct iscsi_host *ihost = shost_priv(shost);
-+	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
- 	int len;
- 
- 	switch (param) {
- 	case ISCSI_HOST_PARAM_NETDEV_NAME:
--		if (!ihost->netdev)
-+		if (!session->netdev)
- 			len = sprintf(buf, "%s\n", "default");
- 		else
--			len = sprintf(buf, "%s\n", ihost->netdev);
-+			len = sprintf(buf, "%s\n", session->netdev);
- 		break;
- 	case ISCSI_HOST_PARAM_HWADDRESS:
--		if (!ihost->hwaddress)
-+		if (!session->hwaddress)
- 			len = sprintf(buf, "%s\n", "default");
- 		else
--			len = sprintf(buf, "%s\n", ihost->hwaddress);
-+			len = sprintf(buf, "%s\n", session->hwaddress);
- 		break;
- 	case ISCSI_HOST_PARAM_INITIATOR_NAME:
--		if (!ihost->initiatorname)
--			len = sprintf(buf, "%s\n", "unknown");
--		else
--			len = sprintf(buf, "%s\n", ihost->initiatorname);
--		break;
--	case ISCSI_HOST_PARAM_IPADDRESS:
--		if (!strlen(ihost->local_address))
-+		if (!session->initiatorname)
- 			len = sprintf(buf, "%s\n", "unknown");
- 		else
--			len = sprintf(buf, "%s\n",
--				      ihost->local_address);
-+			len = sprintf(buf, "%s\n", session->initiatorname);
- 		break;
-+
- 	default:
- 		return -ENOSYS;
- 	}
-@@ -2682,20 +2459,20 @@ EXPORT_SYMBOL_GPL(iscsi_host_get_param);
- int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param,
- 			 char *buf, int buflen)
- {
--	struct iscsi_host *ihost = shost_priv(shost);
-+	struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
- 
- 	switch (param) {
- 	case ISCSI_HOST_PARAM_NETDEV_NAME:
--		if (!ihost->netdev)
--			ihost->netdev = kstrdup(buf, GFP_KERNEL);
-+		if (!session->netdev)
-+			session->netdev = kstrdup(buf, GFP_KERNEL);
- 		break;
- 	case ISCSI_HOST_PARAM_HWADDRESS:
--		if (!ihost->hwaddress)
--			ihost->hwaddress = kstrdup(buf, GFP_KERNEL);
-+		if (!session->hwaddress)
-+			session->hwaddress = kstrdup(buf, GFP_KERNEL);
- 		break;
- 	case ISCSI_HOST_PARAM_INITIATOR_NAME:
--		if (!ihost->initiatorname)
--			ihost->initiatorname = kstrdup(buf, GFP_KERNEL);
-+		if (!session->initiatorname)
-+			session->initiatorname = kstrdup(buf, GFP_KERNEL);
- 		break;
- 	default:
- 		return -ENOSYS;
-Index: ofed_kernel/drivers/scsi/scsi_transport_iscsi.c
-===================================================================
---- ofed_kernel.orig/drivers/scsi/scsi_transport_iscsi.c
-+++ ofed_kernel/drivers/scsi/scsi_transport_iscsi.c
-@@ -30,24 +30,23 @@
- #include <scsi/scsi_transport_iscsi.h>
- #include <scsi/iscsi_if.h>
- 
--#define ISCSI_SESSION_ATTRS 21
-+#define ISCSI_SESSION_ATTRS 19
- #define ISCSI_CONN_ATTRS 13
- #define ISCSI_HOST_ATTRS 4
--
--#define ISCSI_TRANSPORT_VERSION "2.0-870"
-+#define ISCSI_TRANSPORT_VERSION "2.0-869"
- 
- struct iscsi_internal {
- 	int daemon_pid;
- 	struct scsi_transport_template t;
- 	struct iscsi_transport *iscsi_transport;
- 	struct list_head list;
--	struct device dev;
-+	struct class_device cdev;
- 
--	struct device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
-+	struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
- 	struct transport_container conn_cont;
--	struct device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
-+	struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
- 	struct transport_container session_cont;
--	struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
-+	struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
- };
- 
- static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
-@@ -64,12 +63,12 @@ static DEFINE_SPINLOCK(iscsi_transport_l
- #define to_iscsi_internal(tmpl) \
- 	container_of(tmpl, struct iscsi_internal, t)
- 
--#define dev_to_iscsi_internal(_dev) \
--	container_of(_dev, struct iscsi_internal, dev)
-+#define cdev_to_iscsi_internal(_cdev) \
-+	container_of(_cdev, struct iscsi_internal, cdev)
- 
--static void iscsi_transport_release(struct device *dev)
-+static void iscsi_transport_release(struct class_device *cdev)
- {
--	struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
-+	struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
- 	kfree(priv);
- }
- 
-@@ -79,33 +78,37 @@ static void iscsi_transport_release(stru
-  */
- static struct class iscsi_transport_class = {
- 	.name = "iscsi_transport",
--	.dev_release = iscsi_transport_release,
-+	.release = iscsi_transport_release,
- };
- 
- static ssize_t
--show_transport_handle(struct device *dev, struct device_attribute *attr,
--		      char *buf)
-+show_transport_handle(struct class_device *cdev, char *buf)
- {
--	struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
-+	struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
- 	return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
- }
--static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
-+static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
- 
- #define show_transport_attr(name, format)				\
- static ssize_t								\
--show_transport_##name(struct device *dev, 				\
--		      struct device_attribute *attr,char *buf)		\
-+show_transport_##name(struct class_device *cdev, char *buf)		\
- {									\
--	struct iscsi_internal *priv = dev_to_iscsi_internal(dev);	\
-+	struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);	\
- 	return sprintf(buf, format"\n", priv->iscsi_transport->name);	\
- }									\
--static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
-+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
- 
- show_transport_attr(caps, "0x%x");
-+show_transport_attr(max_lun, "%d");
-+show_transport_attr(max_conn, "%d");
-+show_transport_attr(max_cmd_len, "%d");
- 
- static struct attribute *iscsi_transport_attrs[] = {
--	&dev_attr_handle.attr,
--	&dev_attr_caps.attr,
-+	&class_device_attr_handle.attr,
-+	&class_device_attr_caps.attr,
-+	&class_device_attr_max_lun.attr,
-+	&class_device_attr_max_conn.attr,
-+	&class_device_attr_max_cmd_len.attr,
- 	NULL,
- };
- 
-@@ -113,142 +116,21 @@ static struct attribute_group iscsi_tran
- 	.attrs = iscsi_transport_attrs,
- };
- 
--/*
-- * iSCSI endpoint attrs
-- */
--#define iscsi_dev_to_endpoint(_dev) \
--	container_of(_dev, struct iscsi_endpoint, dev)
--
--#define ISCSI_ATTR(_prefix,_name,_mode,_show,_store)	\
--struct device_attribute dev_attr_##_prefix##_##_name =	\
--        __ATTR(_name,_mode,_show,_store)
--
--static void iscsi_endpoint_release(struct device *dev)
--{
--	struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
--	kfree(ep);
--}
--
--static struct class iscsi_endpoint_class = {
--	.name = "iscsi_endpoint",
--	.dev_release = iscsi_endpoint_release,
--};
--
--static ssize_t
--show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf)
--{
--	struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
--	return sprintf(buf, "%u\n", ep->id);
--}
--static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL);
--
--static struct attribute *iscsi_endpoint_attrs[] = {
--	&dev_attr_ep_handle.attr,
--	NULL,
--};
--
--static struct attribute_group iscsi_endpoint_group = {
--	.attrs = iscsi_endpoint_attrs,
--};
--
--#define ISCSI_MAX_EPID -1
--
--static int iscsi_match_epid(struct device *dev, void *data)
--{
--	struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
--	unsigned int *epid = (unsigned int *) data;
--
--	return *epid == ep->id;
--}
--
--struct iscsi_endpoint *
--iscsi_create_endpoint(int dd_size)
--{
--	struct device *dev;
--	struct iscsi_endpoint *ep;
--	unsigned int id;
--	int err;
--
--	for (id = 1; id < ISCSI_MAX_EPID; id++) {
--		dev = class_find_device(&iscsi_endpoint_class, NULL, &id,
--					iscsi_match_epid);
--		if (!dev)
--			break;
--	}
--	if (id == ISCSI_MAX_EPID) {
--		printk(KERN_ERR "Too many connections. Max supported %u\n",
--		       ISCSI_MAX_EPID - 1);
--		return NULL;
--	}
--
--	ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL);
--	if (!ep)
--		return NULL;
--
--	ep->id = id;
--	ep->dev.class = &iscsi_endpoint_class;
--	snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%u", id);
--	err = device_register(&ep->dev);
--        if (err)
--                goto free_ep;
--
--	err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
--	if (err)
--		goto unregister_dev;
--
--	if (dd_size)
--		ep->dd_data = &ep[1];
--	return ep;
--
--unregister_dev:
--	device_unregister(&ep->dev);
--	return NULL;
--
--free_ep:
--	kfree(ep);
--	return NULL;
--}
--EXPORT_SYMBOL_GPL(iscsi_create_endpoint);
--
--void iscsi_destroy_endpoint(struct iscsi_endpoint *ep)
--{
--	sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group);
--	device_unregister(&ep->dev);
--}
--EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint);
--
--struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
--{
--	struct iscsi_endpoint *ep;
--	struct device *dev;
- 
--	dev = class_find_device(&iscsi_endpoint_class, NULL, &handle,
--				iscsi_match_epid);
--	if (!dev)
--		return NULL;
--
--	ep = iscsi_dev_to_endpoint(dev);
--	/*
--	 * we can drop this now because the interface will prevent
--	 * removals and lookups from racing.
--	 */
--	put_device(dev);
--	return ep;
--}
--EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
- 
- static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
--			    struct device *cdev)
-+			    struct class_device *cdev)
- {
- 	struct Scsi_Host *shost = dev_to_shost(dev);
--	struct iscsi_cls_host *ihost = shost->shost_data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 
- 	memset(ihost, 0, sizeof(*ihost));
--	atomic_set(&ihost->nr_scans, 0);
-+	INIT_LIST_HEAD(&ihost->sessions);
- 	mutex_init(&ihost->mutex);
-+	atomic_set(&ihost->nr_scans, 0);
- 
--	snprintf(ihost->scan_workq_name, sizeof(ihost->scan_workq_name),
--		 "iscsi_scan_%d", shost->host_no);
-+	snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d",
-+		shost->host_no);
- 	ihost->scan_workq = create_singlethread_workqueue(
- 						ihost->scan_workq_name);
- 	if (!ihost->scan_workq)
-@@ -257,10 +139,10 @@ static int iscsi_setup_host(struct trans
- }
- 
- static int iscsi_remove_host(struct transport_container *tc, struct device *dev,
--			     struct device *cdev)
-+			     struct class_device *cdev)
- {
- 	struct Scsi_Host *shost = dev_to_shost(dev);
--	struct iscsi_cls_host *ihost = shost->shost_data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 
- 	destroy_workqueue(ihost->scan_workq);
- 	return 0;
-@@ -403,24 +285,6 @@ static int iscsi_is_session_dev(const st
- 	return dev->release == iscsi_session_release;
- }
- 
--static int iscsi_iter_session_fn(struct device *dev, void *data)
--{
--	void (* fn) (struct iscsi_cls_session *) = data;
--
--	if (!iscsi_is_session_dev(dev))
--		return 0;
--	fn(iscsi_dev_to_session(dev));
--	return 0;
--}
--
--void iscsi_host_for_each_session(struct Scsi_Host *shost,
--				 void (*fn)(struct iscsi_cls_session *))
--{
--	device_for_each_child(&shost->shost_gendev, fn,
--			      iscsi_iter_session_fn);
--}
--EXPORT_SYMBOL_GPL(iscsi_host_for_each_session);
--
- /**
-  * iscsi_scan_finished - helper to report when running scans are done
-  * @shost: scsi host
-@@ -431,7 +295,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_for_each_se
-  */
- int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
- {
--	struct iscsi_cls_host *ihost = shost->shost_data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 	/*
- 	 * qla4xxx will have kicked off some session unblocks before calling
- 	 * scsi_scan_host, so just wait for them to complete.
-@@ -440,61 +304,22 @@ int iscsi_scan_finished(struct Scsi_Host
- }
- EXPORT_SYMBOL_GPL(iscsi_scan_finished);
- 
--struct iscsi_scan_data {
--	unsigned int channel;
--	unsigned int id;
--	unsigned int lun;
--};
--
--static int iscsi_user_scan_session(struct device *dev, void *data)
-+static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
-+			   uint id, uint lun)
- {
--	struct iscsi_scan_data *scan_data = data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 	struct iscsi_cls_session *session;
--	struct Scsi_Host *shost;
--	struct iscsi_cls_host *ihost;
--	unsigned long flags;
--	unsigned int id;
--
--	if (!iscsi_is_session_dev(dev))
--		return 0;
--
--	session = iscsi_dev_to_session(dev);
--	shost = iscsi_session_to_shost(session);
--	ihost = shost->shost_data;
- 
- 	mutex_lock(&ihost->mutex);
--	spin_lock_irqsave(&session->lock, flags);
--	if (session->state != ISCSI_SESSION_LOGGED_IN) {
--		spin_unlock_irqrestore(&session->lock, flags);
--		mutex_unlock(&ihost->mutex);
--		return 0;
--	}
--	id = session->target_id;
--	spin_unlock_irqrestore(&session->lock, flags);
--
--	if (id != ISCSI_MAX_TARGET) {
--		if ((scan_data->channel == SCAN_WILD_CARD ||
--		     scan_data->channel == 0) &&
--		    (scan_data->id == SCAN_WILD_CARD ||
--		     scan_data->id == id))
--			scsi_scan_target(&session->dev, 0, id,
--					 scan_data->lun, 1);
-+	list_for_each_entry(session, &ihost->sessions, host_list) {
-+		if ((channel == SCAN_WILD_CARD || channel == 0) &&
-+		    (id == SCAN_WILD_CARD || id == session->target_id))
-+			scsi_scan_target(&session->dev, 0,
-+					 session->target_id, lun, 1);
- 	}
- 	mutex_unlock(&ihost->mutex);
--	return 0;
--}
--
--static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
--			   uint id, uint lun)
--{
--	struct iscsi_scan_data scan_data;
--
--	scan_data.channel = channel;
--	scan_data.id = id;
--	scan_data.lun = lun;
- 
--	return device_for_each_child(&shost->shost_gendev, &scan_data,
--				     iscsi_user_scan_session);
-+	return 0;
- }
- 
- static void iscsi_scan_session(struct work_struct *work)
-@@ -502,14 +327,19 @@ static void iscsi_scan_session(struct wo
- 	struct iscsi_cls_session *session =
- 			container_of(work, struct iscsi_cls_session, scan_work);
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
--	struct iscsi_cls_host *ihost = shost->shost_data;
--	struct iscsi_scan_data scan_data;
-+	struct iscsi_host *ihost = shost->shost_data;
-+	unsigned long flags;
- 
--	scan_data.channel = 0;
--	scan_data.id = SCAN_WILD_CARD;
--	scan_data.lun = SCAN_WILD_CARD;
-+	spin_lock_irqsave(&session->lock, flags);
-+	if (session->state != ISCSI_SESSION_LOGGED_IN) {
-+		spin_unlock_irqrestore(&session->lock, flags);
-+		goto done;
-+	}
-+	spin_unlock_irqrestore(&session->lock, flags);
- 
--	iscsi_user_scan_session(&session->dev, &scan_data);
-+	scsi_scan_target(&session->dev, 0, session->target_id,
-+			 SCAN_WILD_CARD, 1);
-+done:
- 	atomic_dec(&ihost->nr_scans);
- }
- 
-@@ -549,7 +379,7 @@ static void __iscsi_unblock_session(stru
- 			container_of(work, struct iscsi_cls_session,
- 				     unblock_work);
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
--	struct iscsi_cls_host *ihost = shost->shost_data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 	unsigned long flags;
- 
- 	/*
-@@ -617,19 +447,15 @@ static void __iscsi_unbind_session(struc
- 			container_of(work, struct iscsi_cls_session,
- 				     unbind_work);
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
--	struct iscsi_cls_host *ihost = shost->shost_data;
--	unsigned long flags;
-+	struct iscsi_host *ihost = shost->shost_data;
- 
- 	/* Prevent new scans and make sure scanning is not in progress */
- 	mutex_lock(&ihost->mutex);
--	spin_lock_irqsave(&session->lock, flags);
--	if (session->target_id == ISCSI_MAX_TARGET) {
--		spin_unlock_irqrestore(&session->lock, flags);
-+	if (list_empty(&session->host_list)) {
- 		mutex_unlock(&ihost->mutex);
- 		return;
- 	}
--	session->target_id = ISCSI_MAX_TARGET;
--	spin_unlock_irqrestore(&session->lock, flags);
-+	list_del_init(&session->host_list);
- 	mutex_unlock(&ihost->mutex);
- 
- 	scsi_remove_target(&session->dev);
-@@ -639,18 +465,18 @@ static void __iscsi_unbind_session(struc
- static int iscsi_unbind_session(struct iscsi_cls_session *session)
- {
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
--	struct iscsi_cls_host *ihost = shost->shost_data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 
- 	return queue_work(ihost->scan_workq, &session->unbind_work);
- }
- 
- struct iscsi_cls_session *
--iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
--		    int dd_size)
-+iscsi_alloc_session(struct Scsi_Host *shost,
-+		    struct iscsi_transport *transport)
- {
- 	struct iscsi_cls_session *session;
- 
--	session = kzalloc(sizeof(*session) + dd_size,
-+	session = kzalloc(sizeof(*session) + transport->sessiondata_size,
- 			  GFP_KERNEL);
- 	if (!session)
- 		return NULL;
-@@ -659,6 +485,7 @@ iscsi_alloc_session(struct Scsi_Host *sh
- 	session->recovery_tmo = 120;
- 	session->state = ISCSI_SESSION_FREE;
- 	INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
-+	INIT_LIST_HEAD(&session->host_list);
- 	INIT_LIST_HEAD(&session->sess_list);
- 	INIT_WORK(&session->unblock_work, __iscsi_unblock_session);
- 	INIT_WORK(&session->block_work, __iscsi_block_session);
-@@ -671,57 +498,22 @@ iscsi_alloc_session(struct Scsi_Host *sh
- 	session->dev.parent = &shost->shost_gendev;
- 	session->dev.release = iscsi_session_release;
- 	device_initialize(&session->dev);
--	if (dd_size)
-+	if (transport->sessiondata_size)
- 		session->dd_data = &session[1];
- 	return session;
- }
- EXPORT_SYMBOL_GPL(iscsi_alloc_session);
- 
--static int iscsi_get_next_target_id(struct device *dev, void *data)
--{
--	struct iscsi_cls_session *session;
--	unsigned long flags;
--	int err = 0;
--
--	if (!iscsi_is_session_dev(dev))
--		return 0;
--
--	session = iscsi_dev_to_session(dev);
--	spin_lock_irqsave(&session->lock, flags);
--	if (*((unsigned int *) data) == session->target_id)
--		err = -EEXIST;
--	spin_unlock_irqrestore(&session->lock, flags);
--	return err;
--}
--
- int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
- {
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
--	struct iscsi_cls_host *ihost;
-+	struct iscsi_host *ihost;
- 	unsigned long flags;
--	unsigned int id = target_id;
- 	int err;
- 
- 	ihost = shost->shost_data;
- 	session->sid = atomic_add_return(1, &iscsi_session_nr);
--
--	if (id == ISCSI_MAX_TARGET) {
--		for (id = 0; id < ISCSI_MAX_TARGET; id++) {
--			err = device_for_each_child(&shost->shost_gendev, &id,
--						    iscsi_get_next_target_id);
--			if (!err)
--				break;
--		}
--
--		if (id == ISCSI_MAX_TARGET) {
--			iscsi_cls_session_printk(KERN_ERR, session,
--						 "Too many iscsi targets. Max "
--						 "number of targets is %d.\n",
--						 ISCSI_MAX_TARGET - 1);
--			goto release_host;
--		}
--	}
--	session->target_id = id;
-+	session->target_id = target_id;
- 
- 	snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
- 		 session->sid);
-@@ -737,6 +529,10 @@ int iscsi_add_session(struct iscsi_cls_s
- 	list_add(&session->sess_list, &sesslist);
- 	spin_unlock_irqrestore(&sesslock, flags);
- 
-+	mutex_lock(&ihost->mutex);
-+	list_add(&session->host_list, &ihost->sessions);
-+	mutex_unlock(&ihost->mutex);
-+
- 	iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION);
- 	return 0;
- 
-@@ -750,18 +546,18 @@ EXPORT_SYMBOL_GPL(iscsi_add_session);
-  * iscsi_create_session - create iscsi class session
-  * @shost: scsi host
-  * @transport: iscsi transport
-- * @dd_size: private driver data size
-  * @target_id: which target
-  *
-  * This can be called from a LLD or iscsi_transport.
-  */
- struct iscsi_cls_session *
--iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
--		     int dd_size, unsigned int target_id)
-+iscsi_create_session(struct Scsi_Host *shost,
-+		     struct iscsi_transport *transport,
-+		     unsigned int target_id)
- {
- 	struct iscsi_cls_session *session;
- 
--	session = iscsi_alloc_session(shost, transport, dd_size);
-+	session = iscsi_alloc_session(shost, transport);
- 	if (!session)
- 		return NULL;
- 
-@@ -797,7 +593,7 @@ static int iscsi_iter_destroy_conn_fn(st
- void iscsi_remove_session(struct iscsi_cls_session *session)
- {
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
--	struct iscsi_cls_host *ihost = shost->shost_data;
-+	struct iscsi_host *ihost = shost->shost_data;
- 	unsigned long flags;
- 	int err;
- 
-@@ -863,7 +659,6 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_session)
- /**
-  * iscsi_create_conn - create iscsi class connection
-  * @session: iscsi cls session
-- * @dd_size: private driver data size
-  * @cid: connection id
-  *
-  * This can be called from a LLD or iscsi_transport. The connection
-@@ -876,17 +671,18 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_session)
-  * non-zero.
-  */
- struct iscsi_cls_conn *
--iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
-+iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
- {
- 	struct iscsi_transport *transport = session->transport;
- 	struct iscsi_cls_conn *conn;
- 	unsigned long flags;
- 	int err;
- 
--	conn = kzalloc(sizeof(*conn) + dd_size, GFP_KERNEL);
-+	conn = kzalloc(sizeof(*conn) + transport->conndata_size, GFP_KERNEL);
- 	if (!conn)
- 		return NULL;
--	if (dd_size)
-+
-+	if (transport->conndata_size)
- 		conn->dd_data = &conn[1];
- 
- 	INIT_LIST_HEAD(&conn->conn_list);
-@@ -1219,20 +1015,21 @@ int iscsi_session_event(struct iscsi_cls
- EXPORT_SYMBOL_GPL(iscsi_session_event);
- 
- static int
--iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
--			struct iscsi_uevent *ev, uint32_t initial_cmdsn,
--			uint16_t cmds_max, uint16_t queue_depth)
-+iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
- {
- 	struct iscsi_transport *transport = priv->iscsi_transport;
- 	struct iscsi_cls_session *session;
--	uint32_t host_no;
-+	uint32_t hostno;
- 
--	session = transport->create_session(ep, cmds_max, queue_depth,
--					    initial_cmdsn, &host_no);
-+	session = transport->create_session(transport, &priv->t,
-+					    ev->u.c_session.cmds_max,
-+					    ev->u.c_session.queue_depth,
-+					    ev->u.c_session.initial_cmdsn,
-+					    &hostno);
- 	if (!session)
- 		return -ENOMEM;
- 
--	ev->r.c_session_ret.host_no = host_no;
-+	ev->r.c_session_ret.host_no = hostno;
- 	ev->r.c_session_ret.sid = session->sid;
- 	return 0;
- }
-@@ -1307,7 +1104,6 @@ static int
- iscsi_if_transport_ep(struct iscsi_transport *transport,
- 		      struct iscsi_uevent *ev, int msg_type)
- {
--	struct iscsi_endpoint *ep;
- 	struct sockaddr *dst_addr;
- 	int rc = 0;
- 
-@@ -1317,33 +1113,22 @@ iscsi_if_transport_ep(struct iscsi_trans
- 			return -EINVAL;
- 
- 		dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
--		ep = transport->ep_connect(dst_addr,
--					   ev->u.ep_connect.non_blocking);
--		if (IS_ERR(ep))
--			return PTR_ERR(ep);
--
--		ev->r.ep_connect_ret.handle = ep->id;
-+		rc = transport->ep_connect(dst_addr,
-+					   ev->u.ep_connect.non_blocking,
-+					   &ev->r.ep_connect_ret.handle);
- 		break;
- 	case ISCSI_UEVENT_TRANSPORT_EP_POLL:
- 		if (!transport->ep_poll)
- 			return -EINVAL;
- 
--		ep = iscsi_lookup_endpoint(ev->u.ep_poll.ep_handle);
--		if (!ep)
--			return -EINVAL;
--
--		ev->r.retcode = transport->ep_poll(ep,
-+		ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle,
- 						   ev->u.ep_poll.timeout_ms);
- 		break;
- 	case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
- 		if (!transport->ep_disconnect)
- 			return -EINVAL;
- 
--		ep = iscsi_lookup_endpoint(ev->u.ep_disconnect.ep_handle);
--		if (!ep)
--			return -EINVAL;
--
--		transport->ep_disconnect(ep);
-+		transport->ep_disconnect(ev->u.ep_disconnect.ep_handle);
- 		break;
- 	}
- 	return rc;
-@@ -1408,7 +1193,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
- 	struct iscsi_internal *priv;
- 	struct iscsi_cls_session *session;
- 	struct iscsi_cls_conn *conn;
--	struct iscsi_endpoint *ep = NULL;
- 
- 	priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
- 	if (!priv)
-@@ -1422,22 +1206,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
- 
- 	switch (nlh->nlmsg_type) {
- 	case ISCSI_UEVENT_CREATE_SESSION:
--		err = iscsi_if_create_session(priv, ep, ev,
--					      ev->u.c_session.initial_cmdsn,
--					      ev->u.c_session.cmds_max,
--					      ev->u.c_session.queue_depth);
--		break;
--	case ISCSI_UEVENT_CREATE_BOUND_SESSION:
--		ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle);
--		if (!ep) {
--			err = -EINVAL;
--			break;
--		}
--
--		err = iscsi_if_create_session(priv, ep, ev,
--					ev->u.c_bound_session.initial_cmdsn,
--					ev->u.c_bound_session.cmds_max,
--					ev->u.c_bound_session.queue_depth);
-+		err = iscsi_if_create_session(priv, ev);
- 		break;
- 	case ISCSI_UEVENT_DESTROY_SESSION:
- 		session = iscsi_session_lookup(ev->u.d_session.sid);
-@@ -1568,8 +1337,11 @@ iscsi_if_rx(struct sk_buff *skb)
- 	mutex_unlock(&rx_queue_mutex);
- }
- 
-+#define iscsi_cdev_to_conn(_cdev) \
-+	iscsi_dev_to_conn(_cdev->dev)
-+
- #define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store)		\
--struct device_attribute dev_attr_##_prefix##_##_name =	\
-+struct class_device_attribute class_device_attr_##_prefix##_##_name =	\
- 	__ATTR(_name,_mode,_show,_store)
- 
- /*
-@@ -1577,10 +1349,9 @@ struct device_attribute dev_attr_##_pref
-  */
- #define iscsi_conn_attr_show(param)					\
- static ssize_t								\
--show_conn_param_##param(struct device *dev, 				\
--			struct device_attribute *attr, char *buf)	\
-+show_conn_param_##param(struct class_device *cdev, char *buf)		\
- {									\
--	struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent);	\
-+	struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev);		\
- 	struct iscsi_transport *t = conn->transport;			\
- 	return t->get_conn_param(conn, param, buf);			\
- }
-@@ -1604,16 +1375,17 @@ iscsi_conn_attr(address, ISCSI_PARAM_CON
- iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO);
- iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO);
- 
-+#define iscsi_cdev_to_session(_cdev) \
-+	iscsi_dev_to_session(_cdev->dev)
-+
- /*
-  * iSCSI session attrs
-  */
- #define iscsi_session_attr_show(param, perm)				\
- static ssize_t								\
--show_session_param_##param(struct device *dev,				\
--			   struct device_attribute *attr, char *buf)	\
-+show_session_param_##param(struct class_device *cdev, char *buf)	\
- {									\
--	struct iscsi_cls_session *session = 				\
--		iscsi_dev_to_session(dev->parent);			\
-+	struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
- 	struct iscsi_transport *t = session->transport;			\
- 									\
- 	if (perm && !capable(CAP_SYS_ADMIN))				\
-@@ -1643,14 +1415,11 @@ iscsi_session_attr(password_in, ISCSI_PA
- iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0);
- iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0);
- iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0);
--iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0);
--iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0)
- 
- static ssize_t
--show_priv_session_state(struct device *dev, struct device_attribute *attr,
--			char *buf)
-+show_priv_session_state(struct class_device *cdev, char *buf)
- {
--	struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
-+	struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);
- 	return sprintf(buf, "%s\n", iscsi_session_state_name(session->state));
- }
- static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
-@@ -1658,11 +1427,9 @@ static ISCSI_CLASS_ATTR(priv_sess, state
- 
- #define iscsi_priv_session_attr_show(field, format)			\
- static ssize_t								\
--show_priv_session_##field(struct device *dev, 				\
--			  struct device_attribute *attr, char *buf)	\
-+show_priv_session_##field(struct class_device *cdev, char *buf)		\
- {									\
--	struct iscsi_cls_session *session = 				\
--			iscsi_dev_to_session(dev->parent);		\
-+	struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\
- 	return sprintf(buf, format"\n", session->field);		\
- }
- 
-@@ -1677,10 +1444,9 @@ iscsi_priv_session_attr(recovery_tmo, "%
-  */
- #define iscsi_host_attr_show(param)					\
- static ssize_t								\
--show_host_param_##param(struct device *dev, 				\
--			struct device_attribute *attr, char *buf)	\
-+show_host_param_##param(struct class_device *cdev, char *buf)		\
- {									\
--	struct Scsi_Host *shost = transport_class_to_shost(dev);	\
-+	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
- 	struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
- 	return priv->iscsi_transport->get_host_param(shost, param, buf); \
- }
-@@ -1697,7 +1463,7 @@ iscsi_host_attr(initiatorname, ISCSI_HOS
- 
- #define SETUP_PRIV_SESSION_RD_ATTR(field)				\
- do {									\
--	priv->session_attrs[count] = &dev_attr_priv_sess_##field; \
-+	priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
- 	count++;							\
- } while (0)
- 
-@@ -1705,7 +1471,7 @@ do {									\
- #define SETUP_SESSION_RD_ATTR(field, param_flag)			\
- do {									\
- 	if (tt->param_mask & param_flag) {				\
--		priv->session_attrs[count] = &dev_attr_sess_##field; \
-+		priv->session_attrs[count] = &class_device_attr_sess_##field; \
- 		count++;						\
- 	}								\
- } while (0)
-@@ -1713,7 +1479,7 @@ do {									\
- #define SETUP_CONN_RD_ATTR(field, param_flag)				\
- do {									\
- 	if (tt->param_mask & param_flag) {				\
--		priv->conn_attrs[count] = &dev_attr_conn_##field; \
-+		priv->conn_attrs[count] = &class_device_attr_conn_##field; \
- 		count++;						\
- 	}								\
- } while (0)
-@@ -1721,7 +1487,7 @@ do {									\
- #define SETUP_HOST_RD_ATTR(field, param_flag)				\
- do {									\
- 	if (tt->host_param_mask & param_flag) {				\
--		priv->host_attrs[count] = &dev_attr_host_##field; \
-+		priv->host_attrs[count] = &class_device_attr_host_##field; \
- 		count++;						\
- 	}								\
- } while (0)
-@@ -1811,24 +1577,22 @@ iscsi_register_transport(struct iscsi_tr
- 	priv->daemon_pid = -1;
- 	priv->iscsi_transport = tt;
- 	priv->t.user_scan = iscsi_user_scan;
--	if (!(tt->caps & CAP_DATA_PATH_OFFLOAD))
--		priv->t.create_work_queue = 1;
- 
--	priv->dev.class = &iscsi_transport_class;
--	snprintf(priv->dev.bus_id, BUS_ID_SIZE, "%s", tt->name);
--	err = device_register(&priv->dev);
-+	priv->cdev.class = &iscsi_transport_class;
-+	snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
-+	err = class_device_register(&priv->cdev);
- 	if (err)
- 		goto free_priv;
- 
--	err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
-+	err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
- 	if (err)
--		goto unregister_dev;
-+		goto unregister_cdev;
- 
- 	/* host parameters */
- 	priv->t.host_attrs.ac.attrs = &priv->host_attrs[0];
- 	priv->t.host_attrs.ac.class = &iscsi_host_class.class;
- 	priv->t.host_attrs.ac.match = iscsi_host_match;
--	priv->t.host_size = sizeof(struct iscsi_cls_host);
-+	priv->t.host_size = sizeof(struct iscsi_host);
- 	transport_container_register(&priv->t.host_attrs);
- 
- 	SETUP_HOST_RD_ATTR(netdev, ISCSI_HOST_NETDEV_NAME);
-@@ -1886,8 +1650,6 @@ iscsi_register_transport(struct iscsi_tr
- 	SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT);
- 	SETUP_SESSION_RD_ATTR(abort_tmo, ISCSI_ABORT_TMO);
- 	SETUP_SESSION_RD_ATTR(lu_reset_tmo,ISCSI_LU_RESET_TMO);
--	SETUP_SESSION_RD_ATTR(ifacename, ISCSI_IFACE_NAME);
--	SETUP_SESSION_RD_ATTR(initiatorname, ISCSI_INITIATOR_NAME);
- 	SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
- 	SETUP_PRIV_SESSION_RD_ATTR(state);
- 
-@@ -1901,9 +1663,8 @@ iscsi_register_transport(struct iscsi_tr
- 	printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
- 	return &priv->t;
- 
--unregister_dev:
--	device_unregister(&priv->dev);
--	return NULL;
-+unregister_cdev:
-+	class_device_unregister(&priv->cdev);
- free_priv:
- 	kfree(priv);
- 	return NULL;
-@@ -1930,8 +1691,8 @@ int iscsi_unregister_transport(struct is
- 	transport_container_unregister(&priv->session_cont);
- 	transport_container_unregister(&priv->t.host_attrs);
- 
--	sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group);
--	device_unregister(&priv->dev);
-+	sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
-+	class_device_unregister(&priv->cdev);
- 	mutex_unlock(&rx_queue_mutex);
- 
- 	return 0;
-@@ -1951,13 +1712,9 @@ static __init int iscsi_transport_init(v
- 	if (err)
- 		return err;
- 
--	err = class_register(&iscsi_endpoint_class);
--	if (err)
--		goto unregister_transport_class;
--
- 	err = transport_class_register(&iscsi_host_class);
- 	if (err)
--		goto unregister_endpoint_class;
-+		goto unregister_transport_class;
- 
- 	err = transport_class_register(&iscsi_connection_class);
- 	if (err)
-@@ -1967,8 +1724,8 @@ static __init int iscsi_transport_init(v
- 	if (err)
- 		goto unregister_conn_class;
- 
--	nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx,
--				    NULL, THIS_MODULE);
-+	nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
-+			THIS_MODULE);
- 	if (!nls) {
- 		err = -ENOBUFS;
- 		goto unregister_session_class;
-@@ -1988,8 +1745,6 @@ unregister_conn_class:
- 	transport_class_unregister(&iscsi_connection_class);
- unregister_host_class:
- 	transport_class_unregister(&iscsi_host_class);
--unregister_endpoint_class:
--	class_unregister(&iscsi_endpoint_class);
- unregister_transport_class:
- 	class_unregister(&iscsi_transport_class);
- 	return err;
-@@ -2002,7 +1757,6 @@ static void __exit iscsi_transport_exit(
- 	transport_class_unregister(&iscsi_connection_class);
- 	transport_class_unregister(&iscsi_session_class);
- 	transport_class_unregister(&iscsi_host_class);
--	class_unregister(&iscsi_endpoint_class);
- 	class_unregister(&iscsi_transport_class);
- }
- 
-Index: ofed_kernel/include/scsi/libiscsi.h
-===================================================================
---- ofed_kernel.orig/include/scsi/libiscsi.h
-+++ ofed_kernel/include/scsi/libiscsi.h
-@@ -24,7 +24,6 @@
- #define LIBISCSI_H
- 
- #include <linux/types.h>
--#include <linux/wait.h>
- #include <linux/mutex.h>
- #include <linux/timer.h>
- #include <linux/workqueue.h>
-@@ -32,7 +31,6 @@
- #include <scsi/iscsi_if.h>
- 
- struct scsi_transport_template;
--struct scsi_host_template;
- struct scsi_device;
- struct Scsi_Host;
- struct scsi_cmnd;
-@@ -42,7 +40,6 @@ struct iscsi_cls_session;
- struct iscsi_cls_conn;
- struct iscsi_session;
- struct iscsi_nopin;
--struct device;
- 
- /* #define DEBUG_SCSI */
- #ifdef DEBUG_SCSI
-@@ -52,7 +49,9 @@ struct device;
- #endif
- 
- #define ISCSI_DEF_XMIT_CMDS_MAX	128	/* must be power of 2 */
--#define ISCSI_MGMT_CMDS_MAX	15
-+#define ISCSI_MGMT_CMDS_MAX	16	/* must be power of 2 */
-+
-+#define ISCSI_MGMT_ITT_OFFSET	0xa00
- 
- #define ISCSI_DEF_CMD_PER_LUN		32
- #define ISCSI_MAX_CMD_PER_LUN		128
-@@ -70,10 +69,7 @@ enum {
- /* Connection suspend "bit" */
- #define ISCSI_SUSPEND_BIT		1
- 
--#define ISCSI_ITT_MASK			(0x1fff)
--#define ISCSI_TOTAL_CMDS_MAX		4096
--/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */
--#define ISCSI_TOTAL_CMDS_MIN		16
-+#define ISCSI_ITT_MASK			(0xfff)
- #define ISCSI_AGE_SHIFT			28
- #define ISCSI_AGE_MASK			(0xf << ISCSI_AGE_SHIFT)
- 
-@@ -86,6 +82,18 @@ enum {
- 	ISCSI_DIGEST_SIZE = sizeof(__u32),
- };
- 
-+struct iscsi_mgmt_task {
-+	/*
-+	 * Becuae LLDs allocate their hdr differently, this is a pointer to
-+	 * that storage. It must be setup at session creation time.
-+	 */
-+	struct iscsi_hdr	*hdr;
-+	char			*data;		/* mgmt payload */
-+	unsigned		data_count;	/* counts data to be sent */
-+	uint32_t		itt;		/* this ITT */
-+	void			*dd_data;	/* driver/transport data */
-+	struct list_head	running;
-+};
- 
- enum {
- 	ISCSI_TASK_COMPLETED,
-@@ -93,7 +101,7 @@ enum {
- 	ISCSI_TASK_RUNNING,
- };
- 
--struct iscsi_task {
-+struct iscsi_cmd_task {
- 	/*
- 	 * Because LLDs allocate their hdr differently, this is a pointer
- 	 * and length to that storage. It must be setup at session
-@@ -110,7 +118,6 @@ struct iscsi_task {
- 	/* offset in unsolicited stream (bytes); */
- 	unsigned		unsol_offset;
- 	unsigned		data_count;	/* remaining Data-Out */
--	char			*data;		/* mgmt payload */
- 	struct scsi_cmnd	*sc;		/* associated SCSI cmd*/
- 	struct iscsi_conn	*conn;		/* used connection    */
- 
-@@ -121,9 +128,9 @@ struct iscsi_task {
- 	void			*dd_data;	/* driver/transport data */
- };
- 
--static inline void* iscsi_next_hdr(struct iscsi_task *task)
-+static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask)
- {
--	return (void*)task->hdr + task->hdr_len;
-+	return (void*)ctask->hdr + ctask->hdr_len;
- }
- 
- /* Connection's states */
-@@ -139,6 +146,11 @@ struct iscsi_conn {
- 	void			*dd_data;	/* iscsi_transport data */
- 	struct iscsi_session	*session;	/* parent session */
- 	/*
-+	 * LLDs should set this lock. It protects the transport recv
-+	 * code
-+	 */
-+	rwlock_t		*recv_lock;
-+	/*
- 	 * conn_stop() flag: stop to recover, stop to terminate
- 	 */
-         int			stop_stage;
-@@ -147,7 +159,7 @@ struct iscsi_conn {
- 	unsigned long		last_ping;
- 	int			ping_timeout;
- 	int			recv_timeout;
--	struct iscsi_task 	*ping_task;
-+	struct iscsi_mgmt_task	*ping_mtask;
- 
- 	/* iSCSI connection-wide sequencing */
- 	uint32_t		exp_statsn;
-@@ -163,8 +175,9 @@ struct iscsi_conn {
- 	 * should always fit in this buffer
- 	 */
- 	char			*data;
--	struct iscsi_task 	*login_task;	/* mtask used for login/text */
--	struct iscsi_task	*task;		/* xmit task in progress */
-+	struct iscsi_mgmt_task	*login_mtask;	/* mtask used for login/text */
-+	struct iscsi_mgmt_task	*mtask;		/* xmit mtask in progress */
-+	struct iscsi_cmd_task	*ctask;		/* xmit ctask in progress */
- 
- 	/* xmit */
- 	struct list_head	mgmtqueue;	/* mgmt (control) xmit queue */
-@@ -195,6 +208,9 @@ struct iscsi_conn {
- 	/* remote portal currently connected to */
- 	int			portal_port;
- 	char			portal_address[ISCSI_ADDRESS_BUF_LEN];
-+	/* local address */
-+	int			local_port;
-+	char			local_address[ISCSI_ADDRESS_BUF_LEN];
- 
- 	/* MIB-statistics */
- 	uint64_t		txdata_octets;
-@@ -209,7 +225,6 @@ struct iscsi_conn {
- 
- 	/* custom statistics */
- 	uint32_t		eh_abort_cnt;
--	uint32_t		fmr_unalign_cnt;
- };
- 
- struct iscsi_pool {
-@@ -230,7 +245,6 @@ enum {
- };
- 
- struct iscsi_session {
--	struct iscsi_cls_session *cls_session;
- 	/*
- 	 * Syncs up the scsi eh thread with the iscsi eh thread when sending
- 	 * task management functions. This must be taken before the session
-@@ -266,8 +280,10 @@ struct iscsi_session {
- 	char			*password;
- 	char			*password_in;
- 	char			*targetname;
--	char			*ifacename;
- 	char			*initiatorname;
-+	/* hw address or netdev iscsi connection is bound to */
-+	char			*hwaddress;
-+	char			*netdev;
- 	/* control data */
- 	struct iscsi_transport	*tt;
- 	struct Scsi_Host	*host;
-@@ -281,20 +297,12 @@ struct iscsi_session {
- 	int			state;		/* session state           */
- 	int			age;		/* counts session re-opens */
- 
--	int			scsi_cmds_max; 	/* max scsi commands */
- 	int			cmds_max;	/* size of cmds array */
--	struct iscsi_task	**cmds;		/* Original Cmds arr */
-+	struct iscsi_cmd_task	**cmds;		/* Original Cmds arr */
- 	struct iscsi_pool	cmdpool;	/* PDU's pool */
--};
--
--struct iscsi_host {
--	char			*initiatorname;
--	/* hw address or netdev iscsi connection is bound to */
--	char			*hwaddress;
--	char			*netdev;
--	/* local address */
--	int			local_port;
--	char			local_address[ISCSI_ADDRESS_BUF_LEN];
-+	int			mgmtpool_max;	/* size of mgmt array */
-+	struct iscsi_mgmt_task	**mgmt_cmds;	/* Original mgmt arr */
-+	struct iscsi_pool	mgmtpool;	/* Mgmt PDU's pool */
- };
- 
- /*
-@@ -307,44 +315,42 @@ extern int iscsi_eh_device_reset(struct 
- extern int iscsi_queuecommand(struct scsi_cmnd *sc,
- 			      void (*done)(struct scsi_cmnd *));
- 
-+
- /*
-  * iSCSI host helpers.
-  */
--#define iscsi_host_priv(_shost) \
--	(shost_priv(_shost) + sizeof(struct iscsi_host))
--
- extern int iscsi_host_set_param(struct Scsi_Host *shost,
- 				enum iscsi_host_param param, char *buf,
- 				int buflen);
- extern int iscsi_host_get_param(struct Scsi_Host *shost,
- 				enum iscsi_host_param param, char *buf);
--extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
--extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
--					  int dd_data_size, uint16_t qdepth);
--extern void iscsi_host_remove(struct Scsi_Host *shost);
--extern void iscsi_host_free(struct Scsi_Host *shost);
- 
- /*
-  * session management
-  */
- extern struct iscsi_cls_session *
--iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
--		    uint16_t, int, uint32_t, unsigned int);
-+iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
-+		    uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
- extern void iscsi_session_teardown(struct iscsi_cls_session *);
-+extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
- extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
- extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
- 			   enum iscsi_param param, char *buf, int buflen);
- extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
- 				   enum iscsi_param param, char *buf);
- 
-+#define session_to_cls(_sess) \
-+	hostdata_session(_sess->host->hostdata)
-+
- #define iscsi_session_printk(prefix, _sess, fmt, a...)	\
--	iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a)
-+	iscsi_cls_session_printk(prefix,		\
-+		(struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a)
- 
- /*
-  * connection management
-  */
- extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *,
--					       int, uint32_t);
-+					       uint32_t);
- extern void iscsi_conn_teardown(struct iscsi_cls_conn *);
- extern int iscsi_conn_start(struct iscsi_cls_conn *);
- extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
-@@ -353,29 +359,25 @@ extern int iscsi_conn_bind(struct iscsi_
- extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
- extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
- 				enum iscsi_param param, char *buf);
--extern void iscsi_suspend_tx(struct iscsi_conn *conn);
- 
- #define iscsi_conn_printk(prefix, _c, fmt, a...) \
--	iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
--			      fmt, ##a)
-+	iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a)
- 
- /*
-  * pdu and task processing
-  */
- extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
--extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *,
-+extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
- 					struct iscsi_data *hdr);
- extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
- 				char *, uint32_t);
- extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
- 			      char *, int);
--extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
--				char *, int);
--extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
--extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
--extern void iscsi_requeue_task(struct iscsi_task *task);
--extern void iscsi_put_task(struct iscsi_task *task);
--extern void __iscsi_get_task(struct iscsi_task *task);
-+extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *,
-+			    uint32_t *);
-+extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
-+extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
-+				 struct iscsi_mgmt_task *mtask);
- 
- /*
-  * generic helpers
-Index: ofed_kernel/include/scsi/scsi_transport_iscsi.h
-===================================================================
---- ofed_kernel.orig/include/scsi/scsi_transport_iscsi.h
-+++ ofed_kernel/include/scsi/scsi_transport_iscsi.h
-@@ -30,11 +30,11 @@
- 
- struct scsi_transport_template;
- struct iscsi_transport;
--struct iscsi_endpoint;
- struct Scsi_Host;
- struct iscsi_cls_conn;
- struct iscsi_conn;
--struct iscsi_task;
-+struct iscsi_cmd_task;
-+struct iscsi_mgmt_task;
- struct sockaddr;
- 
- /**
-@@ -58,22 +58,19 @@ struct sockaddr;
-  * @stop_conn:		suspend/recover/terminate connection
-  * @send_pdu:		send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
-  * @session_recovery_timedout: notify LLD a block during recovery timed out
-- * @init_task:		Initialize a iscsi_task and any internal structs.
-- *			When offloading the data path, this is called from
-- *			queuecommand with the session lock, or from the
-- *			iscsi_conn_send_pdu context with the session lock.
-- *			When not offloading the data path, this is called
-- *			from the scsi work queue without the session lock.
-- * @xmit_task		Requests LLD to transfer cmd task. Returns 0 or the
-+ * @init_cmd_task:	Initialize a iscsi_cmd_task and any internal structs.
-+ *			Called from queuecommand with session lock held.
-+ * @init_mgmt_task:	Initialize a iscsi_mgmt_task and any internal structs.
-+ *			Called from iscsi_conn_send_generic with xmitmutex.
-+ * @xmit_cmd_task:	Requests LLD to transfer cmd task. Returns 0 or the
-  *			the number of bytes transferred on success, and -Exyz
-- *			value on error. When offloading the data path, this
-- *			is called from queuecommand with the session lock, or
-- *			from the iscsi_conn_send_pdu context with the session
-- *			lock. When not offloading the data path, this is called
-- *			from the scsi work queue without the session lock.
-- * @cleanup_task:	requests LLD to fail task. Called with session lock
-- *			and after the connection has been suspended and
-- *			terminated during recovery. If called
-+ *			value on error.
-+ * @xmit_mgmt_task:	Requests LLD to transfer mgmt task. Returns 0 or the
-+ *			the number of bytes transferred on success, and -Exyz
-+ *			value on error.
-+ * @cleanup_cmd_task:	requests LLD to fail cmd task. Called with xmitmutex
-+ *			and session->lock after the connection has been
-+ *			suspended and terminated during recovery. If called
-  *			from abort task then connection is not suspended
-  *			or terminated but sk_callback_lock is held
-  *
-@@ -86,9 +83,17 @@ struct iscsi_transport {
- 	/* LLD sets this to indicate what values it can export to sysfs */
- 	uint64_t param_mask;
- 	uint64_t host_param_mask;
--	struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,
--					uint16_t cmds_max, uint16_t qdepth,
--					uint32_t sn, uint32_t *hn);
-+	struct scsi_host_template *host_template;
-+	/* LLD connection data size */
-+	int conndata_size;
-+	/* LLD session data size */
-+	int sessiondata_size;
-+	int max_lun;
-+	unsigned int max_conn;
-+	unsigned int max_cmd_len;
-+	struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
-+		struct scsi_transport_template *t, uint16_t, uint16_t,
-+		uint32_t sn, uint32_t *hn);
- 	void (*destroy_session) (struct iscsi_cls_session *session);
- 	struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
- 				uint32_t cid);
-@@ -113,15 +118,20 @@ struct iscsi_transport {
- 			 char *data, uint32_t data_size);
- 	void (*get_stats) (struct iscsi_cls_conn *conn,
- 			   struct iscsi_stats *stats);
--	int (*init_task) (struct iscsi_task *task);
--	int (*xmit_task) (struct iscsi_task *task);
--	void (*cleanup_task) (struct iscsi_conn *conn,
--				  struct iscsi_task *task);
-+	int (*init_cmd_task) (struct iscsi_cmd_task *ctask);
-+	void (*init_mgmt_task) (struct iscsi_conn *conn,
-+				struct iscsi_mgmt_task *mtask);
-+	int (*xmit_cmd_task) (struct iscsi_conn *conn,
-+			      struct iscsi_cmd_task *ctask);
-+	void (*cleanup_cmd_task) (struct iscsi_conn *conn,
-+				  struct iscsi_cmd_task *ctask);
-+	int (*xmit_mgmt_task) (struct iscsi_conn *conn,
-+			       struct iscsi_mgmt_task *mtask);
- 	void (*session_recovery_timedout) (struct iscsi_cls_session *session);
--	struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr,
--					      int non_blocking);
--	int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms);
--	void (*ep_disconnect) (struct iscsi_endpoint *ep);
-+	int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking,
-+			   uint64_t *ep_handle);
-+	int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
-+	void (*ep_disconnect) (uint64_t ep_handle);
- 	int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
- 			  uint32_t enable, struct sockaddr *dst_addr);
- };
-@@ -162,10 +172,9 @@ enum {
- 	ISCSI_SESSION_FREE,
- };
- 
--#define ISCSI_MAX_TARGET -1
--
- struct iscsi_cls_session {
- 	struct list_head sess_list;		/* item in session_list */
-+	struct list_head host_list;
- 	struct iscsi_transport *transport;
- 	spinlock_t lock;
- 	struct work_struct block_work;
-@@ -177,7 +186,7 @@ struct iscsi_cls_session {
- 	int recovery_tmo;
- 	struct delayed_work recovery_work;
- 
--	unsigned int target_id;
-+	int target_id;
- 
- 	int state;
- 	int sid;				/* session id */
-@@ -194,20 +203,12 @@ struct iscsi_cls_session {
- #define starget_to_session(_stgt) \
- 	iscsi_dev_to_session(_stgt->dev.parent)
- 
--struct iscsi_cls_host {
-+struct iscsi_host {
-+	struct list_head sessions;
- 	atomic_t nr_scans;
- 	struct mutex mutex;
- 	struct workqueue_struct *scan_workq;
--	char scan_workq_name[20];
--};
--
--extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
--				void (*fn)(struct iscsi_cls_session *));
--
--struct iscsi_endpoint {
--	void *dd_data;			/* LLD private data */
--	struct device dev;
--	unsigned int id;
-+	char scan_workq_name[KOBJ_NAME_LEN];
- };
- 
- /*
-@@ -221,26 +222,22 @@ struct iscsi_endpoint {
- 
- extern int iscsi_session_chkready(struct iscsi_cls_session *session);
- extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost,
--				struct iscsi_transport *transport, int dd_size);
-+					struct iscsi_transport *transport);
- extern int iscsi_add_session(struct iscsi_cls_session *session,
- 			     unsigned int target_id);
- extern int iscsi_session_event(struct iscsi_cls_session *session,
- 			       enum iscsi_uevent_e event);
- extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
- 						struct iscsi_transport *t,
--						int dd_size,
- 						unsigned int target_id);
- extern void iscsi_remove_session(struct iscsi_cls_session *session);
- extern void iscsi_free_session(struct iscsi_cls_session *session);
- extern int iscsi_destroy_session(struct iscsi_cls_session *session);
- extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
--						int dd_size, uint32_t cid);
-+					    uint32_t cid);
- extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
- extern void iscsi_unblock_session(struct iscsi_cls_session *session);
- extern void iscsi_block_session(struct iscsi_cls_session *session);
- extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
--extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
--extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
--extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
- 
- #endif
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iscsi_02_count_fmr_align_violations.patch b/kernel_patches/backport/2.6.18-EL5.1/iscsi_02_count_fmr_align_violations.patch
deleted file mode 100644
index 1375b29..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iscsi_02_count_fmr_align_violations.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 02753dd2caabfe6b1885cb80a8fb8532b416108d Mon Sep 17 00:00:00 2001
-From: Eli Dorfman <elid at voltaire.com>
-Date: Tue, 29 Apr 2008 10:12:39 +0300
-Subject: [PATCH] IB/iSER: Count fmr alignment violations per session
-
-Count fmr alignment violations per session
-as part of the iscsi statistics.
-
-Signed-off-by: Eli Dorfman <elid at voltaire.com>
----
- include/scsi/libiscsi.h |    1 +
- 1 file changed, 1 insertion(+)
-
-Index: ofed_kernel/include/scsi/libiscsi.h
-===================================================================
---- ofed_kernel.orig/include/scsi/libiscsi.h
-+++ ofed_kernel/include/scsi/libiscsi.h
-@@ -225,6 +225,7 @@ struct iscsi_conn {
- 
- 	/* custom statistics */
- 	uint32_t		eh_abort_cnt;
-+	uint32_t		fmr_unalign_cnt;
- };
- 
- struct iscsi_pool {
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iscsi_03_compat_patch_for_RHEL5_and_SLES10.patch b/kernel_patches/backport/2.6.18-EL5.1/iscsi_03_compat_patch_for_RHEL5_and_SLES10.patch
deleted file mode 100644
index 57fd421..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iscsi_03_compat_patch_for_RHEL5_and_SLES10.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From 66ab30f8dadef133bd04bbdcb434a7f742821bed Mon Sep 17 00:00:00 2001
-From: Doron Shoham <dorons at voltaire.com>
-Date: Sun, 29 Jun 2008 15:41:12 +0300
-Subject: [PATCH] copmat patch for RHEL5 and SLES10
-
-Signed-off-by: Doron Shoham <dorons at voltaire.com>
----
- drivers/scsi/scsi_transport_iscsi.c |   97 +++++++++++++++++++++---------------
- 1 file changed, 57 insertions(+), 40 deletions(-)
-
-Index: ofa_kernel-1.4/drivers/scsi/scsi_transport_iscsi.c
-===================================================================
---- ofa_kernel-1.4.orig/drivers/scsi/scsi_transport_iscsi.c
-+++ ofa_kernel-1.4/drivers/scsi/scsi_transport_iscsi.c
-@@ -20,6 +20,8 @@
-  * along with this program; if not, write to the Free Software
-  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-  */
-+#include <linux/version.h>
-+#include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/mutex.h>
- #include <net/tcp.h>
-@@ -378,8 +380,10 @@ static void __iscsi_unblock_session(stru
- 	struct iscsi_cls_session *session =
- 			container_of(work, struct iscsi_cls_session,
- 				     unblock_work);
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
- 	struct Scsi_Host *shost = iscsi_session_to_shost(session);
- 	struct iscsi_host *ihost = shost->shost_data;
-+#endif
- 	unsigned long flags;
- 
- 	/*
-@@ -397,10 +401,12 @@ static void __iscsi_unblock_session(stru
- 	 * the async scanning code (drivers like iscsi_tcp do login and
- 	 * scanning from userspace).
- 	 */
--	if (shost->hostt->scan_finished) {
--		if (queue_work(ihost->scan_workq, &session->scan_work))
--			atomic_inc(&ihost->nr_scans);
--	}
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
-+		if (shost->hostt->scan_finished) {
-+			if (queue_work(ihost->scan_workq, &session->scan_work))
-+				atomic_inc(&ihost->nr_scans);
-+		}
-+#endif
- }
- 
- /**
-@@ -1294,45 +1300,56 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
-  * Malformed skbs with wrong lengths or invalid creds are not processed.
-  */
- static void
--iscsi_if_rx(struct sk_buff *skb)
-+iscsi_if_rx(struct sock *sk, int len)
- {
-+	struct sk_buff *skb;
-+
- 	mutex_lock(&rx_queue_mutex);
--	while (skb->len >= NLMSG_SPACE(0)) {
--		int err;
--		uint32_t rlen;
--		struct nlmsghdr	*nlh;
--		struct iscsi_uevent *ev;
--
--		nlh = nlmsg_hdr(skb);
--		if (nlh->nlmsg_len < sizeof(*nlh) ||
--		    skb->len < nlh->nlmsg_len) {
--			break;
-+	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
-+		if (NETLINK_CREDS(skb)->uid) {
-+			skb_pull(skb, skb->len);
-+			goto free_skb;
- 		}
- 
--		ev = NLMSG_DATA(nlh);
--		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
--		if (rlen > skb->len)
--			rlen = skb->len;
--
--		err = iscsi_if_recv_msg(skb, nlh);
--		if (err) {
--			ev->type = ISCSI_KEVENT_IF_ERROR;
--			ev->iferror = err;
--		}
--		do {
--			/*
--			 * special case for GET_STATS:
--			 * on success - sending reply and stats from
--			 * inside of if_recv_msg(),
--			 * on error - fall through.
--			 */
--			if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
-+		while (skb->len >= NLMSG_SPACE(0)) {
-+			int err;
-+			uint32_t rlen;
-+			struct nlmsghdr	*nlh;
-+			struct iscsi_uevent *ev;
-+
-+			nlh = nlmsg_hdr(skb);
-+			if (nlh->nlmsg_len < sizeof(*nlh) ||
-+			    skb->len < nlh->nlmsg_len) {
- 				break;
--			err = iscsi_if_send_reply(
--				NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
--				nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
--		} while (err < 0 && err != -ECONNREFUSED);
--		skb_pull(skb, rlen);
-+			}
-+
-+			ev = NLMSG_DATA(nlh);
-+			rlen = NLMSG_ALIGN(nlh->nlmsg_len);
-+			if (rlen > skb->len)
-+				rlen = skb->len;
-+
-+			err = iscsi_if_recv_msg(skb, nlh);
-+			if (err) {
-+				ev->type = ISCSI_KEVENT_IF_ERROR;
-+				ev->iferror = err;
-+			}
-+			do {
-+				/*
-+				 * special case for GET_STATS:
-+				 * on success - sending reply and stats from
-+				 * inside of if_recv_msg(),
-+				 * on error - fall through.
-+				 */
-+				if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
-+					break;
-+				err = iscsi_if_send_reply(
-+					NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
-+					nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
-+			} while (err < 0 && err != -ECONNREFUSED);
-+			skb_pull(skb, rlen);
-+		}
-+free_skb:
-+		kfree_skb(skb);
- 	}
- 	mutex_unlock(&rx_queue_mutex);
- }
-@@ -1738,7 +1755,7 @@ static __init int iscsi_transport_init(v
- 	return 0;
- 
- release_nls:
--	netlink_kernel_release(nls);
-+	sock_release(nls->sk_socket);
- unregister_session_class:
- 	transport_class_unregister(&iscsi_session_class);
- unregister_conn_class:
-@@ -1753,7 +1770,7 @@ unregister_transport_class:
- static void __exit iscsi_transport_exit(void)
- {
- 	destroy_workqueue(iscsi_eh_timer_workq);
--	netlink_kernel_release(nls);
-+	sock_release(nls->sk_socket);
- 	transport_class_unregister(&iscsi_connection_class);
- 	transport_class_unregister(&iscsi_session_class);
- 	transport_class_unregister(&iscsi_host_class);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iser_01_sync_kernel_code_with_2.6.26.patch b/kernel_patches/backport/2.6.18-EL5.1/iser_01_sync_kernel_code_with_2.6.26.patch
deleted file mode 100644
index a147ee2..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iser_01_sync_kernel_code_with_2.6.26.patch
+++ /dev/null
@@ -1,1548 +0,0 @@
-From ad1e1df62ff096cc90257b0b42e843d0773ae981 Mon Sep 17 00:00:00 2001
-From: Doron Shoham <dorons at voltaire.com>
-Date: Tue, 26 Aug 2008 11:37:50 +0300
-Subject: [PATCH] iser backports
-
-Signed-off-by: Doron Shoham <dorons at voltaire.com>
----
- drivers/infiniband/ulp/iser/iscsi_iser.c     |  363 ++++++++++++---------------
- drivers/infiniband/ulp/iser/iscsi_iser.h     |   46 +--
- drivers/infiniband/ulp/iser/iser_initiator.c |  211 +++++++--------
- drivers/infiniband/ulp/iser/iser_memory.c    |   79 ++---
- drivers/infiniband/ulp/iser/iser_verbs.c     |   31 +-
- 5 files changed, 347 insertions(+), 383 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
-+++ ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.c
-@@ -42,6 +42,9 @@
-  *	Zhenyu Wang
-  * Modified by:
-  *      Erez Zilber
-+ *
-+ *
-+ * $Id: iscsi_iser.c 6965 2006-05-07 11:36:20Z ogerlitz $
-  */
- 
- #include <linux/types.h>
-@@ -71,10 +74,6 @@
- 
- #include "iscsi_iser.h"
- 
--static struct scsi_host_template iscsi_iser_sht;
--static struct iscsi_transport iscsi_iser_transport;
--static struct scsi_transport_template *iscsi_iser_scsi_transport;
--
- static unsigned int iscsi_max_lun = 512;
- module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
- 
-@@ -95,6 +94,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
- 		struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
- {
- 	int rc = 0;
-+	uint32_t ret_itt;
- 	int datalen;
- 	int ahslen;
- 
-@@ -110,7 +110,12 @@ iscsi_iser_recv(struct iscsi_conn *conn,
- 	/* read AHS */
- 	ahslen = hdr->hlength * 4;
- 
--	rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
-+	/* verify itt (itt encoding: age+cid+itt) */
-+	rc = iscsi_verify_itt(conn, hdr, &ret_itt);
-+
-+	if (!rc)
-+		rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
-+
- 	if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
- 		goto error;
- 
-@@ -121,33 +126,25 @@ error:
- 
- 
- /**
-- * iscsi_iser_task_init - Initialize task
-- * @task: iscsi task
-+ * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
-  *
-- * Initialize the task for the scsi command or mgmt command.
-- */
-+ **/
- static int
--iscsi_iser_task_init(struct iscsi_task *task)
-+iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_iser_conn *iser_conn  = task->conn->dd_data;
--	struct iscsi_iser_task *iser_task = task->dd_data;
--
--	/* mgmt task */
--	if (!task->sc) {
--		iser_task->desc.data = task->data;
--		return 0;
--	}
-+	struct iscsi_iser_conn     *iser_conn  = ctask->conn->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 
--	iser_task->command_sent = 0;
--	iser_task->iser_conn    = iser_conn;
--	iser_task_rdma_init(iser_task);
-+	iser_ctask->command_sent = 0;
-+	iser_ctask->iser_conn    = iser_conn;
-+	iser_ctask_rdma_init(iser_ctask);
- 	return 0;
- }
- 
- /**
-- * iscsi_iser_mtask_xmit - xmit management(immediate) task
-+ * iscsi_mtask_xmit - xmit management(immediate) task
-  * @conn: iscsi connection
-- * @task: task management task
-+ * @mtask: task management task
-  *
-  * Notes:
-  *	The function can return -EAGAIN in which case caller must
-@@ -156,19 +153,20 @@ iscsi_iser_task_init(struct iscsi_task *
-  *
-  **/
- static int
--iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
-+iscsi_iser_mtask_xmit(struct iscsi_conn *conn,
-+		      struct iscsi_mgmt_task *mtask)
- {
- 	int error = 0;
- 
--	debug_scsi("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
-+	debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
- 
--	error = iser_send_control(conn, task);
-+	error = iser_send_control(conn, mtask);
- 
--	/* since iser xmits control with zero copy, tasks can not be recycled
-+	/* since iser xmits control with zero copy, mtasks can not be recycled
- 	 * right after sending them.
- 	 * The recycling scheme is based on whether a response is expected
--	 * - if yes, the task is recycled at iscsi_complete_pdu
--	 * - if no,  the task is recycled at iser_snd_completion
-+	 * - if yes, the mtask is recycled at iscsi_complete_pdu
-+	 * - if no,  the mtask is recycled at iser_snd_completion
- 	 */
- 	if (error && error != -ENOBUFS)
- 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-@@ -177,86 +175,97 @@ iscsi_iser_mtask_xmit(struct iscsi_conn 
- }
- 
- static int
--iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn,
--				 struct iscsi_task *task)
-+iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn,
-+				 struct iscsi_cmd_task *ctask)
- {
- 	struct iscsi_data  hdr;
- 	int error = 0;
- 
- 	/* Send data-out PDUs while there's still unsolicited data to send */
--	while (task->unsol_count > 0) {
--		iscsi_prep_unsolicit_data_pdu(task, &hdr);
-+	while (ctask->unsol_count > 0) {
-+		iscsi_prep_unsolicit_data_pdu(ctask, &hdr);
- 		debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
--			   hdr.itt, task->data_count);
-+			   hdr.itt, ctask->data_count);
- 
- 		/* the buffer description has been passed with the command */
- 		/* Send the command */
--		error = iser_send_data_out(conn, task, &hdr);
-+		error = iser_send_data_out(conn, ctask, &hdr);
- 		if (error) {
--			task->unsol_datasn--;
--			goto iscsi_iser_task_xmit_unsol_data_exit;
-+			ctask->unsol_datasn--;
-+			goto iscsi_iser_ctask_xmit_unsol_data_exit;
- 		}
--		task->unsol_count -= task->data_count;
-+		ctask->unsol_count -= ctask->data_count;
- 		debug_scsi("Need to send %d more as data-out PDUs\n",
--			   task->unsol_count);
-+			   ctask->unsol_count);
- 	}
- 
--iscsi_iser_task_xmit_unsol_data_exit:
-+iscsi_iser_ctask_xmit_unsol_data_exit:
- 	return error;
- }
- 
- static int
--iscsi_iser_task_xmit(struct iscsi_task *task)
-+iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
-+		      struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_conn *conn = task->conn;
--	struct iscsi_iser_task *iser_task = task->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 	int error = 0;
- 
--	if (!task->sc)
--		return iscsi_iser_mtask_xmit(conn, task);
--
--	if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
--		BUG_ON(scsi_bufflen(task->sc) == 0);
-+	if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
-+		BUG_ON(scsi_bufflen(ctask->sc) == 0);
- 
- 		debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
--			   task->itt, scsi_bufflen(task->sc),
--			   task->imm_count, task->unsol_count);
-+			   ctask->itt, scsi_bufflen(ctask->sc),
-+			   ctask->imm_count, ctask->unsol_count);
- 	}
- 
--	debug_scsi("task deq [cid %d itt 0x%x]\n",
--		   conn->id, task->itt);
-+	debug_scsi("ctask deq [cid %d itt 0x%x]\n",
-+		   conn->id, ctask->itt);
- 
- 	/* Send the cmd PDU */
--	if (!iser_task->command_sent) {
--		error = iser_send_command(conn, task);
-+	if (!iser_ctask->command_sent) {
-+		error = iser_send_command(conn, ctask);
- 		if (error)
--			goto iscsi_iser_task_xmit_exit;
--		iser_task->command_sent = 1;
-+			goto iscsi_iser_ctask_xmit_exit;
-+		iser_ctask->command_sent = 1;
- 	}
- 
- 	/* Send unsolicited data-out PDU(s) if necessary */
--	if (task->unsol_count)
--		error = iscsi_iser_task_xmit_unsol_data(conn, task);
-+	if (ctask->unsol_count)
-+		error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask);
- 
-- iscsi_iser_task_xmit_exit:
-+ iscsi_iser_ctask_xmit_exit:
- 	if (error && error != -ENOBUFS)
- 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
- 	return error;
- }
- 
- static void
--iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
-+iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
- {
--	struct iscsi_iser_task *iser_task = task->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 
--	/* mgmt tasks do not need special cleanup */
--	if (!task->sc)
--		return;
-+	if (iser_ctask->status == ISER_TASK_STATUS_STARTED) {
-+		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
-+		iser_ctask_rdma_finalize(iser_ctask);
-+	}
-+}
- 
--	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
--		iser_task->status = ISER_TASK_STATUS_COMPLETED;
--		iser_task_rdma_finalize(iser_task);
-+static struct iser_conn *
-+iscsi_iser_ib_conn_lookup(__u64 ep_handle)
-+{
-+	struct iser_conn *ib_conn;
-+	struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle;
-+
-+	mutex_lock(&ig.connlist_mutex);
-+	list_for_each_entry(ib_conn, &ig.connlist, conn_list) {
-+		if (ib_conn == uib_conn) {
-+			mutex_unlock(&ig.connlist_mutex);
-+			return ib_conn;
-+		}
- 	}
-+	mutex_unlock(&ig.connlist_mutex);
-+	iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle);
-+	return NULL;
- }
- 
- static struct iscsi_cls_conn *
-@@ -266,7 +275,7 @@ iscsi_iser_conn_create(struct iscsi_cls_
- 	struct iscsi_cls_conn *cls_conn;
- 	struct iscsi_iser_conn *iser_conn;
- 
--	cls_conn = iscsi_conn_setup(cls_session, sizeof(*iser_conn), conn_idx);
-+	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
- 	if (!cls_conn)
- 		return NULL;
- 	conn = cls_conn->dd_data;
-@@ -277,11 +286,21 @@ iscsi_iser_conn_create(struct iscsi_cls_
- 	 */
- 	conn->max_recv_dlength = 128;
- 
--	iser_conn = conn->dd_data;
-+	iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL);
-+	if (!iser_conn)
-+		goto conn_alloc_fail;
-+
-+	/* currently this is the only field which need to be initiated */
-+	rwlock_init(&iser_conn->lock);
-+
- 	conn->dd_data = iser_conn;
- 	iser_conn->iscsi_conn = conn;
- 
- 	return cls_conn;
-+
-+conn_alloc_fail:
-+	iscsi_conn_teardown(cls_conn);
-+	return NULL;
- }
- 
- static void
-@@ -289,18 +308,11 @@ iscsi_iser_conn_destroy(struct iscsi_cls
- {
- 	struct iscsi_conn *conn = cls_conn->dd_data;
- 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
--	struct iser_conn *ib_conn = iser_conn->ib_conn;
- 
- 	iscsi_conn_teardown(cls_conn);
--	/*
--	 * Userspace will normally call the stop callback and
--	 * already have freed the ib_conn, but if it goofed up then
--	 * we free it here.
--	 */
--	if (ib_conn) {
--		ib_conn->iser_conn = NULL;
--		iser_conn_put(ib_conn);
--	}
-+	if (iser_conn->ib_conn)
-+		iser_conn->ib_conn->iser_conn = NULL;
-+	kfree(iser_conn);
- }
- 
- static int
-@@ -311,7 +323,6 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
- 	struct iscsi_conn *conn = cls_conn->dd_data;
- 	struct iscsi_iser_conn *iser_conn;
- 	struct iser_conn *ib_conn;
--	struct iscsi_endpoint *ep;
- 	int error;
- 
- 	error = iscsi_conn_bind(cls_session, cls_conn, is_leading);
-@@ -320,14 +331,12 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
- 
- 	/* the transport ep handle comes from user space so it must be
- 	 * verified against the global ib connections list */
--	ep = iscsi_lookup_endpoint(transport_eph);
--	if (!ep) {
-+	ib_conn = iscsi_iser_ib_conn_lookup(transport_eph);
-+	if (!ib_conn) {
- 		iser_err("can't bind eph %llx\n",
- 			 (unsigned long long)transport_eph);
- 		return -EINVAL;
- 	}
--	ib_conn = ep->dd_data;
--
- 	/* binds the iSER connection retrieved from the previously
- 	 * connected ep_handle to the iSCSI layer connection. exchanges
- 	 * connection pointers */
-@@ -335,30 +344,10 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
- 	iser_conn = conn->dd_data;
- 	ib_conn->iser_conn = iser_conn;
- 	iser_conn->ib_conn  = ib_conn;
--	iser_conn_get(ib_conn);
--	return 0;
--}
- 
--static void
--iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
--{
--	struct iscsi_conn *conn = cls_conn->dd_data;
--	struct iscsi_iser_conn *iser_conn = conn->dd_data;
--	struct iser_conn *ib_conn = iser_conn->ib_conn;
-+	conn->recv_lock = &iser_conn->lock;
- 
--	/*
--	 * Userspace may have goofed up and not bound the connection or
--	 * might have only partially setup the connection.
--	 */
--	if (ib_conn) {
--		iscsi_conn_stop(cls_conn, flag);
--		/*
--		 * There is no unbind event so the stop callback
--		 * must release the ref from the bind.
--		 */
--		iser_conn_put(ib_conn);
--	}
--	iser_conn->ib_conn = NULL;
-+	return 0;
- }
- 
- static int
-@@ -374,75 +363,55 @@ iscsi_iser_conn_start(struct iscsi_cls_c
- 	return iscsi_conn_start(cls_conn);
- }
- 
--static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
--{
--	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
--
--	iscsi_host_remove(shost);
--	iscsi_host_free(shost);
--}
-+static struct iscsi_transport iscsi_iser_transport;
- 
- static struct iscsi_cls_session *
--iscsi_iser_session_create(struct iscsi_endpoint *ep,
--			  uint16_t cmds_max, uint16_t qdepth,
--			  uint32_t initial_cmdsn, uint32_t *hostno)
-+iscsi_iser_session_create(struct iscsi_transport *iscsit,
-+			 struct scsi_transport_template *scsit,
-+			 uint16_t cmds_max, uint16_t qdepth,
-+			 uint32_t initial_cmdsn, uint32_t *hostno)
- {
- 	struct iscsi_cls_session *cls_session;
- 	struct iscsi_session *session;
--	struct Scsi_Host *shost;
- 	int i;
--	struct iscsi_task *task;
--	struct iscsi_iser_task *iser_task;
--	struct iser_conn *ib_conn;
--
--	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
--	if (!shost)
--		return NULL;
--	shost->transportt = iscsi_iser_scsi_transport;
--	shost->max_lun = iscsi_max_lun;
--	shost->max_id = 0;
--	shost->max_channel = 0;
--	shost->max_cmd_len = 16;
--
--	/*
--	 * older userspace tools (before 2.0-870) did not pass us
--	 * the leading conn's ep so this will be NULL;
--	 */
--	if (ep)
--		ib_conn = ep->dd_data;
--
--	if (iscsi_host_add(shost,
--			   ep ? ib_conn->device->ib_device->dma_device : NULL))
--		goto free_host;
--	*hostno = shost->host_no;
-+	uint32_t hn;
-+	struct iscsi_cmd_task  *ctask;
-+	struct iscsi_mgmt_task *mtask;
-+	struct iscsi_iser_cmd_task *iser_ctask;
-+	struct iser_desc *desc;
- 
- 	/*
- 	 * we do not support setting can_queue cmd_per_lun from userspace yet
- 	 * because we preallocate so many resources
- 	 */
--	cls_session = iscsi_session_setup(&iscsi_iser_transport, shost,
-+	cls_session = iscsi_session_setup(iscsit, scsit,
- 					  ISCSI_DEF_XMIT_CMDS_MAX,
--					  sizeof(struct iscsi_iser_task),
--					  initial_cmdsn, 0);
-+					  ISCSI_MAX_CMD_PER_LUN,
-+					  sizeof(struct iscsi_iser_cmd_task),
-+					  sizeof(struct iser_desc),
-+					  initial_cmdsn, &hn);
- 	if (!cls_session)
--		goto remove_host;
--	session = cls_session->dd_data;
-+	return NULL;
-+
-+	*hostno = hn;
-+	session = class_to_transport_session(cls_session);
- 
--	shost->can_queue = session->scsi_cmds_max;
- 	/* libiscsi setup itts, data and pool so just set desc fields */
- 	for (i = 0; i < session->cmds_max; i++) {
--		task = session->cmds[i];
--		iser_task = task->dd_data;
--		task->hdr = (struct iscsi_cmd *)&iser_task->desc.iscsi_header;
--		task->hdr_max = sizeof(iser_task->desc.iscsi_header);
-+		ctask      = session->cmds[i];
-+		iser_ctask = ctask->dd_data;
-+		ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header;
-+		ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header);
- 	}
--	return cls_session;
- 
--remove_host:
--	iscsi_host_remove(shost);
--free_host:
--	iscsi_host_free(shost);
--	return NULL;
-+	for (i = 0; i < session->mgmtpool_max; i++) {
-+		mtask      = session->mgmt_cmds[i];
-+		desc       = mtask->dd_data;
-+		mtask->hdr = &desc->iscsi_header;
-+		desc->data = mtask->data;
-+	}
-+
-+	return cls_session;
- }
- 
- static int
-@@ -515,37 +484,34 @@ iscsi_iser_conn_get_stats(struct iscsi_c
- 	stats->custom[3].value = conn->fmr_unalign_cnt;
- }
- 
--static struct iscsi_endpoint *
--iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking)
-+static int
-+iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking,
-+		      __u64 *ep_handle)
- {
- 	int err;
- 	struct iser_conn *ib_conn;
--	struct iscsi_endpoint *ep;
- 
--	ep = iscsi_create_endpoint(sizeof(*ib_conn));
--	if (!ep)
--		return ERR_PTR(-ENOMEM);
--
--	ib_conn = ep->dd_data;
--	ib_conn->ep = ep;
--	iser_conn_init(ib_conn);
--
--	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr,
--			   non_blocking);
--	if (err) {
--		iscsi_destroy_endpoint(ep);
--		return ERR_PTR(err);
--	}
--	return ep;
-+	err = iser_conn_init(&ib_conn);
-+	if (err)
-+		goto out;
-+
-+	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking);
-+	if (!err)
-+		*ep_handle = (__u64)(unsigned long)ib_conn;
-+
-+out:
-+	return err;
- }
- 
- static int
--iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
-+iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms)
- {
--	struct iser_conn *ib_conn;
-+	struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
- 	int rc;
- 
--	ib_conn = ep->dd_data;
-+	if (!ib_conn)
-+		return -EINVAL;
-+
- 	rc = wait_event_interruptible_timeout(ib_conn->wait,
- 			     ib_conn->state == ISER_CONN_UP,
- 			     msecs_to_jiffies(timeout_ms));
-@@ -567,21 +533,13 @@ iscsi_iser_ep_poll(struct iscsi_endpoint
- }
- 
- static void
--iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
-+iscsi_iser_ep_disconnect(__u64 ep_handle)
- {
- 	struct iser_conn *ib_conn;
- 
--	ib_conn = ep->dd_data;
--	if (ib_conn->iser_conn)
--		/*
--		 * Must suspend xmit path if the ep is bound to the
--		 * iscsi_conn, so we know we are not accessing the ib_conn
--		 * when we free it.
--		 *
--		 * This may not be bound if the ep poll failed.
--		 */
--		iscsi_suspend_tx(ib_conn->iser_conn->iscsi_conn);
--
-+	ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
-+	if (!ib_conn)
-+		return;
- 
- 	iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state);
- 	iser_conn_terminate(ib_conn);
-@@ -592,6 +550,7 @@ static struct scsi_host_template iscsi_i
- 	.name                   = "iSCSI Initiator over iSER, v." DRV_VER,
- 	.queuecommand           = iscsi_queuecommand,
- 	.change_queue_depth	= iscsi_change_queue_depth,
-+	.can_queue		= ISCSI_DEF_XMIT_CMDS_MAX - 1,
- 	.sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
- 	.max_sectors		= 1024,
- 	.cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
-@@ -625,14 +584,17 @@ static struct iscsi_transport iscsi_iser
- 				  ISCSI_USERNAME | ISCSI_PASSWORD |
- 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
- 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
--				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
--				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
-+				  ISCSI_PING_TMO | ISCSI_RECV_TMO,
- 	.host_param_mask	= ISCSI_HOST_HWADDRESS |
- 				  ISCSI_HOST_NETDEV_NAME |
- 				  ISCSI_HOST_INITIATOR_NAME,
-+	.host_template          = &iscsi_iser_sht,
-+	.conndata_size		= sizeof(struct iscsi_conn),
-+	.max_lun                = ISCSI_ISER_MAX_LUN,
-+	.max_cmd_len            = ISCSI_ISER_MAX_CMD_LEN,
- 	/* session management */
- 	.create_session         = iscsi_iser_session_create,
--	.destroy_session        = iscsi_iser_session_destroy,
-+	.destroy_session        = iscsi_session_teardown,
- 	/* connection management */
- 	.create_conn            = iscsi_iser_conn_create,
- 	.bind_conn              = iscsi_iser_conn_bind,
-@@ -641,16 +603,17 @@ static struct iscsi_transport iscsi_iser
- 	.get_conn_param		= iscsi_conn_get_param,
- 	.get_session_param	= iscsi_session_get_param,
- 	.start_conn             = iscsi_iser_conn_start,
--	.stop_conn              = iscsi_iser_conn_stop,
-+	.stop_conn              = iscsi_conn_stop,
- 	/* iscsi host params */
- 	.get_host_param		= iscsi_host_get_param,
- 	.set_host_param		= iscsi_host_set_param,
- 	/* IO */
- 	.send_pdu		= iscsi_conn_send_pdu,
- 	.get_stats		= iscsi_iser_conn_get_stats,
--	.init_task		= iscsi_iser_task_init,
--	.xmit_task		= iscsi_iser_task_xmit,
--	.cleanup_task		= iscsi_iser_cleanup_task,
-+	.init_cmd_task		= iscsi_iser_cmd_init,
-+	.xmit_cmd_task		= iscsi_iser_ctask_xmit,
-+	.xmit_mgmt_task		= iscsi_iser_mtask_xmit,
-+	.cleanup_cmd_task	= iscsi_iser_cleanup_ctask,
- 	/* recovery */
- 	.session_recovery_timedout = iscsi_session_recovery_timedout,
- 
-@@ -670,6 +633,8 @@ static int __init iser_init(void)
- 		return -EINVAL;
- 	}
- 
-+	iscsi_iser_transport.max_lun = iscsi_max_lun;
-+
- 	memset(&ig, 0, sizeof(struct iser_global));
- 
- 	ig.desc_cache = kmem_cache_create("iser_descriptors",
-@@ -685,9 +650,7 @@ static int __init iser_init(void)
- 	mutex_init(&ig.connlist_mutex);
- 	INIT_LIST_HEAD(&ig.connlist);
- 
--	iscsi_iser_scsi_transport = iscsi_register_transport(
--							&iscsi_iser_transport);
--	if (!iscsi_iser_scsi_transport) {
-+	if (!iscsi_register_transport(&iscsi_iser_transport)) {
- 		iser_err("iscsi_register_transport failed\n");
- 		err = -EINVAL;
- 		goto register_transport_failure;
-Index: ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
-+++ ofed_kernel/drivers/infiniband/ulp/iser/iscsi_iser.h
-@@ -36,6 +36,8 @@
-  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  * SOFTWARE.
-+ *
-+ * $Id: iscsi_iser.h 7051 2006-05-10 12:29:11Z ogerlitz $
-  */
- #ifndef __ISCSI_ISER_H__
- #define __ISCSI_ISER_H__
-@@ -94,6 +96,7 @@
- 					/* support upto 512KB in one RDMA */
- #define ISCSI_ISER_SG_TABLESIZE         (0x80000 >> SHIFT_4K)
- #define ISCSI_ISER_MAX_LUN		256
-+#define ISCSI_ISER_MAX_CMD_LEN		16
- 
- /* QP settings */
- /* Maximal bounds on received asynchronous PDUs */
-@@ -171,8 +174,7 @@ struct iser_data_buf {
- /* fwd declarations */
- struct iser_device;
- struct iscsi_iser_conn;
--struct iscsi_iser_task;
--struct iscsi_endpoint;
-+struct iscsi_iser_cmd_task;
- 
- struct iser_mem_reg {
- 	u32  lkey;
-@@ -196,7 +198,7 @@ struct iser_regd_buf {
- #define MAX_REGD_BUF_VECTOR_LEN	2
- 
- struct iser_dto {
--	struct iscsi_iser_task *task;
-+	struct iscsi_iser_cmd_task *ctask;
- 	struct iser_conn *ib_conn;
- 	int                        notify_enable;
- 
-@@ -240,9 +242,7 @@ struct iser_device {
- 
- struct iser_conn {
- 	struct iscsi_iser_conn       *iser_conn; /* iser conn for upcalls  */
--	struct iscsi_endpoint	     *ep;
- 	enum iser_ib_conn_state	     state;	    /* rdma connection state   */
--	atomic_t		     refcount;
- 	spinlock_t		     lock;	    /* used for state changes  */
- 	struct iser_device           *device;       /* device context          */
- 	struct rdma_cm_id            *cma_id;       /* CMA ID		       */
-@@ -261,9 +261,11 @@ struct iser_conn {
- struct iscsi_iser_conn {
- 	struct iscsi_conn            *iscsi_conn;/* ptr to iscsi conn */
- 	struct iser_conn             *ib_conn;   /* iSER IB conn      */
-+
-+	rwlock_t		     lock;
- };
- 
--struct iscsi_iser_task {
-+struct iscsi_iser_cmd_task {
- 	struct iser_desc             desc;
- 	struct iscsi_iser_conn	     *iser_conn;
- 	enum iser_task_status 	     status;
-@@ -296,26 +298,22 @@ extern int iser_debug_level;
- /* allocate connection resources needed for rdma functionality */
- int iser_conn_set_full_featured_mode(struct iscsi_conn *conn);
- 
--int iser_send_control(struct iscsi_conn *conn,
--		      struct iscsi_task *task);
-+int iser_send_control(struct iscsi_conn      *conn,
-+		      struct iscsi_mgmt_task *mtask);
- 
--int iser_send_command(struct iscsi_conn *conn,
--		      struct iscsi_task *task);
-+int iser_send_command(struct iscsi_conn      *conn,
-+		      struct iscsi_cmd_task  *ctask);
- 
--int iser_send_data_out(struct iscsi_conn *conn,
--		       struct iscsi_task *task,
--		       struct iscsi_data *hdr);
-+int iser_send_data_out(struct iscsi_conn     *conn,
-+		       struct iscsi_cmd_task *ctask,
-+		       struct iscsi_data          *hdr);
- 
- void iscsi_iser_recv(struct iscsi_conn *conn,
- 		     struct iscsi_hdr       *hdr,
- 		     char                   *rx_data,
- 		     int                    rx_data_len);
- 
--void iser_conn_init(struct iser_conn *ib_conn);
--
--void iser_conn_get(struct iser_conn *ib_conn);
--
--void iser_conn_put(struct iser_conn *ib_conn);
-+int  iser_conn_init(struct iser_conn **ib_conn);
- 
- void iser_conn_terminate(struct iser_conn *ib_conn);
- 
-@@ -324,9 +322,9 @@ void iser_rcv_completion(struct iser_des
- 
- void iser_snd_completion(struct iser_desc *desc);
- 
--void iser_task_rdma_init(struct iscsi_iser_task *task);
-+void iser_ctask_rdma_init(struct iscsi_iser_cmd_task     *ctask);
- 
--void iser_task_rdma_finalize(struct iscsi_iser_task *task);
-+void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask);
- 
- void iser_dto_buffs_release(struct iser_dto *dto);
- 
-@@ -336,10 +334,10 @@ void iser_reg_single(struct iser_device 
- 		     struct iser_regd_buf    *regd_buf,
- 		     enum dma_data_direction direction);
- 
--void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
-+void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask,
- 				     enum iser_data_dir         cmd_dir);
- 
--int  iser_reg_rdma_mem(struct iscsi_iser_task *task,
-+int  iser_reg_rdma_mem(struct iscsi_iser_cmd_task *ctask,
- 		       enum   iser_data_dir        cmd_dir);
- 
- int  iser_connect(struct iser_conn   *ib_conn,
-@@ -359,10 +357,10 @@ int  iser_post_send(struct iser_desc *tx
- int iser_conn_state_comp(struct iser_conn *ib_conn,
- 			 enum iser_ib_conn_state comp);
- 
--int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
-+int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
- 			    struct iser_data_buf       *data,
- 			    enum   iser_data_dir       iser_dir,
- 			    enum   dma_data_direction  dma_dir);
- 
--void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
-+void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask);
- #endif
-Index: ofed_kernel/drivers/infiniband/ulp/iser/iser_initiator.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/iser/iser_initiator.c
-+++ ofed_kernel/drivers/infiniband/ulp/iser/iser_initiator.c
-@@ -28,6 +28,8 @@
-  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  * SOFTWARE.
-+ *
-+ * $Id: iser_initiator.c 6964 2006-05-07 11:11:43Z ogerlitz $
-  */
- #include <linux/kernel.h>
- #include <linux/slab.h>
-@@ -64,46 +66,46 @@ static void iser_dto_add_regd_buff(struc
- 
- /* Register user buffer memory and initialize passive rdma
-  *  dto descriptor. Total data size is stored in
-- *  iser_task->data[ISER_DIR_IN].data_len
-+ *  iser_ctask->data[ISER_DIR_IN].data_len
-  */
--static int iser_prepare_read_cmd(struct iscsi_task *task,
-+static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask,
- 				 unsigned int edtl)
- 
- {
--	struct iscsi_iser_task *iser_task = task->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 	struct iser_regd_buf *regd_buf;
- 	int err;
--	struct iser_hdr *hdr = &iser_task->desc.iser_header;
--	struct iser_data_buf *buf_in = &iser_task->data[ISER_DIR_IN];
-+	struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
-+	struct iser_data_buf *buf_in = &iser_ctask->data[ISER_DIR_IN];
- 
--	err = iser_dma_map_task_data(iser_task,
-+	err = iser_dma_map_task_data(iser_ctask,
- 				     buf_in,
- 				     ISER_DIR_IN,
- 				     DMA_FROM_DEVICE);
- 	if (err)
- 		return err;
- 
--	if (edtl > iser_task->data[ISER_DIR_IN].data_len) {
-+	if (edtl > iser_ctask->data[ISER_DIR_IN].data_len) {
- 		iser_err("Total data length: %ld, less than EDTL: "
- 			 "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
--			 iser_task->data[ISER_DIR_IN].data_len, edtl,
--			 task->itt, iser_task->iser_conn);
-+			 iser_ctask->data[ISER_DIR_IN].data_len, edtl,
-+			 ctask->itt, iser_ctask->iser_conn);
- 		return -EINVAL;
- 	}
- 
--	err = iser_reg_rdma_mem(iser_task,ISER_DIR_IN);
-+	err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_IN);
- 	if (err) {
- 		iser_err("Failed to set up Data-IN RDMA\n");
- 		return err;
- 	}
--	regd_buf = &iser_task->rdma_regd[ISER_DIR_IN];
-+	regd_buf = &iser_ctask->rdma_regd[ISER_DIR_IN];
- 
- 	hdr->flags    |= ISER_RSV;
- 	hdr->read_stag = cpu_to_be32(regd_buf->reg.rkey);
- 	hdr->read_va   = cpu_to_be64(regd_buf->reg.va);
- 
- 	iser_dbg("Cmd itt:%d READ tags RKEY:%#.4X VA:%#llX\n",
--		 task->itt, regd_buf->reg.rkey,
-+		 ctask->itt, regd_buf->reg.rkey,
- 		 (unsigned long long)regd_buf->reg.va);
- 
- 	return 0;
-@@ -111,43 +113,43 @@ static int iser_prepare_read_cmd(struct 
- 
- /* Register user buffer memory and initialize passive rdma
-  *  dto descriptor. Total data size is stored in
-- *  task->data[ISER_DIR_OUT].data_len
-+ *  ctask->data[ISER_DIR_OUT].data_len
-  */
- static int
--iser_prepare_write_cmd(struct iscsi_task *task,
-+iser_prepare_write_cmd(struct iscsi_cmd_task *ctask,
- 		       unsigned int imm_sz,
- 		       unsigned int unsol_sz,
- 		       unsigned int edtl)
- {
--	struct iscsi_iser_task *iser_task = task->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 	struct iser_regd_buf *regd_buf;
- 	int err;
--	struct iser_dto *send_dto = &iser_task->desc.dto;
--	struct iser_hdr *hdr = &iser_task->desc.iser_header;
--	struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
-+	struct iser_dto *send_dto = &iser_ctask->desc.dto;
-+	struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
-+	struct iser_data_buf *buf_out = &iser_ctask->data[ISER_DIR_OUT];
- 
--	err = iser_dma_map_task_data(iser_task,
-+	err = iser_dma_map_task_data(iser_ctask,
- 				     buf_out,
- 				     ISER_DIR_OUT,
- 				     DMA_TO_DEVICE);
- 	if (err)
- 		return err;
- 
--	if (edtl > iser_task->data[ISER_DIR_OUT].data_len) {
-+	if (edtl > iser_ctask->data[ISER_DIR_OUT].data_len) {
- 		iser_err("Total data length: %ld, less than EDTL: %d, "
- 			 "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
--			 iser_task->data[ISER_DIR_OUT].data_len,
--			 edtl, task->itt, task->conn);
-+			 iser_ctask->data[ISER_DIR_OUT].data_len,
-+			 edtl, ctask->itt, ctask->conn);
- 		return -EINVAL;
- 	}
- 
--	err = iser_reg_rdma_mem(iser_task,ISER_DIR_OUT);
-+	err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_OUT);
- 	if (err != 0) {
- 		iser_err("Failed to register write cmd RDMA mem\n");
- 		return err;
- 	}
- 
--	regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
-+	regd_buf = &iser_ctask->rdma_regd[ISER_DIR_OUT];
- 
- 	if (unsol_sz < edtl) {
- 		hdr->flags     |= ISER_WSV;
-@@ -156,13 +158,13 @@ iser_prepare_write_cmd(struct iscsi_task
- 
- 		iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X "
- 			 "VA:%#llX + unsol:%d\n",
--			 task->itt, regd_buf->reg.rkey,
-+			 ctask->itt, regd_buf->reg.rkey,
- 			 (unsigned long long)regd_buf->reg.va, unsol_sz);
- 	}
- 
- 	if (imm_sz > 0) {
- 		iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
--			 task->itt, imm_sz);
-+			 ctask->itt, imm_sz);
- 		iser_dto_add_regd_buff(send_dto,
- 				       regd_buf,
- 				       0,
-@@ -314,38 +316,38 @@ iser_check_xmit(struct iscsi_conn *conn,
- /**
-  * iser_send_command - send command PDU
-  */
--int iser_send_command(struct iscsi_conn *conn,
--		      struct iscsi_task *task)
-+int iser_send_command(struct iscsi_conn     *conn,
-+		      struct iscsi_cmd_task *ctask)
- {
- 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
--	struct iscsi_iser_task *iser_task = task->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 	struct iser_dto *send_dto = NULL;
- 	unsigned long edtl;
- 	int err = 0;
- 	struct iser_data_buf *data_buf;
- 
--	struct iscsi_cmd *hdr =  task->hdr;
--	struct scsi_cmnd *sc  =  task->sc;
-+	struct iscsi_cmd *hdr =  ctask->hdr;
-+	struct scsi_cmnd *sc  =  ctask->sc;
- 
- 	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
- 		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
- 		return -EPERM;
- 	}
--	if (iser_check_xmit(conn, task))
-+	if (iser_check_xmit(conn, ctask))
- 		return -ENOBUFS;
- 
- 	edtl = ntohl(hdr->data_length);
- 
- 	/* build the tx desc regd header and add it to the tx desc dto */
--	iser_task->desc.type = ISCSI_TX_SCSI_COMMAND;
--	send_dto = &iser_task->desc.dto;
--	send_dto->task = iser_task;
--	iser_create_send_desc(iser_conn, &iser_task->desc);
-+	iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND;
-+	send_dto = &iser_ctask->desc.dto;
-+	send_dto->ctask = iser_ctask;
-+	iser_create_send_desc(iser_conn, &iser_ctask->desc);
- 
- 	if (hdr->flags & ISCSI_FLAG_CMD_READ)
--		data_buf = &iser_task->data[ISER_DIR_IN];
-+		data_buf = &iser_ctask->data[ISER_DIR_IN];
- 	else
--		data_buf = &iser_task->data[ISER_DIR_OUT];
-+		data_buf = &iser_ctask->data[ISER_DIR_OUT];
- 
- 	if (scsi_sg_count(sc)) { /* using a scatter list */
- 		data_buf->buf  = scsi_sglist(sc);
-@@ -355,15 +357,15 @@ int iser_send_command(struct iscsi_conn 
- 	data_buf->data_len = scsi_bufflen(sc);
- 
- 	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
--		err = iser_prepare_read_cmd(task, edtl);
-+		err = iser_prepare_read_cmd(ctask, edtl);
- 		if (err)
- 			goto send_command_error;
- 	}
- 	if (hdr->flags & ISCSI_FLAG_CMD_WRITE) {
--		err = iser_prepare_write_cmd(task,
--					     task->imm_count,
--				             task->imm_count +
--					     task->unsol_count,
-+		err = iser_prepare_write_cmd(ctask,
-+					     ctask->imm_count,
-+				             ctask->imm_count +
-+					     ctask->unsol_count,
- 					     edtl);
- 		if (err)
- 			goto send_command_error;
-@@ -378,27 +380,27 @@ int iser_send_command(struct iscsi_conn 
- 		goto send_command_error;
- 	}
- 
--	iser_task->status = ISER_TASK_STATUS_STARTED;
-+	iser_ctask->status = ISER_TASK_STATUS_STARTED;
- 
--	err = iser_post_send(&iser_task->desc);
-+	err = iser_post_send(&iser_ctask->desc);
- 	if (!err)
- 		return 0;
- 
- send_command_error:
- 	iser_dto_buffs_release(send_dto);
--	iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
-+	iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err);
- 	return err;
- }
- 
- /**
-  * iser_send_data_out - send data out PDU
-  */
--int iser_send_data_out(struct iscsi_conn *conn,
--		       struct iscsi_task *task,
-+int iser_send_data_out(struct iscsi_conn     *conn,
-+		       struct iscsi_cmd_task *ctask,
- 		       struct iscsi_data *hdr)
- {
- 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
--	struct iscsi_iser_task *iser_task = task->dd_data;
-+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
- 	struct iser_desc *tx_desc = NULL;
- 	struct iser_dto *send_dto = NULL;
- 	unsigned long buf_offset;
-@@ -411,7 +413,7 @@ int iser_send_data_out(struct iscsi_conn
- 		return -EPERM;
- 	}
- 
--	if (iser_check_xmit(conn, task))
-+	if (iser_check_xmit(conn, ctask))
- 		return -ENOBUFS;
- 
- 	itt = (__force uint32_t)hdr->itt;
-@@ -432,7 +434,7 @@ int iser_send_data_out(struct iscsi_conn
- 
- 	/* build the tx desc regd header and add it to the tx desc dto */
- 	send_dto = &tx_desc->dto;
--	send_dto->task = iser_task;
-+	send_dto->ctask = iser_ctask;
- 	iser_create_send_desc(iser_conn, tx_desc);
- 
- 	iser_reg_single(iser_conn->ib_conn->device,
-@@ -440,15 +442,15 @@ int iser_send_data_out(struct iscsi_conn
- 
- 	/* all data was registered for RDMA, we can use the lkey */
- 	iser_dto_add_regd_buff(send_dto,
--			       &iser_task->rdma_regd[ISER_DIR_OUT],
-+			       &iser_ctask->rdma_regd[ISER_DIR_OUT],
- 			       buf_offset,
- 			       data_seg_len);
- 
--	if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
-+	if (buf_offset + data_seg_len > iser_ctask->data[ISER_DIR_OUT].data_len) {
- 		iser_err("Offset:%ld & DSL:%ld in Data-Out "
- 			 "inconsistent with total len:%ld, itt:%d\n",
- 			 buf_offset, data_seg_len,
--			 iser_task->data[ISER_DIR_OUT].data_len, itt);
-+			 iser_ctask->data[ISER_DIR_OUT].data_len, itt);
- 		err = -EINVAL;
- 		goto send_data_out_error;
- 	}
-@@ -468,11 +470,10 @@ send_data_out_error:
- }
- 
- int iser_send_control(struct iscsi_conn *conn,
--		      struct iscsi_task *task)
-+		      struct iscsi_mgmt_task *mtask)
- {
- 	struct iscsi_iser_conn *iser_conn = conn->dd_data;
--	struct iscsi_iser_task *iser_task = task->dd_data;
--	struct iser_desc *mdesc = &iser_task->desc;
-+	struct iser_desc *mdesc = mtask->dd_data;
- 	struct iser_dto *send_dto = NULL;
- 	unsigned long data_seg_len;
- 	int err = 0;
-@@ -484,27 +485,27 @@ int iser_send_control(struct iscsi_conn 
- 		return -EPERM;
- 	}
- 
--	if (iser_check_xmit(conn, task))
-+	if (iser_check_xmit(conn,mtask))
- 		return -ENOBUFS;
- 
- 	/* build the tx desc regd header and add it to the tx desc dto */
- 	mdesc->type = ISCSI_TX_CONTROL;
- 	send_dto = &mdesc->dto;
--	send_dto->task = NULL;
-+	send_dto->ctask = NULL;
- 	iser_create_send_desc(iser_conn, mdesc);
- 
- 	device = iser_conn->ib_conn->device;
- 
- 	iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
- 
--	data_seg_len = ntoh24(task->hdr->dlength);
-+	data_seg_len = ntoh24(mtask->hdr->dlength);
- 
- 	if (data_seg_len > 0) {
- 		regd_buf = &mdesc->data_regd_buf;
- 		memset(regd_buf, 0, sizeof(struct iser_regd_buf));
- 		regd_buf->device = device;
--		regd_buf->virt_addr = task->data;
--		regd_buf->data_size = task->data_count;
-+		regd_buf->virt_addr = mtask->data;
-+		regd_buf->data_size = mtask->data_count;
- 		iser_reg_single(device, regd_buf,
- 				DMA_TO_DEVICE);
- 		iser_dto_add_regd_buff(send_dto, regd_buf,
-@@ -534,13 +535,15 @@ send_control_error:
- void iser_rcv_completion(struct iser_desc *rx_desc,
- 			 unsigned long dto_xfer_len)
- {
--	struct iser_dto *dto = &rx_desc->dto;
-+	struct iser_dto        *dto = &rx_desc->dto;
- 	struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
--	struct iscsi_task *task;
--	struct iscsi_iser_task *iser_task;
-+	struct iscsi_session *session = conn->iscsi_conn->session;
-+	struct iscsi_cmd_task *ctask;
-+	struct iscsi_iser_cmd_task *iser_ctask;
- 	struct iscsi_hdr *hdr;
- 	char   *rx_data = NULL;
- 	int     rx_data_len = 0;
-+	unsigned int itt;
- 	unsigned char opcode;
- 
- 	hdr = &rx_desc->iscsi_header;
-@@ -556,24 +559,19 @@ void iser_rcv_completion(struct iser_des
- 	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
- 
- 	if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
--		spin_lock(&conn->iscsi_conn->session->lock);
--		task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
--		if (task)
--			__iscsi_get_task(task);
--		spin_unlock(&conn->iscsi_conn->session->lock);
--
--		if (!task)
-+	        itt = get_itt(hdr->itt); /* mask out cid and age bits */
-+		if (!(itt < session->cmds_max))
- 			iser_err("itt can't be matched to task!!! "
--				 "conn %p opcode %d itt %d\n",
--				 conn->iscsi_conn, opcode, hdr->itt);
--		else {
--			iser_task = task->dd_data;
--			iser_dbg("itt %d task %p\n",hdr->itt, task);
--			iser_task->status = ISER_TASK_STATUS_COMPLETED;
--			iser_task_rdma_finalize(iser_task);
--			iscsi_put_task(task);
--		}
-+				 "conn %p opcode %d cmds_max %d itt %d\n",
-+				 conn->iscsi_conn,opcode,session->cmds_max,itt);
-+		/* use the mapping given with the cmds array indexed by itt */
-+		ctask = (struct iscsi_cmd_task *)session->cmds[itt];
-+		iser_ctask = ctask->dd_data;
-+		iser_dbg("itt %d ctask %p\n",itt,ctask);
-+		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
-+		iser_ctask_rdma_finalize(iser_ctask);
- 	}
-+
- 	iser_dto_buffs_release(dto);
- 
- 	iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
-@@ -594,7 +592,7 @@ void iser_snd_completion(struct iser_des
- 	struct iser_conn       *ib_conn = dto->ib_conn;
- 	struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
- 	struct iscsi_conn      *conn = iser_conn->iscsi_conn;
--	struct iscsi_task *task;
-+	struct iscsi_mgmt_task *mtask;
- 	int resume_tx = 0;
- 
- 	iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
-@@ -617,31 +615,36 @@ void iser_snd_completion(struct iser_des
- 
- 	if (tx_desc->type == ISCSI_TX_CONTROL) {
- 		/* this arithmetic is legal by libiscsi dd_data allocation */
--		task = (void *) ((long)(void *)tx_desc -
--				  sizeof(struct iscsi_task));
--		if (task->hdr->itt == RESERVED_ITT)
--			iscsi_put_task(task);
-+		mtask = (void *) ((long)(void *)tx_desc -
-+				  sizeof(struct iscsi_mgmt_task));
-+		if (mtask->hdr->itt == RESERVED_ITT) {
-+			struct iscsi_session *session = conn->session;
-+
-+			spin_lock(&conn->session->lock);
-+			iscsi_free_mgmt_task(conn, mtask);
-+			spin_unlock(&session->lock);
-+		}
- 	}
- }
- 
--void iser_task_rdma_init(struct iscsi_iser_task *iser_task)
-+void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask)
- 
- {
--	iser_task->status = ISER_TASK_STATUS_INIT;
-+	iser_ctask->status = ISER_TASK_STATUS_INIT;
- 
--	iser_task->dir[ISER_DIR_IN] = 0;
--	iser_task->dir[ISER_DIR_OUT] = 0;
-+	iser_ctask->dir[ISER_DIR_IN] = 0;
-+	iser_ctask->dir[ISER_DIR_OUT] = 0;
- 
--	iser_task->data[ISER_DIR_IN].data_len  = 0;
--	iser_task->data[ISER_DIR_OUT].data_len = 0;
-+	iser_ctask->data[ISER_DIR_IN].data_len  = 0;
-+	iser_ctask->data[ISER_DIR_OUT].data_len = 0;
- 
--	memset(&iser_task->rdma_regd[ISER_DIR_IN], 0,
-+	memset(&iser_ctask->rdma_regd[ISER_DIR_IN], 0,
- 	       sizeof(struct iser_regd_buf));
--	memset(&iser_task->rdma_regd[ISER_DIR_OUT], 0,
-+	memset(&iser_ctask->rdma_regd[ISER_DIR_OUT], 0,
- 	       sizeof(struct iser_regd_buf));
- }
- 
--void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
-+void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
- {
- 	int deferred;
- 	int is_rdma_aligned = 1;
-@@ -650,17 +653,17 @@ void iser_task_rdma_finalize(struct iscs
- 	/* if we were reading, copy back to unaligned sglist,
- 	 * anyway dma_unmap and free the copy
- 	 */
--	if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) {
-+	if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) {
- 		is_rdma_aligned = 0;
--		iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_IN);
-+		iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
- 	}
--	if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
-+	if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) {
- 		is_rdma_aligned = 0;
--		iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_OUT);
-+		iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
- 	}
- 
--	if (iser_task->dir[ISER_DIR_IN]) {
--		regd = &iser_task->rdma_regd[ISER_DIR_IN];
-+	if (iser_ctask->dir[ISER_DIR_IN]) {
-+		regd = &iser_ctask->rdma_regd[ISER_DIR_IN];
- 		deferred = iser_regd_buff_release(regd);
- 		if (deferred) {
- 			iser_err("%d references remain for BUF-IN rdma reg\n",
-@@ -668,8 +671,8 @@ void iser_task_rdma_finalize(struct iscs
- 		}
- 	}
- 
--	if (iser_task->dir[ISER_DIR_OUT]) {
--		regd = &iser_task->rdma_regd[ISER_DIR_OUT];
-+	if (iser_ctask->dir[ISER_DIR_OUT]) {
-+		regd = &iser_ctask->rdma_regd[ISER_DIR_OUT];
- 		deferred = iser_regd_buff_release(regd);
- 		if (deferred) {
- 			iser_err("%d references remain for BUF-OUT rdma reg\n",
-@@ -679,7 +682,7 @@ void iser_task_rdma_finalize(struct iscs
- 
-        /* if the data was unaligned, it was already unmapped and then copied */
-        if (is_rdma_aligned)
--		iser_dma_unmap_task_data(iser_task);
-+		iser_dma_unmap_task_data(iser_ctask);
- }
- 
- void iser_dto_buffs_release(struct iser_dto *dto)
-Index: ofed_kernel/drivers/infiniband/ulp/iser/iser_memory.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/iser/iser_memory.c
-+++ ofed_kernel/drivers/infiniband/ulp/iser/iser_memory.c
-@@ -28,6 +28,8 @@
-  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  * SOFTWARE.
-+ *
-+ * $Id: iser_memory.c 6964 2006-05-07 11:11:43Z ogerlitz $
-  */
- #include <linux/module.h>
- #include <linux/kernel.h>
-@@ -99,13 +101,13 @@ void iser_reg_single(struct iser_device 
- /**
-  * iser_start_rdma_unaligned_sg
-  */
--static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
-+static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
- 					enum iser_data_dir cmd_dir)
- {
- 	int dma_nents;
- 	struct ib_device *dev;
- 	char *mem = NULL;
--	struct iser_data_buf *data = &iser_task->data[cmd_dir];
-+	struct iser_data_buf *data = &iser_ctask->data[cmd_dir];
- 	unsigned long  cmd_data_len = data->data_len;
- 
- 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
-@@ -138,37 +140,37 @@ static int iser_start_rdma_unaligned_sg(
- 		}
- 	}
- 
--	sg_init_one(&iser_task->data_copy[cmd_dir].sg_single, mem, cmd_data_len);
--	iser_task->data_copy[cmd_dir].buf  =
--		&iser_task->data_copy[cmd_dir].sg_single;
--	iser_task->data_copy[cmd_dir].size = 1;
-+	sg_init_one(&iser_ctask->data_copy[cmd_dir].sg_single, mem, cmd_data_len);
-+	iser_ctask->data_copy[cmd_dir].buf  =
-+		&iser_ctask->data_copy[cmd_dir].sg_single;
-+	iser_ctask->data_copy[cmd_dir].size = 1;
- 
--	iser_task->data_copy[cmd_dir].copy_buf  = mem;
-+	iser_ctask->data_copy[cmd_dir].copy_buf  = mem;
- 
--	dev = iser_task->iser_conn->ib_conn->device->ib_device;
-+	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
- 	dma_nents = ib_dma_map_sg(dev,
--				  &iser_task->data_copy[cmd_dir].sg_single,
-+				  &iser_ctask->data_copy[cmd_dir].sg_single,
- 				  1,
- 				  (cmd_dir == ISER_DIR_OUT) ?
- 				  DMA_TO_DEVICE : DMA_FROM_DEVICE);
- 	BUG_ON(dma_nents == 0);
- 
--	iser_task->data_copy[cmd_dir].dma_nents = dma_nents;
-+	iser_ctask->data_copy[cmd_dir].dma_nents = dma_nents;
- 	return 0;
- }
- 
- /**
-  * iser_finalize_rdma_unaligned_sg
-  */
--void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
-+void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
- 				     enum iser_data_dir         cmd_dir)
- {
- 	struct ib_device *dev;
- 	struct iser_data_buf *mem_copy;
- 	unsigned long  cmd_data_len;
- 
--	dev = iser_task->iser_conn->ib_conn->device->ib_device;
--	mem_copy = &iser_task->data_copy[cmd_dir];
-+	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
-+	mem_copy = &iser_ctask->data_copy[cmd_dir];
- 
- 	ib_dma_unmap_sg(dev, &mem_copy->sg_single, 1,
- 			(cmd_dir == ISER_DIR_OUT) ?
-@@ -184,8 +186,8 @@ void iser_finalize_rdma_unaligned_sg(str
- 		/* copy back read RDMA to unaligned sg */
- 		mem	= mem_copy->copy_buf;
- 
--		sgl	= (struct scatterlist *)iser_task->data[ISER_DIR_IN].buf;
--		sg_size = iser_task->data[ISER_DIR_IN].size;
-+		sgl	= (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf;
-+		sg_size = iser_ctask->data[ISER_DIR_IN].size;
- 
- 		p = mem;
- 		for_each_sg(sgl, sg, sg_size, i) {
-@@ -198,7 +200,7 @@ void iser_finalize_rdma_unaligned_sg(str
- 		}
- 	}
- 
--	cmd_data_len = iser_task->data[cmd_dir].data_len;
-+	cmd_data_len = iser_ctask->data[cmd_dir].data_len;
- 
- 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
- 		free_pages((unsigned long)mem_copy->copy_buf,
-@@ -376,15 +378,15 @@ static void iser_page_vec_build(struct i
- 	}
- }
- 
--int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
--			    struct iser_data_buf *data,
--			    enum iser_data_dir iser_dir,
--			    enum dma_data_direction dma_dir)
-+int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
-+			    struct iser_data_buf       *data,
-+			    enum   iser_data_dir       iser_dir,
-+			    enum   dma_data_direction  dma_dir)
- {
- 	struct ib_device *dev;
- 
--	iser_task->dir[iser_dir] = 1;
--	dev = iser_task->iser_conn->ib_conn->device->ib_device;
-+	iser_ctask->dir[iser_dir] = 1;
-+	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
- 
- 	data->dma_nents = ib_dma_map_sg(dev, data->buf, data->size, dma_dir);
- 	if (data->dma_nents == 0) {
-@@ -394,20 +396,20 @@ int iser_dma_map_task_data(struct iscsi_
- 	return 0;
- }
- 
--void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task)
-+void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
- {
- 	struct ib_device *dev;
- 	struct iser_data_buf *data;
- 
--	dev = iser_task->iser_conn->ib_conn->device->ib_device;
-+	dev = iser_ctask->iser_conn->ib_conn->device->ib_device;
- 
--	if (iser_task->dir[ISER_DIR_IN]) {
--		data = &iser_task->data[ISER_DIR_IN];
-+	if (iser_ctask->dir[ISER_DIR_IN]) {
-+		data = &iser_ctask->data[ISER_DIR_IN];
- 		ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE);
- 	}
- 
--	if (iser_task->dir[ISER_DIR_OUT]) {
--		data = &iser_task->data[ISER_DIR_OUT];
-+	if (iser_ctask->dir[ISER_DIR_OUT]) {
-+		data = &iser_ctask->data[ISER_DIR_OUT];
- 		ib_dma_unmap_sg(dev, data->buf, data->size, DMA_TO_DEVICE);
- 	}
- }
-@@ -418,21 +420,21 @@ void iser_dma_unmap_task_data(struct isc
-  *
-  * returns 0 on success, errno code on failure
-  */
--int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task,
-+int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
- 		      enum   iser_data_dir        cmd_dir)
- {
--	struct iscsi_conn    *iscsi_conn = iser_task->iser_conn->iscsi_conn;
--	struct iser_conn     *ib_conn = iser_task->iser_conn->ib_conn;
-+	struct iscsi_conn    *iscsi_conn = iser_ctask->iser_conn->iscsi_conn;
-+	struct iser_conn     *ib_conn = iser_ctask->iser_conn->ib_conn;
- 	struct iser_device   *device = ib_conn->device;
- 	struct ib_device     *ibdev = device->ib_device;
--	struct iser_data_buf *mem = &iser_task->data[cmd_dir];
-+	struct iser_data_buf *mem = &iser_ctask->data[cmd_dir];
- 	struct iser_regd_buf *regd_buf;
- 	int aligned_len;
- 	int err;
- 	int i;
- 	struct scatterlist *sg;
- 
--	regd_buf = &iser_task->rdma_regd[cmd_dir];
-+	regd_buf = &iser_ctask->rdma_regd[cmd_dir];
- 
- 	aligned_len = iser_data_buf_aligned_len(mem, ibdev);
- 	if (aligned_len != mem->dma_nents) {
-@@ -442,13 +444,13 @@ int iser_reg_rdma_mem(struct iscsi_iser_
- 		iser_data_buf_dump(mem, ibdev);
- 
- 		/* unmap the command data before accessing it */
--		iser_dma_unmap_task_data(iser_task);
-+		iser_dma_unmap_task_data(iser_ctask);
- 
- 		/* allocate copy buf, if we are writing, copy the */
- 		/* unaligned scatterlist, dma map the copy        */
--		if (iser_start_rdma_unaligned_sg(iser_task, cmd_dir) != 0)
-+		if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0)
- 				return -ENOMEM;
--		mem = &iser_task->data_copy[cmd_dir];
-+		mem = &iser_ctask->data_copy[cmd_dir];
- 	}
- 
- 	/* if there a single dma entry, FMR is not needed */
-@@ -472,9 +474,8 @@ int iser_reg_rdma_mem(struct iscsi_iser_
- 		err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg);
- 		if (err) {
- 			iser_data_buf_dump(mem, ibdev);
--			iser_err("mem->dma_nents = %d (dlength = 0x%x)\n",
--				 mem->dma_nents,
--				 ntoh24(iser_task->desc.iscsi_header.dlength));
-+			iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", mem->dma_nents,
-+				 ntoh24(iser_ctask->desc.iscsi_header.dlength));
- 			iser_err("page_vec: data_size = 0x%x, length = %d, offset = 0x%x\n",
- 				 ib_conn->page_vec->data_size, ib_conn->page_vec->length,
- 				 ib_conn->page_vec->offset);
-Index: ofed_kernel/drivers/infiniband/ulp/iser/iser_verbs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/iser/iser_verbs.c
-+++ ofed_kernel/drivers/infiniband/ulp/iser/iser_verbs.c
-@@ -29,6 +29,8 @@
-  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  * SOFTWARE.
-+ *
-+ * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $
-  */
- #include <linux/kernel.h>
- #include <linux/module.h>
-@@ -322,18 +324,7 @@ static void iser_conn_release(struct ise
- 		iser_device_try_release(device);
- 	if (ib_conn->iser_conn)
- 		ib_conn->iser_conn->ib_conn = NULL;
--	iscsi_destroy_endpoint(ib_conn->ep);
--}
--
--void iser_conn_get(struct iser_conn *ib_conn)
--{
--	atomic_inc(&ib_conn->refcount);
--}
--
--void iser_conn_put(struct iser_conn *ib_conn)
--{
--	if (atomic_dec_and_test(&ib_conn->refcount))
--		iser_conn_release(ib_conn);
-+	kfree(ib_conn);
- }
- 
- /**
-@@ -357,7 +348,7 @@ void iser_conn_terminate(struct iser_con
- 	wait_event_interruptible(ib_conn->wait,
- 				 ib_conn->state == ISER_CONN_DOWN);
- 
--	iser_conn_put(ib_conn);
-+	iser_conn_release(ib_conn);
- }
- 
- static void iser_connect_error(struct rdma_cm_id *cma_id)
-@@ -482,7 +473,6 @@ static int iser_cma_handler(struct rdma_
- 		break;
- 	case RDMA_CM_EVENT_DISCONNECTED:
- 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
--	case RDMA_CM_EVENT_ADDR_CHANGE:
- 		iser_disconnected_handler(cma_id);
- 		break;
- 	default:
-@@ -492,15 +482,24 @@ static int iser_cma_handler(struct rdma_
- 	return ret;
- }
- 
--void iser_conn_init(struct iser_conn *ib_conn)
-+int iser_conn_init(struct iser_conn **ibconn)
- {
-+	struct iser_conn *ib_conn;
-+
-+	ib_conn = kzalloc(sizeof *ib_conn, GFP_KERNEL);
-+	if (!ib_conn) {
-+		iser_err("can't alloc memory for struct iser_conn\n");
-+		return -ENOMEM;
-+	}
- 	ib_conn->state = ISER_CONN_INIT;
- 	init_waitqueue_head(&ib_conn->wait);
- 	atomic_set(&ib_conn->post_recv_buf_count, 0);
- 	atomic_set(&ib_conn->post_send_buf_count, 0);
--	atomic_set(&ib_conn->refcount, 1);
- 	INIT_LIST_HEAD(&ib_conn->conn_list);
- 	spin_lock_init(&ib_conn->lock);
-+
-+	*ibconn = ib_conn;
-+	return 0;
- }
- 
-  /**
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iser_02_fix_iscsi_if_h.patch b/kernel_patches/backport/2.6.18-EL5.1/iser_02_fix_iscsi_if_h.patch
deleted file mode 100644
index 4371ddd..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iser_02_fix_iscsi_if_h.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From c703d2c0ca18a6a5b8f4ecbd5c02654a15fb11ff Mon Sep 17 00:00:00 2001
-From: Doron Shoham <dorons at voltaire.com>
-Date: Tue, 26 Aug 2008 14:26:17 +0300
-Subject: [PATCH] fix iscsi_if.h
-
-Signed-off-by: Doron Shoham <dorons at voltaire.com>
----
- include/scsi/iscsi_if.h |   93 ++++++++++++++++++++++--------------------------
- 1 file changed, 43 insertions(+), 50 deletions(-)
-
-Index: ofed_kernel/include/scsi/iscsi_if.h
-===================================================================
---- ofed_kernel.orig/include/scsi/iscsi_if.h
-+++ ofed_kernel/include/scsi/iscsi_if.h
-@@ -50,7 +50,6 @@ enum iscsi_uevent_e {
- 	ISCSI_UEVENT_TGT_DSCVR		= UEVENT_BASE + 15,
- 	ISCSI_UEVENT_SET_HOST_PARAM	= UEVENT_BASE + 16,
- 	ISCSI_UEVENT_UNBIND_SESSION	= UEVENT_BASE + 17,
--	ISCSI_UEVENT_CREATE_BOUND_SESSION	= UEVENT_BASE + 18,
- 
- 	/* up events */
- 	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1,
-@@ -79,12 +78,6 @@ struct iscsi_uevent {
- 			uint16_t	cmds_max;
- 			uint16_t	queue_depth;
- 		} c_session;
--		struct msg_create_bound_session {
--			uint64_t	ep_handle;
--			uint32_t	initial_cmdsn;
--			uint16_t	cmds_max;
--			uint16_t	queue_depth;
--		} c_bound_session;
- 		struct msg_destroy_session {
- 			uint32_t	sid;
- 		} d_session;
-@@ -257,49 +250,42 @@ enum iscsi_param {
- 
- 	ISCSI_PARAM_PING_TMO,
- 	ISCSI_PARAM_RECV_TMO,
--
--	ISCSI_PARAM_IFACE_NAME,
--	ISCSI_PARAM_ISID,
--	ISCSI_PARAM_INITIATOR_NAME,
- 	/* must always be last */
- 	ISCSI_PARAM_MAX,
- };
- 
--#define ISCSI_MAX_RECV_DLENGTH		(1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH)
--#define ISCSI_MAX_XMIT_DLENGTH		(1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH)
--#define ISCSI_HDRDGST_EN		(1ULL << ISCSI_PARAM_HDRDGST_EN)
--#define ISCSI_DATADGST_EN		(1ULL << ISCSI_PARAM_DATADGST_EN)
--#define ISCSI_INITIAL_R2T_EN		(1ULL << ISCSI_PARAM_INITIAL_R2T_EN)
--#define ISCSI_MAX_R2T			(1ULL << ISCSI_PARAM_MAX_R2T)
--#define ISCSI_IMM_DATA_EN		(1ULL << ISCSI_PARAM_IMM_DATA_EN)
--#define ISCSI_FIRST_BURST		(1ULL << ISCSI_PARAM_FIRST_BURST)
--#define ISCSI_MAX_BURST			(1ULL << ISCSI_PARAM_MAX_BURST)
--#define ISCSI_PDU_INORDER_EN		(1ULL << ISCSI_PARAM_PDU_INORDER_EN)
--#define ISCSI_DATASEQ_INORDER_EN	(1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN)
--#define ISCSI_ERL			(1ULL << ISCSI_PARAM_ERL)
--#define ISCSI_IFMARKER_EN		(1ULL << ISCSI_PARAM_IFMARKER_EN)
--#define ISCSI_OFMARKER_EN		(1ULL << ISCSI_PARAM_OFMARKER_EN)
--#define ISCSI_EXP_STATSN		(1ULL << ISCSI_PARAM_EXP_STATSN)
--#define ISCSI_TARGET_NAME		(1ULL << ISCSI_PARAM_TARGET_NAME)
--#define ISCSI_TPGT			(1ULL << ISCSI_PARAM_TPGT)
--#define ISCSI_PERSISTENT_ADDRESS	(1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS)
--#define ISCSI_PERSISTENT_PORT		(1ULL << ISCSI_PARAM_PERSISTENT_PORT)
--#define ISCSI_SESS_RECOVERY_TMO		(1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO)
--#define ISCSI_CONN_PORT			(1ULL << ISCSI_PARAM_CONN_PORT)
--#define ISCSI_CONN_ADDRESS		(1ULL << ISCSI_PARAM_CONN_ADDRESS)
--#define ISCSI_USERNAME			(1ULL << ISCSI_PARAM_USERNAME)
--#define ISCSI_USERNAME_IN		(1ULL << ISCSI_PARAM_USERNAME_IN)
--#define ISCSI_PASSWORD			(1ULL << ISCSI_PARAM_PASSWORD)
--#define ISCSI_PASSWORD_IN		(1ULL << ISCSI_PARAM_PASSWORD_IN)
--#define ISCSI_FAST_ABORT		(1ULL << ISCSI_PARAM_FAST_ABORT)
--#define ISCSI_ABORT_TMO			(1ULL << ISCSI_PARAM_ABORT_TMO)
--#define ISCSI_LU_RESET_TMO		(1ULL << ISCSI_PARAM_LU_RESET_TMO)
--#define ISCSI_HOST_RESET_TMO		(1ULL << ISCSI_PARAM_HOST_RESET_TMO)
--#define ISCSI_PING_TMO			(1ULL << ISCSI_PARAM_PING_TMO)
--#define ISCSI_RECV_TMO			(1ULL << ISCSI_PARAM_RECV_TMO)
--#define ISCSI_IFACE_NAME		(1ULL << ISCSI_PARAM_IFACE_NAME)
--#define ISCSI_ISID			(1ULL << ISCSI_PARAM_ISID)
--#define ISCSI_INITIATOR_NAME		(1ULL << ISCSI_PARAM_INITIATOR_NAME)
-+#define ISCSI_MAX_RECV_DLENGTH		(1 << ISCSI_PARAM_MAX_RECV_DLENGTH)
-+#define ISCSI_MAX_XMIT_DLENGTH		(1 << ISCSI_PARAM_MAX_XMIT_DLENGTH)
-+#define ISCSI_HDRDGST_EN		(1 << ISCSI_PARAM_HDRDGST_EN)
-+#define ISCSI_DATADGST_EN		(1 << ISCSI_PARAM_DATADGST_EN)
-+#define ISCSI_INITIAL_R2T_EN		(1 << ISCSI_PARAM_INITIAL_R2T_EN)
-+#define ISCSI_MAX_R2T			(1 << ISCSI_PARAM_MAX_R2T)
-+#define ISCSI_IMM_DATA_EN		(1 << ISCSI_PARAM_IMM_DATA_EN)
-+#define ISCSI_FIRST_BURST		(1 << ISCSI_PARAM_FIRST_BURST)
-+#define ISCSI_MAX_BURST			(1 << ISCSI_PARAM_MAX_BURST)
-+#define ISCSI_PDU_INORDER_EN		(1 << ISCSI_PARAM_PDU_INORDER_EN)
-+#define ISCSI_DATASEQ_INORDER_EN	(1 << ISCSI_PARAM_DATASEQ_INORDER_EN)
-+#define ISCSI_ERL			(1 << ISCSI_PARAM_ERL)
-+#define ISCSI_IFMARKER_EN		(1 << ISCSI_PARAM_IFMARKER_EN)
-+#define ISCSI_OFMARKER_EN		(1 << ISCSI_PARAM_OFMARKER_EN)
-+#define ISCSI_EXP_STATSN		(1 << ISCSI_PARAM_EXP_STATSN)
-+#define ISCSI_TARGET_NAME		(1 << ISCSI_PARAM_TARGET_NAME)
-+#define ISCSI_TPGT			(1 << ISCSI_PARAM_TPGT)
-+#define ISCSI_PERSISTENT_ADDRESS	(1 << ISCSI_PARAM_PERSISTENT_ADDRESS)
-+#define ISCSI_PERSISTENT_PORT		(1 << ISCSI_PARAM_PERSISTENT_PORT)
-+#define ISCSI_SESS_RECOVERY_TMO		(1 << ISCSI_PARAM_SESS_RECOVERY_TMO)
-+#define ISCSI_CONN_PORT			(1 << ISCSI_PARAM_CONN_PORT)
-+#define ISCSI_CONN_ADDRESS		(1 << ISCSI_PARAM_CONN_ADDRESS)
-+#define ISCSI_USERNAME			(1 << ISCSI_PARAM_USERNAME)
-+#define ISCSI_USERNAME_IN		(1 << ISCSI_PARAM_USERNAME_IN)
-+#define ISCSI_PASSWORD			(1 << ISCSI_PARAM_PASSWORD)
-+#define ISCSI_PASSWORD_IN		(1 << ISCSI_PARAM_PASSWORD_IN)
-+#define ISCSI_FAST_ABORT		(1 << ISCSI_PARAM_FAST_ABORT)
-+#define ISCSI_ABORT_TMO			(1 << ISCSI_PARAM_ABORT_TMO)
-+#define ISCSI_LU_RESET_TMO		(1 << ISCSI_PARAM_LU_RESET_TMO)
-+#define ISCSI_HOST_RESET_TMO		(1 << ISCSI_PARAM_HOST_RESET_TMO)
-+#define ISCSI_PING_TMO			(1 << ISCSI_PARAM_PING_TMO)
-+#define ISCSI_RECV_TMO			(1 << ISCSI_PARAM_RECV_TMO)
- 
- /* iSCSI HBA params */
- enum iscsi_host_param {
-@@ -310,13 +296,20 @@ enum iscsi_host_param {
- 	ISCSI_HOST_PARAM_MAX,
- };
- 
--#define ISCSI_HOST_HWADDRESS		(1ULL << ISCSI_HOST_PARAM_HWADDRESS)
--#define ISCSI_HOST_INITIATOR_NAME	(1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME)
--#define ISCSI_HOST_NETDEV_NAME		(1ULL << ISCSI_HOST_PARAM_NETDEV_NAME)
--#define ISCSI_HOST_IPADDRESS		(1ULL << ISCSI_HOST_PARAM_IPADDRESS)
-+#define ISCSI_HOST_HWADDRESS		(1 << ISCSI_HOST_PARAM_HWADDRESS)
-+#define ISCSI_HOST_INITIATOR_NAME	(1 << ISCSI_HOST_PARAM_INITIATOR_NAME)
-+#define ISCSI_HOST_NETDEV_NAME		(1 << ISCSI_HOST_PARAM_NETDEV_NAME)
-+#define ISCSI_HOST_IPADDRESS		(1 << ISCSI_HOST_PARAM_IPADDRESS)
- 
- #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
- #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
-+#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
-+
-+/**
-+ * iscsi_hostdata - get LLD hostdata from scsi_host
-+ * @_hostdata: pointer to scsi host's hostdata
-+ **/
-+#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
- 
- /*
-  * These flags presents iSCSI Data-Path capabilities.
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iw_cxgb3_0010_states.patch b/kernel_patches/backport/2.6.18-EL5.1/iw_cxgb3_0010_states.patch
deleted file mode 100644
index 6b73778..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iw_cxgb3_0010_states.patch
+++ /dev/null
@@ -1,24 +0,0 @@
----
- drivers/infiniband/hw/cxgb3/iwch_cm.c |    2 ++
- 1 file changed, 2 insertions(+)
-
-Index: ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_cm.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/cxgb3/iwch_cm.c
-+++ ofed_kernel/drivers/infiniband/hw/cxgb3/iwch_cm.c
-@@ -47,6 +47,7 @@
- #include "iwch_provider.h"
- #include "iwch_cm.h"
- 
-+#ifdef DEBUG
- static char *states[] = {
- 	"idle",
- 	"listen",
-@@ -62,6 +63,7 @@ static char *states[] = {
- 	"dead",
- 	NULL,
- };
-+#endif
- 
- int peer2peer = 0;
- module_param(peer2peer, int, 0644);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_050_to_2_6_24.patch b/kernel_patches/backport/2.6.18-EL5.1/iw_nes_050_to_2_6_24.patch
deleted file mode 100644
index 55ca7f8..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_050_to_2_6_24.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
-index 0696b4c..f81379d 100644
---- a/drivers/infiniband/hw/nes/nes.c
-+++ b/drivers/infiniband/hw/nes/nes.c
-@@ -1118,19 +1118,19 @@ static ssize_t nes_show_wqm_quanta(struct device_driver *ddp, char *buf)
- static ssize_t nes_store_wqm_quanta(struct device_driver *ddp,
- 					const char *buf, size_t count)
- {
--	unsigned long wqm_quanta_value;
-+	u32 wqm_quanta;
- 	u32 wqm_config1;
- 	u32 i = 0;
- 	struct nes_device *nesdev;
- 
--	strict_strtoul(buf, 0, &wqm_quanta_value);
-+	wqm_quanta = simple_strtoul(buf, NULL, 0);
- 	list_for_each_entry(nesdev, &nes_dev_list, list) {
- 		if (i == ee_flsh_adapter) {
--			nesdev->nesadapter->wqm_quanta = wqm_quanta_value;
-+			nesdev->nesadapter->wqm_quanta = wqm_quanta;
- 			wqm_config1 = nes_read_indexed(nesdev,
- 						NES_IDX_WQM_CONFIG1);
- 			nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG1,
--					((wqm_quanta_value << 1) |
-+					((wqm_quanta << 1) |
- 					(wqm_config1 & 0x00000001)));
- 			break;
- 		}
--- 
-1.5.3.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_100_to_2_6_23.patch b/kernel_patches/backport/2.6.18-EL5.1/iw_nes_100_to_2_6_23.patch
deleted file mode 100644
index f8629a1..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_100_to_2_6_23.patch
+++ /dev/null
@@ -1,387 +0,0 @@
-diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig
-index d449eb6..2aeb7ac 100644
---- a/drivers/infiniband/hw/nes/Kconfig
-+++ b/drivers/infiniband/hw/nes/Kconfig
-@@ -2,7 +2,6 @@ config INFINIBAND_NES
- 	tristate "NetEffect RNIC Driver"
- 	depends on PCI && INET && INFINIBAND
- 	select LIBCRC32C
--	select INET_LRO
- 	---help---
- 	  This is a low-level driver for NetEffect RDMA enabled
- 	  Network Interface Cards (RNIC).
-diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
-index f81379d..e3668df 100644
---- a/drivers/infiniband/hw/nes/nes.c
-+++ b/drivers/infiniband/hw/nes/nes.c
-@@ -360,10 +360,11 @@ struct ib_qp *nes_get_qp(struct ib_device *device, int qpn)
-  */
- static void nes_print_macaddr(struct net_device *netdev)
- {
--	DECLARE_MAC_BUF(mac);
--
--	nes_debug(NES_DBG_INIT, "%s: %s, IRQ %u\n",
--		  netdev->name, print_mac(mac, netdev->dev_addr), netdev->irq);
-+	nes_debug(NES_DBG_INIT, "%s: MAC %02X:%02X:%02X:%02X:%02X:%02X, IRQ %u\n",
-+			netdev->name,
-+			netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
-+			netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5],
-+			netdev->irq);
- }
- 
- /**
-diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
-index 91d5372..ff384f1 100644
---- a/drivers/infiniband/hw/nes/nes_cm.c
-+++ b/drivers/infiniband/hw/nes/nes_cm.c
-@@ -1086,7 +1086,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
- 	struct flowi fl;
- 	struct neighbour *neigh;
- 	int rc = -1;
--	DECLARE_MAC_BUF(mac);
- 
- 	memset(&fl, 0, sizeof fl);
- 	fl.nl_u.ip4_u.daddr = htonl(dst_ip);
-@@ -1100,8 +1099,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
- 	if (neigh) {
- 		if (neigh->nud_state & NUD_VALID) {
- 			nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
--				  " is %s, Gateway is 0x%08X \n", dst_ip,
--				  print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
-+				" is %02X:%02X:%02X:%02X:%02X:%02X, Gateway is"
-+				" 0x%08X \n",
-+				dst_ip, neigh->ha[0], neigh->ha[1], neigh->ha[2],
-+				neigh->ha[3], neigh->ha[4], neigh->ha[5],
-+				ntohl(rt->rt_gateway));
- 			nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
- 					     dst_ip, NES_ARP_ADD);
- 			rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
-@@ -1130,7 +1132,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
- 	int arpindex = 0;
- 	struct nes_device *nesdev;
- 	struct nes_adapter *nesadapter;
--	DECLARE_MAC_BUF(mac);
- 
- 	/* create an hte and cm_node for this instance */
- 	cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC);
-@@ -1197,8 +1198,11 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
- 
- 	/* copy the mac addr to node context */
- 	memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN);
--	nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %s\n",
--		  print_mac(mac, cm_node->rem_mac));
-+	nes_debug(NES_DBG_CM, "Remote mac addr from arp table:%02x,"
-+			" %02x, %02x, %02x, %02x, %02x\n",
-+			cm_node->rem_mac[0], cm_node->rem_mac[1],
-+			cm_node->rem_mac[2], cm_node->rem_mac[3],
-+			cm_node->rem_mac[4], cm_node->rem_mac[5]);
- 
- 	add_hte_node(cm_core, cm_node);
- 	atomic_inc(&cm_nodes_created);
-diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
-index f0fe63d..6386c65 100644
---- a/drivers/infiniband/hw/nes/nes_hw.c
-+++ b/drivers/infiniband/hw/nes/nes_hw.c
-@@ -38,14 +38,9 @@
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <linux/if_vlan.h>
--#include <linux/inet_lro.h>
- 
- #include "nes.h"
- 
--static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
--module_param(nes_lro_max_aggr, uint, 0444);
--MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
--
- static int wide_ppm_offset;
- module_param(wide_ppm_offset, int, 0644);
- MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm");
-@@ -1450,25 +1445,6 @@ static void nes_rq_wqes_timeout(unsigned long parm)
- }
- 
- 
--static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr,
--			       void **tcph, u64 *hdr_flags, void *priv)
--{
--	unsigned int ip_len;
--	struct iphdr *iph;
--	skb_reset_network_header(skb);
--	iph = ip_hdr(skb);
--	if (iph->protocol != IPPROTO_TCP)
--		return -1;
--	ip_len = ip_hdrlen(skb);
--	skb_set_transport_header(skb, ip_len);
--	*tcph = tcp_hdr(skb);
--
--	*hdr_flags = LRO_IPV4 | LRO_TCP;
--	*iphdr = iph;
--	return 0;
--}
--
--
- /**
-  * nes_init_nic_qp
-  */
-@@ -1692,14 +1668,6 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
- 			jumbomode = 1;
- 		nes_nic_init_timer_defaults(nesdev, jumbomode);
- 	}
--	nesvnic->lro_mgr.max_aggr       = nes_lro_max_aggr;
--	nesvnic->lro_mgr.max_desc       = NES_MAX_LRO_DESCRIPTORS;
--	nesvnic->lro_mgr.lro_arr        = nesvnic->lro_desc;
--	nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
--	nesvnic->lro_mgr.features       = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
--	nesvnic->lro_mgr.dev            = netdev;
--	nesvnic->lro_mgr.ip_summed      = CHECKSUM_UNNECESSARY;
--	nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
- 	return 0;
- }
- 
-@@ -2475,7 +2443,7 @@ static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic
- {
- 	struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
- 
--	netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi);
-+	netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index]);
- }
- 
- 
-@@ -2510,13 +2478,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
- 	u16 pkt_type;
- 	u16 rqes_processed = 0;
- 	u8 sq_cqes = 0;
--	u8 nes_use_lro = 0;
- 
- 	head = cq->cq_head;
- 	cq_size = cq->cq_size;
- 	cq->cqes_pending = 1;
--	if (nesvnic->netdev->features & NETIF_F_LRO)
--		nes_use_lro = 1;
- 	do {
- 		if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
- 				NES_NIC_CQE_VALID) {
-@@ -2648,17 +2613,9 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
- 							>> 16);
- 					nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
- 							nesvnic->netdev->name, vlan_tag);
--					if (nes_use_lro)
--						lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
--								nesvnic->vlan_grp, vlan_tag, NULL);
--					else
--						nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
--				} else {
--					if (nes_use_lro)
--						lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
--					else
--						nes_netif_rx(rx_skb);
--				}
-+					nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
-+				} else
-+					nes_netif_rx(rx_skb);
- 
- skip_rx_indicate0:
- 				nesvnic->netdev->last_rx = jiffies;
-@@ -2689,8 +2646,6 @@ skip_rx_indicate0:
- 
- 	} while (1);
- 
--	if (nes_use_lro)
--		lro_flush_all(&nesvnic->lro_mgr);
- 	if (sq_cqes) {
- 		barrier();
- 		/* restart the queue if it had been stopped */
-diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
-index c3654c6..1a81bbb 100644
---- a/drivers/infiniband/hw/nes/nes_hw.h
-+++ b/drivers/infiniband/hw/nes/nes_hw.h
-@@ -33,8 +33,6 @@
- #ifndef __NES_HW_H
- #define __NES_HW_H
- 
--#include <linux/inet_lro.h>
--
- #define NES_PHY_TYPE_CX4       1
- #define NES_PHY_TYPE_1G        2
- #define NES_PHY_TYPE_IRIS      3
-@@ -993,8 +991,6 @@ struct nes_hw_tune_timer {
- #define NES_TIMER_ENABLE_LIMIT      4
- #define NES_MAX_LINK_INTERRUPTS     128
- #define NES_MAX_LINK_CHECK          200
--#define NES_MAX_LRO_DESCRIPTORS     32
--#define NES_LRO_MAX_AGGR            64
- 
- struct nes_adapter {
- 	u64              fw_ver;
-@@ -1169,7 +1165,6 @@ struct nes_vnic {
- 	u32               msg_enable;
- 	/* u32 tx_avail; */
- 	__be32            local_ipaddr;
--	struct napi_struct   napi;
- 	spinlock_t           tx_lock;	/* could use netdev tx lock? */
- 	struct timer_list    rq_wqes_timer;
- 	u32                  nic_mem_size;
-@@ -1197,9 +1192,6 @@ struct nes_vnic {
- 	u8  of_device_registered;
- 	u8  rdma_enabled;
- 	u8  rx_checksum_disabled;
--	u32 lro_max_aggr;
--	struct net_lro_mgr lro_mgr;
--	struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
- };
- 
- struct nes_ib_device {
-diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
-index ef13030..12d9cc6 100644
---- a/drivers/infiniband/hw/nes/nes_nic.c
-+++ b/drivers/infiniband/hw/nes/nes_nic.c
-@@ -96,35 +96,38 @@ static int nics_per_function = 1;
- /**
-  * nes_netdev_poll
-  */
--static int nes_netdev_poll(struct napi_struct *napi, int budget)
-+static int nes_netdev_poll(struct net_device *netdev, int *budget_ptr)
- {
--	struct nes_vnic *nesvnic = container_of(napi, struct nes_vnic, napi);
--	struct net_device *netdev = nesvnic->netdev;
-+	struct nes_vnic *nesvnic = netdev_priv(netdev);
- 	struct nes_device *nesdev = nesvnic->nesdev;
- 	struct nes_hw_nic_cq *nescq = &nesvnic->nic_cq;
--
--	nesvnic->budget = budget;
-+	nesvnic->budget = min(netdev->quota, *budget_ptr);
- 	nescq->cqes_pending = 0;
- 	nescq->rx_cqes_completed = 0;
- 	nescq->cqe_allocs_pending = 0;
- 	nescq->rx_pkts_indicated = 0;
- 
- 	nes_nic_ce_handler(nesdev, nescq);
-+	netdev->quota -= nescq->rx_pkts_indicated;
-+	*budget_ptr -= nescq->rx_pkts_indicated;
- 
--	if (nescq->cqes_pending == 0) {
--		netif_rx_complete(netdev, napi);
-+	if ((nescq->cqes_pending == 0) && (netdev->quota != 0)) {
-+		netif_rx_complete(netdev);
- 		/* clear out completed cqes and arm */
- 		nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
- 				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
- 		nes_read32(nesdev->regs+NES_CQE_ALLOC);
-+
-+		return 0;
- 	} else {
- 		/* clear out completed cqes but don't arm */
- 		nes_write32(nesdev->regs+NES_CQE_ALLOC,
- 				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
- 		nes_debug(NES_DBG_NETDEV, "%s: exiting with work pending\n",
- 				nesvnic->netdev->name);
-+
-+		return 1;
- 	}
--	return nescq->rx_pkts_indicated;
- }
- 
- 
-@@ -238,7 +241,6 @@ static int nes_netdev_open(struct net_device *netdev)
- 		netif_start_queue(netdev);
- 		netif_carrier_on(netdev);
- 	}
--	napi_enable(&nesvnic->napi);
- 	nesvnic->netdev_open = 1;
- 
- 	return 0;
-@@ -266,7 +268,6 @@ static int nes_netdev_stop(struct net_device *netdev)
- 		printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name);
- 
- 	/* Disable network packets */
--	napi_disable(&nesvnic->napi);
- 	netif_stop_queue(netdev);
- 	list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) {
- 		first_nesvnic = container_of(list_pos, struct nes_vnic, list);
-@@ -775,14 +776,16 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
- 	int i;
- 	u32 macaddr_low;
- 	u16 macaddr_high;
--	DECLARE_MAC_BUF(mac);
- 
- 	if (!is_valid_ether_addr(mac_addr->sa_data))
- 		return -EADDRNOTAVAIL;
- 
- 	memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
--	printk(PFX "%s: Address length = %d, Address = %s\n",
--	       __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data));
-+	printk(PFX "%s: Address length = %d, Address = %02X%02X%02X%02X%02X%02X..\n",
-+		   __func__, netdev->addr_len,
-+		   mac_addr->sa_data[0], mac_addr->sa_data[1],
-+		   mac_addr->sa_data[2], mac_addr->sa_data[3],
-+		   mac_addr->sa_data[4], mac_addr->sa_data[5]);
- 	macaddr_high  = ((u16)netdev->dev_addr[0]) << 8;
- 	macaddr_high += (u16)netdev->dev_addr[1];
- 	macaddr_low   = ((u32)netdev->dev_addr[2]) << 24;
-@@ -887,11 +890,11 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
- 			if (mc_index >= max_pft_entries_avaiable)
- 				break;
- 			if (multicast_addr) {
--				DECLARE_MAC_BUF(mac);
--				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n",
--					  print_mac(mac, multicast_addr->dmi_addr),
--					  perfect_filter_register_address+(mc_index * 8),
--					  mc_nic_index);
-+				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address = %02X%02X%02X%02X%02X%02X to register 0x%04X nic_idx=%d\n",
-+						  multicast_addr->dmi_addr[0], multicast_addr->dmi_addr[1],
-+						  multicast_addr->dmi_addr[2], multicast_addr->dmi_addr[3],
-+						  multicast_addr->dmi_addr[4], multicast_addr->dmi_addr[5],
-+						  perfect_filter_register_address+(mc_index * 8), mc_nic_index);
- 				macaddr_high  = ((u16)multicast_addr->dmi_addr[0]) << 8;
- 				macaddr_high += (u16)multicast_addr->dmi_addr[1];
- 				macaddr_low   = ((u32)multicast_addr->dmi_addr[2]) << 24;
-@@ -1040,9 +1043,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
- 	"CQ Depth 32",
- 	"CQ Depth 128",
- 	"CQ Depth 256",
--	"LRO aggregated",
--	"LRO flushed",
--	"LRO no_desc",
- };
- 
- #define NES_ETHTOOL_STAT_COUNT  ARRAY_SIZE(nes_ethtool_stringset)
-@@ -1240,9 +1240,6 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
- 	target_stat_values[++index] = int_mod_cq_depth_32;
- 	target_stat_values[++index] = int_mod_cq_depth_128;
- 	target_stat_values[++index] = int_mod_cq_depth_256;
--	target_stat_values[++index] = nesvnic->lro_mgr.stats.aggregated;
--	target_stat_values[++index] = nesvnic->lro_mgr.stats.flushed;
--	target_stat_values[++index] = nesvnic->lro_mgr.stats.no_desc;
- 
- }
- 
-@@ -1525,8 +1522,6 @@ static struct ethtool_ops nes_ethtool_ops = {
- 	.set_sg = ethtool_op_set_sg,
- 	.get_tso = ethtool_op_get_tso,
- 	.set_tso = ethtool_op_set_tso,
--	.get_flags = ethtool_op_get_flags,
--	.set_flags = ethtool_op_set_flags,
- };
- 
- 
-@@ -1598,7 +1593,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
- 	netdev->type = ARPHRD_ETHER;
- 	netdev->features = NETIF_F_HIGHDMA;
- 	netdev->ethtool_ops = &nes_ethtool_ops;
--	netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
-+	netdev->poll = nes_netdev_poll;
-+	netdev->weight = 128;
- 	nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
- 	netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- 	netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
-@@ -1630,7 +1626,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
- 
- 	if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) {
- 		netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
--		netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
- 	} else {
- 		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- 	}
--- 
-1.5.3.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_200_to_2_6_22.patch b/kernel_patches/backport/2.6.18-EL5.1/iw_nes_200_to_2_6_22.patch
deleted file mode 100644
index 941a042..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_200_to_2_6_22.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
-index e3668df..d1bf14b 100644
---- a/drivers/infiniband/hw/nes/nes.c
-+++ b/drivers/infiniband/hw/nes/nes.c
-@@ -593,16 +593,22 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
- 						nesdev->nesadapter->port_count;
- 	}
- 
--	if ((limit_maxrdreqsz ||
--	     ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) &&
--	      (hw_rev == NE020_REV1))) &&
--	    (pcie_get_readrq(pcidev) > 256)) {
--		if (pcie_set_readrq(pcidev, 256))
--			printk(KERN_ERR PFX "Unable to set max read request"
--				" to 256 bytes\n");
--		else
--			nes_debug(NES_DBG_INIT, "Max read request size set"
--				" to 256 bytes\n");
-+	if (limit_maxrdreqsz ||
-+	    ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) &&
-+	     (hw_rev == NE020_REV1))) {
-+		u16 maxrdreqword;
-+		pci_read_config_word(pcidev, 0x68, &maxrdreqword);
-+		/* set bits 12-14 to 001b = 256 bytes */
-+		if ((maxrdreqword & 0x7000) > 0x1000) {
-+			maxrdreqword &= 0x8fff;
-+			maxrdreqword |= 0x1000;
-+			if (pci_write_config_word(pcidev, 0x68, maxrdreqword))
-+				printk(KERN_ERR PFX "Unable to set max read "
-+					"request to 256 bytes\n");
-+			else
-+				nes_debug(NES_DBG_INIT, "Max read request size"
-+					"set to 256 bytes\n");
-+		}
- 	}
- 
- 	tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev);
-diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
-index 2872e1b..55e6900 100644
---- a/drivers/infiniband/hw/nes/nes.h
-+++ b/drivers/infiniband/hw/nes/nes.h
-@@ -274,14 +274,7 @@ static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
- 	u32 crc_value;
- 	crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad));
- 
--	/*
--	 * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc
--	 * state in cpu order"), behavior of crc32c changes on
--	 * big-endian platforms.  Our algorithm expects the previous
--	 * behavior; otherwise we have RDMA connection establishment
--	 * issue on big-endian.
--	 */
--	return cpu_to_le32(crc_value);
-+	return crc_value;
- }
- 
- static inline void
--- 
-1.5.3.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_210_to_2_6_21.patch b/kernel_patches/backport/2.6.18-EL5.1/iw_nes_210_to_2_6_21.patch
deleted file mode 100644
index 4a20493..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/iw_nes_210_to_2_6_21.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
-index 12d9cc6..95f5a3f 100644
---- a/drivers/infiniband/hw/nes/nes_nic.c
-+++ b/drivers/infiniband/hw/nes/nes_nic.c
-@@ -1549,6 +1549,11 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
- 	spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
- }
- 
-+static void nes_netdev_vlan_rx_kill_vid(struct net_device *netdev, 
-+					unsigned short vid)
-+{
-+}
-+
- 
- /**
-  * nes_netdev_init - initialize network device
-@@ -1598,6 +1603,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
- 	nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
- 	netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- 	netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
-+	netdev->vlan_rx_kill_vid = nes_netdev_vlan_rx_kill_vid;
- 
- 	/* Fill in the port structure */
- 	nesvnic->netdev = netdev;
--- 
-1.5.3.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/linux_genalloc_to_2_6_20.patch b/kernel_patches/backport/2.6.18-EL5.1/linux_genalloc_to_2_6_20.patch
deleted file mode 100644
index f14bb75..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/linux_genalloc_to_2_6_20.patch
+++ /dev/null
@@ -1,21 +0,0 @@
----
- drivers/infiniband/core/Makefile   |    2 ++
- drivers/infiniband/core/genalloc.c |    1 +
- 2 files changed, 3 insertions(+)
-
-Index: ofed_kernel/drivers/infiniband/core/Makefile
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/Makefile
-+++ ofed_kernel/drivers/infiniband/core/Makefile
-@@ -30,3 +30,5 @@ ib_umad-y :=			user_mad.o
- ib_ucm-y :=			ucm.o
- 
- ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_marshall.o
-+
-+ib_core-y +=			genalloc.o
-Index: ofed_kernel/drivers/infiniband/core/genalloc.c
-===================================================================
---- /dev/null
-+++ ofed_kernel/drivers/infiniband/core/genalloc.c
-@@ -0,0 +1 @@
-+#include "src/genalloc.c"
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0030_smp_call_function.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_0030_smp_call_function.patch
deleted file mode 100644
index 72c9dcf..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0030_smp_call_function.patch
+++ /dev/null
@@ -1,35 +0,0 @@
----
- drivers/infiniband/hw/mlx4/wc.c |    6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/mlx4/wc.c
-+++ ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
-@@ -111,7 +111,7 @@ static int read_and_modify_pat(void)
- 	preempt_disable();
- 	rd_old_pat(&ret);
- 	if (!ret)
--		smp_call_function(rd_old_pat, &ret, 1);
-+		smp_call_function(rd_old_pat, &ret, 1, 1);
- 	if (ret)
- 		goto out;
- 
-@@ -119,7 +119,7 @@ static int read_and_modify_pat(void)
- 	if (ret)
- 		goto out;
- 
--	smp_call_function(wr_new_pat, &ret, 1);
-+	smp_call_function(wr_new_pat, &ret, 1, 1);
- 	BUG_ON(ret); /* have inconsistent PAT state */
- out:
- 	preempt_enable();
-@@ -133,7 +133,7 @@ static int restore_pat(void)
- 	preempt_disable();
- 	wr_old_pat(&ret);
- 	if (!ret) {
--		smp_call_function(wr_old_pat, &ret, 1);
-+		smp_call_function(wr_old_pat, &ret, 1, 1);
- 		BUG_ON(ret); /* have inconsistent PAT state */
- 	}
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0040_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_0040_pci_dma_mapping_error_to_2_6_26.patch
deleted file mode 100644
index 79c71db..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0040_pci_dma_mapping_error_to_2_6_26.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- drivers/net/mlx4/eq.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: ofed_kernel/drivers/net/mlx4/eq.c
-===================================================================
---- ofed_kernel.orig/drivers/net/mlx4/eq.c
-+++ ofed_kernel/drivers/net/mlx4/eq.c
-@@ -532,7 +532,7 @@ int mlx4_map_eq_icm(struct mlx4_dev *dev
- 		return -ENOMEM;
- 	priv->eq_table.icm_dma  = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0,
- 					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
--	if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) {
-+	if (pci_dma_mapping_error(priv->eq_table.icm_dma)) {
- 		__free_page(priv->eq_table.icm_page);
- 		return -ENOMEM;
- 	}
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0050_wc.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_0050_wc.patch
deleted file mode 100644
index 1506824..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0050_wc.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- drivers/infiniband/hw/mlx4/wc.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/mlx4/wc.c
-+++ ofed_kernel/drivers/infiniband/hw/mlx4/wc.c
-@@ -143,7 +143,7 @@ static int restore_pat(void)
- 
- int mlx4_enable_wc(void)
- {
--	struct cpuinfo_x86 *c = &cpu_data(0);
-+	struct cpuinfo_x86 *c = &(cpu_data)[0];
- 	int ret;
- 
- 	if (wc_enabled)
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0060_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_0060_sysfs.patch
deleted file mode 100644
index d195c0b..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_0060_sysfs.patch
+++ /dev/null
@@ -1,236 +0,0 @@
----
- drivers/infiniband/hw/mlx4/main.c |  153 +++++++++++++++++---------------------
- 1 file changed, 71 insertions(+), 82 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/mlx4/main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/mlx4/main.c
-+++ ofed_kernel/drivers/infiniband/hw/mlx4/main.c
-@@ -581,51 +581,42 @@ out:
- 	return err;
- }
- 
--static ssize_t show_hca(struct device *device, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_hca(struct class_device *cdev, char *buf)
- {
--	struct mlx4_ib_dev *dev =
--		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
-+	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
- 	return sprintf(buf, "MT%d\n", dev->dev->pdev->device);
- }
- 
--static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
--			   char *buf)
-+static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
- {
--	struct mlx4_ib_dev *dev =
--		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
-+	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
- 	return sprintf(buf, "%d.%d.%d\n", (int) (dev->dev->caps.fw_ver >> 32),
- 		       (int) (dev->dev->caps.fw_ver >> 16) & 0xffff,
- 		       (int) dev->dev->caps.fw_ver & 0xffff);
- }
- 
--static ssize_t show_rev(struct device *device, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_rev(struct class_device *cdev, char *buf)
- {
--	struct mlx4_ib_dev *dev =
--		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
-+	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
- 	return sprintf(buf, "%x\n", dev->dev->rev_id);
- }
- 
--static ssize_t show_board(struct device *device, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_board(struct class_device *cdev, char *buf)
- {
--	struct mlx4_ib_dev *dev =
--		container_of(device, struct mlx4_ib_dev, ib_dev.dev);
--	return sprintf(buf, "%.*s\n", MLX4_BOARD_ID_LEN,
--		       dev->dev->board_id);
--}
--
--static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
--static DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
--static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
--static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
--
--static struct device_attribute *mlx4_class_attributes[] = {
--	&dev_attr_hw_rev,
--	&dev_attr_fw_ver,
--	&dev_attr_hca_type,
--	&dev_attr_board_id
-+	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev);
-+	return sprintf(buf, "%.*s\n", MLX4_BOARD_ID_LEN, dev->dev->board_id);
-+}
-+
-+static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
-+static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
-+static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
-+static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
-+
-+static struct class_device_attribute *mlx4_class_attributes[] = {
-+	&class_device_attr_hw_rev,
-+	&class_device_attr_fw_ver,
-+	&class_device_attr_hca_type,
-+	&class_device_attr_board_id
- };
- 
- /*
-@@ -633,23 +624,22 @@ static struct device_attribute *mlx4_cla
-  * the function for _name
-  */
- #define DEVICE_DIAG_RPRT_ATTR(_name, _offset, _op_mod)		\
--static ssize_t show_rprt_##_name(struct device *dev,		\
--				 struct device_attribute *attr,	\
-+static ssize_t show_rprt_##_name(struct class_device *cdev,	\
- 				 char *buf){			\
--	return show_diag_rprt(dev, buf, _offset, _op_mod);	\
-+	return show_diag_rprt(cdev, buf, _offset, _op_mod);	\
- }								\
--static DEVICE_ATTR(_name, S_IRUGO, show_rprt_##_name, NULL);
-+static CLASS_DEVICE_ATTR(_name, S_IRUGO, show_rprt_##_name, NULL);
- 
- #define MLX4_DIAG_RPRT_CLEAR_DIAGS 3
- 
--static size_t show_diag_rprt(struct device *device, char *buf,
-+static size_t show_diag_rprt(struct class_device *cdev, char *buf,
-                               u32 offset, u8 op_modifier)
- {
- 	size_t ret;
- 	u32 counter_offset = offset;
- 	u32 diag_counter = 0;
--	struct mlx4_ib_dev *dev = container_of(device, struct mlx4_ib_dev,
--					       ib_dev.dev);
-+	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev,
-+					       ib_dev.class_dev);
- 
- 	ret = mlx4_query_diag_counters(dev->dev, 1, op_modifier,
- 				       &counter_offset, &diag_counter);
-@@ -659,13 +649,12 @@ static size_t show_diag_rprt(struct devi
- 	return sprintf(buf,"%d\n", diag_counter);
- }
- 
--static ssize_t clear_diag_counters(struct device *device,
--				   struct device_attribute *attr,
-+static ssize_t clear_diag_counters(struct class_device *cdev,
- 				   const char *buf, size_t length)
- {
- 	size_t ret;
--	struct mlx4_ib_dev *dev = container_of(device, struct mlx4_ib_dev,
--					       ib_dev.dev);
-+	struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev,
-+					       ib_dev.class_dev);
- 
- 	ret = mlx4_query_diag_counters(dev->dev, 0, MLX4_DIAG_RPRT_CLEAR_DIAGS,
- 				       NULL, NULL);
-@@ -711,45 +700,45 @@ DEVICE_DIAG_RPRT_ATTR(num_cqovf		, 0x1A0
- DEVICE_DIAG_RPRT_ATTR(num_eqovf		, 0x1A4, 2);
- DEVICE_DIAG_RPRT_ATTR(num_baddb		, 0x1A8, 2);
- 
--static DEVICE_ATTR(clear_diag, S_IWUGO, NULL, clear_diag_counters);
-+static CLASS_DEVICE_ATTR(clear_diag, S_IWUGO, NULL, clear_diag_counters);
- 
- static struct attribute *diag_rprt_attrs[] = {
--	&dev_attr_rq_num_lle.attr,
--	&dev_attr_sq_num_lle.attr,
--	&dev_attr_rq_num_lqpoe.attr,
--	&dev_attr_sq_num_lqpoe.attr,
--	&dev_attr_rq_num_leeoe.attr,
--	&dev_attr_sq_num_leeoe.attr,
--	&dev_attr_rq_num_lpe.attr,
--	&dev_attr_sq_num_lpe.attr,
--	&dev_attr_rq_num_wrfe.attr,
--	&dev_attr_sq_num_wrfe.attr,
--	&dev_attr_sq_num_mwbe.attr,
--	&dev_attr_sq_num_bre.attr,
--	&dev_attr_rq_num_lae.attr,
--	&dev_attr_sq_num_rire.attr,
--	&dev_attr_rq_num_rire.attr,
--	&dev_attr_sq_num_rae.attr,
--	&dev_attr_rq_num_rae.attr,
--	&dev_attr_sq_num_roe.attr,
--	&dev_attr_sq_num_tree.attr,
--	&dev_attr_sq_num_rree.attr,
--	&dev_attr_rq_num_rnr.attr,
--	&dev_attr_sq_num_rnr.attr,
--	&dev_attr_sq_num_rabrte.attr,
--	&dev_attr_sq_num_ieecne.attr,
--	&dev_attr_sq_num_ieecse.attr,
--	&dev_attr_rq_num_oos.attr,
--	&dev_attr_sq_num_oos.attr,
--	&dev_attr_rq_num_mce.attr,
--	&dev_attr_rq_num_rsync.attr,
--	&dev_attr_sq_num_rsync.attr,
--	&dev_attr_rq_num_udsdprd.attr,
--	&dev_attr_rq_num_ucsdprd.attr,
--	&dev_attr_num_cqovf.attr,
--	&dev_attr_num_eqovf.attr,
--	&dev_attr_num_baddb.attr,
--	&dev_attr_clear_diag.attr,
-+	&class_device_attr_rq_num_lle.attr,
-+	&class_device_attr_sq_num_lle.attr,
-+	&class_device_attr_rq_num_lqpoe.attr,
-+	&class_device_attr_sq_num_lqpoe.attr,
-+	&class_device_attr_rq_num_leeoe.attr,
-+	&class_device_attr_sq_num_leeoe.attr,
-+	&class_device_attr_rq_num_lpe.attr,
-+	&class_device_attr_sq_num_lpe.attr,
-+	&class_device_attr_rq_num_wrfe.attr,
-+	&class_device_attr_sq_num_wrfe.attr,
-+	&class_device_attr_sq_num_mwbe.attr,
-+	&class_device_attr_sq_num_bre.attr,
-+	&class_device_attr_rq_num_lae.attr,
-+	&class_device_attr_sq_num_rire.attr,
-+	&class_device_attr_rq_num_rire.attr,
-+	&class_device_attr_sq_num_rae.attr,
-+	&class_device_attr_rq_num_rae.attr,
-+	&class_device_attr_sq_num_roe.attr,
-+	&class_device_attr_sq_num_tree.attr,
-+	&class_device_attr_sq_num_rree.attr,
-+	&class_device_attr_rq_num_rnr.attr,
-+	&class_device_attr_sq_num_rnr.attr,
-+	&class_device_attr_sq_num_rabrte.attr,
-+	&class_device_attr_sq_num_ieecne.attr,
-+	&class_device_attr_sq_num_ieecse.attr,
-+	&class_device_attr_rq_num_oos.attr,
-+	&class_device_attr_sq_num_oos.attr,
-+	&class_device_attr_rq_num_mce.attr,
-+	&class_device_attr_rq_num_rsync.attr,
-+	&class_device_attr_sq_num_rsync.attr,
-+	&class_device_attr_rq_num_udsdprd.attr,
-+	&class_device_attr_rq_num_ucsdprd.attr,
-+	&class_device_attr_num_cqovf.attr,
-+	&class_device_attr_num_eqovf.attr,
-+	&class_device_attr_num_baddb.attr,
-+	&class_device_attr_clear_diag.attr,
- 	NULL
- };
- 
-@@ -906,12 +895,12 @@ static void *mlx4_ib_add(struct mlx4_dev
- 		goto err_reg;
- 
- 	for (i = 0; i < ARRAY_SIZE(mlx4_class_attributes); ++i) {
--		if (device_create_file(&ibdev->ib_dev.dev,
--				       mlx4_class_attributes[i]))
-+		if (class_device_create_file(&ibdev->ib_dev.class_dev,
-+					       mlx4_class_attributes[i]))
- 			goto err_reg;
- 	}
- 
--	if(sysfs_create_group(&ibdev->ib_dev.dev.kobj, &diag_counters_group))
-+	if(sysfs_create_group(&ibdev->ib_dev.class_dev.kobj, &diag_counters_group))
- 		goto err_reg;
- 
- 	return ibdev;
-@@ -942,7 +931,7 @@ static void mlx4_ib_remove(struct mlx4_d
- 	if (!ibdev->num_ports)
- 		return;
- 
--	sysfs_remove_group(&ibdev->ib_dev.dev.kobj, &diag_counters_group);
-+	sysfs_remove_group(&ibdev->ib_dev.class_dev.kobj, &diag_counters_group);
- 
- 	for (p = 1; p <= ibdev->num_ports; ++p)
- 		mlx4_CLOSE_PORT(dev, p);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0010_do_not_use_netdev_ops.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0010_do_not_use_netdev_ops.patch
deleted file mode 100644
index 4d3b269..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0010_do_not_use_netdev_ops.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 34a43622ec035aa41a5383c31245838472784c1b Mon Sep 17 00:00:00 2001
-From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
-Date: Sun, 31 May 2009 11:59:25 +0300
-Subject: [PATCH 1/8] mlx4_en: Don't use netdev_ops
-
-Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
----
- drivers/net/mlx4/en_netdev.c |   34 +++++++++++++++-------------------
- 1 files changed, 15 insertions(+), 19 deletions(-)
-
-diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
-index a38adf5..4ad5f3c 100644
---- a/drivers/net/mlx4/en_netdev.c
-+++ b/drivers/net/mlx4/en_netdev.c
-@@ -933,24 +933,6 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
- 	return 0;
- }
- 
--static const struct net_device_ops mlx4_netdev_ops = {
--	.ndo_open		= mlx4_en_open,
--	.ndo_stop		= mlx4_en_close,
--	.ndo_start_xmit		= mlx4_en_xmit,
--	.ndo_select_queue	= mlx4_en_select_queue,
--	.ndo_get_stats		= mlx4_en_get_stats,
--	.ndo_set_multicast_list	= mlx4_en_set_multicast,
--	.ndo_set_mac_address	= mlx4_en_set_mac,
--	.ndo_validate_addr	= eth_validate_addr,
--	.ndo_change_mtu		= mlx4_en_change_mtu,
--	.ndo_tx_timeout		= mlx4_en_tx_timeout,
--	.ndo_vlan_rx_register	= mlx4_en_vlan_rx_register,
--	.ndo_vlan_rx_add_vid	= mlx4_en_vlan_rx_add_vid,
--	.ndo_vlan_rx_kill_vid	= mlx4_en_vlan_rx_kill_vid,
--#ifdef CONFIG_NET_POLL_CONTROLLER
--	.ndo_poll_controller	= mlx4_en_netpoll,
--#endif
--};
- 
- int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
- 			struct mlx4_en_port_profile *prof)
-@@ -1026,7 +1008,21 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
- 	/*
- 	 * Initialize netdev entry points
- 	 */
--	dev->netdev_ops = &mlx4_netdev_ops;
-+	dev->open		= mlx4_en_open;
-+	dev->stop		= mlx4_en_close;
-+	dev->hard_start_xmit	= mlx4_en_xmit,
-+	dev->select_queue	= mlx4_en_select_queue,
-+	dev->get_stats		= mlx4_en_get_stats,
-+	dev->set_multicast_list	= mlx4_en_set_multicast,
-+	dev->set_mac_address	= mlx4_en_set_mac,
-+	dev->change_mtu		= mlx4_en_change_mtu,
-+	dev->tx_timeout		= mlx4_en_tx_timeout,
-+	dev->vlan_rx_register	= mlx4_en_vlan_rx_register,
-+	dev->vlan_rx_add_vid	= mlx4_en_vlan_rx_add_vid,
-+	dev->vlan_rx_kill_vid	= mlx4_en_vlan_rx_kill_vid,
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+	dev->poll_controller	= mlx4_en_netpoll,
-+#endif
- 	dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
- 
- 	SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
--- 
-1.6.1.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0020_cancel_multiqueue.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0020_cancel_multiqueue.patch
deleted file mode 100644
index 693e14f..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0020_cancel_multiqueue.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From b0f37433227a9c88f289f7ff69d7b7d11b5c0ba4 Mon Sep 17 00:00:00 2001
-From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
-Date: Sun, 31 May 2009 13:00:22 +0300
-Subject: [PATCH 2/8] mlx4_en: cancel multiqueue
-
-Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
----
- drivers/net/mlx4/en_netdev.c |    3 +--
- drivers/net/mlx4/en_tx.c     |    8 ++++----
- drivers/net/mlx4/mlx4_en.h   |    1 -
- 3 files changed, 5 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
-index 4ad5f3c..34e082c 100644
---- a/drivers/net/mlx4/en_netdev.c
-+++ b/drivers/net/mlx4/en_netdev.c
-@@ -942,7 +942,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
- 	int i;
- 	int err;
- 
--	dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num);
-+	dev = alloc_etherdev(sizeof(struct mlx4_en_priv));
- 	if (dev == NULL) {
- 		mlx4_err(mdev, "Net device allocation failed\n");
- 		return -ENOMEM;
-@@ -1011,7 +1011,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
- 	dev->open		= mlx4_en_open;
- 	dev->stop		= mlx4_en_close;
- 	dev->hard_start_xmit	= mlx4_en_xmit,
--	dev->select_queue	= mlx4_en_select_queue,
- 	dev->get_stats		= mlx4_en_get_stats,
- 	dev->set_multicast_list	= mlx4_en_set_multicast,
- 	dev->set_mac_address	= mlx4_en_set_mac,
-diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
-index 2a86d08..cba7a02 100644
---- a/drivers/net/mlx4/en_tx.c
-+++ b/drivers/net/mlx4/en_tx.c
-@@ -386,7 +386,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
- 		if ((u32) (ring->prod - ring->cons) <=
- 		     ring->size - HEADROOM - MAX_DESC_TXBBS) {
- 			ring->blocked = 0;
--			netif_tx_wake_queue(netdev_get_tx_queue(dev, cq->ring));
-+			netif_wake_queue(dev);
- 			priv->port_stats.wake_queue++;
- 		}
- 	}
-@@ -605,7 +605,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
- 	tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
- }
- 
--u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
-+static int mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
- {
- 	struct mlx4_en_priv *priv = netdev_priv(dev);
- 	u16 vlan_tag = 0;
-@@ -697,7 +697,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
- 		return NETDEV_TX_OK;
- 	}
- 
--	tx_ind = skb->queue_mapping;
-+	tx_ind = mlx4_en_select_queue(dev, skb);
- 	ring = &priv->tx_ring[tx_ind];
- 	if (priv->vlgrp && vlan_tx_tag_present(skb))
- 		vlan_tag = vlan_tx_tag_get(skb);
-@@ -706,7 +706,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
- 	if (unlikely(((int)(ring->prod - ring->cons)) >
- 		     ring->size - HEADROOM - MAX_DESC_TXBBS)) {
- 		/* every full Tx ring stops queue */
--		netif_tx_stop_queue(netdev_get_tx_queue(dev, tx_ind));
-+		netif_stop_queue(dev);
- 		ring->blocked = 1;
- 		priv->port_stats.queue_stopped++;
- 
-diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
-index b45774c..f35f318 100644
---- a/drivers/net/mlx4/mlx4_en.h
-+++ b/drivers/net/mlx4/mlx4_en.h
-@@ -556,7 +556,6 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
- 
- void mlx4_en_poll_tx_cq(unsigned long data);
- void mlx4_en_tx_irq(struct mlx4_cq *mcq);
--u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb);
- int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
- 
- int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring,
--- 
-1.6.1.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0030_lro_backport.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0030_lro_backport.patch
deleted file mode 100644
index eefeae0..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0030_lro_backport.patch
+++ /dev/null
@@ -1,893 +0,0 @@
-From 4f3262d88349cd4ac0cc0b8ecd458b7db4fe63e5 Mon Sep 17 00:00:00 2001
-From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
-Date: Sun, 31 May 2009 14:57:40 +0300
-Subject: [PATCH] mlx4_en: use own lro implemetation
-
-Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
----
- drivers/net/mlx4/Makefile     |    2 +-
- drivers/net/mlx4/en_ethtool.c |   17 --
- drivers/net/mlx4/en_lro.c     |  540 +++++++++++++++++++++++++++++++++++++++++
- drivers/net/mlx4/en_rx.c      |  109 +++------
- drivers/net/mlx4/mlx4_en.h    |   52 ++++-
- 5 files changed, 623 insertions(+), 97 deletions(-)
- create mode 100644 drivers/net/mlx4/en_lro.c
-
-diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
-index 87c2259..ed94870 100644
---- a/drivers/net/mlx4/Makefile
-+++ b/drivers/net/mlx4/Makefile
-@@ -6,4 +6,4 @@ mlx4_core-y :=	alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
- obj-$(CONFIG_MLX4_EN)               += mlx4_en.o
- 
- mlx4_en-y := 	en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
--		en_resources.o en_netdev.o en_frag.o
-+		en_resources.o en_netdev.o en_frag.o en_lro.o
-diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
-index 091f990..19a10f3 100644
---- a/drivers/net/mlx4/en_ethtool.c
-+++ b/drivers/net/mlx4/en_ethtool.c
-@@ -39,21 +39,6 @@
- #include "en_port.h"
- 
- 
--static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
--{
--	int i;
--
--	priv->port_stats.lro_aggregated = 0;
--	priv->port_stats.lro_flushed = 0;
--	priv->port_stats.lro_no_desc = 0;
--
--	for (i = 0; i < priv->rx_ring_num; i++) {
--		priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
--		priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
--		priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
--	}
--}
--
- static void
- mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
- {
-@@ -163,8 +148,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
- 
- 	spin_lock_bh(&priv->stats_lock);
- 
--	mlx4_en_update_lro_stats(priv);
--
- 	for (i = 0; i < NUM_MAIN_STATS; i++)
- 		data[index++] = ((unsigned long *) &priv->stats)[i];
- 	for (i = 0; i < NUM_PORT_STATS; i++)
-diff --git a/drivers/net/mlx4/en_lro.c b/drivers/net/mlx4/en_lro.c
-new file mode 100644
-index 0000000..bb5563f
---- /dev/null
-+++ b/drivers/net/mlx4/en_lro.c
-@@ -0,0 +1,540 @@
-+/*
-+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
-+ *
-+ * This software is available to you under a choice of one of two
-+ * licenses.  You may choose to be licensed under the terms of the GNU
-+ * General Public License (GPL) Version 2, available from the file
-+ * COPYING in the main directory of this source tree, or the
-+ * OpenIB.org BSD license below:
-+ *
-+ *     Redistribution and use in source and binary forms, with or
-+ *     without modification, are permitted provided that the following
-+ *     conditions are met:
-+ *
-+ *      - Redistributions of source code must retain the above
-+ *        copyright notice, this list of conditions and the following
-+ *        disclaimer.
-+ *
-+ *      - Redistributions in binary form must reproduce the above
-+ *        copyright notice, this list of conditions and the following
-+ *        disclaimer in the documentation and/or other materials
-+ *        provided with the distribution.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ *
-+ */
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ip.h>
-+#include <linux/tcp.h>
-+#include <net/tcp.h>
-+#include <linux/if_vlan.h>
-+#include <linux/delay.h>
-+
-+#include "mlx4_en.h"
-+
-+/* LRO hash function - using sum of source and destination port LSBs is
-+ * good enough */
-+#define LRO_INDEX(th, size) \
-+	((*((u8*) &th->source + 1) + *((u8*) &th->dest + 1)) & (size - 1))
-+
-+/* #define CONFIG_MLX4_EN_DEBUG_LRO */
-+
-+#ifdef CONFIG_MLX4_EN_DEBUG_LRO
-+static void mlx4_en_lro_validate(struct mlx4_en_priv* priv, struct mlx4_en_lro *lro)
-+{
-+	int i;
-+	int size, size2;
-+	struct sk_buff *skb = lro->skb;
-+	skb_frag_t *frags;
-+	int len, len2;
-+	int cur_skb = 0;
-+
-+	/* Sum fragment sizes of first skb */
-+	len = skb->len;
-+	size = skb_headlen(skb);
-+	frags = skb_shinfo(skb)->frags;
-+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+		size += frags[i].size;
-+	}
-+
-+	/* Add in fragments of linked skb's */
-+	skb = skb_shinfo(skb)->frag_list;
-+	while (skb) {
-+		cur_skb++;
-+		len2 = skb->len;
-+		if (skb_headlen(skb)) {
-+			mlx4_err(priv->mdev, "Bad LRO format: non-zero headlen "
-+				  "in fraglist (skb:%d)\n", cur_skb);
-+			return;
-+		}
-+
-+		size2 = 0;
-+		frags = skb_shinfo(skb)->frags;
-+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+			size2 += frags[i].size;
-+		}
-+
-+		if (size2 != len2) {
-+			mlx4_err(priv->mdev, "Bad skb size:%d in LRO fraglist. "
-+			          "Expected:%d (skb:%d)\n", size2, len2, cur_skb);
-+			return;
-+		}
-+		size += size2;
-+		skb = skb->next;
-+	}
-+
-+	if (size != len)
-+		mlx4_err(priv->mdev, "Bad LRO size:%d expected:%d\n", size, len);
-+}
-+#endif /* MLX4_EN_DEBUG_LRO */
-+
-+static void mlx4_en_lro_flush_single(struct mlx4_en_priv* priv,
-+		   struct mlx4_en_rx_ring* ring, struct mlx4_en_lro *lro)
-+{
-+	struct sk_buff *skb = lro->skb;
-+	struct iphdr *iph = (struct iphdr *) skb->data;
-+	struct tcphdr *th = (struct tcphdr *)(iph + 1);
-+	unsigned int headlen = skb_headlen(skb);
-+	__wsum tcp_hdr_csum;
-+	u32 *ts;
-+
-+	/* Update IP length and checksum */
-+	iph->tot_len = htons(lro->tot_len);
-+	iph->check = 0;
-+	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-+
-+	/* Update latest TCP ack, window, psh, and timestamp */
-+	th->ack_seq = lro->ack_seq;
-+	th->window = lro->window;
-+	th->psh = !!lro->psh;
-+	if (lro->has_timestamp) {
-+		ts = (u32 *) (th + 1);
-+		ts[1] = htonl(lro->tsval);
-+		ts[2] = lro->tsecr;
-+	}
-+	th->check = 0;
-+	tcp_hdr_csum = csum_partial((u8 *)th, th->doff << 2, 0);
-+	lro->data_csum = csum_add(lro->data_csum, tcp_hdr_csum);
-+	th->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
-+				      lro->tot_len - (iph->ihl << 2),
-+				      IPPROTO_TCP, lro->data_csum);
-+
-+	/* Update skb */
-+	skb->len = lro->tot_len;
-+	skb->data_len = lro->tot_len - headlen;
-+	skb->truesize = skb->len + sizeof(struct sk_buff);
-+	skb_shinfo(skb)->gso_size = lro->mss;
-+
-+#ifdef CONFIG_MLX4_EN_DEBUG_LRO
-+	mlx4_en_lro_validate(priv, lro);
-+#endif /* CONFIG_MLX4_EN_DEBUG_LRO */
-+
-+	/* Push it up the stack */
-+	if (priv->vlgrp && lro->has_vlan)
-+		vlan_hwaccel_receive_skb(skb, priv->vlgrp,
-+					be16_to_cpu(lro->vlan_prio));
-+	else
-+		netif_receive_skb(skb);
-+	priv->dev->last_rx = jiffies;
-+
-+	/* Increment stats */
-+	priv->port_stats.lro_flushed++;
-+
-+	/* Move session back to the free list */
-+	hlist_del(&lro->node);
-+	hlist_del(&lro->flush_node);
-+	hlist_add_head(&lro->node, &ring->lro_free);
-+}
-+
-+void mlx4_en_lro_flush(struct mlx4_en_priv* priv, struct mlx4_en_rx_ring *ring, u8 all)
-+{
-+	struct mlx4_en_lro *lro;
-+	struct hlist_node *node, *tmp;
-+
-+	hlist_for_each_entry_safe(lro, node, tmp, &ring->lro_flush, flush_node) {
-+		if (all || time_after(jiffies, lro->expires))
-+			mlx4_en_lro_flush_single(priv, ring, lro);
-+	}
-+}
-+
-+static inline int mlx4_en_lro_append(struct mlx4_en_priv *priv,
-+				   struct mlx4_en_lro *lro,
-+				   struct mlx4_en_rx_desc *rx_desc,
-+				   struct skb_frag_struct *skb_frags,
-+				   struct mlx4_en_rx_alloc *page_alloc,
-+				   unsigned int data_len,
-+				   int hlen)
-+{
-+	struct sk_buff *skb = lro->skb_last;
-+	struct skb_shared_info *info;
-+	struct skb_frag_struct *frags_copy;
-+	int nr_frags;
-+
-+	if (skb_shinfo(skb)->nr_frags + priv->num_frags > MAX_SKB_FRAGS)
-+		return -ENOMEM;
-+
-+	info = skb_shinfo(skb);
-+
-+	/* Copy fragments from descriptor ring to skb */
-+	frags_copy = info->frags + info->nr_frags;
-+	nr_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags,
-+						frags_copy,
-+						page_alloc,
-+						data_len + hlen);
-+	if (!nr_frags) {
-+		en_dbg(DRV, priv, "Failed completing rx desc during LRO append\n");
-+		return -ENOMEM;
-+	}
-+
-+	/* Skip over headers */
-+	frags_copy[0].page_offset += hlen;
-+
-+	if (nr_frags == 1)
-+		frags_copy[0].size = data_len;
-+	else {
-+		/* Adjust size of last fragment to match packet length.
-+		 * Note: if this fragment is also the first one, the
-+		 *       operation is completed in the next line */
-+		frags_copy[nr_frags - 1].size = hlen + data_len -
-+				priv->frag_info[nr_frags - 1].frag_prefix_size;
-+
-+		/* Adjust size of first fragment */
-+		frags_copy[0].size -= hlen;
-+	}
-+
-+	/* Update skb bookkeeping */
-+	skb->len += data_len;
-+	skb->data_len += data_len;
-+	info->nr_frags += nr_frags;
-+	return 0;
-+}
-+
-+static inline struct mlx4_en_lro *mlx4_en_lro_find_session(struct mlx4_en_dev *mdev,
-+						       struct mlx4_en_rx_ring *ring,
-+						       struct iphdr *iph,
-+						       struct tcphdr *th)
-+{
-+	struct mlx4_en_lro *lro;
-+	struct hlist_node *node;
-+	int index = LRO_INDEX(th, mdev->profile.num_lro);
-+	struct hlist_head *list = &ring->lro_hash[index];
-+
-+	hlist_for_each_entry(lro, node, list, node) {
-+		if (lro->sport_dport == *((u32*) &th->source) &&
-+		    lro->saddr == iph->saddr &&
-+		    lro->daddr == iph->daddr)
-+			return lro;
-+	}
-+	return NULL;
-+}
-+
-+static inline struct mlx4_en_lro *mlx4_en_lro_alloc_session(struct mlx4_en_priv *priv,
-+							struct mlx4_en_rx_ring *ring)
-+{
-+	return hlist_empty(&ring->lro_free) ? NULL :
-+		hlist_entry(ring->lro_free.first, struct mlx4_en_lro, node);
-+}
-+
-+static __wsum mlx4_en_lro_tcp_data_csum(struct iphdr *iph,
-+					struct tcphdr *th, int len)
-+{
-+	__wsum tcp_csum;
-+	__wsum tcp_hdr_csum;
-+	__wsum tcp_ps_hdr_csum;
-+
-+	tcp_csum = ~csum_unfold(th->check);
-+	tcp_hdr_csum = csum_partial((u8 *)th, th->doff << 2, tcp_csum);
-+
-+	tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-+					     len + (th->doff << 2),
-+					     IPPROTO_TCP, 0);
-+
-+	return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum),
-+			tcp_ps_hdr_csum);
-+}
-+
-+int mlx4_en_lro_rx(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring,
-+					  struct mlx4_en_rx_desc *rx_desc,
-+					  struct skb_frag_struct *skb_frags,
-+					  unsigned int length,
-+					  struct mlx4_cqe *cqe)
-+{
-+	struct mlx4_en_dev *mdev = priv->mdev;
-+	struct mlx4_en_lro *lro;
-+	struct sk_buff *skb;
-+	struct iphdr *iph;
-+	struct tcphdr *th;
-+	dma_addr_t dma;
-+	int tcp_hlen;
-+	int tcp_data_len;
-+	int hlen;
-+	u16 ip_len;
-+	void *va;
-+	u32 *ts;
-+	u32 seq;
-+	u32 tsval = (u32) ~0UL;
-+	u32 tsecr = 0;
-+	u32 ack_seq;
-+	u16 window;
-+
-+	/* This packet is eligible for LRO if it is:
-+	 * - DIX Ethernet (type interpretation)
-+	 * - TCP/IP (v4)
-+	 * - without IP options
-+	 * - not an IP fragment */
-+	if (!mlx4_en_can_lro(cqe->status))
-+			return -1;
-+
-+	/* Get pointer to TCP header. We already know that the packet is DIX Ethernet/IPv4/TCP
-+	 * with no VLAN (HW stripped it) and no IP options */
-+	va = page_address(skb_frags[0].page) + skb_frags[0].page_offset;
-+	iph = va + ETH_HLEN;
-+	th = (struct tcphdr *)(iph + 1);
-+
-+	/* Synchronsize headers for processing */
-+	dma = be64_to_cpu(rx_desc->data[0].addr);
-+#define MAX_LRO_HEADER		(ETH_HLEN + \
-+				 sizeof(*iph) + \
-+				 sizeof(*th) + \
-+				 TCPOLEN_TSTAMP_ALIGNED)
-+	dma_sync_single_range_for_cpu(&mdev->pdev->dev, dma, 0,
-+				      MAX_LRO_HEADER, DMA_FROM_DEVICE);
-+
-+	/* We only handle aligned timestamp options */
-+	tcp_hlen = (th->doff << 2);
-+	if (tcp_hlen == sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) {
-+		ts = (u32*) (th + 1);
-+		if (unlikely(*ts != htonl((TCPOPT_NOP << 24) |
-+					  (TCPOPT_NOP << 16) |
-+					  (TCPOPT_TIMESTAMP << 8) |
-+					  TCPOLEN_TIMESTAMP)))
-+			goto sync_device;
-+		tsval = ntohl(ts[1]);
-+		tsecr = ts[2];
-+	} else if (tcp_hlen != sizeof(*th))
-+		goto sync_device;
-+	
-+
-+	/* At this point we know we have a TCP packet that is likely to be
-+	 * eligible for LRO. Therefore, see now if we have an oustanding
-+	 * session that corresponds to this packet so we could flush it if
-+	 * something still prevents LRO */
-+	lro = mlx4_en_lro_find_session(mdev, ring, iph, th);
-+
-+	/* ensure no bits set besides ack or psh */
-+	if (th->fin || th->syn || th->rst || th->urg || th->ece ||
-+	    th->cwr || !th->ack) {
-+		if (lro) {
-+			/* First flush session to keep packets in-order */
-+			mlx4_en_lro_flush_single(priv, ring, lro);
-+		}
-+		goto sync_device;
-+	}
-+
-+	/* Get ip length and verify that the frame is big enough */
-+	ip_len = ntohs(iph->tot_len);
-+	if (unlikely(length < ETH_HLEN + ip_len)) {
-+		en_warn(priv, "Cannot LRO - ip payload exceeds frame!\n");
-+		goto sync_device;
-+	}
-+
-+	/* Get TCP payload length */
-+	tcp_data_len = ip_len - tcp_hlen - sizeof(struct iphdr);
-+	seq = ntohl(th->seq);
-+	if (!tcp_data_len)
-+		goto flush_session;
-+
-+	if (lro) {
-+		/* Check VLAN tag */
-+		if (cqe->vlan_my_qpn & MLX4_CQE_VLAN_PRESENT_MASK) {
-+			if (cqe->sl_vid != lro->vlan_prio || !lro->has_vlan) {
-+				mlx4_en_lro_flush_single(priv, ring, lro);
-+				goto sync_device;
-+			}
-+		} else if (lro->has_vlan) {
-+			mlx4_en_lro_flush_single(priv, ring, lro);
-+			goto sync_device;
-+		}
-+
-+		/* Check sequence number */
-+		if (unlikely(seq != lro->next_seq)) {
-+			mlx4_en_lro_flush_single(priv, ring, lro);
-+			goto sync_device;
-+		}
-+
-+		/* If the cummulative IP length is over 64K, flush and start
-+		 * a new session */
-+		if (lro->tot_len + tcp_data_len > 0xffff) {
-+			mlx4_en_lro_flush_single(priv, ring, lro);
-+			goto new_session;
-+		}
-+
-+		/* Check timestamps */
-+		if (tcp_hlen != sizeof(*th)) {
-+			if (unlikely(lro->tsval > tsval || !tsecr))
-+				goto sync_device;
-+		}
-+
-+		window = th->window;
-+		ack_seq = th->ack_seq;
-+		if (likely(tcp_data_len)) {
-+			/* Append the data! */
-+			hlen = ETH_HLEN + sizeof(struct iphdr) + tcp_hlen;
-+			if (mlx4_en_lro_append(priv, lro, rx_desc, skb_frags,
-+							ring->page_alloc,
-+							tcp_data_len, hlen)) {
-+				mlx4_en_lro_flush_single(priv, ring, lro);
-+				goto sync_device;
-+			}
-+		} else {
-+			/* No data */
-+			dma_sync_single_range_for_device(&mdev->dev->pdev->dev, dma,
-+							 0, MAX_LRO_HEADER,
-+							 DMA_FROM_DEVICE);
-+		}
-+
-+		/* Update session */
-+		lro->psh |= th->psh;
-+		lro->next_seq += tcp_data_len;
-+		lro->data_csum = csum_block_add(lro->data_csum,
-+					mlx4_en_lro_tcp_data_csum(iph, th,
-+								  tcp_data_len),
-+					lro->tot_len);
-+		lro->tot_len += tcp_data_len;
-+		lro->tsval = tsval;
-+		lro->tsecr = tsecr;
-+		lro->ack_seq = ack_seq;
-+		lro->window = window;
-+		if (tcp_data_len > lro->mss)
-+			lro->mss = tcp_data_len;
-+		priv->port_stats.lro_aggregated++;
-+		if (th->psh)
-+			mlx4_en_lro_flush_single(priv, ring, lro);
-+		return 0;
-+	}
-+
-+new_session:
-+	if (th->psh)
-+		goto sync_device;
-+	lro = mlx4_en_lro_alloc_session(priv, ring);
-+	if (lro) {
-+		skb = mlx4_en_rx_skb(priv, rx_desc, skb_frags, ring->page_alloc,
-+							     ETH_HLEN + ip_len);
-+		if (skb) {
-+			int index;
-+
-+			/* Add in the skb */
-+			lro->skb = skb;
-+			lro->skb_last = skb;
-+			skb->protocol = eth_type_trans(skb, priv->dev);
-+			skb->ip_summed = CHECKSUM_UNNECESSARY;
-+
-+			/* Initialize session */
-+			lro->saddr = iph->saddr;
-+			lro->daddr = iph->daddr;
-+			lro->sport_dport = *((u32*) &th->source);
-+
-+			lro->next_seq = seq + tcp_data_len;
-+			lro->tot_len = ip_len;
-+			lro->psh = th->psh;
-+			lro->ack_seq = th->ack_seq;
-+			lro->window = th->window;
-+			lro->mss = tcp_data_len;
-+			lro->data_csum = mlx4_en_lro_tcp_data_csum(iph, th,
-+						tcp_data_len);
-+
-+			/* Handle vlans */
-+			if (cqe->vlan_my_qpn & MLX4_CQE_VLAN_PRESENT_MASK) {
-+				lro->vlan_prio = cqe->sl_vid;
-+				lro->has_vlan = 1;
-+			} else
-+				lro->has_vlan = 0;
-+
-+			/* Handle timestamps */
-+			if (tcp_hlen != sizeof(*th)) {
-+				lro->tsval = tsval;
-+				lro->tsecr = tsecr;
-+				lro->has_timestamp = 1;
-+			} else {
-+				lro->tsval = (u32) ~0UL;
-+				lro->has_timestamp = 0;
-+			}
-+
-+			/* Activate this session */
-+			lro->expires = jiffies + HZ / 25;
-+			hlist_del(&lro->node);
-+			index = LRO_INDEX(th, mdev->profile.num_lro);
-+
-+			hlist_add_head(&lro->node, &ring->lro_hash[index]);
-+			hlist_add_head(&lro->flush_node, &ring->lro_flush);
-+			priv->port_stats.lro_aggregated++;
-+			return 0;
-+		} else {
-+			/* Packet is dropped because we were not able to allocate new
-+			 * page for fragments */
-+			dma_sync_single_range_for_device(&mdev->pdev->dev, dma,
-+							 0, MAX_LRO_HEADER,
-+							 DMA_FROM_DEVICE);
-+			return 0;
-+		}
-+	} else {
-+		priv->port_stats.lro_no_desc++;
-+	}
-+
-+flush_session:
-+	if (lro)
-+		mlx4_en_lro_flush_single(priv, ring, lro);
-+sync_device:
-+	dma_sync_single_range_for_device(&mdev->pdev->dev, dma, 0,
-+					 MAX_LRO_HEADER, DMA_FROM_DEVICE);
-+	return -1;
-+}
-+
-+void mlx4_en_lro_destroy(struct mlx4_en_rx_ring *ring)
-+{
-+	struct mlx4_en_lro *lro;
-+	struct hlist_node *node, *tmp;
-+
-+	hlist_for_each_entry_safe(lro, node, tmp, &ring->lro_free, node) {
-+		hlist_del(&lro->node);
-+		kfree(lro);
-+	}
-+	kfree(ring->lro_hash);
-+}
-+
-+int mlx4_en_lro_init(struct mlx4_en_rx_ring *ring, int num_lro)
-+{
-+	struct mlx4_en_lro *lro;
-+	int i;
-+
-+	INIT_HLIST_HEAD(&ring->lro_free);
-+	INIT_HLIST_HEAD(&ring->lro_flush);
-+	ring->lro_hash = kmalloc(sizeof(struct hlist_head) * num_lro,
-+				 GFP_KERNEL);
-+	if (!ring->lro_hash)
-+		return -ENOMEM;
-+
-+	for (i = 0; i < num_lro; i++) {
-+		INIT_HLIST_HEAD(&ring->lro_hash[i]);
-+		lro = kzalloc(sizeof(struct mlx4_en_lro), GFP_KERNEL);
-+		if (!lro) {
-+			mlx4_en_lro_destroy(ring);
-+			return -ENOMEM;
-+		}
-+		INIT_HLIST_NODE(&lro->node);
-+		INIT_HLIST_NODE(&lro->flush_node);
-+		hlist_add_head(&lro->node, &ring->lro_free);
-+	}
-+	return 0;
-+}
-+
-+
-diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
-index a4b1203..6bc6113 100644
---- a/drivers/net/mlx4/en_rx.c
-+++ b/drivers/net/mlx4/en_rx.c
-@@ -51,18 +51,6 @@ static void mlx4_en_srq_event(struct mlx4_srq *srq, enum mlx4_event type)
- 	return;
- }
- 
--static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
--				   void **ip_hdr, void **tcpudp_hdr,
--				   u64 *hdr_flags, void *priv)
--{
--	*mac_hdr = page_address(frags->page) + frags->page_offset;
--	*ip_hdr = *mac_hdr + ETH_HLEN;
--	*tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr));
--	*hdr_flags = LRO_IPV4 | LRO_TCP;
--
--	return 0;
--}
--
- static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
- 			      struct mlx4_en_rx_desc *rx_desc,
- 			      struct skb_frag_struct *skb_frags,
-@@ -455,23 +443,14 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
- 	}
- 	ring->buf = ring->wqres.buf.direct.buf;
- 
--	/* Configure lro mngr */
--	memset(&ring->lro, 0, sizeof(struct net_lro_mgr));
--	ring->lro.dev = priv->dev;
--	ring->lro.features = LRO_F_NAPI;
--	ring->lro.frag_align_pad = NET_IP_ALIGN;
--	ring->lro.ip_summed = CHECKSUM_UNNECESSARY;
--	ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY;
--	ring->lro.max_desc = mdev->profile.num_lro;
--	ring->lro.max_aggr = MAX_SKB_FRAGS;
--	ring->lro.lro_arr = kzalloc(mdev->profile.num_lro *
--				    sizeof(struct net_lro_desc),
--				    GFP_KERNEL);
--	if (!ring->lro.lro_arr) {
--		en_err(priv, "Failed to allocate lro array\n");
--		goto err_map;
-+	/* Allocate LRO sessions */
-+	if (mdev->profile.num_lro) {
-+		err =  mlx4_en_lro_init(ring, mdev->profile.num_lro);
-+		if (err) {
-+			en_err(priv, "Failed allocating lro sessions\n");
-+			goto err_map;
-+		}
- 	}
--	ring->lro.get_frag_header = mlx4_en_get_frag_header;
- 
- 	return 0;
- 
-@@ -588,7 +567,8 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
- {
- 	struct mlx4_en_dev *mdev = priv->mdev;
- 
--	kfree(ring->lro.lro_arr);
-+	if (mdev->profile.num_lro)
-+		mlx4_en_lro_destroy(ring);
- 	mlx4_en_unmap_buffer(&ring->wqres.buf);
- 	mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
- 	vfree(ring->rx_info);
-@@ -608,12 +588,12 @@ void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
- 
- 
- /* Unmap a completed descriptor and free unused pages */
--static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
--				    struct mlx4_en_rx_desc *rx_desc,
--				    struct skb_frag_struct *skb_frags,
--				    struct skb_frag_struct *skb_frags_rx,
--				    struct mlx4_en_rx_alloc *page_alloc,
--				    int length)
-+int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
-+			     struct mlx4_en_rx_desc *rx_desc,
-+			     struct skb_frag_struct *skb_frags,
-+			     struct skb_frag_struct *skb_frags_rx,
-+			     struct mlx4_en_rx_alloc *page_alloc,
-+			     int length)
- {
- 	struct mlx4_en_dev *mdev = priv->mdev;
- 	struct mlx4_en_frag_info *frag_info;
-@@ -656,11 +636,11 @@ fail:
- }
- 
- 
--static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
--				      struct mlx4_en_rx_desc *rx_desc,
--				      struct skb_frag_struct *skb_frags,
--				      struct mlx4_en_rx_alloc *page_alloc,
--				      unsigned int length)
-+struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
-+			       struct mlx4_en_rx_desc *rx_desc,
-+			       struct skb_frag_struct *skb_frags,
-+			       struct mlx4_en_rx_alloc *page_alloc,
-+			       unsigned int length)
- {
- 	struct mlx4_en_dev *mdev = priv->mdev;
- 	struct sk_buff *skb;
-@@ -901,14 +881,13 @@ out:
- int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
- {
- 	struct mlx4_en_priv *priv = netdev_priv(dev);
-+	struct mlx4_en_dev *mdev = priv->mdev;
- 	struct mlx4_cqe *cqe;
- 	struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
- 	struct skb_frag_struct *skb_frags;
--	struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS];
- 	struct mlx4_en_rx_desc *rx_desc;
- 	struct sk_buff *skb;
- 	int index;
--	int nr;
- 	unsigned int length;
- 	int polled = 0;
- 	int ip_summed;
-@@ -946,40 +925,12 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
- 
- 		if (likely(priv->rx_csum)) {
- 			if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
--			    (cqe->checksum == cpu_to_be16(0xffff))) {
-+			    (cqe->checksum == 0xffff)) {
- 				priv->port_stats.rx_chksum_good++;
--				/* This packet is eligible for LRO if it is:
--				 * - DIX Ethernet (type interpretation)
--				 * - TCP/IP (v4)
--				 * - without IP options
--				 * - not an IP fragment */
--				if (mlx4_en_can_lro(cqe->status) &&
--				    dev->features & NETIF_F_LRO) {
--
--					nr = mlx4_en_complete_rx_desc(
--						priv, rx_desc,
--						skb_frags, lro_frags,
--						ring->page_alloc, length);
--					if (!nr)
--						goto next;
--
--					if (priv->vlgrp && (cqe->vlan_my_qpn &
--							    cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) {
--						lro_vlan_hwaccel_receive_frags(
--						       &ring->lro, lro_frags,
--						       length, length,
--						       priv->vlgrp,
--						       be16_to_cpu(cqe->sl_vid),
--						       NULL, 0);
--					} else
--						lro_receive_frags(&ring->lro,
--								  lro_frags,
--								  length,
--								  length,
--								  NULL, 0);
--
-+				if (mdev->profile.num_lro &&
-+				    !mlx4_en_lro_rx(priv, ring, rx_desc,
-+						    skb_frags, length, cqe))
- 					goto next;
--				}
- 
- 				/* LRO not possible, complete processing here */
- 				ip_summed = CHECKSUM_UNNECESSARY;
-@@ -1002,7 +953,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
- 
- 		skb->ip_summed = ip_summed;
- 		skb->protocol = eth_type_trans(skb, dev);
--		skb_record_rx_queue(skb, cq->ring);
- 
- 		/* Push it up the stack */
- 		if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) &
-@@ -1012,6 +962,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
- 		} else
- 			netif_receive_skb(skb);
- 
-+		dev->last_rx = jiffies;
-+
- next:
- 		++cq->mcq.cons_index;
- 		index = (cq->mcq.cons_index) & ring->size_mask;
-@@ -1019,13 +971,15 @@ next:
- 		if (++polled == budget) {
- 			/* We are here because we reached the NAPI budget -
- 			 * flush only pending LRO sessions */
--			lro_flush_all(&ring->lro);
-+			if (mdev->profile.num_lro)
-+				mlx4_en_lro_flush(priv, ring, 0);
- 			goto out;
- 		}
- 	}
- 
- 	/* If CQ is empty flush all LRO sessions unconditionally */
--	lro_flush_all(&ring->lro);
-+	if (mdev->profile.num_lro)
-+		mlx4_en_lro_flush(priv, ring, 1);
- 
- out:
- 	AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
-@@ -1042,7 +996,6 @@ out:
- 	return polled;
- }
- 
--
- void mlx4_en_rx_irq(struct mlx4_cq *mcq)
- {
- 	struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
-diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
-index b45774c..e9174c4 100644
---- a/drivers/net/mlx4/mlx4_en.h
-+++ b/drivers/net/mlx4/mlx4_en.h
-@@ -296,11 +296,41 @@ struct mlx4_en_rx_desc {
- 	struct mlx4_wqe_data_seg data[0];
- };
- 
-+struct mlx4_en_lro {
-+	struct hlist_node node;
-+	struct hlist_node flush_node;
-+
-+	/* Id fields come first: */
-+	u32 saddr;
-+	u32 daddr;
-+	u32 sport_dport;
-+	u32 next_seq;
-+	u16 tot_len;
-+	u8 psh;
-+
-+	u32 tsval;
-+	u32 tsecr;
-+	u32 ack_seq;
-+	u16 window;
-+	__be16 vlan_prio;
-+	u16 has_vlan;
-+	u16 has_timestamp;
-+	u16 mss;
-+	__wsum  data_csum;
-+
-+	unsigned long expires;
-+	struct sk_buff *skb;
-+	struct sk_buff *skb_last;
-+};
-+
- struct mlx4_en_rx_ring {
- 	struct mlx4_srq srq;
- 	struct mlx4_hwq_resources wqres;
- 	struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
--	struct net_lro_mgr lro;
-+	struct mlx4_en_lro lro;
-+	struct hlist_head *lro_hash;
-+	struct hlist_head lro_free;
-+	struct hlist_head lro_flush;
- 	u32 size ;	/* number of Rx descs*/
- 	u32 actual_size;
- 	u32 size_mask;
-@@ -592,12 +622,32 @@ void mlx4_en_calc_rx_buf(struct net_device *dev);
- void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
- 				 struct mlx4_en_rss_map *rss_map,
- 				 int num_entries, int num_rings);
-+
-+void mlx4_en_lro_flush(struct mlx4_en_priv* priv, struct mlx4_en_rx_ring *ring, u8 all);
-+int mlx4_en_lro_rx(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring,
-+		   struct mlx4_en_rx_desc *rx_desc,
-+		   struct skb_frag_struct *skb_frags,
-+		   unsigned int length, struct mlx4_cqe *cqe);
-+void mlx4_en_lro_destroy(struct mlx4_en_rx_ring *ring);
-+int mlx4_en_lro_init(struct mlx4_en_rx_ring *ring, int num_lro);
-+
- void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num);
- int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
- void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv);
- int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
- void mlx4_en_rx_refill(struct work_struct *work);
- void mlx4_en_rx_irq(struct mlx4_cq *mcq);
-+struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
-+			       struct mlx4_en_rx_desc *rx_desc,
-+			       struct skb_frag_struct *skb_frags,
-+			       struct mlx4_en_rx_alloc *page_alloc,
-+			       unsigned int length);
-+int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
-+			     struct mlx4_en_rx_desc *rx_desc,
-+			     struct skb_frag_struct *skb_frags,
-+			     struct skb_frag_struct *skb_frags_rx,
-+			     struct mlx4_en_rx_alloc *page_alloc,
-+			     int length);
- 
- int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, u64 mac, u64 clear, u8 mode);
- int mlx4_SET_VLAN_FLTR(struct mlx4_dev *dev, u8 port, struct vlan_group *grp);
--- 
-1.6.0
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0040_napi_backports.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0040_napi_backports.patch
deleted file mode 100644
index 34b579f..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0040_napi_backports.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From 455790331499dd90a37c14cebdeef88fbee15357 Mon Sep 17 00:00:00 2001
-From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
-Date: Sun, 31 May 2009 15:11:45 +0300
-Subject: [PATCH 4/8] mlx4_en: napi backport
-
-Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
----
- drivers/net/mlx4/en_cq.c     |   21 +++++++++++++++++----
- drivers/net/mlx4/en_netdev.c |    5 ++---
- drivers/net/mlx4/en_rx.c     |   26 +++++++++++++++-----------
- drivers/net/mlx4/mlx4_en.h   |    4 ++--
- 4 files changed, 36 insertions(+), 20 deletions(-)
-
-diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c
-index 17bf8f5..2da0976 100644
---- a/drivers/net/mlx4/en_cq.c
-+++ b/drivers/net/mlx4/en_cq.c
-@@ -34,6 +34,7 @@
- #include <linux/mlx4/cq.h>
- #include <linux/mlx4/qp.h>
- #include <linux/mlx4/cmd.h>
-+#include <linux/delay.h>
- 
- #include "mlx4_en.h"
- 
-@@ -106,8 +107,17 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
- 		cq->timer.function = mlx4_en_poll_tx_cq;
- 		cq->timer.data = (unsigned long) cq;
- 	} else {
--		netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
--		napi_enable(&cq->napi);
-+		char name[IFNAMSIZ];
-+
-+		snprintf(name, IFNAMSIZ, "mlx4_en-%d-%d", priv->port, cq->ring);
-+		cq->poll_dev = alloc_netdev(0, name, ether_setup);
-+		if (!cq->poll_dev)
-+			return -ENOMEM;
-+
-+		cq->poll_dev->priv = cq;
-+		cq->poll_dev->weight = 64;
-+		cq->poll_dev->poll = mlx4_en_poll_rx_cq;
-+		set_bit(__LINK_STATE_START, &cq->poll_dev->state);
- 	}
- 
- 	return 0;
-@@ -130,8 +140,11 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
- 	if (cq->is_tx)
- 		del_timer(&cq->timer);
- 	else {
--		napi_disable(&cq->napi);
--		netif_napi_del(&cq->napi);
-+		while (test_bit(__LINK_STATE_RX_SCHED,
-+				&cq->poll_dev->state))
-+			msleep(1);
-+		free_netdev(cq->poll_dev);
-+		cq->poll_dev = NULL;
- 	}
- 
- 	mlx4_cq_free(mdev->dev, &cq->mcq);
-diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
-index 34e082c..cb34cc4 100644
---- a/drivers/net/mlx4/en_netdev.c
-+++ b/drivers/net/mlx4/en_netdev.c
-@@ -329,7 +329,8 @@ static void mlx4_en_netpoll(struct net_device *dev)
- 	for (i = 0; i < priv->rx_ring_num; i++) {
- 		cq = &priv->rx_cq[i];
- 		spin_lock_irqsave(&cq->lock, flags);
--		napi_synchronize(&cq->napi);
-+		while (test_bit(__LINK_STATE_RX_SCHED, &cq->poll_dev->state))
-+			msleep(1);
- 		if (priv->rx_ring[i].use_frags)
- 			mlx4_en_process_rx_cq(dev, cq, 0);
- 		else
-@@ -734,8 +735,6 @@ void mlx4_en_stop_port(struct net_device *dev)
- 	/* Free RX Rings */
- 	for (i = 0; i < priv->rx_ring_num; i++) {
- 		mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
--		while (test_bit(NAPI_STATE_SCHED, &priv->rx_cq[i].napi.state))
--			msleep(1);
- 		mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
- 	}
- }
-diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
-index f079888..1f5a8d2 100644
---- a/drivers/net/mlx4/en_rx.c
-+++ b/drivers/net/mlx4/en_rx.c
-@@ -1002,33 +1002,37 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
- 	struct mlx4_en_priv *priv = netdev_priv(cq->dev);
- 
- 	if (priv->port_up)
--		napi_schedule(&cq->napi);
-+		netif_rx_schedule(cq->poll_dev);
- 	else
- 		mlx4_en_arm_cq(priv, cq);
- }
- 
- /* Rx CQ polling - called by NAPI */
--int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
-+int mlx4_en_poll_rx_cq(struct net_device *poll_dev, int *budget)
- {
--	struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
-+	struct mlx4_en_cq *cq = poll_dev->priv;
- 	struct net_device *dev = cq->dev;
- 	struct mlx4_en_priv *priv = netdev_priv(dev);
- 	int done;
-+	int work = min(*budget, poll_dev->quota);
- 
- 	if (priv->rx_ring[cq->ring].use_frags)
--		done = mlx4_en_process_rx_cq(dev, cq, budget);
-+		done = mlx4_en_process_rx_cq(dev, cq, work);
- 	else
--		done = mlx4_en_process_rx_cq_skb(dev, cq, budget);
-+		done = mlx4_en_process_rx_cq_skb(dev, cq, work);
-+	dev->quota -= done;
-+	*budget -= done;
- 
- 	/* If we used up all the quota - we're probably not done yet... */
--	if (done == budget)
-+	if (done == work) {
- 		INC_PERF_COUNTER(priv->pstats.napi_quota);
--	else {
--		/* Done for now */
--		napi_complete(napi);
--		mlx4_en_arm_cq(priv, cq);
-+		return 1;
- 	}
--	return done;
-+
-+	/* Done for now */
-+	netif_rx_complete(poll_dev);
-+	mlx4_en_arm_cq(priv, cq);
-+	return 0;
- }
- 
- 
-diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
-index ac1164c..ec318a7 100644
---- a/drivers/net/mlx4/mlx4_en.h
-+++ b/drivers/net/mlx4/mlx4_en.h
-@@ -371,7 +371,7 @@ struct mlx4_en_cq {
- 	int                     ring;
- 	spinlock_t              lock;
- 	struct net_device      *dev;
--	struct napi_struct	napi;
-+	struct net_device      *poll_dev; /* for napi */
- 	/* Per-core Tx cq processing support */
- 	struct timer_list timer;
- 	int size;
-@@ -610,7 +610,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev,
- int mlx4_en_process_rx_cq_skb(struct net_device *dev,
- 			      struct mlx4_en_cq *cq,
- 			      int budget);
--int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
-+int mlx4_en_poll_rx_cq(struct net_device *poll_dev, int *budget);;
- void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
- 			     int is_tx, int rss, int qpn, int cqn, int srqn,
- 			     struct mlx4_qp_context *context);
--- 
-1.6.1.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0050_no_set_flags_support.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0050_no_set_flags_support.patch
deleted file mode 100644
index da1c443..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0050_no_set_flags_support.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 9e8b37de6c50238ded500d77e7a6317798842fc5 Mon Sep 17 00:00:00 2001
-From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
-Date: Sun, 31 May 2009 15:17:17 +0300
-Subject: [PATCH 5/8] mlx4_en: no set_flag support
-
-Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
----
- drivers/net/mlx4/en_ethtool.c |    2 --
- 1 files changed, 0 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
-index 397ceb9..a30ba2c 100644
---- a/drivers/net/mlx4/en_ethtool.c
-+++ b/drivers/net/mlx4/en_ethtool.c
-@@ -414,8 +414,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
- 	.set_pauseparam = mlx4_en_set_pauseparam,
- 	.get_ringparam = mlx4_en_get_ringparam,
- 	.set_ringparam = mlx4_en_set_ringparam,
--	.get_flags = ethtool_op_get_flags,
--	.set_flags = ethtool_op_set_flags,
- };
- 
- 
--- 
-1.6.1.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0060_ethtool_interface.patch b/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0060_ethtool_interface.patch
deleted file mode 100644
index 4ec818b..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mlx4_en_0060_ethtool_interface.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0096a7c598645ee54f98af40e96c98ff45b190eb Mon Sep 17 00:00:00 2001
-From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
-Date: Sun, 31 May 2009 15:20:43 +0300
-Subject: [PATCH 6/8] mlx4_en: ethtool interface
-
-Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
----
- drivers/net/mlx4/en_ethtool.c |    7 ++-----
- 1 files changed, 2 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
-index a30ba2c..973416a 100644
---- a/drivers/net/mlx4/en_ethtool.c
-+++ b/drivers/net/mlx4/en_ethtool.c
-@@ -144,13 +144,10 @@ static void mlx4_en_get_wol(struct net_device *netdev,
- 	return;
- }
- 
--static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
-+static int mlx4_en_get_sset_count(struct net_device *dev)
- {
- 	struct mlx4_en_priv *priv = netdev_priv(dev);
- 
--	if (sset != ETH_SS_STATS)
--		return -EOPNOTSUPP;
--
- 	return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
- }
- 
-@@ -403,7 +400,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
- 	.get_tx_csum = ethtool_op_get_tx_csum,
- 	.set_tx_csum = ethtool_op_set_tx_ipv6_csum,
- 	.get_strings = mlx4_en_get_strings,
--	.get_sset_count = mlx4_en_get_sset_count,
-+	.get_stats_count = mlx4_en_get_sset_count,
- 	.get_ethtool_stats = mlx4_en_get_ethtool_stats,
- 	.get_wol = mlx4_en_get_wol,
- 	.get_msglevel = mlx4_en_get_msglevel,
--- 
-1.6.1.3
-
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mthca_0000_pci_dma_mapping_error_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/mthca_0000_pci_dma_mapping_error_to_2_6_26.patch
deleted file mode 100644
index ac803bf..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mthca_0000_pci_dma_mapping_error_to_2_6_26.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- drivers/infiniband/hw/mthca/mthca_eq.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/mthca/mthca_eq.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/mthca/mthca_eq.c
-+++ ofed_kernel/drivers/infiniband/hw/mthca/mthca_eq.c
-@@ -780,7 +780,7 @@ int mthca_map_eq_icm(struct mthca_dev *d
- 		return -ENOMEM;
- 	dev->eq_table.icm_dma  = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0,
- 					      PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
--	if (pci_dma_mapping_error(dev->pdev, dev->eq_table.icm_dma)) {
-+	if (pci_dma_mapping_error(dev->eq_table.icm_dma)) {
- 		__free_page(dev->eq_table.icm_page);
- 		return -ENOMEM;
- 	}
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mthca_0001_pcix_to_2_6_22.patch b/kernel_patches/backport/2.6.18-EL5.1/mthca_0001_pcix_to_2_6_22.patch
deleted file mode 100644
index 4d81461..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mthca_0001_pcix_to_2_6_22.patch
+++ /dev/null
@@ -1,57 +0,0 @@
----
- drivers/infiniband/hw/mthca/mthca_main.c |   33 +++++++++++++++++++++++--------
- 1 file changed, 25 insertions(+), 8 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/mthca/mthca_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/mthca/mthca_main.c
-+++ ofed_kernel/drivers/infiniband/hw/mthca/mthca_main.c
-@@ -131,23 +131,40 @@ static char mthca_version[] __devinitdat
- 
- static int mthca_tune_pci(struct mthca_dev *mdev)
- {
-+	int cap;
-+	u16 val;
-+
- 	if (!tune_pci)
- 		return 0;
- 
- 	/* First try to max out Read Byte Count */
--	if (pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX)) {
--		if (pcix_set_mmrbc(mdev->pdev, pcix_get_max_mmrbc(mdev->pdev))) {
--			mthca_err(mdev, "Couldn't set PCI-X max read count, "
--				"aborting.\n");
-+	cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
-+	if (cap) {
-+		if (pci_read_config_word(mdev->pdev, cap + PCI_X_CMD, &val)) {
-+			mthca_err(mdev, "Couldn't read PCI-X command register, "
-+				  "aborting.\n");
-+			return -ENODEV;
-+		}
-+		val = (val & ~PCI_X_CMD_MAX_READ) | (3 << 2);
-+		if (pci_write_config_word(mdev->pdev, cap + PCI_X_CMD, val)) {
-+			mthca_err(mdev, "Couldn't write PCI-X command register, "
-+				  "aborting.\n");
- 			return -ENODEV;
- 		}
- 	} else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE))
- 		mthca_info(mdev, "No PCI-X capability, not setting RBC.\n");
- 
--	if (pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP)) {
--		if (pcie_set_readrq(mdev->pdev, 4096)) {
--			mthca_err(mdev, "Couldn't write PCI Express read request, "
--				"aborting.\n");
-+	cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP);
-+	if (cap) {
-+		if (pci_read_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, &val)) {
-+			mthca_err(mdev, "Couldn't read PCI Express device control "
-+				  "register, aborting.\n");
-+			return -ENODEV;
-+		}
-+		val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12);
-+		if (pci_write_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, val)) {
-+			mthca_err(mdev, "Couldn't write PCI Express device control "
-+				  "register, aborting.\n");
- 			return -ENODEV;
- 		}
- 	} else if (mdev->mthca_flags & MTHCA_FLAG_PCIE)
diff --git a/kernel_patches/backport/2.6.18-EL5.1/mthca_0010_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/mthca_0010_sysfs.patch
deleted file mode 100644
index 473aa45..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/mthca_0010_sysfs.patch
+++ /dev/null
@@ -1,94 +0,0 @@
----
- drivers/infiniband/hw/mthca/mthca_provider.c |   50 +++++++++++----------------
- 1 file changed, 21 insertions(+), 29 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/mthca/mthca_provider.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/mthca/mthca_provider.c
-+++ ofed_kernel/drivers/infiniband/hw/mthca/mthca_provider.c
-@@ -1186,29 +1186,23 @@ static int mthca_unmap_fmr(struct list_h
- 	return 0;
- }
- 
--static ssize_t show_rev(struct device *device, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_rev(struct class_device *cdev, char *buf)
- {
--	struct mthca_dev *dev =
--		container_of(device, struct mthca_dev, ib_dev.dev);
-+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
- 	return sprintf(buf, "%x\n", dev->rev_id);
- }
- 
--static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
--			   char *buf)
-+static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
- {
--	struct mthca_dev *dev =
--		container_of(device, struct mthca_dev, ib_dev.dev);
-+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
- 	return sprintf(buf, "%d.%d.%d\n", (int) (dev->fw_ver >> 32),
- 		       (int) (dev->fw_ver >> 16) & 0xffff,
- 		       (int) dev->fw_ver & 0xffff);
- }
- 
--static ssize_t show_hca(struct device *device, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_hca(struct class_device *cdev, char *buf)
- {
--	struct mthca_dev *dev =
--		container_of(device, struct mthca_dev, ib_dev.dev);
-+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
- 	switch (dev->pdev->device) {
- 	case PCI_DEVICE_ID_MELLANOX_TAVOR:
- 		return sprintf(buf, "MT23108\n");
-@@ -1224,24 +1218,22 @@ static ssize_t show_hca(struct device *d
- 	}
- }
- 
--static ssize_t show_board(struct device *device, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_board(struct class_device *cdev, char *buf)
- {
--	struct mthca_dev *dev =
--		container_of(device, struct mthca_dev, ib_dev.dev);
-+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
- 	return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
- }
- 
--static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
--static DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
--static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
--static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
--
--static struct device_attribute *mthca_dev_attributes[] = {
--	&dev_attr_hw_rev,
--	&dev_attr_fw_ver,
--	&dev_attr_hca_type,
--	&dev_attr_board_id
-+static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
-+static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
-+static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
-+static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
-+
-+static struct class_device_attribute *mthca_class_attributes[] = {
-+	&class_device_attr_hw_rev,
-+	&class_device_attr_fw_ver,
-+	&class_device_attr_hca_type,
-+	&class_device_attr_board_id
- };
- 
- static int mthca_init_node_data(struct mthca_dev *dev)
-@@ -1403,9 +1395,9 @@ int mthca_register_device(struct mthca_d
- 	if (ret)
- 		return ret;
- 
--	for (i = 0; i < ARRAY_SIZE(mthca_dev_attributes); ++i) {
--		ret = device_create_file(&dev->ib_dev.dev,
--					 mthca_dev_attributes[i]);
-+	for (i = 0; i < ARRAY_SIZE(mthca_class_attributes); ++i) {
-+		ret = class_device_create_file(&dev->ib_dev.class_dev,
-+					       mthca_class_attributes[i]);
- 		if (ret) {
- 			ib_unregister_device(&dev->ib_dev);
- 			return ret;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/nes_0010_sysfs.patch b/kernel_patches/backport/2.6.18-EL5.1/nes_0010_sysfs.patch
deleted file mode 100644
index 8df7939..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/nes_0010_sysfs.patch
+++ /dev/null
@@ -1,120 +0,0 @@
----
- drivers/infiniband/hw/nes/nes_verbs.c |   50 +++++++++++++++-------------------
- 1 file changed, 23 insertions(+), 27 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/hw/nes/nes_verbs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/nes/nes_verbs.c
-+++ ofed_kernel/drivers/infiniband/hw/nes/nes_verbs.c
-@@ -2676,11 +2676,10 @@ static int nes_dereg_mr(struct ib_mr *ib
- /**
-  * show_rev
-  */
--static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
--			char *buf)
-+static ssize_t show_rev(struct class_device *cdev, char *buf)
- {
- 	struct nes_ib_device *nesibdev =
--			container_of(dev, struct nes_ib_device, ibdev.dev);
-+			container_of(cdev, struct nes_ib_device, ibdev.class_dev);
- 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
- 
- 	nes_debug(NES_DBG_INIT, "\n");
-@@ -2691,11 +2690,10 @@ static ssize_t show_rev(struct device *d
- /**
-  * show_fw_ver
-  */
--static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
--			   char *buf)
-+static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
- {
- 	struct nes_ib_device *nesibdev =
--			container_of(dev, struct nes_ib_device, ibdev.dev);
-+			container_of(cdev, struct nes_ib_device, ibdev.class_dev);
- 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
- 
- 	nes_debug(NES_DBG_INIT, "\n");
-@@ -2709,8 +2707,7 @@ static ssize_t show_fw_ver(struct device
- /**
-  * show_hca
-  */
--static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
--		        char *buf)
-+static ssize_t show_hca(struct class_device *cdev, char *buf)
- {
- 	nes_debug(NES_DBG_INIT, "\n");
- 	return sprintf(buf, "NES020\n");
-@@ -2720,24 +2717,23 @@ static ssize_t show_hca(struct device *d
- /**
-  * show_board
-  */
--static ssize_t show_board(struct device *dev, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_board(struct class_device *cdev, char *buf)
- {
- 	nes_debug(NES_DBG_INIT, "\n");
- 	return sprintf(buf, "%.*s\n", 32, "NES020 Board ID");
- }
- 
- 
--static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
--static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
--static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
--static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
--
--static struct device_attribute *nes_dev_attributes[] = {
--	&dev_attr_hw_rev,
--	&dev_attr_fw_ver,
--	&dev_attr_hca_type,
--	&dev_attr_board_id
-+static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
-+static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
-+static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
-+static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
-+
-+static struct class_device_attribute *nes_class_attributes[] = {
-+	&class_device_attr_hw_rev,
-+	&class_device_attr_fw_ver,
-+	&class_device_attr_hca_type,
-+	&class_device_attr_board_id
- };
- 
- 
-@@ -3646,7 +3642,7 @@ struct nes_ib_device *nes_init_ofa_devic
- 	nesibdev->ibdev.phys_port_cnt = 1;
- 	nesibdev->ibdev.num_comp_vectors = 1;
- 	nesibdev->ibdev.dma_device = &nesdev->pcidev->dev;
--	nesibdev->ibdev.dev.parent = &nesdev->pcidev->dev;
-+	nesibdev->ibdev.class_dev.dev = &nesdev->pcidev->dev;
- 	nesibdev->ibdev.query_device = nes_query_device;
- 	nesibdev->ibdev.query_port = nes_query_port;
- 	nesibdev->ibdev.modify_port = nes_modify_port;
-@@ -3741,13 +3737,13 @@ int nes_register_ofa_device(struct nes_i
- 	nesibdev->max_qp = (nesadapter->max_qp-NES_FIRST_QPN) / nesadapter->port_count;
- 	nesibdev->max_pd = nesadapter->max_pd / nesadapter->port_count;
- 
--	for (i = 0; i < ARRAY_SIZE(nes_dev_attributes); ++i) {
--		ret = device_create_file(&nesibdev->ibdev.dev, nes_dev_attributes[i]);
-+	for (i = 0; i < ARRAY_SIZE(nes_class_attributes); ++i) {
-+		ret = class_device_create_file(&nesibdev->ibdev.class_dev, nes_class_attributes[i]);
- 		if (ret) {
- 			while (i > 0) {
- 				i--;
--				device_remove_file(&nesibdev->ibdev.dev,
--						   nes_dev_attributes[i]);
-+				class_device_remove_file(&nesibdev->ibdev.class_dev,
-+						nes_class_attributes[i]);
- 			}
- 			ib_unregister_device(&nesibdev->ibdev);
- 			return ret;
-@@ -3768,8 +3764,8 @@ static void nes_unregister_ofa_device(st
- 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
- 	int i;
- 
--	for (i = 0; i < ARRAY_SIZE(nes_dev_attributes); ++i) {
--		device_remove_file(&nesibdev->ibdev.dev, nes_dev_attributes[i]);
-+	for (i = 0; i < ARRAY_SIZE(nes_class_attributes); ++i) {
-+		class_device_remove_file(&nesibdev->ibdev.class_dev, nes_class_attributes[i]);
- 	}
- 
- 	if (nesvnic->of_device_registered) {
diff --git a/kernel_patches/backport/2.6.18-EL5.1/qlgc_vnic_01_class_device.patch b/kernel_patches/backport/2.6.18-EL5.1/qlgc_vnic_01_class_device.patch
deleted file mode 100644
index e4ec8f8..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/qlgc_vnic_01_class_device.patch
+++ /dev/null
@@ -1,1099 +0,0 @@
----
- drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c      |   75 ++++---
- drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h      |    2 +-
- drivers/infiniband/ulp/qlgc_vnic/vnic_main.c    |   11 +-
- drivers/infiniband/ulp/qlgc_vnic/vnic_main.h    |    5 +-
- drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c |    6 +-
- drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h |    2 +-
- drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c   |  126 ++++++------
- drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h   |   18 +-
- drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c     |  257 ++++++++++++-----------
- drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h     |   18 +-
- 10 files changed, 266 insertions(+), 254 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.c
-@@ -89,33 +89,34 @@ int vnic_ib_init(void)
- 		goto err_ib_reg;
- 	}
- 
--	interface_dev.dev.class = &vnic_class;
--	interface_dev.dev.release = vnic_release_dev;
--	snprintf(interface_dev.dev.bus_id,
-+ 	interface_cdev.class_dev.class = &vnic_class;
-+ 	snprintf(interface_cdev.class_dev.class_id,
- 		 BUS_ID_SIZE, "interfaces");
--	init_completion(&interface_dev.released);
--	ret = device_register(&interface_dev.dev);
-+ 	init_completion(&interface_cdev.released);
-+  	ret = class_device_register(&interface_cdev.class_dev);
- 	if (ret) {
- 		printk(KERN_ERR PFX "couldn't register class interfaces;"
- 		       " error %d", ret);
- 		goto err_class_dev;
- 	}
--	ret = device_create_file(&interface_dev.dev,
--				       &dev_attr_delete_vnic);
-+ 	ret = class_device_create_file(&interface_cdev.class_dev,
-+ 				       &class_device_attr_delete_vnic);
- 	if (ret) {
- 		printk(KERN_ERR PFX "couldn't create class file"
- 		       " 'delete_vnic'; error %d", ret);
- 		goto err_class_file;
- 	}
- 
--	ret = device_create_file(&interface_dev.dev, &dev_attr_force_failover);
-+	ret = class_device_create_file(&interface_cdev.class_dev,
-+					&class_device_attr_force_failover);
- 	if (ret) {
- 		printk(KERN_ERR PFX "couldn't create class file"
- 		       " 'force_failover'; error %d", ret);
- 		goto err_force_failover_file;
- 	}
- 
--	ret = device_create_file(&interface_dev.dev, &dev_attr_unfailover);
-+	ret = class_device_create_file(&interface_cdev.class_dev,
-+					&class_device_attr_unfailover);
- 	if (ret) {
- 		printk(KERN_ERR PFX "couldn't create class file"
- 		       " 'unfailover'; error %d", ret);
-@@ -125,11 +126,13 @@ int vnic_ib_init(void)
- 
- 	return ret;
- err_unfailover_file:
--	device_remove_file(&interface_dev.dev, &dev_attr_force_failover);
-+	class_device_remove_file(&interface_cdev.class_dev,
-+				 &class_device_attr_force_failover);
- err_force_failover_file:
--	device_remove_file(&interface_dev.dev, &dev_attr_delete_vnic);
-+	class_device_remove_file(&interface_cdev.class_dev,
-+				 &class_device_attr_delete_vnic);
- err_class_file:
--	device_unregister(&interface_dev.dev);
-+	class_device_unregister(&interface_cdev.class_dev);
- err_class_dev:
- 	ib_unregister_client(&vnic_client);
- err_ib_reg:
-@@ -148,29 +151,29 @@ static struct vnic_ib_port *vnic_add_port(struct vnic_ib_device *device,
- 	if (!port)
- 		return NULL;
- 
--	init_completion(&port->pdev_info.released);
-+	init_completion(&port->cdev_info.released);
- 	port->dev = device;
- 	port->port_num = port_num;
- 
--	port->pdev_info.dev.class = &vnic_class;
--	port->pdev_info.dev.parent = NULL;
--	port->pdev_info.dev.release = vnic_release_dev;
--	snprintf(port->pdev_info.dev.bus_id, BUS_ID_SIZE,
-+	port->cdev_info.class_dev.class = &vnic_class;
-+	port->cdev_info.class_dev.dev = device->dev->dma_device;
-+	snprintf(port->cdev_info.class_dev.class_id, BUS_ID_SIZE,
- 		 "vnic-%s-%d", device->dev->name, port_num);
- 
--	if (device_register(&port->pdev_info.dev))
-+ 	if (class_device_register(&port->cdev_info.class_dev))
- 		goto free_port;
- 
--	if (device_create_file(&port->pdev_info.dev,
--				     &dev_attr_create_primary))
-+ 	if (class_device_create_file(&port->cdev_info.class_dev,
-+ 				     &class_device_attr_create_primary))
- 		goto err_class;
--	if (device_create_file(&port->pdev_info.dev,
--				     &dev_attr_create_secondary))
-+
-+ 	if (class_device_create_file(&port->cdev_info.class_dev,
-+ 				     &class_device_attr_create_secondary))
- 		goto err_class;
- 
- 	return port;
- err_class:
--	device_unregister(&port->pdev_info.dev);
-+	class_device_unregister(&port->cdev_info.class_dev);
- free_port:
- 	kfree(port);
- 
-@@ -219,14 +222,16 @@ static void vnic_remove_one(struct ib_device *device)
- 	list_for_each_entry_safe(port, tmp_port,
- 				 &vnic_dev->port_list, list) {
- 
--		device_remove_file(&port->pdev_info.dev, &dev_attr_create_primary);
--		device_remove_file(&port->pdev_info.dev, &dev_attr_create_secondary);
--		device_unregister(&port->pdev_info.dev);
-+		class_device_remove_file(&port->cdev_info.class_dev,
-+				&class_device_attr_create_primary);
-+		class_device_remove_file(&port->cdev_info.class_dev,
-+				&class_device_attr_create_secondary);
-+		class_device_unregister(&port->cdev_info.class_dev);
- 		/*
- 		 * wait for sysfs entries to go away, so that no new vnics
- 		 * are created
- 		 */
--		wait_for_completion(&port->pdev_info.released);
-+		wait_for_completion(&port->cdev_info.released);
- 		kfree(port);
- 
- 	}
-@@ -254,13 +259,15 @@ void vnic_ib_cleanup(void)
- 
- 	if (!vnic_ib_inited)
- 		return;
--
--	device_remove_file(&interface_dev.dev, &dev_attr_unfailover);
--	device_remove_file(&interface_dev.dev, &dev_attr_force_failover);
--	device_remove_file(&interface_dev.dev, &dev_attr_delete_vnic);
--
--	device_unregister(&interface_dev.dev);
--	wait_for_completion(&interface_dev.released);
-+	class_device_remove_file(&interface_cdev.class_dev,
-+				&class_device_attr_unfailover);
-+	class_device_remove_file(&interface_cdev.class_dev,
-+				&class_device_attr_force_failover);
-+	class_device_remove_file(&interface_cdev.class_dev,
-+				&class_device_attr_delete_vnic);
-+
-+ 	class_device_unregister(&interface_cdev.class_dev);
-+ 	wait_for_completion(&interface_cdev.released);
- 
- 	ib_unregister_client(&vnic_client);
- 	ib_sa_unregister_client(&vnic_sa_client);
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_ib.h
-@@ -109,7 +109,7 @@ struct vnic_ib_device {
- struct vnic_ib_port {
- 	struct vnic_ib_device	*dev;
- 	u8			port_num;
--	struct dev_info		pdev_info;
-+	struct class_dev_info	cdev_info;
- 	struct list_head	list;
- };
- 
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
-@@ -770,11 +770,11 @@ static void vnic_handle_free_vnic_evt(struct vnic *vnic)
- 		kfree(vnic->mc_list);
- 	}
- 
--	sysfs_remove_group(&vnic->dev_info.dev.kobj,
--			   &vnic_dev_attr_group);
--	vnic_cleanup_stats_files(vnic);
--	device_unregister(&vnic->dev_info.dev);
--	wait_for_completion(&vnic->dev_info.released);
-+ 	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);
-+  	wait_for_completion(&vnic->class_dev_info.released);
- 	free_netdev(vnic->netdevice);
- }
- 
-@@ -1092,6 +1092,7 @@ struct vnic *vnic_allocate(struct vnic_config *config)
- 	vnic->state = VNIC_UNINITIALIZED;
- 	vnic->config = config;
- 
-+
- 	netpath_init(&vnic->primary_path, vnic, 0);
- 	netpath_init(&vnic->secondary_path, vnic, 1);
- 
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
-@@ -36,7 +36,6 @@
- #include <linux/timex.h>
- #include <linux/netdevice.h>
- #include <linux/kthread.h>
--#include <linux/fs.h>
- 
- #include "vnic_config.h"
- #include "vnic_netpath.h"
-@@ -104,7 +103,7 @@ struct vnic {
- 	int				failed_over;
- 	int				mac_set;
- 	struct net_device		*netdevice;
--	struct dev_info			dev_info;
-+	struct class_dev_info		class_dev_info;
- 	struct dev_mc_list		*mc_list;
- 	int				mc_list_len;
- 	int				mc_count;
-@@ -130,7 +129,7 @@ struct vnic {
- 		cycles_t	carrier_off_time;
- 		u32		carrier_off_num;
- 	} statistics;
--	struct dev_info		stat_info;
-+	struct class_dev_info	stat_info;
- #endif	/* CONFIG_INFINIBAND_QLGC_VNIC_STATS */
- };
- 
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.c
-@@ -82,10 +82,10 @@ void netpath_free(struct netpath *netpath)
- 		return;
- 	viport_free(netpath->viport);
- 	netpath->viport = NULL;
--	sysfs_remove_group(&netpath->dev_info.dev.kobj,
-+	sysfs_remove_group(&netpath->class_dev_info.class_dev.kobj,
- 			   &vnic_path_attr_group);
--	device_unregister(&netpath->dev_info.dev);
--	wait_for_completion(&netpath->dev_info.released);
-+	class_device_unregister(&netpath->class_dev_info.class_dev);
-+	wait_for_completion(&netpath->class_dev_info.released);
- }
- 
- void netpath_init(struct netpath *netpath, struct vnic *vnic,
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_netpath.h
-@@ -57,7 +57,7 @@ struct netpath {
- 	u8 			delay_reconnect;
- 	struct timer_list	timer;
- 	enum netpath_ts		timer_state;
--	struct dev_info		dev_info;
-+	struct class_dev_info	class_dev_info;
- };
- 
- void netpath_init(struct netpath *netpath, struct vnic *vnic,
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.c
-@@ -43,22 +43,22 @@ cycles_t vnic_recv_ref;
-  *       RDMA times, IOs etc
-  *
-  */
--static ssize_t show_lifetime(struct device *dev,
--			     struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_lifetime(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 	cycles_t time = get_cycles() - vnic->statistics.start_time;
- 
- 	return sprintf(buf, "%llu\n", (unsigned long long)time);
- }
- 
--static DEVICE_ATTR(lifetime, S_IRUGO, show_lifetime, NULL);
-+static CLASS_DEVICE_ATTR(lifetime, S_IRUGO, show_lifetime, NULL);
- 
--static ssize_t show_conntime(struct device *dev,
--			     struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_conntime(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	if (vnic->statistics.conn_time)
-@@ -67,12 +67,12 @@ static ssize_t show_conntime(struct device *dev,
- 	return 0;
- }
- 
--static DEVICE_ATTR(connection_time, S_IRUGO, show_conntime, NULL);
-+static CLASS_DEVICE_ATTR(connection_time, S_IRUGO, show_conntime, NULL);
- 
--static ssize_t show_disconnects(struct device *dev,
--				struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_disconnects(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 	u32 num;
- 
-@@ -84,13 +84,13 @@ static ssize_t show_disconnects(struct device *dev,
- 	return sprintf(buf, "%d\n", num);
- }
- 
--static DEVICE_ATTR(disconnects, S_IRUGO, show_disconnects, NULL);
-+static CLASS_DEVICE_ATTR(disconnects, S_IRUGO, show_disconnects, NULL);
- 
--static ssize_t show_total_disconn_time(struct device *dev,
--				       struct device_attribute *dev_attr,
-+static ssize_t show_total_disconn_time(struct class_device *class_dev,
- 				       char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 	cycles_t time;
- 
-@@ -103,12 +103,14 @@ static ssize_t show_total_disconn_time(struct device *dev,
- 	return sprintf(buf, "%llu\n", (unsigned long long)time);
- }
- 
--static DEVICE_ATTR(total_disconn_time, S_IRUGO, show_total_disconn_time, NULL);
-+static CLASS_DEVICE_ATTR(total_disconn_time, S_IRUGO,
-+			 show_total_disconn_time, NULL);
- 
--static ssize_t show_carrier_losses(struct device *dev,
--				   struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_carrier_losses(struct class_device *class_dev,
-+				   char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 	u32 num;
- 
-@@ -120,13 +122,14 @@ static ssize_t show_carrier_losses(struct device *dev,
- 	return sprintf(buf, "%d\n", num);
- }
- 
--static DEVICE_ATTR(carrier_losses, S_IRUGO, show_carrier_losses, NULL);
-+static CLASS_DEVICE_ATTR(carrier_losses, S_IRUGO,
-+			 show_carrier_losses, NULL);
- 
--static ssize_t show_total_carr_loss_time(struct device *dev,
--					 struct device_attribute *dev_attr,
-+static ssize_t show_total_carr_loss_time(struct class_device *class_dev,
- 					 char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 	cycles_t time;
- 
-@@ -139,93 +142,94 @@ static ssize_t show_total_carr_loss_time(struct device *dev,
- 	return sprintf(buf, "%llu\n", (unsigned long long)time);
- }
- 
--static DEVICE_ATTR(total_carrier_loss_time, S_IRUGO,
-+static CLASS_DEVICE_ATTR(total_carrier_loss_time, S_IRUGO,
- 			 show_total_carr_loss_time, NULL);
- 
--static ssize_t show_total_recv_time(struct device *dev,
--				    struct device_attribute *dev_attr,
-+static ssize_t show_total_recv_time(struct class_device *class_dev,
- 				    char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	return sprintf(buf, "%llu\n",
- 		       (unsigned long long)vnic->statistics.recv_time);
- }
- 
--static DEVICE_ATTR(total_recv_time, S_IRUGO, show_total_recv_time, NULL);
-+static CLASS_DEVICE_ATTR(total_recv_time, S_IRUGO,
-+			 show_total_recv_time, NULL);
- 
--static ssize_t show_recvs(struct device *dev,
--			  struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_recvs(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	return sprintf(buf, "%d\n", vnic->statistics.recv_num);
- }
- 
--static DEVICE_ATTR(recvs, S_IRUGO, show_recvs, NULL);
-+static CLASS_DEVICE_ATTR(recvs, S_IRUGO, show_recvs, NULL);
- 
--static ssize_t show_multicast_recvs(struct device *dev,
--				    struct device_attribute *dev_attr,
--				    char *buf)
-+static ssize_t show_multicast_recvs(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	return sprintf(buf, "%d\n", vnic->statistics.multicast_recv_num);
- }
- 
--static DEVICE_ATTR(multicast_recvs, S_IRUGO, show_multicast_recvs, NULL);
-+static CLASS_DEVICE_ATTR(multicast_recvs, S_IRUGO, show_multicast_recvs, NULL);
- 
--static ssize_t show_total_xmit_time(struct device *dev,
--				    struct device_attribute *dev_attr,
-+static ssize_t show_total_xmit_time(struct class_device *class_dev,
- 				    char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	return sprintf(buf, "%llu\n",
- 		       (unsigned long long)vnic->statistics.xmit_time);
- }
- 
--static DEVICE_ATTR(total_xmit_time, S_IRUGO, show_total_xmit_time, NULL);
-+static CLASS_DEVICE_ATTR(total_xmit_time, S_IRUGO,
-+			 show_total_xmit_time, NULL);
- 
--static ssize_t show_xmits(struct device *dev,
--			  struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_xmits(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	return sprintf(buf, "%d\n", vnic->statistics.xmit_num);
- }
- 
--static DEVICE_ATTR(xmits, S_IRUGO, show_xmits, NULL);
-+static CLASS_DEVICE_ATTR(xmits, S_IRUGO, show_xmits, NULL);
- 
--static ssize_t show_failed_xmits(struct device *dev,
--				 struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_failed_xmits(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic *vnic = container_of(info, struct vnic, stat_info);
- 
- 	return sprintf(buf, "%d\n", vnic->statistics.xmit_fail);
- }
- 
--static DEVICE_ATTR(failed_xmits, S_IRUGO, show_failed_xmits, NULL);
-+static CLASS_DEVICE_ATTR(failed_xmits, S_IRUGO, show_failed_xmits, NULL);
- 
- static struct attribute *vnic_stats_attrs[] = {
--	&dev_attr_lifetime.attr,
--	&dev_attr_xmits.attr,
--	&dev_attr_total_xmit_time.attr,
--	&dev_attr_failed_xmits.attr,
--	&dev_attr_recvs.attr,
--	&dev_attr_multicast_recvs.attr,
--	&dev_attr_total_recv_time.attr,
--	&dev_attr_connection_time.attr,
--	&dev_attr_disconnects.attr,
--	&dev_attr_total_disconn_time.attr,
--	&dev_attr_carrier_losses.attr,
--	&dev_attr_total_carrier_loss_time.attr,
-+	&class_device_attr_lifetime.attr,
-+	&class_device_attr_xmits.attr,
-+	&class_device_attr_total_xmit_time.attr,
-+	&class_device_attr_failed_xmits.attr,
-+	&class_device_attr_recvs.attr,
-+	&class_device_attr_multicast_recvs.attr,
-+	&class_device_attr_total_recv_time.attr,
-+	&class_device_attr_connection_time.attr,
-+	&class_device_attr_disconnects.attr,
-+	&class_device_attr_total_disconn_time.attr,
-+	&class_device_attr_carrier_losses.attr,
-+	&class_device_attr_total_carrier_loss_time.attr,
- 	NULL
- };
- 
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_stats.h
-@@ -35,7 +35,6 @@
- 
- #include "vnic_main.h"
- #include "vnic_ib.h"
--#include "vnic_sys.h"
- 
- #ifdef CONFIG_INFINIBAND_QLGC_VNIC_STATS
- 
-@@ -113,25 +112,24 @@ static inline void vnic_carrier_loss_stats(struct vnic *vnic)
- static inline int vnic_setup_stats_files(struct vnic *vnic)
- {
- 	init_completion(&vnic->stat_info.released);
--	vnic->stat_info.dev.class = NULL;
--	vnic->stat_info.dev.parent = &vnic->dev_info.dev;
--	vnic->stat_info.dev.release = vnic_release_dev;
--	snprintf(vnic->stat_info.dev.bus_id, BUS_ID_SIZE,
-+	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 (device_register(&vnic->stat_info.dev)) {
-+	if (class_device_register(&vnic->stat_info.class_dev)) {
- 		SYS_ERROR("create_vnic: error in registering"
- 			  " stat class dev\n");
- 		goto stats_out;
- 	}
- 
--	if (sysfs_create_group(&vnic->stat_info.dev.kobj,
-+	if (sysfs_create_group(&vnic->stat_info.class_dev.kobj,
- 			       &vnic_stats_attr_group))
- 		goto err_stats_file;
- 
- 	return 0;
- err_stats_file:
--	device_unregister(&vnic->stat_info.dev);
-+	class_device_unregister(&vnic->stat_info.class_dev);
- 	wait_for_completion(&vnic->stat_info.released);
- stats_out:
- 	return -1;
-@@ -139,9 +137,9 @@ stats_out:
- 
- static inline void vnic_cleanup_stats_files(struct vnic *vnic)
- {
--	sysfs_remove_group(&vnic->dev_info.dev.kobj,
-+	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
- 			   &vnic_stats_attr_group);
--	device_unregister(&vnic->stat_info.dev);
-+	class_device_unregister(&vnic->stat_info.class_dev);
- 	wait_for_completion(&vnic->stat_info.released);
- }
- 
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.c
-@@ -77,21 +77,20 @@ static match_table_t vnic_opt_tokens = {
- 	{VNIC_OPT_ERR, NULL}
- };
- 
--void vnic_release_dev(struct device *dev)
-+static void vnic_release_class_dev(struct class_device *class_dev)
- {
--	struct dev_info *dev_info =
--	    container_of(dev, struct dev_info, dev);
--
--	complete(&dev_info->released);
-+	struct class_dev_info *cdev_info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
- 
-+	complete(&cdev_info->released);
- }
- 
- struct class vnic_class = {
- 	.name = "infiniband_qlgc_vnic",
--	.dev_release = vnic_release_dev
-+	.release = vnic_release_class_dev
- };
- 
--struct dev_info interface_dev;
-+struct class_dev_info interface_cdev;
- 
- static int vnic_parse_options(const char *buf, struct path_param *param)
- {
-@@ -285,11 +284,11 @@ out:
- 
- }
- 
--static ssize_t show_vnic_state(struct device *dev,
--			       struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_vnic_state(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
--	struct vnic *vnic = container_of(info, struct vnic, dev_info);
-+	struct class_dev_info *info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
-+	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
- 	switch (vnic->state) {
- 	case VNIC_UNINITIALIZED:
- 		return sprintf(buf, "VNIC_UNINITIALIZED\n");
-@@ -301,13 +300,13 @@ static ssize_t show_vnic_state(struct device *dev,
- 
- }
- 
--static DEVICE_ATTR(vnic_state, S_IRUGO, show_vnic_state, NULL);
-+static CLASS_DEVICE_ATTR(vnic_state, S_IRUGO, show_vnic_state, NULL);
- 
--static ssize_t show_rx_csum(struct device *dev,
--			    struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_rx_csum(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
--	struct vnic *vnic = container_of(info, struct vnic, dev_info);
-+	struct class_dev_info *info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
-+	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
- 
- 	if (vnic->config->use_rx_csum)
- 		return sprintf(buf, "true\n");
-@@ -315,13 +314,13 @@ static ssize_t show_rx_csum(struct device *dev,
- 		return sprintf(buf, "false\n");
- }
- 
--static DEVICE_ATTR(rx_csum, S_IRUGO, show_rx_csum, NULL);
-+static CLASS_DEVICE_ATTR(rx_csum, S_IRUGO, show_rx_csum, NULL);
- 
--static ssize_t show_tx_csum(struct device *dev,
--			    struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_tx_csum(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
--	struct vnic *vnic = container_of(info, struct vnic, dev_info);
-+	struct class_dev_info *info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
-+	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
- 
- 	if (vnic->config->use_tx_csum)
- 		return sprintf(buf, "true\n");
-@@ -329,13 +328,13 @@ static ssize_t show_tx_csum(struct device *dev,
- 		return sprintf(buf, "false\n");
- }
- 
--static DEVICE_ATTR(tx_csum, S_IRUGO, show_tx_csum, NULL);
-+static CLASS_DEVICE_ATTR(tx_csum, S_IRUGO, show_tx_csum, NULL);
- 
--static ssize_t show_current_path(struct device *dev,
--				 struct device_attribute *dev_attr, char *buf)
--{
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
--	struct vnic *vnic = container_of(info, struct vnic, dev_info);
-+static ssize_t show_current_path(struct class_device *class_dev, char *buf)
-+ {
-+ 	struct class_dev_info *info =
-+ 	    container_of(class_dev, struct class_dev_info, class_dev);
-+ 	struct vnic *vnic = container_of(info, struct vnic, class_dev_info);
- 	unsigned long flags;
- 	size_t length;
- 
-@@ -350,13 +349,13 @@ static ssize_t show_current_path(struct device *dev,
- 	return length;
- }
- 
--static DEVICE_ATTR(current_path, S_IRUGO, show_current_path, NULL);
-+static CLASS_DEVICE_ATTR(current_path, S_IRUGO, show_current_path, NULL);
- 
- static struct attribute *vnic_dev_attrs[] = {
--	&dev_attr_vnic_state.attr,
--	&dev_attr_rx_csum.attr,
--	&dev_attr_tx_csum.attr,
--	&dev_attr_current_path.attr,
-+	&class_device_attr_vnic_state.attr,
-+	&class_device_attr_rx_csum.attr,
-+	&class_device_attr_tx_csum.attr,
-+	&class_device_attr_current_path.attr,
- 	NULL
- };
- 
-@@ -513,21 +512,20 @@ static struct vnic *create_vnic(struct path_param *param)
- 		goto free_vnic_config;
- 	}
- 
--	init_completion(&vnic->dev_info.released);
-+	init_completion(&vnic->class_dev_info.released);
- 
--	vnic->dev_info.dev.class = NULL;
--	vnic->dev_info.dev.parent = &interface_dev.dev;
--	vnic->dev_info.dev.release = vnic_release_dev;
--	snprintf(vnic->dev_info.dev.bus_id, BUS_ID_SIZE,
-+	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 (device_register(&vnic->dev_info.dev)) {
-+	if (class_device_register(&vnic->class_dev_info.class_dev)) {
- 		SYS_ERROR("create_vnic: error in registering"
- 			  " vnic class dev\n");
- 		goto free_vnic;
- 	}
- 
--	if (sysfs_create_group(&vnic->dev_info.dev.kobj,
-+	if (sysfs_create_group(&vnic->class_dev_info.class_dev.kobj,
- 			       &vnic_dev_attr_group)) {
- 		SYS_ERROR("create_vnic: error in creating"
- 			  "vnic attr group\n");
-@@ -540,11 +538,11 @@ static struct vnic *create_vnic(struct path_param *param)
- 
- 	return vnic;
- err_stats:
--	sysfs_remove_group(&vnic->dev_info.dev.kobj,
-+	sysfs_remove_group(&vnic->class_dev_info.class_dev.kobj,
- 			   &vnic_dev_attr_group);
- err_attr:
--	device_unregister(&vnic->dev_info.dev);
--	wait_for_completion(&vnic->dev_info.released);
-+	class_device_unregister(&vnic->class_dev_info.class_dev);
-+	wait_for_completion(&vnic->class_dev_info.released);
- free_vnic:
- 	list_del(&vnic->list_ptrs);
- 	kfree(vnic);
-@@ -553,9 +551,8 @@ free_vnic_config:
- 	return NULL;
- }
- 
--static ssize_t vnic_sysfs_force_failover(struct device *dev,
--					struct device_attribute *dev_attr, const char *buf,
--					size_t count)
-+static ssize_t vnic_sysfs_force_failover(struct class_device *class_dev,
-+				  const char *buf, size_t count)
- {
- 	struct vnic *vnic;
- 	struct list_head *ptr;
-@@ -579,11 +576,10 @@ static ssize_t vnic_sysfs_force_failover(struct device *dev,
- 	return ret;
- }
- 
--DEVICE_ATTR(force_failover, S_IWUSR, NULL, vnic_sysfs_force_failover);
-+CLASS_DEVICE_ATTR(force_failover, S_IWUSR, NULL, vnic_sysfs_force_failover);
- 
--static ssize_t vnic_sysfs_unfailover(struct device *dev,
--					struct device_attribute *dev_attr, const char *buf,
--					size_t count)
-+static ssize_t vnic_sysfs_unfailover(struct class_device *class_dev,
-+			      const char *buf, size_t count)
- {
- 	struct vnic *vnic;
- 	struct list_head *ptr;
-@@ -607,9 +603,9 @@ static ssize_t vnic_sysfs_unfailover(struct device *dev,
- 	return ret;
- }
- 
--DEVICE_ATTR(unfailover, S_IWUSR, NULL, vnic_sysfs_unfailover);
-+CLASS_DEVICE_ATTR(unfailover, S_IWUSR, NULL, vnic_sysfs_unfailover);
- 
--static ssize_t vnic_delete(struct device *dev, struct device_attribute *dev_attr,
-+static ssize_t vnic_delete(struct class_device *class_dev,
- 			   const char *buf, size_t count)
- {
- 	struct vnic *vnic;
-@@ -634,13 +630,14 @@ static ssize_t vnic_delete(struct device *dev, struct device_attribute *dev_attr
- 	return ret;
- }
- 
--DEVICE_ATTR(delete_vnic, S_IWUSR, NULL, vnic_delete);
-+CLASS_DEVICE_ATTR(delete_vnic, S_IWUSR, NULL, vnic_delete);
- 
--static ssize_t show_viport_state(struct device *dev,
--				 struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_viport_state(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct class_dev_info *info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
-+	struct netpath *path =
-+	    container_of(info, struct netpath, class_dev_info);
- 	switch (path->viport->state) {
- 	case VIPORT_DISCONNECTED:
- 		return sprintf(buf, "VIPORT_DISCONNECTED\n");
-@@ -652,13 +649,14 @@ static ssize_t show_viport_state(struct device *dev,
- 
- }
- 
--static DEVICE_ATTR(viport_state, S_IRUGO, show_viport_state, NULL);
-+static CLASS_DEVICE_ATTR(viport_state, S_IRUGO, show_viport_state, NULL);
- 
--static ssize_t show_link_state(struct device *dev,
--			       struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_link_state(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct class_dev_info *info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
-+	struct netpath *path =
-+	    container_of(info, struct netpath, class_dev_info);
- 
- 	switch (path->viport->link_state) {
- 	case LINK_UNINITIALIZED:
-@@ -739,14 +737,15 @@ static ssize_t show_link_state(struct device *dev,
- 	}
- 
- }
--static DEVICE_ATTR(link_state, S_IRUGO, show_link_state, NULL);
-+static CLASS_DEVICE_ATTR(link_state, S_IRUGO, show_link_state, NULL);
- 
--static ssize_t show_heartbeat(struct device *dev,
--			      struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_heartbeat(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+	    container_of(info, struct netpath, class_dev_info);
- 
- 	/* hb_inteval is in jiffies, convert it back to
- 	 * 1/100ths of a second
-@@ -755,20 +754,21 @@ static ssize_t show_heartbeat(struct device *dev,
- 		(jiffies_to_msecs(path->viport->config->hb_interval)/10));
- }
- 
--static DEVICE_ATTR(heartbeat, S_IRUGO, show_heartbeat, NULL);
-+static CLASS_DEVICE_ATTR(heartbeat, S_IRUGO, show_heartbeat, NULL);
- 
--static ssize_t show_ioc_guid(struct device *dev,
--			     struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_ioc_guid(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+		container_of(info, struct netpath, class_dev_info);
- 
- 	return sprintf(buf, "%llx\n",
- 				__be64_to_cpu(path->viport->config->ioc_guid));
- }
- 
--static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
-+static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
- 
- static inline void get_dgid_string(u8 *dgid, char *buf)
- {
-@@ -783,64 +783,68 @@ static inline void get_dgid_string(u8 *dgid, char *buf)
- 	strcat(buf, "\n");
- }
- 
--static ssize_t show_dgid(struct device *dev,
--			 struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_dgid(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+		container_of(info, struct netpath, class_dev_info);
- 
- 	get_dgid_string(path->viport->config->path_info.path.dgid.raw, buf);
- 
- 	return strlen(buf);
- }
- 
--static DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL);
-+static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL);
- 
--static ssize_t show_pkey(struct device *dev,
--			 struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_pkey(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+		container_of(info, struct netpath, class_dev_info);
- 
- 	return sprintf(buf, "%x\n", path->viport->config->path_info.path.pkey);
- }
- 
--static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
-+static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
- 
--static ssize_t show_hca_info(struct device *dev,
--			     struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_hca_info(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+		container_of(info, struct netpath, class_dev_info);
- 
- 	return sprintf(buf, "vnic-%s-%d\n", path->viport->config->ibdev->name,
- 						path->viport->config->port);
- }
- 
--static DEVICE_ATTR(hca_info, S_IRUGO, show_hca_info, NULL);
-+static CLASS_DEVICE_ATTR(hca_info, S_IRUGO, show_hca_info, NULL);
- 
--static ssize_t show_ioc_string(struct device *dev,
--			       struct device_attribute *dev_attr, char *buf)
-+static ssize_t show_ioc_string(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+		container_of(info, struct netpath, class_dev_info);
- 
- 	return sprintf(buf, "%s\n", path->viport->config->ioc_string);
- }
- 
--static  DEVICE_ATTR(ioc_string, S_IRUGO, show_ioc_string, NULL);
-+static  CLASS_DEVICE_ATTR(ioc_string, S_IRUGO, show_ioc_string, NULL);
- 
--static ssize_t show_multicast_state(struct device *dev,
--				    struct device_attribute *dev_attr,
--				    char *buf)
-+static ssize_t show_multicast_state(struct class_device *class_dev, char *buf)
- {
--	struct dev_info *info =	container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *info =
-+		container_of(class_dev, struct class_dev_info, class_dev);
- 
--	struct netpath *path = container_of(info, struct netpath, dev_info);
-+	struct netpath *path =
-+		container_of(info, struct netpath, class_dev_info);
- 
- 	if (!(path->viport->features_supported & VNIC_FEAT_INBOUND_IB_MC))
- 		return sprintf(buf, "feature not enabled\n");
-@@ -871,18 +875,18 @@ static ssize_t show_multicast_state(struct device *dev,
- 	return sprintf(buf, "invalid state\n");
- }
- 
--static  DEVICE_ATTR(multicast_state, S_IRUGO, show_multicast_state, NULL);
-+static  CLASS_DEVICE_ATTR(multicast_state, S_IRUGO, show_multicast_state, NULL);
- 
- static struct attribute *vnic_path_attrs[] = {
--	&dev_attr_viport_state.attr,
--	&dev_attr_link_state.attr,
--	&dev_attr_heartbeat.attr,
--	&dev_attr_ioc_guid.attr,
--	&dev_attr_dgid.attr,
--	&dev_attr_pkey.attr,
--	&dev_attr_hca_info.attr,
--	&dev_attr_ioc_string.attr,
--	&dev_attr_multicast_state.attr,
-+	&class_device_attr_viport_state.attr,
-+	&class_device_attr_link_state.attr,
-+	&class_device_attr_heartbeat.attr,
-+	&class_device_attr_ioc_guid.attr,
-+	&class_device_attr_dgid.attr,
-+	&class_device_attr_pkey.attr,
-+	&class_device_attr_hca_info.attr,
-+	&class_device_attr_ioc_string.attr,
-+	&class_device_attr_multicast_state.attr,
- 	NULL
- };
- 
-@@ -893,19 +897,20 @@ struct attribute_group vnic_path_attr_group = {
- 
- static int setup_path_class_files(struct netpath *path, char *name)
- {
--	init_completion(&path->dev_info.released);
-+	init_completion(&path->class_dev_info.released);
- 
--	path->dev_info.dev.class = NULL;
--	path->dev_info.dev.parent = &path->parent->dev_info.dev;
--	path->dev_info.dev.release = vnic_release_dev;
--	snprintf(path->dev_info.dev.bus_id, BUS_ID_SIZE, name);
-+	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 (device_register(&path->dev_info.dev)) {
-+	if (class_device_register(&path->class_dev_info.class_dev)) {
- 		SYS_ERROR("error in registering path class dev\n");
- 		goto out;
- 	}
- 
--	if (sysfs_create_group(&path->dev_info.dev.kobj,
-+	if (sysfs_create_group(&path->class_dev_info.class_dev.kobj,
- 			       &vnic_path_attr_group)) {
- 		SYS_ERROR("error in creating vnic path group attrs");
- 		goto err_path;
-@@ -914,8 +919,8 @@ static int setup_path_class_files(struct netpath *path, char *name)
- 	return 0;
- 
- err_path:
--	device_unregister(&path->dev_info.dev);
--	wait_for_completion(&path->dev_info.released);
-+	class_device_unregister(&path->class_dev_info.class_dev);
-+	wait_for_completion(&path->class_dev_info.released);
- out:
- 	return -1;
- 
-@@ -1046,13 +1051,13 @@ static ssize_t update_params_and_connect(struct path_param *params,
- 	}
- }
- 
--static ssize_t vnic_create_primary(struct device *dev,
--				   struct device_attribute *dev_attr,
-+static ssize_t vnic_create_primary(struct class_device *class_dev,
- 				   const char *buf, size_t count)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *cdev =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic_ib_port *target =
--	    container_of(info, struct vnic_ib_port, pdev_info);
-+	    container_of(cdev, struct vnic_ib_port, cdev_info);
- 
- 	struct path_param param;
- 	int ret = -EINVAL;
-@@ -1114,15 +1119,15 @@ out:
- 	return ret;
- }
- 
--DEVICE_ATTR(create_primary, S_IWUSR, NULL, vnic_create_primary);
-+CLASS_DEVICE_ATTR(create_primary, S_IWUSR, NULL, vnic_create_primary);
- 
--static ssize_t vnic_create_secondary(struct device *dev,
--				     struct device_attribute *dev_attr,
-+static ssize_t vnic_create_secondary(struct class_device *class_dev,
- 				     const char *buf, size_t count)
- {
--	struct dev_info *info = container_of(dev, struct dev_info, dev);
-+	struct class_dev_info *cdev =
-+	    container_of(class_dev, struct class_dev_info, class_dev);
- 	struct vnic_ib_port *target =
--	    container_of(info, struct vnic_ib_port, pdev_info);
-+	    container_of(cdev, struct vnic_ib_port, cdev_info);
- 
- 	struct path_param param;
- 	struct vnic *vnic = NULL;
-@@ -1186,4 +1191,4 @@ out:
- 	return ret;
- }
- 
--DEVICE_ATTR(create_secondary, S_IWUSR, NULL, vnic_create_secondary);
-+CLASS_DEVICE_ATTR(create_secondary, S_IWUSR, NULL, vnic_create_secondary);
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_sys.h
-@@ -33,21 +33,19 @@
- #ifndef VNIC_SYS_H_INCLUDED
- #define VNIC_SYS_H_INCLUDED
- 
--struct dev_info {
--	struct device		dev;
-+struct class_dev_info {
-+	struct class_device	class_dev;
- 	struct completion	released;
- };
- 
- extern struct class vnic_class;
--extern struct dev_info interface_dev;
-+extern struct class_dev_info interface_cdev;
- extern struct attribute_group vnic_dev_attr_group;
- extern struct attribute_group vnic_path_attr_group;
--extern struct device_attribute dev_attr_create_primary;
--extern struct device_attribute dev_attr_create_secondary;
--extern struct device_attribute dev_attr_delete_vnic;
--extern struct device_attribute dev_attr_force_failover;
--extern struct device_attribute dev_attr_unfailover;
--
--extern void vnic_release_dev(struct device *dev);
-+extern struct class_device_attribute class_device_attr_create_primary;
-+extern struct class_device_attribute class_device_attr_create_secondary;
-+extern struct class_device_attribute class_device_attr_delete_vnic;
-+extern struct class_device_attribute class_device_attr_force_failover;
-+extern struct class_device_attribute class_device_attr_unfailover;
- 
- #endif	/*VNIC_SYS_H_INCLUDED*/
diff --git a/kernel_patches/backport/2.6.18-EL5.1/qlgc_vnic_02_dev_stats.patch b/kernel_patches/backport/2.6.18-EL5.1/qlgc_vnic_02_dev_stats.patch
deleted file mode 100644
index 0c86da1..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/qlgc_vnic_02_dev_stats.patch
+++ /dev/null
@@ -1,46 +0,0 @@
----
- drivers/infiniband/ulp/qlgc_vnic/vnic_main.c |    6 +++---
- drivers/infiniband/ulp/qlgc_vnic/vnic_main.h |    1 +
- 2 files changed, 4 insertions(+), 3 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.c
-@@ -204,13 +204,13 @@ static struct net_device_stats *vnic_get
- 	if (np && np->viport) {
- 		atomic_inc(&np->viport->reference_count);
- 		spin_unlock_irqrestore(&vnic->current_path_lock, flags);
--		viport_get_stats(np->viport, &vnic->netdevice->stats);
-+		viport_get_stats(np->viport, &vnic->stats);
- 		atomic_dec(&np->viport->reference_count);
- 		wake_up(&np->viport->reference_queue);
- 	} else
- 		spin_unlock_irqrestore(&vnic->current_path_lock, flags);
- 
--	return &vnic->netdevice->stats;
-+	return &vnic->stats;
- }
- 
- static int vnic_open(struct net_device *device)
-@@ -259,7 +259,7 @@ static int vnic_hard_start_xmit(struct s
- 	if (ret) {
- 		vnic_xmit_fail_stats(vnic);
- 		dev_kfree_skb_any(skb);
--		vnic->netdevice->stats.tx_dropped++;
-+		vnic->stats.tx_dropped++;
- 		goto out;
- 	}
- 
-Index: ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
-+++ ofed_kernel/drivers/infiniband/ulp/qlgc_vnic/vnic_main.h
-@@ -102,6 +102,7 @@ struct vnic {
- 	int				forced_failover;
- 	int				failed_over;
- 	int				mac_set;
-+	struct net_device_stats 	stats;
- 	struct net_device		*netdevice;
- 	struct class_dev_info		class_dev_info;
- 	struct dev_mc_list		*mc_list;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/rds_to_2_6_26.patch b/kernel_patches/backport/2.6.18-EL5.1/rds_to_2_6_26.patch
deleted file mode 100644
index c4503f3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/rds_to_2_6_26.patch
+++ /dev/null
@@ -1,18 +0,0 @@
----
- net/rds/connection.c |    3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-Index: ofed_kernel/net/rds/connection.c
-===================================================================
---- ofed_kernel.orig/net/rds/connection.c
-+++ ofed_kernel/net/rds/connection.c
-@@ -51,8 +51,7 @@ static struct kmem_cache *rds_conn_slab;
- static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
- {
- 	/* Pass NULL, don't need struct net for hash */
--	unsigned long hash = inet_ehashfn(NULL,
--					  be32_to_cpu(laddr), 0, 
-+	unsigned long hash = inet_ehashfn(be32_to_cpu(laddr), 0,
- 					  be32_to_cpu(faddr), 0);
- 	return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
- }
diff --git a/kernel_patches/backport/2.6.18-EL5.1/rnfs_fs.patch b/kernel_patches/backport/2.6.18-EL5.1/rnfs_fs.patch
deleted file mode 100644
index a7687ad..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/rnfs_fs.patch
+++ /dev/null
@@ -1,2841 +0,0 @@
-diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
-index 03acfd6..992e4aa 100644
---- a/drivers/infiniband/core/Makefile
-+++ b/drivers/infiniband/core/Makefile
-@@ -31,4 +31,4 @@ ib_ucm-y :=			ucm.o
- 
- ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_marshall.o
- 
--ib_core-y +=			genalloc.o
-+ib_core-y +=			genalloc.o namespace.o writeback.o
-diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
-index 8ea4d01..5d49041 100644
---- a/drivers/infiniband/core/device.c
-+++ b/drivers/infiniband/core/device.c
-@@ -39,7 +39,7 @@
- #include <linux/init.h>
- #include <linux/mutex.h>
- #include <linux/workqueue.h>
--
-+#include <linux/mount.h>
- #include "core_priv.h"
- 
- MODULE_AUTHOR("Roland Dreier");
-@@ -735,6 +735,10 @@ static int __init ib_core_init(void)
- 		dma_map_sg_hp_wa = 1;
- #endif
- 
-+	ret = init_mnt_writers();
-+	if (ret)
-+		printk(KERN_WARNING "Couldn't init mnt_writers\n");
-+
- 	ret = ib_sysfs_setup();
- 	if (ret)
- 		printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
-diff --git a/drivers/infiniband/core/namespace.c b/drivers/infiniband/core/namespace.c
-new file mode 100644
-index 0000000..de57f8b
---- /dev/null
-+++ b/drivers/infiniband/core/namespace.c
-@@ -0,0 +1 @@
-+#include "src/namespace.c"
-diff --git a/drivers/infiniband/core/writeback.c b/drivers/infiniband/core/writeback.c
-new file mode 100644
-index 0000000..b838ead
---- /dev/null
-+++ b/drivers/infiniband/core/writeback.c
-@@ -0,0 +1 @@
-+#include "src/writeback.c"
-diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
-index cc91227..262397b 100644
---- a/fs/exportfs/expfs.c
-+++ b/fs/exportfs/expfs.c
-@@ -361,11 +361,14 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
- 	const struct export_operations *nop = mnt->mnt_sb->s_export_op;
- 	struct dentry *result, *alias;
- 	int err;
-+	__u32 objp[2];
- 
-+	objp[0] = fid->i32.ino;
-+	objp[1] = fid->i32.gen;
- 	/*
- 	 * Try to get any dentry for the given file handle from the filesystem.
- 	 */
--	result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
-+	result = nop->get_dentry(mnt->mnt_sb, &objp);
- 	if (!result)
- 		result = ERR_PTR(-ESTALE);
- 	if (IS_ERR(result))
-@@ -417,11 +420,10 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
- 		 * file handle.  If this fails we'll have to give up.
- 		 */
- 		err = -ESTALE;
--		if (!nop->fh_to_parent)
-+		if (!nop->get_parent)
- 			goto err_result;
- 
--		target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
--				fh_len, fileid_type);
-+		target_dir = nop->get_parent(result);
- 		if (!target_dir)
- 			goto err_result;
- 		err = PTR_ERR(target_dir);
-diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
-index 0b45fd3..2c45814 100644
---- a/fs/lockd/clntlock.c
-+++ b/fs/lockd/clntlock.c
-@@ -168,7 +168,7 @@ __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock
- 			continue;
- 		if (!nlm_cmp_addr(&block->b_host->h_addr, addr))
- 			continue;
--		if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0)
-+		if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_dentry->d_inode), fh) != 0)
- 			continue;
- 		/* Alright, we found a lock. Set the return status
- 		 * and wake up the caller
-diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
-index 31668b6..8c72d30 100644
---- a/fs/lockd/clntproc.c
-+++ b/fs/lockd/clntproc.c
-@@ -128,12 +128,12 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
- 
- 	nlmclnt_next_cookie(&argp->cookie);
- 	argp->state   = nsm_local_state;
--	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_path.dentry->d_inode), sizeof(struct nfs_fh));
--	lock->caller  = utsname()->nodename;
-+	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
-+	lock->caller  = system_utsname.nodename;
- 	lock->oh.data = req->a_owner;
- 	lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
- 				(unsigned int)fl->fl_u.nfs_fl.owner->pid,
--				utsname()->nodename);
-+				system_utsname.nodename);
- 	lock->svid = fl->fl_u.nfs_fl.owner->pid;
- 	lock->fl.fl_start = fl->fl_start;
- 	lock->fl.fl_end = fl->fl_end;
-diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
-index e4d5635..771edc1 100644
---- a/fs/lockd/mon.c
-+++ b/fs/lockd/mon.c
-@@ -194,7 +194,7 @@ static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
-  */
- static __be32 *xdr_encode_my_id(__be32 *p, struct nsm_args *argp)
- {
--	p = xdr_encode_nsm_string(p, utsname()->nodename);
-+	p = xdr_encode_nsm_string(p, system_utsname.nodename);
- 	if (!p)
- 		return ERR_PTR(-EIO);
- 
-diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
-index cf0d5c2..2e6ec1b 100644
---- a/fs/lockd/svclock.c
-+++ b/fs/lockd/svclock.c
-@@ -304,7 +304,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
- {
- 	locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
- 	memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
--	call->a_args.lock.caller = utsname()->nodename;
-+	call->a_args.lock.caller = system_utsname.nodename;
- 	call->a_args.lock.oh.len = lock->oh.len;
- 
- 	/* set default data area */
-@@ -367,8 +367,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
- 	__be32			ret;
- 
- 	dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
--				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
--				file->f_file->f_path.dentry->d_inode->i_ino,
-+				file->f_file->f_dentry->d_inode->i_sb->s_id,
-+				file->f_file->f_dentry->d_inode->i_ino,
- 				lock->fl.fl_type, lock->fl.fl_pid,
- 				(long long)lock->fl.fl_start,
- 				(long long)lock->fl.fl_end,
-@@ -417,11 +417,18 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
- 			ret = nlm_granted;
- 			goto out;
- 		case -EAGAIN:
--			ret = nlm_lck_denied;
--			goto out;
-+			if (wait) {
-+				ret = nlm_lck_blocked;
-+				break;
-+			} else {
-+				ret = nlm_lck_denied;
-+				goto out;
-+			}
- 		case FILE_LOCK_DEFERRED:
--			if (wait)
-+			if (wait) {
-+				ret = nlm_lck_blocked;
- 				break;
-+			}
- 			/* Filesystem lock operation is in progress
- 			   Add it to the queue waiting for callback */
- 			ret = nlmsvc_defer_lock_rqst(rqstp, block);
-@@ -434,8 +441,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
- 			goto out;
- 	}
- 
--	ret = nlm_lck_blocked;
--
- 	/* Append to list of blocked */
- 	nlmsvc_insert_block(block, NLM_NEVER);
- out:
-@@ -458,8 +463,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
- 	__be32			ret;
- 
- 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
--				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
--				file->f_file->f_path.dentry->d_inode->i_ino,
-+				file->f_file->f_dentry->d_inode->i_sb->s_id,
-+				file->f_file->f_dentry->d_inode->i_ino,
- 				lock->fl.fl_type,
- 				(long long)lock->fl.fl_start,
- 				(long long)lock->fl.fl_end);
-@@ -547,8 +552,8 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
- 	int	error;
- 
- 	dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
--				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
--				file->f_file->f_path.dentry->d_inode->i_ino,
-+				file->f_file->f_dentry->d_inode->i_sb->s_id,
-+				file->f_file->f_dentry->d_inode->i_ino,
- 				lock->fl.fl_pid,
- 				(long long)lock->fl.fl_start,
- 				(long long)lock->fl.fl_end);
-@@ -576,8 +581,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
- 	int status = 0;
- 
- 	dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
--				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
--				file->f_file->f_path.dentry->d_inode->i_ino,
-+				file->f_file->f_dentry->d_inode->i_sb->s_id,
-+				file->f_file->f_dentry->d_inode->i_ino,
- 				lock->fl.fl_pid,
- 				(long long)lock->fl.fl_start,
- 				(long long)lock->fl.fl_end);
-@@ -595,63 +600,6 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
- }
- 
- /*
-- * This is a callback from the filesystem for VFS file lock requests.
-- * It will be used if fl_grant is defined and the filesystem can not
-- * respond to the request immediately.
-- * For GETLK request it will copy the reply to the nlm_block.
-- * For SETLK or SETLKW request it will get the local posix lock.
-- * In all cases it will move the block to the head of nlm_blocked q where
-- * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
-- * deferred rpc for GETLK and SETLK.
-- */
--static void
--nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
--			     int result)
--{
--	block->b_flags |= B_GOT_CALLBACK;
--	if (result == 0)
--		block->b_granted = 1;
--	else
--		block->b_flags |= B_TIMED_OUT;
--	if (conf) {
--		if (block->b_fl)
--			__locks_copy_lock(block->b_fl, conf);
--	}
--}
--
--static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf,
--					int result)
--{
--	struct nlm_block *block;
--	int rc = -ENOENT;
--
--	lock_kernel();
--	list_for_each_entry(block, &nlm_blocked, b_list) {
--		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
--			dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
--							block, block->b_flags);
--			if (block->b_flags & B_QUEUED) {
--				if (block->b_flags & B_TIMED_OUT) {
--					rc = -ENOLCK;
--					break;
--				}
--				nlmsvc_update_deferred_block(block, conf, result);
--			} else if (result == 0)
--				block->b_granted = 1;
--
--			nlmsvc_insert_block(block, 0);
--			svc_wake_up(block->b_daemon);
--			rc = 0;
--			break;
--		}
--	}
--	unlock_kernel();
--	if (rc == -ENOENT)
--		printk(KERN_WARNING "lockd: grant for unknown block\n");
--	return rc;
--}
--
--/*
-  * Unblock a blocked lock request. This is a callback invoked from the
-  * VFS layer when a lock on which we blocked is removed.
-  *
-@@ -683,7 +631,6 @@ static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
- struct lock_manager_operations nlmsvc_lock_operations = {
- 	.fl_compare_owner = nlmsvc_same_owner,
- 	.fl_notify = nlmsvc_notify_blocked,
--	.fl_grant = nlmsvc_grant_deferred,
- };
- 
- /*
-diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
-index 198b4e5..2109091 100644
---- a/fs/lockd/svcsubs.c
-+++ b/fs/lockd/svcsubs.c
-@@ -45,7 +45,7 @@ static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
- 
- static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
- {
--	struct inode *inode = file->f_file->f_path.dentry->d_inode;
-+	struct inode *inode = file->f_file->f_dentry->d_inode;
- 
- 	dprintk("lockd: %s %s/%ld\n",
- 		msg, inode->i_sb->s_id, inode->i_ino);
-@@ -396,7 +396,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file)
- {
- 	struct super_block *sb = datap;
- 
--	return sb == file->f_file->f_path.mnt->mnt_sb;
-+	return sb == file->f_file->f_vfsmnt->mnt_sb;
- }
- 
- /**
-diff --git a/fs/nfs/client.c b/fs/nfs/client.c
-index 5ee23e7..afbb834 100644
---- a/fs/nfs/client.c
-+++ b/fs/nfs/client.c
-@@ -248,6 +248,7 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
- 				(const struct sockaddr_in6 *)sa2);
- 	}
- 	BUG();
-+	return -EINVAL;
- }
- 
- /*
-diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
-index 74f92b7..90d0a97 100644
---- a/fs/nfs/dir.c
-+++ b/fs/nfs/dir.c
-@@ -66,7 +66,7 @@ const struct file_operations nfs_dir_operations = {
- 	.fsync		= nfs_fsync_dir,
- };
- 
--const struct inode_operations nfs_dir_inode_operations = {
-+struct inode_operations nfs_dir_inode_operations = {
- 	.create		= nfs_create,
- 	.lookup		= nfs_lookup,
- 	.link		= nfs_link,
-@@ -82,7 +82,7 @@ const struct inode_operations nfs_dir_inode_operations = {
- };
- 
- #ifdef CONFIG_NFS_V3
--const struct inode_operations nfs3_dir_inode_operations = {
-+struct inode_operations nfs3_dir_inode_operations = {
- 	.create		= nfs_create,
- 	.lookup		= nfs_lookup,
- 	.link		= nfs_link,
-@@ -105,7 +105,7 @@ const struct inode_operations nfs3_dir_inode_operations = {
- #ifdef CONFIG_NFS_V4
- 
- static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
--const struct inode_operations nfs4_dir_inode_operations = {
-+struct inode_operations nfs4_dir_inode_operations = {
- 	.create		= nfs_create,
- 	.lookup		= nfs_atomic_lookup,
- 	.link		= nfs_link,
-@@ -134,8 +134,8 @@ nfs_opendir(struct inode *inode, struct file *filp)
- 	int res;
- 
- 	dfprintk(FILE, "NFS: open dir(%s/%s)\n",
--			filp->f_path.dentry->d_parent->d_name.name,
--			filp->f_path.dentry->d_name.name);
-+			filp->f_dentry->d_parent->d_name.name,
-+			filp->f_dentry->d_name.name);
- 
- 	nfs_inc_stats(inode, NFSIOS_VFSOPEN);
- 
-@@ -175,7 +175,7 @@ static
- int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
- {
- 	struct file	*file = desc->file;
--	struct inode	*inode = file->f_path.dentry->d_inode;
-+	struct inode	*inode = file->f_dentry->d_inode;
- 	struct rpc_cred	*cred = nfs_file_cred(file);
- 	unsigned long	timestamp;
- 	int		error;
-@@ -186,7 +186,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
- 
-  again:
- 	timestamp = jiffies;
--	error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page,
-+	error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page,
- 					  NFS_SERVER(inode)->dtsize, desc->plus);
- 	if (error < 0) {
- 		/* We requested READDIRPLUS, but the server doesn't grok it */
-@@ -311,7 +311,7 @@ int find_dirent_index(nfs_readdir_descriptor_t *desc)
- static inline
- int find_dirent_page(nfs_readdir_descriptor_t *desc)
- {
--	struct inode	*inode = desc->file->f_path.dentry->d_inode;
-+	struct inode	*inode = desc->file->f_dentry->d_inode;
- 	struct page	*page;
- 	int		status;
- 
-@@ -467,7 +467,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
- 		     filldir_t filldir)
- {
- 	struct file	*file = desc->file;
--	struct inode	*inode = file->f_path.dentry->d_inode;
-+	struct inode	*inode = file->f_dentry->d_inode;
- 	struct rpc_cred	*cred = nfs_file_cred(file);
- 	struct page	*page = NULL;
- 	int		status;
-@@ -482,7 +482,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
- 		goto out;
- 	}
- 	timestamp = jiffies;
--	status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred,
-+	status = NFS_PROTO(inode)->readdir(file->f_dentry, cred,
- 						*desc->dir_cookie, page,
- 						NFS_SERVER(inode)->dtsize,
- 						desc->plus);
-@@ -520,7 +520,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
-  */
- static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
- {
--	struct dentry	*dentry = filp->f_path.dentry;
-+	struct dentry	*dentry = filp->f_dentry;
- 	struct inode	*inode = dentry->d_inode;
- 	nfs_readdir_descriptor_t my_desc,
- 			*desc = &my_desc;
-@@ -601,7 +601,7 @@ out:
- 
- static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
- {
--	struct dentry *dentry = filp->f_path.dentry;
-+	struct dentry *dentry = filp->f_dentry;
- 	struct inode *inode = dentry->d_inode;
- 
- 	dfprintk(FILE, "NFS: llseek dir(%s/%s, %lld, %d)\n",
-@@ -973,7 +973,7 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd)
- 	if (nd->flags & LOOKUP_DIRECTORY)
- 		return 0;
- 	/* Are we trying to write to a read only partition? */
--	if (__mnt_is_readonly(nd->path.mnt) &&
-+	if (__mnt_is_readonly(nd->mnt) &&
- 	    (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
- 		return 0;
- 	return 1;
-@@ -1083,7 +1083,7 @@ no_open:
- 
- static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
- {
--	struct dentry *parent = desc->file->f_path.dentry;
-+	struct dentry *parent = desc->file->f_dentry;
- 	struct inode *dir = parent->d_inode;
- 	struct nfs_entry *entry = desc->entry;
- 	struct dentry *dentry, *alias;
-@@ -1907,7 +1907,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
- 	return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
- }
- 
--int nfs_permission(struct inode *inode, int mask)
-+int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
- {
- 	struct rpc_cred *cred;
- 	int res = 0;
-@@ -1917,7 +1917,7 @@ int nfs_permission(struct inode *inode, int mask)
- 	if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
- 		goto out;
- 	/* Is this sys_access() ? */
--	if (mask & MAY_ACCESS)
-+	if (nd != NULL && (nd->flags & LOOKUP_ACCESS))
- 		goto force_lookup;
- 
- 	switch (inode->i_mode & S_IFMT) {
-@@ -1926,7 +1926,8 @@ int nfs_permission(struct inode *inode, int mask)
- 		case S_IFREG:
- 			/* NFSv4 has atomic_open... */
- 			if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
--					&& (mask & MAY_OPEN))
-+					&& nd != NULL
-+					&& (nd->flags & LOOKUP_OPEN))
- 				goto out;
- 			break;
- 		case S_IFDIR:
-diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
-index 08f6b04..91f5069 100644
---- a/fs/nfs/direct.c
-+++ b/fs/nfs/direct.c
-@@ -116,7 +116,7 @@ static inline int put_dreq(struct nfs_direct_req *dreq)
- ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs)
- {
- 	dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n",
--			iocb->ki_filp->f_path.dentry->d_name.name,
-+			iocb->ki_filp->f_dentry->d_name.name,
- 			(long long) pos, nr_segs);
- 
- 	return -EINVAL;
-@@ -891,8 +891,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
- 	nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
- 
- 	dfprintk(FILE, "NFS: direct read(%s/%s, %zd@%Ld)\n",
--		file->f_path.dentry->d_parent->d_name.name,
--		file->f_path.dentry->d_name.name,
-+		file->f_dentry->d_parent->d_name.name,
-+		file->f_dentry->d_name.name,
- 		count, (long long) pos);
- 
- 	retval = 0;
-@@ -948,8 +948,8 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
- 	nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
- 
- 	dfprintk(FILE, "NFS: direct write(%s/%s, %zd@%Ld)\n",
--		file->f_path.dentry->d_parent->d_name.name,
--		file->f_path.dentry->d_name.name,
-+		file->f_dentry->d_parent->d_name.name,
-+		file->f_dentry->d_name.name,
- 		count, (long long) pos);
- 
- 	retval = generic_write_checks(file, &pos, &count, 0);
-diff --git a/fs/nfs/file.c b/fs/nfs/file.c
-index 7846065..7962293 100644
---- a/fs/nfs/file.c
-+++ b/fs/nfs/file.c
-@@ -45,16 +45,13 @@ static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
- static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
- 					struct pipe_inode_info *pipe,
- 					size_t count, unsigned int flags);
--static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
--				unsigned long nr_segs, loff_t pos);
--static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
--				unsigned long nr_segs, loff_t pos);
-+static ssize_t nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos);
-+static ssize_t nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos);
- static int  nfs_file_flush(struct file *, fl_owner_t id);
- static int  nfs_file_fsync(struct file *, struct dentry *dentry, int datasync);
- static int nfs_check_flags(int flags);
- static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
- static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
--static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
- 
- static struct vm_operations_struct nfs_file_vm_ops;
- 
-@@ -77,17 +74,16 @@ const struct file_operations nfs_file_operations = {
- 	.flock		= nfs_flock,
- 	.splice_read	= nfs_file_splice_read,
- 	.check_flags	= nfs_check_flags,
--	.setlease	= nfs_setlease,
- };
- 
--const struct inode_operations nfs_file_inode_operations = {
-+struct inode_operations nfs_file_inode_operations = {
- 	.permission	= nfs_permission,
- 	.getattr	= nfs_getattr,
- 	.setattr	= nfs_setattr,
- };
- 
- #ifdef CONFIG_NFS_V3
--const struct inode_operations nfs3_file_inode_operations = {
-+struct inode_operations nfs3_file_inode_operations = {
- 	.permission	= nfs_permission,
- 	.getattr	= nfs_getattr,
- 	.setattr	= nfs_setattr,
-@@ -120,8 +116,8 @@ nfs_file_open(struct inode *inode, struct file *filp)
- 	int res;
- 
- 	dprintk("NFS: open file(%s/%s)\n",
--			filp->f_path.dentry->d_parent->d_name.name,
--			filp->f_path.dentry->d_name.name);
-+			filp->f_dentry->d_parent->d_name.name,
-+			filp->f_dentry->d_name.name);
- 
- 	res = nfs_check_flags(filp->f_flags);
- 	if (res)
-@@ -135,7 +131,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
- static int
- nfs_file_release(struct inode *inode, struct file *filp)
- {
--	struct dentry *dentry = filp->f_path.dentry;
-+	struct dentry *dentry = filp->f_dentry;
- 
- 	dprintk("NFS: release(%s/%s)\n",
- 			dentry->d_parent->d_name.name,
-@@ -178,11 +174,9 @@ force_reval:
- 
- static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
- {
--	loff_t loff;
--
- 	dprintk("NFS: llseek file(%s/%s, %lld, %d)\n",
--			filp->f_path.dentry->d_parent->d_name.name,
--			filp->f_path.dentry->d_name.name,
-+			filp->f_dentry->d_parent->d_name.name,
-+			filp->f_dentry->d_name.name,
- 			offset, origin);
- 
- 	/* origin == SEEK_END => we must revalidate the cached file length */
-@@ -192,10 +186,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
- 		if (retval < 0)
- 			return (loff_t)retval;
- 	}
--	lock_kernel();	/* BKL needed? */
--	loff = generic_file_llseek_unlocked(filp, offset, origin);
--	unlock_kernel();
--	return loff;
-+	return remote_llseek(filp, offset, origin);
- }
- 
- /*
-@@ -230,7 +221,7 @@ static int
- nfs_file_flush(struct file *file, fl_owner_t id)
- {
- 	struct nfs_open_context *ctx = nfs_file_open_context(file);
--	struct dentry	*dentry = file->f_path.dentry;
-+	struct dentry	*dentry = file->f_dentry;
- 	struct inode	*inode = dentry->d_inode;
- 	int		status;
- 
-@@ -250,16 +241,15 @@ nfs_file_flush(struct file *file, fl_owner_t id)
- }
- 
- static ssize_t
--nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
--		unsigned long nr_segs, loff_t pos)
-+nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
- {
--	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
-+	struct dentry * dentry = iocb->ki_filp->f_dentry;
- 	struct inode * inode = dentry->d_inode;
- 	ssize_t result;
--	size_t count = iov_length(iov, nr_segs);
-+	struct iovec local_iov = { .iov_base = buf, .iov_len = count };
- 
- 	if (iocb->ki_filp->f_flags & O_DIRECT)
--		return nfs_file_direct_read(iocb, iov, nr_segs, pos);
-+		return nfs_file_direct_read(iocb, &local_iov, 1, pos);
- 
- 	dprintk("NFS: read(%s/%s, %lu@%lu)\n",
- 		dentry->d_parent->d_name.name, dentry->d_name.name,
-@@ -268,7 +258,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
- 	result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
- 	nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
- 	if (!result)
--		result = generic_file_aio_read(iocb, iov, nr_segs, pos);
-+		result = generic_file_aio_read(iocb, buf, count, pos);
- 	return result;
- }
- 
-@@ -277,7 +267,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
- 		     struct pipe_inode_info *pipe, size_t count,
- 		     unsigned int flags)
- {
--	struct dentry *dentry = filp->f_path.dentry;
-+	struct dentry *dentry = filp->f_dentry;
- 	struct inode *inode = dentry->d_inode;
- 	ssize_t res;
- 
-@@ -294,7 +284,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
- static int
- nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
- {
--	struct dentry *dentry = file->f_path.dentry;
-+	struct dentry *dentry = file->f_dentry;
- 	struct inode *inode = dentry->d_inode;
- 	int	status;
- 
-@@ -337,44 +327,15 @@ nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
-  * If the writer ends up delaying the write, the writer needs to
-  * increment the page use counts until he is done with the page.
-  */
--static int nfs_write_begin(struct file *file, struct address_space *mapping,
--			loff_t pos, unsigned len, unsigned flags,
--			struct page **pagep, void **fsdata)
-+static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
- {
--	int ret;
--	pgoff_t index;
--	struct page *page;
--	index = pos >> PAGE_CACHE_SHIFT;
--
--	dfprintk(PAGECACHE, "NFS: write_begin(%s/%s(%ld), %u@%lld)\n",
--		file->f_path.dentry->d_parent->d_name.name,
--		file->f_path.dentry->d_name.name,
--		mapping->host->i_ino, len, (long long) pos);
--
--	page = __grab_cache_page(mapping, index);
--	if (!page)
--		return -ENOMEM;
--	*pagep = page;
--
--	ret = nfs_flush_incompatible(file, page);
--	if (ret) {
--		unlock_page(page);
--		page_cache_release(page);
--	}
--	return ret;
-+	return nfs_flush_incompatible(file, page);
- }
- 
--static int nfs_write_end(struct file *file, struct address_space *mapping,
--			loff_t pos, unsigned len, unsigned copied,
--			struct page *page, void *fsdata)
-+static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
- {
--	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
- 	int status;
--
--	dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n",
--		file->f_path.dentry->d_parent->d_name.name,
--		file->f_path.dentry->d_name.name,
--		mapping->host->i_ino, len, (long long) pos);
-+	unsigned copied = to - offset;
- 
- 	/*
- 	 * Zero any uninitialised parts of the page, and then mark the page
-@@ -382,14 +343,13 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
- 	 */
- 	if (!PageUptodate(page)) {
- 		unsigned pglen = nfs_page_length(page);
--		unsigned end = offset + len;
- 
- 		if (pglen == 0) {
- 			zero_user_segments(page, 0, offset,
--					end, PAGE_CACHE_SIZE);
-+					to, PAGE_CACHE_SIZE);
- 			SetPageUptodate(page);
--		} else if (end >= pglen) {
--			zero_user_segment(page, end, PAGE_CACHE_SIZE);
-+		} else if (to >= pglen) {
-+			zero_user_segment(page, to, PAGE_CACHE_SIZE);
- 			if (offset == 0)
- 				SetPageUptodate(page);
- 		} else
-@@ -398,9 +358,6 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
- 
- 	status = nfs_updatepage(file, page, offset, copied);
- 
--	unlock_page(page);
--	page_cache_release(page);
--
- 	if (status < 0)
- 		return status;
- 	return copied;
-@@ -424,34 +381,23 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
- 	return 0;
- }
- 
--static int nfs_launder_page(struct page *page)
--{
--	struct inode *inode = page->mapping->host;
--
--	dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
--		inode->i_ino, (long long)page_offset(page));
--
--	return nfs_wb_page(inode, page);
--}
--
- const struct address_space_operations nfs_file_aops = {
- 	.readpage = nfs_readpage,
- 	.readpages = nfs_readpages,
- 	.set_page_dirty = __set_page_dirty_nobuffers,
- 	.writepage = nfs_writepage,
- 	.writepages = nfs_writepages,
--	.write_begin = nfs_write_begin,
--	.write_end = nfs_write_end,
-+	.prepare_write = nfs_prepare_write,
-+	.commit_write = nfs_commit_write,
- 	.invalidatepage = nfs_invalidate_page,
- 	.releasepage = nfs_release_page,
- 	.direct_IO = nfs_direct_IO,
--	.launder_page = nfs_launder_page,
- };
- 
- static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
- {
- 	struct file *filp = vma->vm_file;
--	struct dentry *dentry = filp->f_path.dentry;
-+	struct dentry *dentry = filp->f_dentry;
- 	unsigned pagelen;
- 	int ret = -EINVAL;
- 	struct address_space *mapping;
-@@ -484,7 +430,8 @@ out_unlock:
- }
- 
- static struct vm_operations_struct nfs_file_vm_ops = {
--	.fault = filemap_fault,
-+	.nopage		= filemap_nopage,
-+	.populate	= filemap_populate,
- 	.page_mkwrite = nfs_vm_page_mkwrite,
- };
- 
-@@ -500,16 +447,16 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
- 	return 0;
- }
- 
--static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
--				unsigned long nr_segs, loff_t pos)
-+static ssize_t
-+nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
- {
--	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
-+	struct dentry * dentry = iocb->ki_filp->f_dentry;
- 	struct inode * inode = dentry->d_inode;
- 	ssize_t result;
--	size_t count = iov_length(iov, nr_segs);
-+	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
- 
- 	if (iocb->ki_filp->f_flags & O_DIRECT)
--		return nfs_file_direct_write(iocb, iov, nr_segs, pos);
-+		return nfs_file_direct_write(iocb, &local_iov, 1, pos);
- 
- 	dprintk("NFS: write(%s/%s, %lu@%Ld)\n",
- 		dentry->d_parent->d_name.name, dentry->d_name.name,
-@@ -532,7 +479,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
- 		goto out;
- 
- 	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
--	result = generic_file_aio_write(iocb, iov, nr_segs, pos);
-+	result = generic_file_aio_write(iocb, buf, count, pos);
- 	/* Return error values for O_SYNC and IS_SYNC() */
- 	if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
- 		int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
-@@ -549,14 +496,19 @@ out_swapfile:
- 
- static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
- {
-+	struct file_lock cfl;
- 	struct inode *inode = filp->f_mapping->host;
- 	int status = 0;
- 
- 	lock_kernel();
- 	/* Try local locking first */
--	posix_test_lock(filp, fl);
--	if (fl->fl_type != F_UNLCK) {
-+	if (posix_test_lock(filp, fl, &cfl)) {
- 		/* found a conflict */
-+		fl->fl_start = cfl.fl_start;
-+		fl->fl_end = cfl.fl_end;
-+		fl->fl_type = cfl.fl_type;
-+		fl->fl_pid = cfl.fl_pid;
-+
- 		goto out;
- 	}
- 
-@@ -662,8 +614,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
- 	int ret = -ENOLCK;
- 
- 	dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n",
--			filp->f_path.dentry->d_parent->d_name.name,
--			filp->f_path.dentry->d_name.name,
-+			filp->f_dentry->d_parent->d_name.name,
-+			filp->f_dentry->d_name.name,
- 			fl->fl_type, fl->fl_flags,
- 			(long long)fl->fl_start, (long long)fl->fl_end);
- 
-@@ -695,8 +647,8 @@ out_err:
- static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
- {
- 	dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n",
--			filp->f_path.dentry->d_parent->d_name.name,
--			filp->f_path.dentry->d_name.name,
-+			filp->f_dentry->d_parent->d_name.name,
-+			filp->f_dentry->d_name.name,
- 			fl->fl_type, fl->fl_flags);
- 
- 	/*
-@@ -718,16 +670,3 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
- 		return do_unlk(filp, cmd, fl);
- 	return do_setlk(filp, cmd, fl);
- }
--
--/*
-- * There is no protocol support for leases, so we have no way to implement
-- * them correctly in the face of opens by other clients.
-- */
--static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
--{
--	dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
--			file->f_path.dentry->d_parent->d_name.name,
--			file->f_path.dentry->d_name.name, arg);
--
--	return -EINVAL;
--}
-diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
-index fae9719..5bf9b3c 100644
---- a/fs/nfs/getroot.c
-+++ b/fs/nfs/getroot.c
-@@ -30,7 +30,6 @@
- #include <linux/nfs_idmap.h>
- #include <linux/vfs.h>
- #include <linux/namei.h>
--#include <linux/mnt_namespace.h>
- #include <linux/security.h>
- 
- #include <asm/system.h>
-diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
-index 86147b0..148aebe 100644
---- a/fs/nfs/idmap.c
-+++ b/fs/nfs/idmap.c
-@@ -376,7 +376,7 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
- static ssize_t
- idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
- {
--	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
-+	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
- 	struct idmap *idmap = (struct idmap *)rpci->private;
- 	struct idmap_msg im_in, *im = &idmap->idmap_im;
- 	struct idmap_hashtable *h;
-diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
-index 52daefa..6a5b54c 100644
---- a/fs/nfs/inode.c
-+++ b/fs/nfs/inode.c
-@@ -612,7 +612,7 @@ static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
-  */
- static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
- {
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	struct nfs_inode *nfsi = NFS_I(inode);
- 
- 	filp->private_data = get_nfs_open_context(ctx);
-@@ -644,7 +644,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
- 
- static void nfs_file_clear_open_context(struct file *filp)
- {
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	struct nfs_open_context *ctx = nfs_file_open_context(filp);
- 
- 	if (ctx) {
-@@ -667,7 +667,7 @@ int nfs_open(struct inode *inode, struct file *filp)
- 	cred = rpc_lookup_cred();
- 	if (IS_ERR(cred))
- 		return PTR_ERR(cred);
--	ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred);
-+	ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
- 	put_rpccred(cred);
- 	if (ctx == NULL)
- 		return -ENOMEM;
-@@ -1242,7 +1242,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
- #endif
- }
- 
--static void init_once(void *foo)
-+static void init_once(void *foo, struct kmem_cache *cachep, unsigned long temp)
- {
- 	struct nfs_inode *nfsi = (struct nfs_inode *) foo;
- 
-diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
-index 66df08d..1e11b1d 100644
---- a/fs/nfs/namespace.c
-+++ b/fs/nfs/namespace.c
-@@ -107,29 +107,29 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
- 
- 	BUG_ON(IS_ROOT(dentry));
- 	dprintk("%s: enter\n", __func__);
--	dput(nd->path.dentry);
--	nd->path.dentry = dget(dentry);
-+	dput(nd->dentry);
-+	nd->dentry = dget(dentry);
- 
- 	/* Look it up again */
--	parent = dget_parent(nd->path.dentry);
-+	parent = dget_parent(nd->dentry);
- 	err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
--						  &nd->path.dentry->d_name,
-+						  &nd->dentry->d_name,
- 						  &fh, &fattr);
- 	dput(parent);
- 	if (err != 0)
- 		goto out_err;
- 
- 	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
--		mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
-+		mnt = nfs_do_refmount(nd->mnt, nd->dentry);
- 	else
--		mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh,
-+		mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh,
- 				      &fattr);
- 	err = PTR_ERR(mnt);
- 	if (IS_ERR(mnt))
- 		goto out_err;
- 
- 	mntget(mnt);
--	err = do_add_mount(mnt, &nd->path, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
-+	err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE,
- 			   &nfs_automount_list);
- 	if (err < 0) {
- 		mntput(mnt);
-@@ -137,9 +137,9 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
- 			goto out_follow;
- 		goto out_err;
- 	}
--	path_put(&nd->path);
--	nd->path.mnt = mnt;
--	nd->path.dentry = dget(mnt->mnt_root);
-+	backport_path_put(nd);
-+	nd->mnt = mnt;
-+	nd->dentry = dget(mnt->mnt_root);
- 	schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
- out:
- 	dprintk("%s: done, returned %d\n", __func__, err);
-@@ -147,22 +147,22 @@ out:
- 	dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
- 	return ERR_PTR(err);
- out_err:
--	path_put(&nd->path);
-+	backport_path_put(nd);
- 	goto out;
- out_follow:
--	while (d_mountpoint(nd->path.dentry) &&
--	       follow_down(&nd->path.mnt, &nd->path.dentry))
-+	while (d_mountpoint(nd->dentry) &&
-+	       follow_down(&nd->mnt, &nd->dentry))
- 		;
- 	err = 0;
- 	goto out;
- }
- 
--const struct inode_operations nfs_mountpoint_inode_operations = {
-+struct inode_operations nfs_mountpoint_inode_operations = {
- 	.follow_link	= nfs_follow_mountpoint,
- 	.getattr	= nfs_getattr,
- };
- 
--const struct inode_operations nfs_referral_inode_operations = {
-+struct inode_operations nfs_referral_inode_operations = {
- 	.follow_link	= nfs_follow_mountpoint,
- };
- 
-diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
-index 1e750e4..bdeef69 100644
---- a/fs/nfs/nfs3proc.c
-+++ b/fs/nfs/nfs3proc.c
-@@ -779,7 +779,7 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
- static int
- nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
- {
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 
- 	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
- }
-diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
-index ea79064..7a8e6fa 100644
---- a/fs/nfs/nfs4_fs.h
-+++ b/fs/nfs/nfs4_fs.h
-@@ -165,7 +165,7 @@ struct nfs4_state_recovery_ops {
- };
- 
- extern struct dentry_operations nfs4_dentry_operations;
--extern const struct inode_operations nfs4_dir_inode_operations;
-+extern struct inode_operations nfs4_dir_inode_operations;
- 
- /* inode.c */
- extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
-diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
-index c910413..02f1156 100644
---- a/fs/nfs/nfs4proc.c
-+++ b/fs/nfs/nfs4proc.c
-@@ -1384,7 +1384,7 @@ struct dentry *
- nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
- {
- 	struct path path = {
--		.mnt = nd->path.mnt,
-+		.mnt = nd->mnt,
- 		.dentry = dentry,
- 	};
- 	struct dentry *parent;
-@@ -1421,8 +1421,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
- 	}
- 	res = d_add_unique(dentry, igrab(state->inode));
- 	if (res != NULL)
--		path.dentry = res;
--	nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
-+		dentry = res;
-+	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
- 	nfs_unblock_sillyrename(parent);
- 	nfs4_intent_set_file(nd, &path, state);
- 	return res;
-@@ -1432,7 +1432,7 @@ int
- nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
- {
- 	struct path path = {
--		.mnt = nd->path.mnt,
-+		.mnt = nd->mnt,
- 		.dentry = dentry,
- 	};
- 	struct rpc_cred *cred;
-@@ -1880,7 +1880,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-                  int flags, struct nameidata *nd)
- {
- 	struct path path = {
--		.mnt = nd->path.mnt,
-+		.mnt = nd->mnt,
- 		.dentry = dentry,
- 	};
- 	struct nfs4_state *state;
-@@ -3671,7 +3671,7 @@ struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops = {
- 	.recover_lock	= nfs4_lock_expired,
- };
- 
--static const struct inode_operations nfs4_file_inode_operations = {
-+static struct inode_operations nfs4_file_inode_operations = {
- 	.permission	= nfs_permission,
- 	.getattr	= nfs_getattr,
- 	.setattr	= nfs_setattr,
-diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
-index 4dbb84d..c351a41 100644
---- a/fs/nfs/proc.c
-+++ b/fs/nfs/proc.c
-@@ -595,7 +595,7 @@ nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
- static int
- nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
- {
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 
- 	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
- }
-diff --git a/fs/nfs/super.c b/fs/nfs/super.c
-index e9b2017..85ea5fd 100644
---- a/fs/nfs/super.c
-+++ b/fs/nfs/super.c
-@@ -201,7 +201,7 @@ static match_table_t nfs_secflavor_tokens = {
- };
- 
- 
--static void nfs_umount_begin(struct super_block *);
-+static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags);
- static int  nfs_statfs(struct dentry *, struct kstatfs *);
- static int  nfs_show_options(struct seq_file *, struct vfsmount *);
- static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
-@@ -228,7 +228,7 @@ struct file_system_type nfs_xdev_fs_type = {
- 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
- };
- 
--static const struct super_operations nfs_sops = {
-+static struct super_operations nfs_sops = {
- 	.alloc_inode	= nfs_alloc_inode,
- 	.destroy_inode	= nfs_destroy_inode,
- 	.write_inode	= nfs_write_inode,
-@@ -274,7 +274,7 @@ struct file_system_type nfs4_referral_fs_type = {
- 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
- };
- 
--static const struct super_operations nfs4_sops = {
-+static struct super_operations nfs4_sops = {
- 	.alloc_inode	= nfs_alloc_inode,
- 	.destroy_inode	= nfs_destroy_inode,
- 	.write_inode	= nfs_write_inode,
-@@ -287,10 +287,7 @@ static const struct super_operations nfs4_sops = {
- };
- #endif
- 
--static struct shrinker acl_shrinker = {
--	.shrink		= nfs_access_cache_shrinker,
--	.seeks		= DEFAULT_SEEKS,
--};
-+static struct shrinker *acl_shrinker;
- 
- /*
-  * Register the NFS filesystems
-@@ -311,7 +308,7 @@ int __init register_nfs_fs(void)
- 	if (ret < 0)
- 		goto error_2;
- #endif
--	register_shrinker(&acl_shrinker);
-+	acl_shrinker = set_shrinker(DEFAULT_SEEKS, nfs_access_cache_shrinker);
- 	return 0;
- 
- #ifdef CONFIG_NFS_V4
-@@ -329,7 +326,8 @@ error_0:
-  */
- void __exit unregister_nfs_fs(void)
- {
--	unregister_shrinker(&acl_shrinker);
-+	if (acl_shrinker != NULL)
-+		remove_shrinker(acl_shrinker);
- #ifdef CONFIG_NFS_V4
- 	unregister_filesystem(&nfs4_fs_type);
- #endif
-@@ -649,11 +647,13 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
-  * Begin unmount by attempting to remove all automounted mountpoints we added
-  * in response to xdev traversals and referrals
-  */
--static void nfs_umount_begin(struct super_block *sb)
-+static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
- {
--	struct nfs_server *server = NFS_SB(sb);
-+	struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
- 	struct rpc_clnt *rpc;
- 
-+	if (!(flags & MNT_FORCE))
-+		return;
- 	/* -EIO all pending I/O */
- 	rpc = server->client_acl;
- 	if (!IS_ERR(rpc))
-diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
-index 412738d..b17f14a 100644
---- a/fs/nfs/symlink.c
-+++ b/fs/nfs/symlink.c
-@@ -70,7 +70,7 @@ read_failed:
- /*
-  * symlinks can't do much...
-  */
--const struct inode_operations nfs_symlink_inode_operations = {
-+struct inode_operations nfs_symlink_inode_operations = {
- 	.readlink	= generic_readlink,
- 	.follow_link	= nfs_follow_link,
- 	.put_link	= page_put_link,
-diff --git a/fs/nfs/write.c b/fs/nfs/write.c
-index 3229e21..7dd87ba 100644
---- a/fs/nfs/write.c
-+++ b/fs/nfs/write.c
-@@ -20,6 +20,8 @@
- #include <linux/nfs_page.h>
- #include <linux/backing-dev.h>
- 
-+#include <linux/mpage.h>
-+
- #include <asm/uaccess.h>
- 
- #include "delegation.h"
-@@ -198,7 +200,7 @@ static int nfs_set_page_writeback(struct page *page)
- 		struct inode *inode = page->mapping->host;
- 		struct nfs_server *nfss = NFS_SERVER(inode);
- 
--		if (atomic_long_inc_return(&nfss->writeback) >
-+		if (atomic_long_inc_return((atomic_long_t *)&nfss->writeback) >
- 				NFS_CONGESTION_ON_THRESH)
- 			set_bdi_congested(&nfss->backing_dev_info, WRITE);
- 	}
-@@ -211,7 +213,7 @@ static void nfs_end_page_writeback(struct page *page)
- 	struct nfs_server *nfss = NFS_SERVER(inode);
- 
- 	end_page_writeback(page);
--	if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
-+	if (atomic_long_dec_return((atomic_long_t *)&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
- 		clear_bdi_congested(&nfss->backing_dev_info, WRITE);
- }
- 
-@@ -726,8 +728,8 @@ int nfs_updatepage(struct file *file, struct page *page,
- 	nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
- 
- 	dprintk("NFS:       nfs_updatepage(%s/%s %d@%lld)\n",
--		file->f_path.dentry->d_parent->d_name.name,
--		file->f_path.dentry->d_name.name, count,
-+		file->f_dentry->d_parent->d_name.name,
-+		file->f_dentry->d_name.name, count,
- 		(long long)(page_offset(page) + offset));
- 
- 	/* If we're not using byte range locks, and we know the page
-diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
-index 9dc036f..4bafc01 100644
---- a/fs/nfsd/export.c
-+++ b/fs/nfsd/export.c
-@@ -168,14 +168,15 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
- 			goto out;
- 
- 		dprintk("Found the path %s\n", buf);
--		key.ek_path = nd.path;
-+		key.ek_path.dentry = nd.dentry;
-+		key.ek_path.mnt = nd.mnt;
- 
- 		ek = svc_expkey_update(&key, ek);
- 		if (ek)
- 			cache_put(&ek->h, &svc_expkey_cache);
- 		else
- 			err = -ENOMEM;
--		path_put(&nd.path);
-+		backport_path_put(&nd);
- 	}
- 	cache_flush();
-  out:
-@@ -204,7 +205,7 @@ static int expkey_show(struct seq_file *m,
- 	if (test_bit(CACHE_VALID, &h->flags) && 
- 	    !test_bit(CACHE_NEGATIVE, &h->flags)) {
- 		seq_printf(m, " ");
--		seq_path(m, &ek->ek_path, "\\ \t\n");
-+		seq_path(m, ek->ek_path.mnt, ek->ek_path.dentry, "\\ \t\n");
- 	}
- 	seq_printf(m, "\n");
- 	return 0;
-@@ -346,7 +347,7 @@ static void svc_export_request(struct cache_detail *cd,
- 	char *pth;
- 
- 	qword_add(bpp, blen, exp->ex_client->name);
--	pth = d_path(&exp->ex_path, *bpp, *blen);
-+	pth = d_path(exp->ex_path.dentry, exp->ex_path.mnt, *bpp, *blen);
- 	if (IS_ERR(pth)) {
- 		/* is this correct? */
- 		(*bpp)[0] = '\n';
-@@ -385,7 +386,7 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
- 	}
- 
- 	if (!inode->i_sb->s_export_op ||
--	    !inode->i_sb->s_export_op->fh_to_dentry) {
-+	    !inode->i_sb->s_export_op->get_dentry) {
- 		dprintk("exp_export: export of invalid fs type.\n");
- 		return -EINVAL;
- 	}
-@@ -504,7 +505,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
- 	struct svc_export exp, *expp;
- 	int an_int;
- 
--	nd.path.dentry = NULL;
-+	nd.dentry = NULL;
- 	exp.ex_pathname = NULL;
- 
- 	/* fs locations */
-@@ -544,8 +545,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
- 
- 	exp.h.flags = 0;
- 	exp.ex_client = dom;
--	exp.ex_path.mnt = nd.path.mnt;
--	exp.ex_path.dentry = nd.path.dentry;
-+	exp.ex_path.mnt = nd.mnt;
-+	exp.ex_path.dentry = nd.dentry;
- 	exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
- 	err = -ENOMEM;
- 	if (!exp.ex_pathname)
-@@ -607,7 +608,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
- 				goto out;
- 		}
- 
--		err = check_export(nd.path.dentry->d_inode, exp.ex_flags,
-+		err = check_export(nd.dentry->d_inode, exp.ex_flags,
- 				   exp.ex_uuid);
- 		if (err) goto out;
- 	}
-@@ -626,8 +627,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
- 	nfsd4_fslocs_free(&exp.ex_fslocs);
- 	kfree(exp.ex_uuid);
- 	kfree(exp.ex_pathname);
--	if (nd.path.dentry)
--		path_put(&nd.path);
-+	if (nd.dentry)
-+		backport_path_put(&nd);
-  out_no_path:
- 	if (dom)
- 		auth_domain_put(dom);
-@@ -650,7 +651,7 @@ static int svc_export_show(struct seq_file *m,
- 		return 0;
- 	}
- 	exp = container_of(h, struct svc_export, h);
--	seq_path(m, &exp->ex_path, " \t\n\\");
-+	seq_path(m, exp->ex_path.mnt, exp->ex_path.dentry, " \t\n\\");
- 	seq_putc(m, '\t');
- 	seq_escape(m, exp->ex_client->name, " \t\n\\");
- 	seq_putc(m, '(');
-@@ -1026,7 +1027,7 @@ exp_export(struct nfsctl_export *nxp)
- 		goto out_put_clp;
- 	err = -EINVAL;
- 
--	exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);
-+	exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
- 
- 	memset(&new, 0, sizeof(new));
- 
-@@ -1034,8 +1035,8 @@ exp_export(struct nfsctl_export *nxp)
- 	if ((nxp->ex_flags & NFSEXP_FSID) &&
- 	    (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
- 	    fsid_key->ek_path.mnt &&
--	    (fsid_key->ek_path.mnt != nd.path.mnt ||
--	     fsid_key->ek_path.dentry != nd.path.dentry))
-+	    (fsid_key->ek_path.mnt != nd.mnt ||
-+	     fsid_key->ek_path.dentry != nd.dentry))
- 		goto finish;
- 
- 	if (!IS_ERR(exp)) {
-@@ -1051,7 +1052,7 @@ exp_export(struct nfsctl_export *nxp)
- 		goto finish;
- 	}
- 
--	err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
-+	err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL);
- 	if (err) goto finish;
- 
- 	err = -ENOMEM;
-@@ -1064,7 +1065,8 @@ exp_export(struct nfsctl_export *nxp)
- 	if (!new.ex_pathname)
- 		goto finish;
- 	new.ex_client = clp;
--	new.ex_path = nd.path;
-+	new.ex_path.mnt = nd.mnt;
-+	new.ex_path.dentry = nd.dentry;
- 	new.ex_flags = nxp->ex_flags;
- 	new.ex_anon_uid = nxp->ex_anon_uid;
- 	new.ex_anon_gid = nxp->ex_anon_gid;
-@@ -1090,7 +1092,7 @@ finish:
- 		exp_put(exp);
- 	if (fsid_key && !IS_ERR(fsid_key))
- 		cache_put(&fsid_key->h, &svc_expkey_cache);
--	path_put(&nd.path);
-+	backport_path_put(&nd);
- out_put_clp:
- 	auth_domain_put(clp);
- out_unlock:
-@@ -1143,8 +1145,8 @@ exp_unexport(struct nfsctl_export *nxp)
- 		goto out_domain;
- 
- 	err = -EINVAL;
--	exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
--	path_put(&nd.path);
-+	exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
-+	backport_path_put(&nd);
- 	if (IS_ERR(exp))
- 		goto out_domain;
- 
-@@ -1180,12 +1182,12 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
- 		printk("nfsd: exp_rootfh path not found %s", path);
- 		return err;
- 	}
--	inode = nd.path.dentry->d_inode;
-+	inode = nd.dentry->d_inode;
- 
- 	dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
--		 path, nd.path.dentry, clp->name,
-+		 path, nd.dentry, clp->name,
- 		 inode->i_sb->s_id, inode->i_ino);
--	exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
-+	exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
- 	if (IS_ERR(exp)) {
- 		err = PTR_ERR(exp);
- 		goto out;
-@@ -1195,7 +1197,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
- 	 * fh must be initialized before calling fh_compose
- 	 */
- 	fh_init(&fh, maxsize);
--	if (fh_compose(&fh, exp, nd.path.dentry, NULL))
-+	if (fh_compose(&fh, exp, nd.dentry, NULL))
- 		err = -EINVAL;
- 	else
- 		err = 0;
-@@ -1203,7 +1205,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
- 	fh_put(&fh);
- 	exp_put(exp);
- out:
--	path_put(&nd.path);
-+	backport_path_put(&nd);
- 	return err;
- }
- 
-diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
-index 145b3c8..ad22c29 100644
---- a/fs/nfsd/nfs4recover.c
-+++ b/fs/nfsd/nfs4recover.c
-@@ -121,9 +121,9 @@ out_no_tfm:
- static void
- nfsd4_sync_rec_dir(void)
- {
--	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
--	nfsd_sync_dir(rec_dir.path.dentry);
--	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
-+	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
-+	nfsd_sync_dir(rec_dir.dentry);
-+	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
- }
- 
- int
-@@ -143,9 +143,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
- 	nfs4_save_user(&uid, &gid);
- 
- 	/* lock the parent */
--	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
-+	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
- 
--	dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1);
-+	dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
- 	if (IS_ERR(dentry)) {
- 		status = PTR_ERR(dentry);
- 		goto out_unlock;
-@@ -155,15 +155,15 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
- 		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
- 		goto out_put;
- 	}
--	status = mnt_want_write(rec_dir.path.mnt);
-+	status = mnt_want_write(rec_dir.mnt);
- 	if (status)
- 		goto out_put;
--	status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
--	mnt_drop_write(rec_dir.path.mnt);
-+	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
-+	mnt_drop_write(rec_dir.mnt);
- out_put:
- 	dput(dentry);
- out_unlock:
--	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
-+	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
- 	if (status == 0) {
- 		clp->cl_firststate = 1;
- 		nfsd4_sync_rec_dir();
-@@ -226,7 +226,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
- 
- 	nfs4_save_user(&uid, &gid);
- 
--	filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY);
-+	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
- 	status = PTR_ERR(filp);
- 	if (IS_ERR(filp))
- 		goto out;
-@@ -291,9 +291,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
- 
- 	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
- 
--	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
--	dentry = lookup_one_len(name, rec_dir.path.dentry, namlen);
--	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
-+	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
-+	dentry = lookup_one_len(name, rec_dir.dentry, namlen);
-+	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
- 	if (IS_ERR(dentry)) {
- 		status = PTR_ERR(dentry);
- 		return status;
-@@ -302,7 +302,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
- 	if (!dentry->d_inode)
- 		goto out;
- 
--	status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry);
-+	status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
- out:
- 	dput(dentry);
- 	return status;
-@@ -318,7 +318,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
- 	if (!rec_dir_init || !clp->cl_firststate)
- 		return;
- 
--	status = mnt_want_write(rec_dir.path.mnt);
-+	status = mnt_want_write(rec_dir.mnt);
- 	if (status)
- 		goto out;
- 	clp->cl_firststate = 0;
-@@ -327,7 +327,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
- 	nfs4_reset_user(uid, gid);
- 	if (status == 0)
- 		nfsd4_sync_rec_dir();
--	mnt_drop_write(rec_dir.path.mnt);
-+	mnt_drop_write(rec_dir.mnt);
- out:
- 	if (status)
- 		printk("NFSD: Failed to remove expired client state directory"
-@@ -357,17 +357,17 @@ nfsd4_recdir_purge_old(void) {
- 
- 	if (!rec_dir_init)
- 		return;
--	status = mnt_want_write(rec_dir.path.mnt);
-+	status = mnt_want_write(rec_dir.mnt);
- 	if (status)
- 		goto out;
--	status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old);
-+	status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
- 	if (status == 0)
- 		nfsd4_sync_rec_dir();
--	mnt_drop_write(rec_dir.path.mnt);
-+	mnt_drop_write(rec_dir.mnt);
- out:
- 	if (status)
- 		printk("nfsd4: failed to purge old clients from recovery"
--			" directory %s\n", rec_dir.path.dentry->d_name.name);
-+			" directory %s\n", rec_dir.dentry->d_name.name);
- }
- 
- static int
-@@ -387,10 +387,10 @@ int
- nfsd4_recdir_load(void) {
- 	int status;
- 
--	status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir);
-+	status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
- 	if (status)
- 		printk("nfsd4: failed loading clients from recovery"
--			" directory %s\n", rec_dir.path.dentry->d_name.name);
-+			" directory %s\n", rec_dir.dentry->d_name.name);
- 	return status;
- }
- 
-@@ -429,5 +429,5 @@ nfsd4_shutdown_recdir(void)
- 	if (!rec_dir_init)
- 		return;
- 	rec_dir_init = 0;
--	path_put(&rec_dir.path);
-+	backport_path_put(&rec_dir);
- }
-diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
-index 1578d7a..1c6df07 100644
---- a/fs/nfsd/nfs4state.c
-+++ b/fs/nfsd/nfs4state.c
-@@ -1576,7 +1576,7 @@ static __be32
- nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
- {
- 	struct file *filp = stp->st_vfs_file;
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	unsigned int share_access, new_writer;
- 	__be32 status;
- 
-@@ -1923,7 +1923,7 @@ search_close_lru(u32 st_id, int flags)
- static inline int
- nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
- {
--	return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode;
-+	return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_dentry->d_inode;
- }
- 
- static int
-@@ -2838,7 +2838,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- 	 * only the dentry:inode set.
- 	 */
- 	memset(&file, 0, sizeof (struct file));
--	file.f_path.dentry = cstate->current_fh.fh_dentry;
-+	file.f_dentry = cstate->current_fh.fh_dentry;
- 
- 	status = nfs_ok;
- 	error = vfs_test_lock(&file, &file_lock);
-@@ -2934,7 +2934,7 @@ static int
- check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
- {
- 	struct file_lock **flpp;
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	int status = 0;
- 
- 	lock_kernel();
-@@ -3294,11 +3294,11 @@ nfs4_reset_recoverydir(char *recdir)
- 	if (status)
- 		return status;
- 	status = -ENOTDIR;
--	if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) {
-+	if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
- 		nfs4_set_recdir(recdir);
- 		status = 0;
- 	}
--	path_put(&nd.path);
-+	backport_path_put(&nd);
- 	return status;
- }
- 
-diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
-index c53e65f..fc2871b 100644
---- a/fs/nfsd/nfsctl.c
-+++ b/fs/nfsd/nfsctl.c
-@@ -121,7 +121,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
- 
- static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
- {
--	ino_t ino =  file->f_path.dentry->d_inode->i_ino;
-+	ino_t ino = file->f_dentry->d_inode->i_ino;
- 	char *data;
- 	ssize_t rv;
- 
-@@ -360,9 +360,9 @@ static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
- 	if (error)
- 		return error;
- 
--	error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
-+	error = nlmsvc_unlock_all_by_sb(nd.mnt->mnt_sb);
- 
--	path_put(&nd.path);
-+	backport_path_put(&nd);
- 	return error;
- }
- 
-diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
-index 80292ff..47eb160 100644
---- a/fs/nfsd/nfssvc.c
-+++ b/fs/nfsd/nfssvc.c
-@@ -574,3 +574,5 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
- 	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
- 	return 1;
- }
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
-index 18060be..becacce 100644
---- a/fs/nfsd/vfs.c
-+++ b/fs/nfsd/vfs.c
-@@ -23,7 +23,6 @@
- #include <linux/file.h>
- #include <linux/mount.h>
- #include <linux/major.h>
--#include <linux/splice.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/fcntl.h>
-@@ -766,10 +765,10 @@ static int
- nfsd_sync(struct file *filp)
- {
-         int err;
--	struct inode *inode = filp->f_path.dentry->d_inode;
--	dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
-+	struct inode *inode = filp->f_dentry->d_inode;
-+	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
- 	mutex_lock(&inode->i_mutex);
--	err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
-+	err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
- 	mutex_unlock(&inode->i_mutex);
- 
- 	return err;
-@@ -828,53 +827,39 @@ found:
- 	return ra;
- }
- 
--/*
-- * Grab and keep cached pages associated with a file in the svc_rqst
-- * so that they can be passed to the network sendmsg/sendpage routines
-- * directly. They will be released after the sending has completed.
-- */
- static int
--nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
--		  struct splice_desc *sd)
-+nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset , unsigned long size)
- {
--	struct svc_rqst *rqstp = sd->u.data;
-+	unsigned long count = desc->count;
-+	struct svc_rqst *rqstp = desc->arg.data;
- 	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
--	struct page *page = buf->page;
--	size_t size;
--	int ret;
--
--	ret = buf->ops->confirm(pipe, buf);
--	if (unlikely(ret))
--		return ret;
- 
--	size = sd->len;
-+	if (size > count)
-+		size = count;
- 
- 	if (rqstp->rq_res.page_len == 0) {
- 		get_page(page);
--		put_page(*pp);
--		*pp = page;
--		rqstp->rq_resused++;
--		rqstp->rq_res.page_base = buf->offset;
-+		if (*pp)
-+			put_page(*pp);
-+		rqstp->rq_respages[rqstp->rq_resused++] = page;
-+		rqstp->rq_res.page_base = offset;
- 		rqstp->rq_res.page_len = size;
--	} else if (page != pp[-1]) {
-+	} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) {
- 		get_page(page);
- 		if (*pp)
- 			put_page(*pp);
- 		*pp = page;
--		rqstp->rq_resused++;
-+		rqstp->rq_respages[rqstp->rq_resused++] = page;
- 		rqstp->rq_res.page_len += size;
--	} else
-+	} else {
- 		rqstp->rq_res.page_len += size;
-+	}
- 
-+	desc->count = count - size;
-+	desc->written += size;
- 	return size;
- }
- 
--static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
--				    struct splice_desc *sd)
--{
--	return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
--}
--
- static inline int svc_msnfs(struct svc_fh *ffhp)
- {
- #ifdef MSNFS
-@@ -895,7 +880,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- 	int		host_err;
- 
- 	err = nfserr_perm;
--	inode = file->f_path.dentry->d_inode;
-+	inode = file->f_dentry->d_inode;
- 
- 	if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
- 		goto out;
-@@ -906,16 +891,9 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- 	if (ra && ra->p_set)
- 		file->f_ra = ra->p_ra;
- 
--	if (file->f_op->splice_read && rqstp->rq_splice_ok) {
--		struct splice_desc sd = {
--			.len		= 0,
--			.total_len	= *count,
--			.pos		= offset,
--			.u.data		= rqstp,
--		};
--
-+	if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
- 		rqstp->rq_resused = 1;
--		host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
-+		host_err = file->f_op->sendfile(file, &offset, *count, nfsd_read_actor, rqstp);
- 	} else {
- 		oldfs = get_fs();
- 		set_fs(KERNEL_DS);
-@@ -937,7 +915,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- 		nfsdstats.io_read += host_err;
- 		*count = host_err;
- 		err = 0;
--		fsnotify_access(file->f_path.dentry);
-+		fsnotify_access(file->f_dentry);
- 	} else 
- 		err = nfserrno(host_err);
- out:
-@@ -971,11 +949,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- 	err = nfserr_perm;
- 
- 	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
--		(!lock_may_write(file->f_path.dentry->d_inode, offset, cnt)))
-+		(!lock_may_write(file->f_dentry->d_inode, offset, cnt)))
- 		goto out;
- #endif
- 
--	dentry = file->f_path.dentry;
-+	dentry = file->f_dentry;
- 	inode = dentry->d_inode;
- 	exp   = fhp->fh_export;
- 
-@@ -1004,7 +982,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- 	set_fs(oldfs);
- 	if (host_err >= 0) {
- 		nfsdstats.io_write += cnt;
--		fsnotify_modify(file->f_path.dentry);
-+		fsnotify_modify(file->f_dentry);
- 	}
- 
- 	/* clear setuid/setgid flag after write */
-diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
-index 27e772c..d932fb1 100644
---- a/include/linux/exportfs.h
-+++ b/include/linux/exportfs.h
-@@ -89,85 +89,9 @@ struct fid {
- 	};
- };
- 
--/**
-- * struct export_operations - for nfsd to communicate with file systems
-- * @encode_fh:      encode a file handle fragment from a dentry
-- * @fh_to_dentry:   find the implied object and get a dentry for it
-- * @fh_to_parent:   find the implied object's parent and get a dentry for it
-- * @get_name:       find the name for a given inode in a given directory
-- * @get_parent:     find the parent of a given directory
-- *
-- * See Documentation/filesystems/Exporting for details on how to use
-- * this interface correctly.
-- *
-- * encode_fh:
-- *    @encode_fh should store in the file handle fragment @fh (using at most
-- *    @max_len bytes) information that can be used by @decode_fh to recover the
-- *    file refered to by the &struct dentry @de.  If the @connectable flag is
-- *    set, the encode_fh() should store sufficient information so that a good
-- *    attempt can be made to find not only the file but also it's place in the
-- *    filesystem.   This typically means storing a reference to de->d_parent in
-- *    the filehandle fragment.  encode_fh() should return the number of bytes
-- *    stored or a negative error code such as %-ENOSPC
-- *
-- * fh_to_dentry:
-- *    @fh_to_dentry is given a &struct super_block (@sb) and a file handle
-- *    fragment (@fh, @fh_len). It should return a &struct dentry which refers
-- *    to the same file that the file handle fragment refers to.  If it cannot,
-- *    it should return a %NULL pointer if the file was found but no acceptable
-- *    &dentries were available, or an %ERR_PTR error code indicating why it
-- *    couldn't be found (e.g. %ENOENT or %ENOMEM).  Any suitable dentry can be
-- *    returned including, if necessary, a new dentry created with d_alloc_root.
-- *    The caller can then find any other extant dentries by following the
-- *    d_alias links.
-- *
-- * fh_to_parent:
-- *    Same as @fh_to_dentry, except that it returns a pointer to the parent
-- *    dentry if it was encoded into the filehandle fragment by @encode_fh.
-- *
-- * get_name:
-- *    @get_name should find a name for the given @child in the given @parent
-- *    directory.  The name should be stored in the @name (with the
-- *    understanding that it is already pointing to a a %NAME_MAX+1 sized
-- *    buffer.   get_name() should return %0 on success, a negative error code
-- *    or error.  @get_name will be called without @parent->i_mutex held.
-- *
-- * get_parent:
-- *    @get_parent should find the parent directory for the given @child which
-- *    is also a directory.  In the event that it cannot be found, or storage
-- *    space cannot be allocated, a %ERR_PTR should be returned.
-- *
-- * Locking rules:
-- *    get_parent is called with child->d_inode->i_mutex down
-- *    get_name is not (which is possibly inconsistent)
-- */
--
--struct export_operations {
--	int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
--			int connectable);
--	struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
--			int fh_len, int fh_type);
--	struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
--			int fh_len, int fh_type);
--	int (*get_name)(struct dentry *parent, char *name,
--			struct dentry *child);
--	struct dentry * (*get_parent)(struct dentry *child);
--};
--
- extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
- 	int *max_len, int connectable);
- extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
- 	int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
- 	void *context);
--
--/*
-- * Generic helpers for filesystems.
-- */
--extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
--	struct fid *fid, int fh_len, int fh_type,
--	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
--extern struct dentry *generic_fh_to_parent(struct super_block *sb,
--	struct fid *fid, int fh_len, int fh_type,
--	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
--
- #endif /* LINUX_EXPORTFS_H */
-diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
-index dbb87ab..9236e80 100644
---- a/include/linux/lockd/lockd.h
-+++ b/include/linux/lockd/lockd.h
-@@ -230,7 +230,7 @@ int           nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
- 
- static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
- {
--	return file->f_file->f_path.dentry->d_inode;
-+	return file->f_file->f_dentry->d_inode;
- }
- 
- /*
-diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
-index 78a5922..e59d828 100644
---- a/include/linux/nfs_fs.h
-+++ b/include/linux/nfs_fs.h
-@@ -9,6 +9,7 @@
- #ifndef _LINUX_NFS_FS_H
- #define _LINUX_NFS_FS_H
- 
-+#include <linux/path.h>
- #include <linux/magic.h>
- 
- /* Default timeout values */
-@@ -331,7 +332,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
- extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
- extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
- extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
--extern int nfs_permission(struct inode *, int);
-+extern int nfs_permission(struct inode *, int, struct nameidata *);
- extern int nfs_open(struct inode *, struct file *);
- extern int nfs_release(struct inode *, struct file *);
- extern int nfs_attribute_timeout(struct inode *inode);
-@@ -358,9 +359,9 @@ static inline void nfs_fattr_init(struct nfs_fattr *fattr)
- /*
-  * linux/fs/nfs/file.c
-  */
--extern const struct inode_operations nfs_file_inode_operations;
-+extern struct inode_operations nfs_file_inode_operations;
- #ifdef CONFIG_NFS_V3
--extern const struct inode_operations nfs3_file_inode_operations;
-+extern struct inode_operations nfs3_file_inode_operations;
- #endif /* CONFIG_NFS_V3 */
- extern const struct file_operations nfs_file_operations;
- extern const struct address_space_operations nfs_file_aops;
-@@ -408,9 +409,9 @@ extern ssize_t nfs_file_direct_write(struct kiocb *iocb,
- /*
-  * linux/fs/nfs/dir.c
-  */
--extern const struct inode_operations nfs_dir_inode_operations;
-+extern struct inode_operations nfs_dir_inode_operations;
- #ifdef CONFIG_NFS_V3
--extern const struct inode_operations nfs3_dir_inode_operations;
-+extern struct inode_operations nfs3_dir_inode_operations;
- #endif /* CONFIG_NFS_V3 */
- extern const struct file_operations nfs_dir_operations;
- extern struct dentry_operations nfs_dentry_operations;
-@@ -423,7 +424,7 @@ extern void nfs_access_zap_cache(struct inode *inode);
- /*
-  * linux/fs/nfs/symlink.c
-  */
--extern const struct inode_operations nfs_symlink_inode_operations;
-+extern struct inode_operations nfs_symlink_inode_operations;
- 
- /*
-  * linux/fs/nfs/sysctl.c
-@@ -439,8 +440,8 @@ extern void nfs_unregister_sysctl(void);
- /*
-  * linux/fs/nfs/namespace.c
-  */
--extern const struct inode_operations nfs_mountpoint_inode_operations;
--extern const struct inode_operations nfs_referral_inode_operations;
-+extern struct inode_operations nfs_mountpoint_inode_operations;
-+extern struct inode_operations nfs_referral_inode_operations;
- extern int nfs_mountpoint_expiry_timeout;
- extern void nfs_release_automount_timer(void);
- 
-diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
-index 8c77c11..d9007dc 100644
---- a/include/linux/nfs_xdr.h
-+++ b/include/linux/nfs_xdr.h
-@@ -782,8 +782,8 @@ struct nfs_access_entry;
- struct nfs_rpc_ops {
- 	u32	version;		/* Protocol version */
- 	struct dentry_operations *dentry_ops;
--	const struct inode_operations *dir_inode_ops;
--	const struct inode_operations *file_inode_ops;
-+	struct inode_operations *dir_inode_ops;
-+	struct inode_operations *file_inode_ops;
- 
- 	int	(*getroot) (struct nfs_server *, struct nfs_fh *,
- 			    struct nfs_fsinfo *);
-diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
-index 5431512..3753e4b 100644
---- a/include/linux/nfsd/export.h
-+++ b/include/linux/nfsd/export.h
-@@ -15,6 +15,7 @@
- # include <linux/types.h>
- # include <linux/in.h>
- #endif
-+#include <linux/path.h>
- 
- /*
-  * Important limits for the exports stuff.
-diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
-deleted file mode 100644
-index 8e41202..0000000
---- a/include/linux/pipe_fs_i.h
-+++ /dev/null
-@@ -1,151 +0,0 @@
--#ifndef _LINUX_PIPE_FS_I_H
--#define _LINUX_PIPE_FS_I_H
--
--#define PIPEFS_MAGIC 0x50495045
--
--#define PIPE_BUFFERS (16)
--
--#define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */
--#define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */
--#define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */
--
--/**
-- *	struct pipe_buffer - a linux kernel pipe buffer
-- *	@page: the page containing the data for the pipe buffer
-- *	@offset: offset of data inside the @page
-- *	@len: length of data inside the @page
-- *	@ops: operations associated with this buffer. See @pipe_buf_operations.
-- *	@flags: pipe buffer flags. See above.
-- *	@private: private data owned by the ops.
-- **/
--struct pipe_buffer {
--	struct page *page;
--	unsigned int offset, len;
--	const struct pipe_buf_operations *ops;
--	unsigned int flags;
--	unsigned long private;
--};
--
--/**
-- *	struct pipe_inode_info - a linux kernel pipe
-- *	@wait: reader/writer wait point in case of empty/full pipe
-- *	@nrbufs: the number of non-empty pipe buffers in this pipe
-- *	@curbuf: the current pipe buffer entry
-- *	@tmp_page: cached released page
-- *	@readers: number of current readers of this pipe
-- *	@writers: number of current writers of this pipe
-- *	@waiting_writers: number of writers blocked waiting for room
-- *	@r_counter: reader counter
-- *	@w_counter: writer counter
-- *	@fasync_readers: reader side fasync
-- *	@fasync_writers: writer side fasync
-- *	@inode: inode this pipe is attached to
-- *	@bufs: the circular array of pipe buffers
-- **/
--struct pipe_inode_info {
--	wait_queue_head_t wait;
--	unsigned int nrbufs, curbuf;
--	struct page *tmp_page;
--	unsigned int readers;
--	unsigned int writers;
--	unsigned int waiting_writers;
--	unsigned int r_counter;
--	unsigned int w_counter;
--	struct fasync_struct *fasync_readers;
--	struct fasync_struct *fasync_writers;
--	struct inode *inode;
--	struct pipe_buffer bufs[PIPE_BUFFERS];
--};
--
--/*
-- * Note on the nesting of these functions:
-- *
-- * ->confirm()
-- *	->steal()
-- *	...
-- *	->map()
-- *	...
-- *	->unmap()
-- *
-- * That is, ->map() must be called on a confirmed buffer,
-- * same goes for ->steal(). See below for the meaning of each
-- * operation. Also see kerneldoc in fs/pipe.c for the pipe
-- * and generic variants of these hooks.
-- */
--struct pipe_buf_operations {
--	/*
--	 * This is set to 1, if the generic pipe read/write may coalesce
--	 * data into an existing buffer. If this is set to 0, a new pipe
--	 * page segment is always used for new data.
--	 */
--	int can_merge;
--
--	/*
--	 * ->map() returns a virtual address mapping of the pipe buffer.
--	 * The last integer flag reflects whether this should be an atomic
--	 * mapping or not. The atomic map is faster, however you can't take
--	 * page faults before calling ->unmap() again. So if you need to eg
--	 * access user data through copy_to/from_user(), then you must get
--	 * a non-atomic map. ->map() uses the KM_USER0 atomic slot for
--	 * atomic maps, so you can't map more than one pipe_buffer at once
--	 * and you have to be careful if mapping another page as source
--	 * or destination for a copy (IOW, it has to use something else
--	 * than KM_USER0).
--	 */
--	void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
--
--	/*
--	 * Undoes ->map(), finishes the virtual mapping of the pipe buffer.
--	 */
--	void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
--
--	/*
--	 * ->confirm() verifies that the data in the pipe buffer is there
--	 * and that the contents are good. If the pages in the pipe belong
--	 * to a file system, we may need to wait for IO completion in this
--	 * hook. Returns 0 for good, or a negative error value in case of
--	 * error.
--	 */
--	int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *);
--
--	/*
--	 * When the contents of this pipe buffer has been completely
--	 * consumed by a reader, ->release() is called.
--	 */
--	void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
--
--	/*
--	 * Attempt to take ownership of the pipe buffer and its contents.
--	 * ->steal() returns 0 for success, in which case the contents
--	 * of the pipe (the buf->page) is locked and now completely owned
--	 * by the caller. The page may then be transferred to a different
--	 * mapping, the most often used case is insertion into different
--	 * file address space cache.
--	 */
--	int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
--
--	/*
--	 * Get a reference to the pipe buffer.
--	 */
--	void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
--};
--
--/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
--   memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
--#define PIPE_SIZE		PAGE_SIZE
--
--/* Drop the inode semaphore and wait for a pipe event, atomically */
--void pipe_wait(struct pipe_inode_info *pipe);
--
--struct pipe_inode_info * alloc_pipe_info(struct inode * inode);
--void free_pipe_info(struct inode * inode);
--void __free_pipe_info(struct pipe_inode_info *);
--
--/* Generic pipe buffer ops functions */
--void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
--void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
--void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
--int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
--int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
--
--#endif
-diff --git a/include/linux/splice.h b/include/linux/splice.h
-deleted file mode 100644
-index 528dcb9..0000000
---- a/include/linux/splice.h
-+++ /dev/null
-@@ -1,74 +0,0 @@
--/*
-- * Function declerations and data structures related to the splice
-- * implementation.
-- *
-- * Copyright (C) 2007 Jens Axboe <jens.axboe at oracle.com>
-- *
-- */
--#ifndef SPLICE_H
--#define SPLICE_H
--
--#include <linux/pipe_fs_i.h>
--
--/*
-- * splice is tied to pipes as a transport (at least for now), so we'll just
-- * add the splice flags here.
-- */
--#define SPLICE_F_MOVE	(0x01)	/* move pages instead of copying */
--#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
--				 /* we may still block on the fd we splice */
--				 /* from/to, of course */
--#define SPLICE_F_MORE	(0x04)	/* expect more data */
--#define SPLICE_F_GIFT	(0x08)	/* pages passed in are a gift */
--
--/*
-- * Passed to the actors
-- */
--struct splice_desc {
--	unsigned int len, total_len;	/* current and remaining length */
--	unsigned int flags;		/* splice flags */
--	/*
--	 * actor() private data
--	 */
--	union {
--		void __user *userptr;	/* memory to write to */
--		struct file *file;	/* file to read/write */
--		void *data;		/* cookie */
--	} u;
--	loff_t pos;			/* file position */
--};
--
--struct partial_page {
--	unsigned int offset;
--	unsigned int len;
--	unsigned long private;
--};
--
--/*
-- * Passed to splice_to_pipe
-- */
--struct splice_pipe_desc {
--	struct page **pages;		/* page map */
--	struct partial_page *partial;	/* pages[] may not be contig */
--	int nr_pages;			/* number of pages in map */
--	unsigned int flags;		/* splice flags */
--	const struct pipe_buf_operations *ops;/* ops associated with output pipe */
--	void (*spd_release)(struct splice_pipe_desc *, unsigned int);
--};
--
--typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
--			   struct splice_desc *);
--typedef int (splice_direct_actor)(struct pipe_inode_info *,
--				  struct splice_desc *);
--
--extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
--				loff_t *, size_t, unsigned int,
--				splice_actor *);
--extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
--				  struct splice_desc *, splice_actor *);
--extern ssize_t splice_to_pipe(struct pipe_inode_info *,
--			      struct splice_pipe_desc *);
--extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
--				      splice_direct_actor *);
--
--#endif
-diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
-index 10709cb..9bbadbd 100644
---- a/include/linux/sunrpc/debug.h
-+++ b/include/linux/sunrpc/debug.h
-@@ -88,6 +88,7 @@ enum {
- 	CTL_SLOTTABLE_TCP,
- 	CTL_MIN_RESVPORT,
- 	CTL_MAX_RESVPORT,
-+	CTL_TRANSPORT,
- };
- 
- #endif /* _LINUX_SUNRPC_DEBUG_H_ */
-diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
-index dc69068..3a0f48f 100644
---- a/include/linux/sunrpc/svc.h
-+++ b/include/linux/sunrpc/svc.h
-@@ -255,7 +255,7 @@ struct svc_rqst {
- 						 * determine what device number
- 						 * to report (real or virtual)
- 						 */
--	int			rq_splice_ok;   /* turned off in gss privacy
-+	int			rq_sendfile_ok;   /* turned off in gss privacy
- 						 * to prevent encrypting page
- 						 * cache pages */
- 	wait_queue_head_t	rq_wait;	/* synchronization */
-diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
-index 6bfea9e..f0a110d 100644
---- a/net/sunrpc/auth.c
-+++ b/net/sunrpc/auth.c
-@@ -566,19 +566,16 @@ rpcauth_uptodatecred(struct rpc_task *task)
- 		test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
- }
- 
--static struct shrinker rpc_cred_shrinker = {
--	.shrink = rpcauth_cache_shrinker,
--	.seeks = DEFAULT_SEEKS,
--};
-+static struct shrinker *rpc_cred_shrinker;
- 
- void __init rpcauth_init_module(void)
- {
- 	rpc_init_authunix();
- 	rpc_init_generic_auth();
--	register_shrinker(&rpc_cred_shrinker);
-+	rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker);
- }
- 
- void __exit rpcauth_remove_module(void)
- {
--	unregister_shrinker(&rpc_cred_shrinker);
-+	remove_shrinker(rpc_cred_shrinker);
- }
-diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
-index 853a414..71ba862 100644
---- a/net/sunrpc/auth_gss/auth_gss.c
-+++ b/net/sunrpc/auth_gss/auth_gss.c
-@@ -481,7 +481,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
- 	const void *p, *end;
- 	void *buf;
- 	struct gss_upcall_msg *gss_msg;
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	struct gss_cl_ctx *ctx;
- 	uid_t uid;
- 	ssize_t err = -EFBIG;
-diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
-index 81ae3d6..acfb1d1 100644
---- a/net/sunrpc/auth_gss/svcauth_gss.c
-+++ b/net/sunrpc/auth_gss/svcauth_gss.c
-@@ -859,7 +859,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
- 	u32 priv_len, maj_stat;
- 	int pad, saved_len, remaining_len, offset;
- 
--	rqstp->rq_splice_ok = 0;
-+	rqstp->rq_sendfile_ok = 0;
- 
- 	priv_len = svc_getnl(&buf->head[0]);
- 	if (rqstp->rq_deferred) {
-diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
-index c996671..58e606e 100644
---- a/net/sunrpc/cache.c
-+++ b/net/sunrpc/cache.c
-@@ -696,7 +696,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
- {
- 	struct cache_reader *rp = filp->private_data;
- 	struct cache_request *rq;
--	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
-+	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
- 	int err;
- 
- 	if (count == 0)
-@@ -773,7 +773,7 @@ cache_write(struct file *filp, const char __user *buf, size_t count,
- 	    loff_t *ppos)
- {
- 	int err;
--	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
-+	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
- 
- 	if (count == 0)
- 		return 0;
-@@ -804,7 +804,7 @@ cache_poll(struct file *filp, poll_table *wait)
- 	unsigned int mask;
- 	struct cache_reader *rp = filp->private_data;
- 	struct cache_queue *cq;
--	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
-+	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
- 
- 	poll_wait(filp, &queue_wait, wait);
- 
-@@ -1239,7 +1239,7 @@ static int c_show(struct seq_file *m, void *p)
- 	return cd->cache_show(m, cd, cp);
- }
- 
--static const struct seq_operations cache_content_op = {
-+static struct seq_operations cache_content_op = {
- 	.start	= c_start,
- 	.next	= c_next,
- 	.stop	= c_stop,
-@@ -1269,7 +1269,7 @@ static const struct file_operations content_file_operations = {
- static ssize_t read_flush(struct file *file, char __user *buf,
- 			    size_t count, loff_t *ppos)
- {
--	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
-+	struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data;
- 	char tbuf[20];
- 	unsigned long p = *ppos;
- 	size_t len;
-@@ -1290,7 +1290,7 @@ static ssize_t read_flush(struct file *file, char __user *buf,
- static ssize_t write_flush(struct file * file, const char __user * buf,
- 			     size_t count, loff_t *ppos)
- {
--	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
-+	struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data;
- 	char tbuf[20];
- 	char *ep;
- 	long flushtime;
-diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
-index 76739e9..11bfb52 100644
---- a/net/sunrpc/clnt.c
-+++ b/net/sunrpc/clnt.c
-@@ -213,10 +213,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
- 	}
- 
- 	/* save the nodename */
--	clnt->cl_nodelen = strlen(utsname()->nodename);
-+	clnt->cl_nodelen = strlen(system_utsname.nodename);
- 	if (clnt->cl_nodelen > UNX_MAXNODENAME)
- 		clnt->cl_nodelen = UNX_MAXNODENAME;
--	memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
-+	memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
- 	rpc_register_client(clnt);
- 	return clnt;
- 
-diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
-index 23a2b8f..003a6ec 100644
---- a/net/sunrpc/rpc_pipe.c
-+++ b/net/sunrpc/rpc_pipe.c
-@@ -26,6 +26,7 @@
- #include <linux/sunrpc/clnt.h>
- #include <linux/workqueue.h>
- #include <linux/sunrpc/rpc_pipe_fs.h>
-+#include <linux/path.h>
- 
- static struct vfsmount *rpc_mount __read_mostly;
- static int rpc_mount_count;
-@@ -224,7 +225,7 @@ out:
- static ssize_t
- rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
- {
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	struct rpc_inode *rpci = RPC_I(inode);
- 	struct rpc_pipe_msg *msg;
- 	int res = 0;
-@@ -267,7 +268,7 @@ out_unlock:
- static ssize_t
- rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset)
- {
--	struct inode *inode = filp->f_path.dentry->d_inode;
-+	struct inode *inode = filp->f_dentry->d_inode;
- 	struct rpc_inode *rpci = RPC_I(inode);
- 	int res;
- 
-@@ -285,7 +286,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
- 	struct rpc_inode *rpci;
- 	unsigned int mask = 0;
- 
--	rpci = RPC_I(filp->f_path.dentry->d_inode);
-+	rpci = RPC_I(filp->f_dentry->d_inode);
- 	poll_wait(filp, &rpci->waitq, wait);
- 
- 	mask = POLLOUT | POLLWRNORM;
-@@ -300,7 +301,7 @@ static int
- rpc_pipe_ioctl(struct inode *ino, struct file *filp,
- 		unsigned int cmd, unsigned long arg)
- {
--	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
-+	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
- 	int len;
- 
- 	switch (cmd) {
-@@ -495,7 +496,7 @@ rpc_lookup_parent(char *path, struct nameidata *nd)
- static void
- rpc_release_path(struct nameidata *nd)
- {
--	path_put(&nd->path);
-+	backport_path_put(nd);
- 	rpc_put_mount();
- }
- 
-@@ -668,7 +669,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
- 
- 	if ((error = rpc_lookup_parent(path, nd)) != 0)
- 		return ERR_PTR(error);
--	dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len,
-+	dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len,
- 				   1);
- 	if (IS_ERR(dentry))
- 		rpc_release_path(nd);
-@@ -696,7 +697,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
- 	dentry = rpc_lookup_negative(path, &nd);
- 	if (IS_ERR(dentry))
- 		return dentry;
--	dir = nd.path.dentry->d_inode;
-+	dir = nd.dentry->d_inode;
- 	if ((error = __rpc_mkdir(dir, dentry)) != 0)
- 		goto err_dput;
- 	RPC_I(dentry->d_inode)->private = rpc_client;
-@@ -897,7 +898,7 @@ static struct file_system_type rpc_pipe_fs_type = {
- };
- 
- static void
--init_once(void *foo)
-+init_once(void *foo, struct kmem_cache *cachep, unsigned long temp)
- {
- 	struct rpc_inode *rpci = (struct rpc_inode *) foo;
- 
-diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
-index 24db2b4..6f9e46c 100644
---- a/net/sunrpc/rpcb_clnt.c
-+++ b/net/sunrpc/rpcb_clnt.c
-@@ -117,18 +117,6 @@ static void rpcb_map_release(void *data)
- 	kfree(map);
- }
- 
--static const struct sockaddr_in rpcb_inaddr_loopback = {
--	.sin_family		= AF_INET,
--	.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
--	.sin_port		= htons(RPCBIND_PORT),
--};
--
--static const struct sockaddr_in6 rpcb_in6addr_loopback = {
--	.sin6_family		= AF_INET6,
--	.sin6_addr		= IN6ADDR_LOOPBACK_INIT,
--	.sin6_port		= htons(RPCBIND_PORT),
--};
--
- static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
- 					  size_t addrlen, u32 version)
- {
-@@ -249,6 +237,12 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
- 		.rpc_resp	= okay,
- 	};
- 
-+	struct sockaddr_in rpcb_inaddr_loopback = {
-+		.sin_family		= AF_INET,
-+		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
-+		.sin_port		= htons(RPCBIND_PORT),
-+	};
-+
- 	dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
- 			"rpcbind\n", (port ? "" : "un"),
- 			prog, vers, prot, port);
-@@ -272,6 +266,12 @@ static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
- 	unsigned short port = ntohs(address_to_register->sin_port);
- 	char buf[32];
- 
-+	struct sockaddr_in rpcb_inaddr_loopback = {
-+		.sin_family		= AF_INET,
-+		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
-+		.sin_port		= htons(RPCBIND_PORT),
-+	};
-+
- 	/* Construct AF_INET universal address */
- 	snprintf(buf, sizeof(buf),
- 			NIPQUAD_FMT".%u.%u",
-@@ -303,6 +303,12 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
- 	unsigned short port = ntohs(address_to_register->sin6_port);
- 	char buf[64];
- 
-+	struct sockaddr_in6 rpcb_in6addr_loopback = {
-+		.sin6_family		= AF_INET6,
-+		.sin6_addr		= IN6ADDR_LOOPBACK_INIT,
-+		.sin6_port		= htons(RPCBIND_PORT),
-+	};
-+
- 	/* Construct AF_INET6 universal address */
- 	snprintf(buf, sizeof(buf),
- 			NIP6_FMT".%u.%u",
-diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
-index 50b049c..5053a5f 100644
---- a/net/sunrpc/stats.c
-+++ b/net/sunrpc/stats.c
-@@ -264,7 +264,7 @@ rpc_proc_init(void)
- 	dprintk("RPC:       registering /proc/net/rpc\n");
- 	if (!proc_net_rpc) {
- 		struct proc_dir_entry *ent;
--		ent = proc_mkdir("rpc", init_net.proc_net);
-+		ent = proc_mkdir("rpc", proc_net);
- 		if (ent) {
- 			ent->owner = THIS_MODULE;
- 			proc_net_rpc = ent;
-@@ -278,7 +278,7 @@ rpc_proc_exit(void)
- 	dprintk("RPC:       unregistering /proc/net/rpc\n");
- 	if (proc_net_rpc) {
- 		proc_net_rpc = NULL;
--		remove_proc_entry("rpc", init_net.proc_net);
-+		remove_proc_entry("rpc", proc_net);
- 	}
- }
- 
-diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
-index 5a32cb7..e0e87c6 100644
---- a/net/sunrpc/svc.c
-+++ b/net/sunrpc/svc.c
-@@ -174,7 +174,7 @@ fail:
- static int
- svc_pool_map_init_percpu(struct svc_pool_map *m)
- {
--	unsigned int maxpools = nr_cpu_ids;
-+	unsigned int maxpools = highest_possible_processor_id() + 1;
- 	unsigned int pidx = 0;
- 	unsigned int cpu;
- 	int err;
-@@ -202,7 +202,7 @@ svc_pool_map_init_percpu(struct svc_pool_map *m)
- static int
- svc_pool_map_init_pernode(struct svc_pool_map *m)
- {
--	unsigned int maxpools = nr_node_ids;
-+	unsigned int maxpools = highest_possible_processor_id() + 1;
- 	unsigned int pidx = 0;
- 	unsigned int node;
- 	int err;
-@@ -310,13 +310,12 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx)
- 	switch (m->mode) {
- 	case SVC_POOL_PERCPU:
- 	{
--		set_cpus_allowed_ptr(task, &cpumask_of_cpu(node));
-+		set_cpus_allowed(task, cpumask_of_cpu(node));
- 		break;
- 	}
- 	case SVC_POOL_PERNODE:
- 	{
--		node_to_cpumask_ptr(nodecpumask, node);
--		set_cpus_allowed_ptr(task, nodecpumask);
-+		set_cpus_allowed(task, node_to_cpumask(node));
- 		break;
- 	}
- 	}
-@@ -831,7 +830,7 @@ svc_process(struct svc_rqst *rqstp)
- 	rqstp->rq_res.tail[0].iov_base = NULL;
- 	rqstp->rq_res.tail[0].iov_len = 0;
- 	/* Will be turned off only in gss privacy case: */
--	rqstp->rq_splice_ok = 1;
-+	rqstp->rq_sendfile_ok = 1;
- 
- 	/* Setup reply header */
- 	rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
-diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
-index f24800f..b30d725 100644
---- a/net/sunrpc/svcauth_unix.c
-+++ b/net/sunrpc/svcauth_unix.c
-@@ -678,7 +678,7 @@ int
- svcauth_unix_set_client(struct svc_rqst *rqstp)
- {
- 	struct sockaddr_in *sin;
--	struct sockaddr_in6 *sin6, sin6_storage;
-+	struct sockaddr_in6 *sin6 = NULL, sin6_storage;
- 	struct ip_map *ipm;
- 
- 	switch (rqstp->rq_addr.ss_family) {
-diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
-index 3e65719..cbb47a6 100644
---- a/net/sunrpc/svcsock.c
-+++ b/net/sunrpc/svcsock.c
-@@ -472,12 +472,16 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
- 	if (len < 0)
- 		return len;
- 	rqstp->rq_addrlen = len;
--	if (skb->tstamp.tv64 == 0) {
--		skb->tstamp = ktime_get_real();
-+	if (skb->tstamp.off_sec == 0) {
-+		struct timeval tv;
-+
-+		tv.tv_sec = xtime.tv_sec;
-+		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
-+		skb_set_timestamp(skb, &tv);
- 		/* Don't enable netstamp, sunrpc doesn't
- 		   need that much accuracy */
- 	}
--	svsk->sk_sk->sk_stamp = skb->tstamp;
-+	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
- 	set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
- 
- 	/*
-diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
-index 5231f7a..1482e34 100644
---- a/net/sunrpc/sysctl.c
-+++ b/net/sunrpc/sysctl.c
-@@ -135,6 +135,7 @@ done:
- 
- static ctl_table debug_table[] = {
- 	{
-+		.ctl_name	= CTL_RPCDEBUG, 
- 		.procname	= "rpc_debug",
- 		.data		= &rpc_debug,
- 		.maxlen		= sizeof(int),
-@@ -142,6 +143,7 @@ static ctl_table debug_table[] = {
- 		.proc_handler	= &proc_dodebug
- 	},
- 	{
-+		.ctl_name	= CTL_NFSDEBUG,
- 		.procname	= "nfs_debug",
- 		.data		= &nfs_debug,
- 		.maxlen		= sizeof(int),
-@@ -149,6 +151,7 @@ static ctl_table debug_table[] = {
- 		.proc_handler	= &proc_dodebug
- 	},
- 	{
-+		.ctl_name	= CTL_NFSDDEBUG,
- 		.procname	= "nfsd_debug",
- 		.data		= &nfsd_debug,
- 		.maxlen		= sizeof(int),
-@@ -156,6 +159,7 @@ static ctl_table debug_table[] = {
- 		.proc_handler	= &proc_dodebug
- 	},
- 	{
-+		.ctl_name	= CTL_NLMDEBUG,
- 		.procname	= "nlm_debug",
- 		.data		= &nlm_debug,
- 		.maxlen		= sizeof(int),
-@@ -163,6 +167,7 @@ static ctl_table debug_table[] = {
- 		.proc_handler	= &proc_dodebug
- 	},
- 	{
-+		.ctl_name	= CTL_TRANSPORT,
- 		.procname	= "transports",
- 		.maxlen		= 256,
- 		.mode		= 0444,
-diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
-index 6fb493c..761ad29 100644
---- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
-+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
-@@ -247,10 +247,6 @@ static void rq_comp_handler(struct ib_cq *cq, void *cq_context)
- 	struct svcxprt_rdma *xprt = cq_context;
- 	unsigned long flags;
- 
--	/* Guard against unconditional flush call for destroyed QP */
--	if (atomic_read(&xprt->sc_xprt.xpt_ref.refcount)==0)
--		return;
--
- 	/*
- 	 * Set the bit regardless of whether or not it's on the list
- 	 * because it may be on the list already due to an SQ
-@@ -411,10 +407,6 @@ static void sq_comp_handler(struct ib_cq *cq, void *cq_context)
- 	struct svcxprt_rdma *xprt = cq_context;
- 	unsigned long flags;
- 
--	/* Guard against unconditional flush call for destroyed QP */
--	if (atomic_read(&xprt->sc_xprt.xpt_ref.refcount)==0)
--		return;
--
- 	/*
- 	 * Set the bit regardless of whether or not it's on the list
- 	 * because it may be on the list already due to an RQ
-@@ -1116,9 +1108,6 @@ static void __svc_rdma_free(struct work_struct *work)
- 		container_of(work, struct svcxprt_rdma, sc_work);
- 	dprintk("svcrdma: svc_rdma_free(%p)\n", rdma);
- 
--	/* We should only be called from kref_put */
--	BUG_ON(atomic_read(&rdma->sc_xprt.xpt_ref.refcount) != 0);
--
- 	/*
- 	 * Destroy queued, but not processed read completions. Note
- 	 * that this cleanup has to be done before destroying the
-diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
-index 8710117..ce94fa4 100644
---- a/net/sunrpc/xprtrdma/svc_rdma.c
-+++ b/net/sunrpc/xprtrdma/svc_rdma.c
-@@ -116,6 +116,7 @@ static int read_reset_stat(ctl_table *table, int write,
- static struct ctl_table_header *svcrdma_table_header;
- static ctl_table svcrdma_parm_table[] = {
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "max_requests",
- 		.data		= &svcrdma_max_requests,
- 		.maxlen		= sizeof(unsigned int),
-@@ -126,6 +127,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.extra2		= &max_max_requests
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "max_req_size",
- 		.data		= &svcrdma_max_req_size,
- 		.maxlen		= sizeof(unsigned int),
-@@ -136,6 +138,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.extra2		= &max_max_inline
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "max_outbound_read_requests",
- 		.data		= &svcrdma_ord,
- 		.maxlen		= sizeof(unsigned int),
-@@ -147,6 +150,7 @@ static ctl_table svcrdma_parm_table[] = {
- 	},
- 
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_read",
- 		.data		= &rdma_stat_read,
- 		.maxlen		= sizeof(atomic_t),
-@@ -154,6 +158,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_recv",
- 		.data		= &rdma_stat_recv,
- 		.maxlen		= sizeof(atomic_t),
-@@ -161,6 +166,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_write",
- 		.data		= &rdma_stat_write,
- 		.maxlen		= sizeof(atomic_t),
-@@ -168,6 +174,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_sq_starve",
- 		.data		= &rdma_stat_sq_starve,
- 		.maxlen		= sizeof(atomic_t),
-@@ -175,6 +182,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_rq_starve",
- 		.data		= &rdma_stat_rq_starve,
- 		.maxlen		= sizeof(atomic_t),
-@@ -182,6 +190,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_rq_poll",
- 		.data		= &rdma_stat_rq_poll,
- 		.maxlen		= sizeof(atomic_t),
-@@ -189,6 +198,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_rq_prod",
- 		.data		= &rdma_stat_rq_prod,
- 		.maxlen		= sizeof(atomic_t),
-@@ -196,6 +206,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_sq_poll",
- 		.data		= &rdma_stat_sq_poll,
- 		.maxlen		= sizeof(atomic_t),
-@@ -203,6 +214,7 @@ static ctl_table svcrdma_parm_table[] = {
- 		.proc_handler	= &read_reset_stat,
- 	},
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "rdma_stat_sq_prod",
- 		.data		= &rdma_stat_sq_prod,
- 		.maxlen		= sizeof(atomic_t),
-@@ -216,6 +228,7 @@ static ctl_table svcrdma_parm_table[] = {
- 
- static ctl_table svcrdma_table[] = {
- 	{
-+		.ctl_name	= CTL_UNNUMBERED,
- 		.procname	= "svc_rdma",
- 		.mode		= 0555,
- 		.child		= svcrdma_parm_table
diff --git a/kernel_patches/backport/2.6.18-EL5.1/sdp_0080_revert_to_2_6_28.patch b/kernel_patches/backport/2.6.18-EL5.1/sdp_0080_revert_to_2_6_28.patch
deleted file mode 100644
index 59385b0..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/sdp_0080_revert_to_2_6_28.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-diff --git a/drivers/infiniband/ulp/sdp/sdp_main.c b/drivers/infiniband/ulp/sdp/sdp_main.c
-index 7a38c47..51801e0 100644
---- a/drivers/infiniband/ulp/sdp/sdp_main.c
-+++ b/drivers/infiniband/ulp/sdp/sdp_main.c
-@@ -580,7 +580,7 @@ adjudge_to_death:
- 		/* TODO: tcp_fin_time to get timeout */
- 		sdp_dbg(sk, "%s: entering time wait refcnt %d\n", __func__,
- 			atomic_read(&sk->sk_refcnt));
--		percpu_counter_inc(sk->sk_prot->orphan_count);
-+		atomic_inc(sk->sk_prot->orphan_count);
- 	}
- 
- 	/* TODO: limit number of orphaned sockets.
-@@ -861,7 +861,7 @@ void sdp_cancel_dreq_wait_timeout(struct sdp_sock *ssk)
- 		sock_put(&ssk->isk.sk, SOCK_REF_DREQ_TO);
- 	}
- 
--	percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
-+	atomic_dec(ssk->isk.sk.sk_prot->orphan_count);
- }
- 
- void sdp_destroy_work(struct work_struct *work)
-@@ -902,7 +902,7 @@ void sdp_dreq_wait_timeout_work(struct work_struct *work)
- 	sdp_sk(sk)->dreq_wait_timeout = 0;
- 
- 	if (sk->sk_state == TCP_FIN_WAIT1)
--		percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
-+		atomic_dec(ssk->isk.sk.sk_prot->orphan_count);
- 
- 	sdp_exch_state(sk, TCPF_LAST_ACK | TCPF_FIN_WAIT1, TCP_TIME_WAIT);
- 
-@@ -2162,9 +2162,9 @@ void sdp_urg(struct sdp_sock *ssk, struct sk_buff *skb)
- 		sk->sk_data_ready(sk, 0);
- }
- 
--static struct percpu_counter *sockets_allocated;
-+static atomic_t sockets_allocated;
- static atomic_t memory_allocated;
--static struct percpu_counter *orphan_count;
-+static atomic_t orphan_count;
- static int memory_pressure;
- struct proto sdp_proto = {
-         .close       = sdp_close,
-@@ -2182,8 +2182,10 @@ struct proto sdp_proto = {
-         .get_port    = sdp_get_port,
- 	/* Wish we had this: .listen   = sdp_listen */
- 	.enter_memory_pressure = sdp_enter_memory_pressure,
-+	.sockets_allocated = &sockets_allocated,
- 	.memory_allocated = &memory_allocated,
- 	.memory_pressure = &memory_pressure,
-+	.orphan_count = &orphan_count,
-         .sysctl_mem             = sysctl_tcp_mem,
-         .sysctl_wmem            = sysctl_tcp_wmem,
-         .sysctl_rmem            = sysctl_tcp_rmem,
-@@ -2538,15 +2540,6 @@ static int __init sdp_init(void)
- 	spin_lock_init(&sock_list_lock);
- 	spin_lock_init(&sdp_large_sockets_lock);
- 
--	sockets_allocated = kmalloc(sizeof(*sockets_allocated), GFP_KERNEL);
--	orphan_count = kmalloc(sizeof(*orphan_count), GFP_KERNEL);
--	percpu_counter_init(sockets_allocated, 0);
--	percpu_counter_init(orphan_count, 0);
--
--	sdp_proto.sockets_allocated = sockets_allocated;
--	sdp_proto.orphan_count = orphan_count;
--
--
- 	sdp_workqueue = create_singlethread_workqueue("sdp");
- 	if (!sdp_workqueue) {
- 		return -ENOMEM;
-@@ -2581,9 +2574,9 @@ static void __exit sdp_exit(void)
- 	sock_unregister(PF_INET_SDP);
- 	proto_unregister(&sdp_proto);
- 
--	if (percpu_counter_read_positive(orphan_count))
--		printk(KERN_WARNING "%s: orphan_count %lld\n", __func__,
--		       percpu_counter_read_positive(orphan_count));
-+	if (atomic_read(&orphan_count))
-+		printk(KERN_WARNING "%s: orphan_count %d\n", __func__,
-+		       atomic_read(&orphan_count));
- 	destroy_workqueue(sdp_workqueue);
- 	flush_scheduled_work();
- 
-@@ -2596,8 +2589,6 @@ static void __exit sdp_exit(void)
- 	sdp_proc_unregister();
- 
- 	ib_unregister_client(&sdp_client);
--	kfree(orphan_count);
--	kfree(sockets_allocated);
- }
- 
- module_init(sdp_init);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/sdp_0090_revert_to_2_6_24.patch b/kernel_patches/backport/2.6.18-EL5.1/sdp_0090_revert_to_2_6_24.patch
deleted file mode 100644
index 893db9b..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/sdp_0090_revert_to_2_6_24.patch
+++ /dev/null
@@ -1,242 +0,0 @@
----
- drivers/infiniband/ulp/sdp/sdp.h       |   26 --------------------------
- drivers/infiniband/ulp/sdp/sdp_bcopy.c |   24 ++++++++++++------------
- drivers/infiniband/ulp/sdp/sdp_cma.c   |    2 --
- drivers/infiniband/ulp/sdp/sdp_main.c  |   19 +++++++++----------
- 4 files changed, 21 insertions(+), 50 deletions(-)
-
-Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp.h
-===================================================================
---- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp.h
-+++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp.h
-@@ -317,30 +317,4 @@
- void sdp_start_keepalive_timer(struct sock *sk);
- void sdp_bzcopy_write_space(struct sdp_sock *ssk);
- 
--static inline struct sk_buff *sdp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
--{
--	struct sk_buff *skb;
--
--	/* The TCP header must be at least 32-bit aligned.  */
--	size = ALIGN(size, 4);
--
--	skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
--	if (skb) {
--		if (sk_wmem_schedule(sk, skb->truesize)) {
--			/*
--			 * Make sure that we have exactly size bytes
--			 * available to the caller, no more, no less.
--			 */
--			skb_reserve(skb, skb_tailroom(skb) - size);
--			return skb;
--		}
--		__kfree_skb(skb);
--	} else {
--		sk->sk_prot->enter_memory_pressure(sk);
--		sk_stream_moderate_sndbuf(sk);
--	}
--	return NULL;
--}
--
--
- #endif
-Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_bcopy.c
-===================================================================
---- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_bcopy.c
-+++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_bcopy.c
-@@ -139,7 +139,7 @@
- 	}
- 
- 
--	sk_mem_reclaim(sk);
-+	sk_stream_mem_reclaim(sk);
- 
- 	if (!sock_flag(sk, SOCK_DEAD)) {
- 		sk->sk_state_change(sk);
-@@ -190,7 +190,7 @@
- 	struct ib_send_wr *bad_wr;
- 
- 	h->mid = mid;
--	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG))
-+	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_URG))
- 		h->flags = SDP_OOB_PRES | SDP_OOB_PEND;
- 	else
- 		h->flags = 0;
-@@ -234,7 +234,7 @@
- 	ssk->tx_wr.num_sge = frags + 1;
- 	ssk->tx_wr.opcode = IB_WR_SEND;
- 	ssk->tx_wr.send_flags = IB_SEND_SIGNALED;
--	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG))
-+	if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_URG))
- 		ssk->tx_wr.send_flags |= IB_SEND_SOLICITED;
- 	rc = ib_post_send(ssk->qp, &ssk->tx_wr, &bad_wr);
- 	++ssk->tx_head;
-@@ -304,11 +304,11 @@
- 	/* TODO: allocate from cache */
- 
- 	if (unlikely(ssk->isk.sk.sk_allocation)) {
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
- 					  ssk->isk.sk.sk_allocation);
- 		gfp_page = ssk->isk.sk.sk_allocation | __GFP_HIGHMEM;
- 	} else {
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk, SDP_HEAD_SIZE,
- 					  GFP_KERNEL);
- 		gfp_page = GFP_HIGHUSER;
- 	}
-@@ -476,7 +476,7 @@
- 	if (likely(ssk->bufs > 1) &&
- 	    likely(ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE)) {
- 		struct sk_buff *skb;
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk,
- 					  sizeof(struct sdp_bsdh),
- 					  GFP_KERNEL);
- 		if (!skb)
-@@ -514,7 +514,7 @@
- 	    ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE) {
- 		struct sdp_chrecvbuf *resp_size;
- 		ssk->recv_request = 0;
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk,
- 					  sizeof(struct sdp_bsdh) +
- 					  sizeof(*resp_size),
- 					  gfp_page);
-@@ -539,7 +539,7 @@
- 	    ssk->tx_head > ssk->sent_request_head + SDP_RESIZE_WAIT &&
- 	    ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE) {
- 		struct sdp_chrecvbuf *req_size;
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk,
- 					  sizeof(struct sdp_bsdh) +
- 					  sizeof(*req_size),
- 					  gfp_page);
-@@ -561,7 +561,7 @@
- 	    likely(ssk->tx_head - ssk->tx_tail < SDP_TX_SIZE) &&
- 	    likely((1 << ssk->isk.sk.sk_state) &
- 		    (TCPF_ESTABLISHED | TCPF_FIN_WAIT1))) {
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk,
- 					  sizeof(struct sdp_bsdh),
- 					  GFP_KERNEL);
- 		/* FIXME */
-@@ -573,7 +573,7 @@
- 		!ssk->isk.sk.sk_send_head &&
- 		ssk->bufs > (ssk->remote_credits >= ssk->rx_head - ssk->rx_tail)) {
- 		ssk->sdp_disconnect = 0;
--		skb = sdp_stream_alloc_skb(&ssk->isk.sk,
-+		skb = sk_stream_alloc_skb(&ssk->isk.sk,
- 					  sizeof(struct sdp_bsdh),
- 					  gfp_page);
- 		/* FIXME */
-@@ -778,7 +778,7 @@
- 	}
- 
- out:
--	sk_wmem_free_skb(&ssk->isk.sk, skb);
-+	sk_stream_free_skb(&ssk->isk.sk, skb);
- 
- 	return 0;
- }
-@@ -864,7 +864,7 @@
- 
- 	sdp_poll_cq(ssk, cq);
- 	release_sock(sk);
--	sk_mem_reclaim(sk);
-+	sk_stream_mem_reclaim(sk);
- 	lock_sock(sk);
- 	cq = ssk->cq;
- 	if (unlikely(!cq))
-Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_cma.c
-===================================================================
---- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_cma.c
-+++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_cma.c
-@@ -161,8 +161,6 @@
- 		goto err_cq;
- 	}
- 
--	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
--
-         qp_init_attr.send_cq = qp_init_attr.recv_cq = cq;
- 
- 	rc = rdma_create_qp(id, pd, &qp_init_attr);
-Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
-===================================================================
---- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_main.c
-+++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
-@@ -509,7 +509,7 @@
- 		__kfree_skb(skb);
- 	}
- 
--	sk_mem_reclaim(sk);
-+	sk_stream_mem_reclaim(sk);
- 
- 	/* As outlined in draft-ietf-tcpimpl-prob-03.txt, section
- 	 * 3.10, we send a RST here because data was lost.  To
-@@ -1200,7 +1200,7 @@
- {
- 	if (unlikely(flags & MSG_OOB)) {
- 		struct sk_buff *skb = sk->sk_write_queue.prev;
--		TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_URG;
-+		TCP_SKB_CB(skb)->flags |= TCPCB_URG;
- 	}
- }
- 
-@@ -1217,8 +1217,7 @@
- {
-         skb_header_release(skb);
-         __skb_queue_tail(&sk->sk_write_queue, skb);
--	sk->sk_wmem_queued += skb->truesize;
--        sk_mem_charge(sk, skb->truesize);
-+	sk_charge_skb(sk, skb);
-         if (!sk->sk_send_head)
-                 sk->sk_send_head = skb;
-         if (ssk->nonagle & TCP_NAGLE_PUSH)
-@@ -1382,7 +1381,7 @@
- 		if (copy > PAGE_SIZE - off)
- 			copy = PAGE_SIZE - off;
- 
--		if (!sk_wmem_schedule(sk, copy))
-+		if (!sk_stream_wmem_schedule(sk, copy))
- 			return SDP_DO_WAIT_MEM;
- 
- 		if (!page) {
-@@ -1454,7 +1453,7 @@
- 		if (left <= this_page)
- 			this_page = left;
- 
--		if (!sk_wmem_schedule(sk, copy))
-+		if (!sk_stream_wmem_schedule(sk, copy))
- 			return SDP_DO_WAIT_MEM;
- 
- 		skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
-@@ -1662,8 +1661,8 @@
- 						goto wait_for_sndbuf;
- 				}
- 
--				skb = sdp_stream_alloc_skb(sk, select_size(sk, ssk),
--							   sk->sk_allocation);
-+				skb = sk_stream_alloc_pskb(sk, select_size(sk, ssk),
-+							   0, sk->sk_allocation);
- 				if (!skb)
- 					goto wait_for_memory;
- 
-@@ -1687,7 +1686,7 @@
- 
- 			/* OOB data byte should be the last byte of
- 			   the data payload */
--			if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG) &&
-+			if (unlikely(TCP_SKB_CB(skb)->flags & TCPCB_URG) &&
- 			    !(flags & MSG_OOB)) {
- 				sdp_mark_push(ssk, skb);
- 				goto new_segment;
-@@ -1763,7 +1762,7 @@
- 		if (sk->sk_send_head == skb)
- 			sk->sk_send_head = NULL;
- 		__skb_unlink(skb, &sk->sk_write_queue);
--		sk_wmem_free_skb(sk, skb);
-+		sk_stream_free_skb(sk, skb);
- 	}
- 
- do_error:
diff --git a/kernel_patches/backport/2.6.18-EL5.1/sdp_0100_revert_to_2_6_23.patch b/kernel_patches/backport/2.6.18-EL5.1/sdp_0100_revert_to_2_6_23.patch
deleted file mode 100644
index 0d22e37..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/sdp_0100_revert_to_2_6_23.patch
+++ /dev/null
@@ -1,54 +0,0 @@
----
- drivers/infiniband/ulp/sdp/sdp_main.c |   12 ++++--------
- 1 file changed, 4 insertions(+), 8 deletions(-)
-
-Index: ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
-===================================================================
---- ofed_1_4.orig/drivers/infiniband/ulp/sdp/sdp_main.c
-+++ ofed_1_4/drivers/infiniband/ulp/sdp/sdp_main.c
-@@ -2158,16 +2158,13 @@
- 	.sendpage   = sock_no_sendpage,
- };
- 
--static int sdp_create_socket(struct net *net, struct socket *sock, int protocol)
-+static int sdp_create_socket(struct socket *sock, int protocol)
- {
- 	struct sock *sk;
- 	int rc;
- 
- 	sdp_dbg(NULL, "%s: type %d protocol %d\n", __func__, sock->type, protocol);
- 
--	if (net != &init_net)
--		return -EAFNOSUPPORT;
--
- 	if (sock->type != SOCK_STREAM) {
- 		sdp_warn(NULL, "SDP: unsupported type %d.\n", sock->type);
- 		return -ESOCKTNOSUPPORT;
-@@ -2179,7 +2176,7 @@
- 		return -EPROTONOSUPPORT;
- 	}
- 
--	sk = sk_alloc(net, PF_INET_SDP, GFP_KERNEL, &sdp_proto);
-+	sk = sk_alloc(PF_INET_SDP, GFP_KERNEL, &sdp_proto, 1);
- 	if (!sk) {
- 		sdp_warn(NULL, "SDP: failed to allocate socket.\n");
- 		return -ENOMEM;
-@@ -2363,8 +2360,7 @@
- 	sdp_seq_afinfo.seq_fops->llseek        = seq_lseek;
- 	sdp_seq_afinfo.seq_fops->release       = seq_release_private;
- 
--	p = proc_net_fops_create(&init_net, sdp_seq_afinfo.name, S_IRUGO,
--				 sdp_seq_afinfo.seq_fops);
-+ 	p = proc_net_fops_create(sdp_seq_afinfo.name, S_IRUGO, sdp_seq_afinfo.seq_fops);
- 	if (p)
- 		p->data = &sdp_seq_afinfo;
- 	else
-@@ -2375,7 +2371,7 @@
- 
- static void sdp_proc_unregister(void)
- {
--	proc_net_remove(&init_net, sdp_seq_afinfo.name);
-+	proc_net_remove(sdp_seq_afinfo.name);
- 	memset(sdp_seq_afinfo.seq_fops, 0, sizeof(*sdp_seq_afinfo.seq_fops));
- }
- 
diff --git a/kernel_patches/backport/2.6.18-EL5.1/sdp_0120_revert_2_6_27_to_2_6_24.patch b/kernel_patches/backport/2.6.18-EL5.1/sdp_0120_revert_2_6_27_to_2_6_24.patch
deleted file mode 100644
index bc538c3..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/sdp_0120_revert_2_6_27_to_2_6_24.patch
+++ /dev/null
@@ -1,51 +0,0 @@
----
- drivers/infiniband/ulp/sdp/sdp_cma.c  |    1 +
- drivers/infiniband/ulp/sdp/sdp_main.c |    8 ++++----
- 2 files changed, 5 insertions(+), 4 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/sdp/sdp_cma.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/sdp/sdp_cma.c
-+++ ofed_kernel/drivers/infiniband/ulp/sdp/sdp_cma.c
-@@ -31,6 +31,7 @@
-  *
-  * $Id$
-  */
-+#include <asm/semaphore.h>
- #include <linux/device.h>
- #include <linux/in.h>
- #include <linux/err.h>
-Index: ofed_kernel/drivers/infiniband/ulp/sdp/sdp_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/sdp/sdp_main.c
-+++ ofed_kernel/drivers/infiniband/ulp/sdp/sdp_main.c
-@@ -523,7 +523,7 @@ static void sdp_close(struct sock *sk, l
- 	if (data_was_unread ||
- 		(sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) {
- 		/* Unread data was tossed, zap the connection. */
--		NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
-+		NET_INC_STATS_USER(LINUX_MIB_TCPABORTONCLOSE);
- 		sdp_exch_state(sk, TCPF_CLOSE_WAIT | TCPF_ESTABLISHED,
- 			       TCP_TIME_WAIT);
- 
-@@ -1845,7 +1845,7 @@ static int sdp_recvmsg(struct kiocb *ioc
- 			if (offset < skb->len)
- 				goto found_ok_skb;
- 
--			WARN_ON(!(flags & MSG_PEEK));
-+			BUG_TRAP(flags & MSG_PEEK);
- 			skb = skb->next;
- 		} while (skb != (struct sk_buff *)&sk->sk_receive_queue);
- 
-@@ -2082,9 +2082,9 @@ static unsigned int sdp_poll(struct file
- 	return mask;
- }
- 
--static void sdp_enter_memory_pressure(struct sock *sk)
-+static void sdp_enter_memory_pressure(void)
- {
--	sdp_dbg(sk, "%s\n", __func__);
-+	sdp_dbg(NULL, "%s\n", __func__);
- }
- 
- void sdp_urg(struct sdp_sock *ssk, struct sk_buff *skb)
diff --git a/kernel_patches/backport/2.6.18-EL5.1/srp_0100_revert_role_to_2_6_23.patch b/kernel_patches/backport/2.6.18-EL5.1/srp_0100_revert_role_to_2_6_23.patch
deleted file mode 100644
index 6e18ae8..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/srp_0100_revert_role_to_2_6_23.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-commit aebd5e476ecc8ceb53577b20f2a352ff4ceffd8d
-Author: FUJITA Tomonori <tomof at acm.org>
-Date:   Wed Jul 11 15:08:15 2007 +0900
-
-    [SCSI] transport_srp: add rport roles attribute
-    
-    This adds a 'roles' attribute to rport like transport_fc. The role can
-    be initiator or target. That is, the initiator driver creates target
-    remote ports and the target driver creates initiator remote ports.
-    
-    Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
-    Signed-off-by: Mike Christie <michaelc at cs.wisc.edu>
-    Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
-
----
- drivers/infiniband/ulp/srp/ib_srp.c |    1 -
- 1 file changed, 1 deletion(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
-+++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-@@ -1741,7 +1741,6 @@ static int srp_add_target(struct srp_hos
- 
- 	memcpy(ids.port_id, &target->id_ext, 8);
- 	memcpy(ids.port_id + 8, &target->ioc_guid, 8);
--	ids.roles = SRP_RPORT_ROLE_TARGET;
- 	rport = srp_rport_add(target->scsi_host, &ids);
- 	if (IS_ERR(rport)) {
- 		scsi_remove_host(target->scsi_host);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/srp_0200_revert_srp_transport_to_2.6.23.patch b/kernel_patches/backport/2.6.18-EL5.1/srp_0200_revert_srp_transport_to_2.6.23.patch
deleted file mode 100644
index 924dc9c..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/srp_0200_revert_srp_transport_to_2.6.23.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-commit 3236822b1c9b67ad10745d965515b528818f1120
-Author: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
-Date:   Wed Jun 27 16:33:12 2007 +0900
-
-    [SCSI] ib_srp: convert to use the srp transport class
-    
-    This converts ib_srp to use the srp transport class.
-    
-    I don't have ib hardware so I've not tested this patch.
-    
-    Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
-    Cc: Roland Dreier <rolandd at cisco.com>
-    Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
-
----
- drivers/infiniband/ulp/srp/Kconfig  |    1 -
- drivers/infiniband/ulp/srp/ib_srp.c |   28 ----------------------------
- 2 files changed, 29 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/srp/Kconfig
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/Kconfig
-+++ ofed_kernel/drivers/infiniband/ulp/srp/Kconfig
-@@ -1,7 +1,6 @@
- config INFINIBAND_SRP
- 	tristate "InfiniBand SCSI RDMA Protocol"
- 	depends on SCSI
--	select SCSI_SRP_ATTRS
- 	---help---
- 	  Support for the SCSI RDMA Protocol over InfiniBand.  This
- 	  allows you to access storage devices that speak SRP over
-Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
-+++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-@@ -45,7 +45,6 @@
- #include <scsi/scsi_device.h>
- #include <scsi/scsi_dbg.h>
- #include <scsi/srp.h>
--#include <scsi/scsi_transport_srp.h>
- 
- #include "ib_srp.h"
- 
-@@ -90,8 +89,6 @@ static void srp_remove_one(struct ib_dev
- static void srp_completion(struct ib_cq *cq, void *target_ptr);
- static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
- 
--static struct scsi_transport_template *ib_srp_transport_template;
--
- static struct ib_client srp_client = {
- 	.name   = "srp",
- 	.add    = srp_add_one,
-@@ -447,7 +444,6 @@ static void srp_remove_work(struct work_
- 	list_del(&target->list);
- 	spin_unlock(&target->srp_host->target_lock);
- 
--	srp_remove_host(target->scsi_host);
- 	scsi_remove_host(target->scsi_host);
- 	ib_destroy_cm_id(target->cm_id);
- 	srp_free_target_ib(target);
-@@ -1730,23 +1726,12 @@ static struct scsi_host_template srp_tem
- 
- static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
- {
--	struct srp_rport_identifiers ids;
--	struct srp_rport *rport;
--
- 	sprintf(target->target_name, "SRP.T10:%016llX",
- 		 (unsigned long long) be64_to_cpu(target->id_ext));
- 
- 	if (scsi_add_host(target->scsi_host, host->srp_dev->dev->dma_device))
- 		return -ENODEV;
- 
--	memcpy(ids.port_id, &target->id_ext, 8);
--	memcpy(ids.port_id + 8, &target->ioc_guid, 8);
--	rport = srp_rport_add(target->scsi_host, &ids);
--	if (IS_ERR(rport)) {
--		scsi_remove_host(target->scsi_host);
--		return PTR_ERR(rport);
--	}
--
- 	spin_lock(&host->target_lock);
- 	list_add_tail(&target->list, &host->target_list);
- 	spin_unlock(&host->target_lock);
-@@ -1973,7 +1958,6 @@ static ssize_t srp_create_target(struct 
- 	if (!target_host)
- 		return -ENOMEM;
- 
--	target_host->transportt = ib_srp_transport_template;
- 	target_host->max_lun     = SRP_MAX_LUN;
- 	target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
- 
-@@ -2307,7 +2291,6 @@ static void srp_remove_one(struct ib_dev
- 
- 		list_for_each_entry_safe(target, tmp_target,
- 					 &host->target_list, list) {
--			srp_remove_host(target->scsi_host);
- 			scsi_remove_host(target->scsi_host);
- 			srp_disconnect_target(target);
- 			ib_destroy_cm_id(target->cm_id);
-@@ -2326,9 +2309,6 @@ static void srp_remove_one(struct ib_dev
- 	kfree(srp_dev);
- }
- 
--static struct srp_function_template ib_srp_transport_functions = {
--};
--
- static int __init srp_init_module(void)
- {
- 	int ret;
-@@ -2338,11 +2318,6 @@ static int __init srp_init_module(void)
- 		srp_sg_tablesize = 255;
- 	}
- 
--	ib_srp_transport_template =
--		srp_attach_transport(&ib_srp_transport_functions);
--	if (!ib_srp_transport_template)
--		return -ENOMEM;
--
- 	srp_template.sg_tablesize = srp_sg_tablesize;
- 	srp_max_iu_len = (sizeof (struct srp_cmd) +
- 			  sizeof (struct srp_indirect_buf) +
-@@ -2354,7 +2329,6 @@ static int __init srp_init_module(void)
- 	ret = class_register(&srp_class);
- 	if (ret) {
- 		printk(KERN_ERR PFX "couldn't register class infiniband_srp\n");
--		srp_release_transport(ib_srp_transport_template);
- 		return ret;
- 	}
- 
-@@ -2363,7 +2337,6 @@ static int __init srp_init_module(void)
- 	ret = ib_register_client(&srp_client);
- 	if (ret) {
- 		printk(KERN_ERR PFX "couldn't register IB client\n");
--		srp_release_transport(ib_srp_transport_template);
- 		ib_sa_unregister_client(&srp_sa_client);
- 		class_unregister(&srp_class);
- 		return ret;
-@@ -2377,7 +2350,6 @@ static void __exit srp_cleanup_module(vo
- 	ib_unregister_client(&srp_client);
- 	ib_sa_unregister_client(&srp_sa_client);
- 	class_unregister(&srp_class);
--	srp_release_transport(ib_srp_transport_template);
- }
- 
- module_init(srp_init_module);
diff --git a/kernel_patches/backport/2.6.18-EL5.1/srp_class_device_if.patch b/kernel_patches/backport/2.6.18-EL5.1/srp_class_device_if.patch
deleted file mode 100644
index 5634d8e..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/srp_class_device_if.patch
+++ /dev/null
@@ -1,333 +0,0 @@
----
- drivers/infiniband/ulp/srp/ib_srp.c |  154 ++++++++++++++++--------------------
- drivers/infiniband/ulp/srp/ib_srp.h |    2 
- 2 files changed, 72 insertions(+), 84 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
-+++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-@@ -1517,10 +1517,9 @@ static int srp_reset_host(struct scsi_cm
- 	return ret;
- }
- 
--static ssize_t show_id_ext(struct device *dev, struct device_attribute *attr,
--			   char *buf)
-+static ssize_t show_id_ext(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1530,10 +1529,9 @@ static ssize_t show_id_ext(struct device
- 		       (unsigned long long) be64_to_cpu(target->id_ext));
- }
- 
--static ssize_t show_ioc_guid(struct device *dev, struct device_attribute *attr,
--			     char *buf)
-+static ssize_t show_ioc_guid(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1543,10 +1541,9 @@ static ssize_t show_ioc_guid(struct devi
- 		       (unsigned long long) be64_to_cpu(target->ioc_guid));
- }
- 
--static ssize_t show_service_id(struct device *dev,
--			       struct device_attribute *attr, char *buf)
-+static ssize_t show_service_id(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1556,10 +1553,9 @@ static ssize_t show_service_id(struct de
- 		       (unsigned long long) be64_to_cpu(target->service_id));
- }
- 
--static ssize_t show_pkey(struct device *dev, struct device_attribute *attr,
--			 char *buf)
-+static ssize_t show_pkey(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1568,10 +1564,9 @@ static ssize_t show_pkey(struct device *
- 	return sprintf(buf, "0x%04x\n", be16_to_cpu(target->path.pkey));
- }
- 
--static ssize_t show_dgid(struct device *dev, struct device_attribute *attr,
--			 char *buf)
-+static ssize_t show_dgid(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1588,10 +1583,9 @@ static ssize_t show_dgid(struct device *
- 		       be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
- }
- 
--static ssize_t show_orig_dgid(struct device *dev,
--			      struct device_attribute *attr, char *buf)
-+static ssize_t show_orig_dgid(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1608,10 +1602,9 @@ static ssize_t show_orig_dgid(struct dev
- 		       be16_to_cpu(target->orig_dgid[7]));
- }
- 
--static ssize_t show_zero_req_lim(struct device *dev,
--				 struct device_attribute *attr, char *buf)
-+static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	if (target->state == SRP_TARGET_DEAD ||
- 	    target->state == SRP_TARGET_REMOVED)
-@@ -1620,27 +1613,24 @@ static ssize_t show_zero_req_lim(struct 
- 	return sprintf(buf, "%d\n", target->zero_req_lim);
- }
- 
--static ssize_t show_local_ib_port(struct device *dev,
--				  struct device_attribute *attr, char *buf)
-+static ssize_t show_local_ib_port(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	return sprintf(buf, "%d\n", target->srp_host->port);
- }
- 
--static ssize_t show_local_ib_device(struct device *dev,
--				    struct device_attribute *attr, char *buf)
-+static ssize_t show_local_ib_device(struct class_device *cdev, char *buf)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name);
- }
- 
--static ssize_t srp_target_oofabric(struct device *dev,
--				   struct device_attribute *attr, const char *buf,
--				   size_t count)
-+static ssize_t srp_target_oofabric(struct class_device *cdev,
-+ 				   const char *buf, size_t count)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	shost_printk(KERN_DEBUG, target->scsi_host, PFX
- 		     "Get async_event out-of-fabric at state=%d qp_err=%d\n",
-@@ -1657,11 +1647,10 @@ static ssize_t srp_target_oofabric(struc
- 	return count;
- }
- 
--static ssize_t srp_target_infabric(struct device *dev,
--				   struct device_attribute *attr, const char *buf,
--				   size_t count)
-+static ssize_t srp_target_infabric(struct class_device *cdev,
-+ 				   const char *buf, size_t count)
- {
--	struct srp_target_port *target = host_to_target(class_to_shost(dev));
-+ 	struct srp_target_port *target = host_to_target(class_to_shost(cdev));
- 
- 	shost_printk(KERN_DEBUG, target->scsi_host, PFX
- 		     "Get async_event in-fabric at state=%d qp_err=%d\n",
-@@ -1681,30 +1670,30 @@ static ssize_t srp_target_infabric(struc
- 	return count;
- }
- 
--static DEVICE_ATTR(id_ext,	    S_IRUGO, show_id_ext,	   NULL);
--static DEVICE_ATTR(ioc_guid,	    S_IRUGO, show_ioc_guid,	   NULL);
--static DEVICE_ATTR(service_id,	    S_IRUGO, show_service_id,	   NULL);
--static DEVICE_ATTR(pkey,	    S_IRUGO, show_pkey,		   NULL);
--static DEVICE_ATTR(dgid,	    S_IRUGO, show_dgid,		   NULL);
--static DEVICE_ATTR(orig_dgid,	    S_IRUGO, show_orig_dgid,	   NULL);
--static DEVICE_ATTR(zero_req_lim,    S_IRUGO, show_zero_req_lim,	   NULL);
--static DEVICE_ATTR(local_ib_port,   S_IRUGO, show_local_ib_port,   NULL);
--static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
--static DEVICE_ATTR(target_oofabric, S_IWUSR, NULL,  srp_target_oofabric);
--static DEVICE_ATTR(target_infabric, S_IWUSR, NULL,  srp_target_infabric);
--
--static struct device_attribute *srp_host_attrs[] = {
--	&dev_attr_id_ext,
--	&dev_attr_ioc_guid,
--	&dev_attr_service_id,
--	&dev_attr_pkey,
--	&dev_attr_dgid,
--	&dev_attr_orig_dgid,
--	&dev_attr_zero_req_lim,
--	&dev_attr_local_ib_port,
--	&dev_attr_local_ib_device,
--	&dev_attr_target_oofabric,
--	&dev_attr_target_infabric,
-+static CLASS_DEVICE_ATTR(id_ext,	  S_IRUGO, show_id_ext,		 NULL);
-+static CLASS_DEVICE_ATTR(ioc_guid,	  S_IRUGO, show_ioc_guid,	 NULL);
-+static CLASS_DEVICE_ATTR(service_id,	  S_IRUGO, show_service_id,	 NULL);
-+static CLASS_DEVICE_ATTR(pkey,		  S_IRUGO, show_pkey,		 NULL);
-+static CLASS_DEVICE_ATTR(dgid,		  S_IRUGO, show_dgid,		 NULL);
-+static CLASS_DEVICE_ATTR(orig_dgid,	  S_IRUGO, show_orig_dgid,	 NULL);
-+static CLASS_DEVICE_ATTR(zero_req_lim,	  S_IRUGO, show_zero_req_lim,	 NULL);
-+static CLASS_DEVICE_ATTR(local_ib_port,   S_IRUGO, show_local_ib_port,	 NULL);
-+static CLASS_DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
-+static CLASS_DEVICE_ATTR(target_oofabric, S_IWUSR, NULL,  srp_target_oofabric);
-+static CLASS_DEVICE_ATTR(target_infabric, S_IWUSR, NULL,  srp_target_infabric);
-+
-+static struct class_device_attribute *srp_host_attrs[] = {
-+	&class_device_attr_id_ext,
-+	&class_device_attr_ioc_guid,
-+	&class_device_attr_service_id,
-+	&class_device_attr_pkey,
-+	&class_device_attr_dgid,
-+	&class_device_attr_orig_dgid,
-+	&class_device_attr_zero_req_lim,
-+	&class_device_attr_local_ib_port,
-+	&class_device_attr_local_ib_device,
-+ 	&class_device_attr_target_oofabric,
-+ 	&class_device_attr_target_infabric,
- 	NULL
- };
- 
-@@ -1744,17 +1733,17 @@ static int srp_add_target(struct srp_hos
- 	return 0;
- }
- 
--static void srp_release_dev(struct device *dev)
-+static void srp_release_class_dev(struct class_device *class_dev)
- {
- 	struct srp_host *host =
--		container_of(dev, struct srp_host, dev);
-+		container_of(class_dev, struct srp_host, class_dev);
- 
- 	complete(&host->released);
- }
- 
- static struct class srp_class = {
- 	.name    = "infiniband_srp",
--	.dev_release = srp_release_dev
-+	.release = srp_release_class_dev
- };
- 
- /*
-@@ -1942,12 +1931,11 @@ out:
- 	return ret;
- }
- 
--static ssize_t srp_create_target(struct device *dev,
--				 struct device_attribute *attr,
-+static ssize_t srp_create_target(struct class_device *class_dev,
- 				 const char *buf, size_t count)
- {
- 	struct srp_host *host =
--		container_of(dev, struct srp_host, dev);
-+		container_of(class_dev, struct srp_host, class_dev);
- 	struct Scsi_Host *target_host;
- 	struct srp_target_port *target;
- 	int ret;
-@@ -2033,27 +2021,27 @@ err:
- 	return ret;
- }
- 
--static DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);
-+static CLASS_DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);
- 
--static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
--			  char *buf)
-+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
- {
--	struct srp_host *host = container_of(dev, struct srp_host, dev);
-+	struct srp_host *host =
-+		container_of(class_dev, struct srp_host, class_dev);
- 
- 	return sprintf(buf, "%s\n", host->srp_dev->dev->name);
- }
- 
--static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
-+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
- 
--static ssize_t show_port(struct device *dev, struct device_attribute *attr,
--			 char *buf)
-+static ssize_t show_port(struct class_device *class_dev, char *buf)
- {
--	struct srp_host *host = container_of(dev, struct srp_host, dev);
-+	struct srp_host *host =
-+		container_of(class_dev, struct srp_host, class_dev);
- 
- 	return sprintf(buf, "%d\n", host->port);
- }
- 
--static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
-+static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
- 
- static struct srp_host *srp_add_port(struct srp_device *device, u8 port)
- {
-@@ -2069,24 +2057,24 @@ static struct srp_host *srp_add_port(str
- 	host->srp_dev = device;
- 	host->port = port;
- 
--	host->dev.class = &srp_class;
--	host->dev.parent = device->dev->dma_device;
--	snprintf(host->dev.bus_id, BUS_ID_SIZE, "srp-%s-%d",
-+ 	host->class_dev.class = &srp_class;
-+ 	host->class_dev.dev   = device->dev->dma_device;
-+ 	snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",
- 		 device->dev->name, port);
- 
--	if (device_register(&host->dev))
-+ 	if (class_device_register(&host->class_dev))
- 		goto free_host;
--	if (device_create_file(&host->dev, &dev_attr_add_target))
-+ 	if (class_device_create_file(&host->class_dev, &class_device_attr_add_target))
- 		goto err_class;
--	if (device_create_file(&host->dev, &dev_attr_ibdev))
-+ 	if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev))
- 		goto err_class;
--	if (device_create_file(&host->dev, &dev_attr_port))
-+ 	if (class_device_create_file(&host->class_dev, &class_device_attr_port))
- 		goto err_class;
- 
- 	return host;
- 
- err_class:
--	device_unregister(&host->dev);
-+ 	class_device_unregister(&host->class_dev);
- 
- free_host:
- 	kfree(host);
-@@ -2263,7 +2251,7 @@ static void srp_remove_one(struct ib_dev
- 	ib_unregister_event_handler(&srp_dev->event_handler);
- 
- 	list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) {
--		device_unregister(&host->dev);
-+		class_device_unregister(&host->class_dev);
- 		/*
- 		 * Wait for the sysfs entry to go away, so that no new
- 		 * target ports can be created.
-Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.h
-+++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
-@@ -98,7 +98,7 @@ struct srp_device {
- struct srp_host {
- 	struct srp_device      *srp_dev;
- 	u8			port;
--	struct device		dev;
-+	struct class_device	class_dev;
- 	struct list_head	target_list;
- 	spinlock_t		target_lock;
- 	struct completion	released;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/srp_cmd_to_2_6_22.patch b/kernel_patches/backport/2.6.18-EL5.1/srp_cmd_to_2_6_22.patch
deleted file mode 100644
index 7af01c7..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/srp_cmd_to_2_6_22.patch
+++ /dev/null
@@ -1,79 +0,0 @@
----
- drivers/infiniband/ulp/srp/ib_srp.c |   33 +++++++++++++++++++++++++++++----
- drivers/infiniband/ulp/srp/ib_srp.h |    5 +++++
- 2 files changed, 34 insertions(+), 4 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.c
-+++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.c
-@@ -510,6 +510,9 @@ static void srp_unmap_data(struct scsi_c
- 			   struct srp_target_port *target,
- 			   struct srp_request *req)
- {
-+	struct scatterlist *scat;
-+	int nents;
-+
- 	if (!scsi_sglist(scmnd) ||
- 	    (scmnd->sc_data_direction != DMA_TO_DEVICE &&
- 	     scmnd->sc_data_direction != DMA_FROM_DEVICE))
-@@ -520,8 +523,20 @@ static void srp_unmap_data(struct scsi_c
- 		req->fmr = NULL;
- 	}
- 
--	ib_dma_unmap_sg(target->srp_host->srp_dev->dev, scsi_sglist(scmnd),
--			scsi_sg_count(scmnd), scmnd->sc_data_direction);
-+	/*
-+	 * This handling of non-SG commands can be killed when the
-+	 * SCSI midlayer no longer generates non-SG commands.
-+	 */
-+	if (likely(scsi_sg_count(scmnd))) {
-+		nents = scsi_sg_count(scmnd);
-+		scat  = scsi_sglist(scmnd);
-+	} else {
-+		nents = 1;
-+		scat  = &req->fake_sg;
-+	}
-+
-+	ib_dma_unmap_sg(target->srp_host->srp_dev->dev, scat, nents,
-+			scmnd->sc_data_direction);
- }
- 
- static void srp_remove_req(struct srp_target_port *target, struct srp_request *req)
-@@ -721,8 +736,18 @@ static int srp_map_data(struct scsi_cmnd
- 		return -EINVAL;
- 	}
- 
--	nents = scsi_sg_count(scmnd);
--	scat  = scsi_sglist(scmnd);
-+	/*
-+	 * This handling of non-SG commands can be killed when the
-+	 * SCSI midlayer no longer generates non-SG commands.
-+	 */
-+	if (likely(scsi_sg_count(scmnd))) {
-+		nents = scsi_sg_count(scmnd);
-+		scat  = scsi_sglist(scmnd);
-+	} else {
-+		nents = 1;
-+		scat  = &req->fake_sg;
-+		sg_init_one(scat, scmnd->request_buffer, scmnd->request_bufflen);
-+	}
- 
- 	dev = target->srp_host->srp_dev;
- 	ibdev = dev->dev;
-Index: ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srp/ib_srp.h
-+++ ofed_kernel/drivers/infiniband/ulp/srp/ib_srp.h
-@@ -111,6 +111,11 @@ struct srp_request {
- 	struct srp_iu	       *cmd;
- 	struct srp_iu	       *tsk_mgmt;
- 	struct ib_pool_fmr     *fmr;
-+	/*
-+	 * Fake scatterlist used when scsi_sg_count(scmnd)==0.  Can be killed
-+	 * when the SCSI midlayer no longer generates non-SG commands.
-+	 */
-+	struct scatterlist	fake_sg;
- 	struct completion	done;
- 	short			index;
- 	u8			cmd_done;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/srpt_class_dev.patch b/kernel_patches/backport/2.6.18-EL5.1/srpt_class_dev.patch
deleted file mode 100644
index c6187cf..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/srpt_class_dev.patch
+++ /dev/null
@@ -1,121 +0,0 @@
----
- drivers/infiniband/ulp/srpt/ib_srpt.c |   42 ++++++++++++++++------------------
- drivers/infiniband/ulp/srpt/ib_srpt.h |    2 -
- 2 files changed, 21 insertions(+), 23 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srpt/ib_srpt.c
-+++ ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.c
-@@ -2297,20 +2297,19 @@ struct scst_tgt_template srpt_template =
- 	.task_mgmt_fn_done = srpt_tsk_mgmt_done
- };
- 
--static void srpt_release_class_dev(struct device *dev)
-+static void srpt_release_class_dev(struct class_device *class_dev)
- {
- }
- 
- static struct class srpt_class = {
- 	.name = "infiniband_srpt",
--	.dev_release = srpt_release_class_dev
-+	.release = srpt_release_class_dev
- };
- 
--static ssize_t show_login_info(struct device *dev,
--			       struct device_attribute *attr, char *buf)
-+static ssize_t show_login_info(struct class_device *class_dev, char *buf)
- {
- 	struct srpt_device *sdev =
--		container_of(dev, struct srpt_device, dev);
-+		container_of(class_dev, struct srpt_device, class_dev);
- 	struct srpt_port *sport;
- 	int i;
- 	int len = 0;
-@@ -2338,16 +2337,15 @@ static ssize_t show_login_info(struct de
- 	return len;
- }
- 
--static DEVICE_ATTR(login_info, S_IRUGO, show_login_info, NULL);
-+static CLASS_DEVICE_ATTR(login_info, S_IRUGO, show_login_info, NULL);
- 
--static ssize_t show_mem_info(struct device *dev, struct device_attribute *attr,
--			     char *buf)
-+static ssize_t show_mem_info(struct class_device *class_dev, char *buf)
- {
- 	return sprintf(buf, "mem_avail= %d mem_elements= %d mem_size= %d\n",
- 		       mem_avail, mem_elements, mem_size);
- }
- 
--static DEVICE_ATTR(mem_info, S_IRUGO, show_mem_info, NULL);
-+static CLASS_DEVICE_ATTR(mem_info, S_IRUGO, show_mem_info, NULL);
- 
- static void srpt_add_one(struct ib_device *device)
- {
-@@ -2362,23 +2360,23 @@ static void srpt_add_one(struct ib_devic
- 	sdev->device = device;
- 	init_completion(&sdev->scst_released);
- 
--	sdev->dev.class = &srpt_class;
--	sdev->dev.parent = device->dma_device;
--	snprintf(sdev->dev.bus_id, BUS_ID_SIZE, "srpt-%s", device->name);
-+	sdev->class_dev.class = &srpt_class;
-+	sdev->class_dev.dev = device->dma_device;
-+	snprintf(sdev->class_dev.class_id, BUS_ID_SIZE, "srpt-%s", device->name);
- 
--	if (device_register(&sdev->dev))
-+	if (class_device_register(&sdev->class_dev))
- 		goto free_dev;
--	if (device_create_file(&sdev->dev, &dev_attr_login_info))
--		goto err_dev;
--	if (device_create_file(&sdev->dev, &dev_attr_mem_info))
--		goto err_dev;
-+	if (class_device_create_file(&sdev->class_dev, &class_device_attr_login_info))
-+		goto err_class;
-+	if (class_device_create_file(&sdev->class_dev, &class_device_attr_mem_info))
-+		goto err_class;
- 
- 	if (ib_query_device(device, &sdev->dev_attr))
--		goto err_dev;
-+		goto err_class;
- 
- 	sdev->pd = ib_alloc_pd(device);
- 	if (IS_ERR(sdev->pd))
--		goto err_dev;
-+		goto err_class;
- 
- 	sdev->mr = ib_get_dma_mr(sdev->pd, IB_ACCESS_LOCAL_WRITE);
- 	if (IS_ERR(sdev->mr))
-@@ -2450,8 +2448,8 @@ static void srpt_add_one(struct ib_devic
- 	ib_dereg_mr(sdev->mr);
-       err_pd:
- 	ib_dealloc_pd(sdev->pd);
--      err_dev:
--	device_unregister(&sdev->dev);
-+      err_class:
-+	class_device_unregister(&sdev->class_dev);
-       free_dev:
- 	kfree(sdev);
- }
-@@ -2472,7 +2470,7 @@ static void srpt_remove_one(struct ib_de
- 	ib_destroy_srq(sdev->srq);
- 	ib_dereg_mr(sdev->mr);
- 	ib_dealloc_pd(sdev->pd);
--	device_unregister(&sdev->dev);
-+	class_device_unregister(&sdev->class_dev);
- 
- 	for (i = 0; i < SRPT_SRQ_SIZE; ++i)
- 		srpt_free_ioctx(sdev, sdev->ioctx_ring[i]);
-Index: ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.h
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/ulp/srpt/ib_srpt.h
-+++ ofed_kernel/drivers/infiniband/ulp/srpt/ib_srpt.h
-@@ -171,7 +171,7 @@ struct srpt_device {
- 	struct srpt_port port[2];
- 	struct ib_event_handler event_handler;
- 	struct completion scst_released;
--	struct device dev;
-+	struct class_device class_dev;
- 
- 	struct scst_tgt *scst_tgt;
- };
diff --git a/kernel_patches/backport/2.6.18-EL5.1/uverbs_main_1_to_2_6_24.patch b/kernel_patches/backport/2.6.18-EL5.1/uverbs_main_1_to_2_6_24.patch
deleted file mode 100644
index cf5446d..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/uverbs_main_1_to_2_6_24.patch
+++ /dev/null
@@ -1,39 +0,0 @@
----
- drivers/infiniband/core/uverbs_main.c |   19 ++++++++++++-------
- 1 file changed, 12 insertions(+), 7 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
-+++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
-@@ -553,18 +553,23 @@ struct file *ib_uverbs_alloc_event_file(
- 		goto err;
- 	}
- 
--	/*
--	 * fops_get() can't fail here, because we're coming from a
--	 * system call on a uverbs file, which will already have a
--	 * module reference.
--	 */
--	filp = alloc_file(uverbs_event_mnt, dget(uverbs_event_mnt->mnt_root),
--			  FMODE_READ, fops_get(&uverbs_event_fops));
-+	filp = get_empty_filp();
- 	if (!filp) {
- 		ret = -ENFILE;
- 		goto err_fd;
- 	}
- 
-+	/*
-+	 * fops_get() can't fail here, because we're coming from a
-+	 * system call on a uverbs file, which will already have a
-+	 * module reference.
-+	 */
-+	filp->f_op 	   = fops_get(&uverbs_event_fops);
-+	filp->f_path.mnt 	   = mntget(uverbs_event_mnt);
-+	filp->f_path.dentry 	   = dget(uverbs_event_mnt->mnt_root);
-+	filp->f_mapping    = filp->f_path.dentry->d_inode->i_mapping;
-+	filp->f_flags      = O_RDONLY;
-+	filp->f_mode       = FMODE_READ;
- 	filp->private_data = ev_file;
- 
- 	return filp;
diff --git a/kernel_patches/backport/2.6.18-EL5.1/uverbs_main_2_to_2_6_19.patch b/kernel_patches/backport/2.6.18-EL5.1/uverbs_main_2_to_2_6_19.patch
deleted file mode 100644
index 11ae95b..0000000
--- a/kernel_patches/backport/2.6.18-EL5.1/uverbs_main_2_to_2_6_19.patch
+++ /dev/null
@@ -1,70 +0,0 @@
----
- drivers/infiniband/core/uverbs_main.c        |    6 +++---
- drivers/infiniband/hw/ipath/ipath_file_ops.c |    4 ++--
- drivers/infiniband/hw/ipath/ipath_fs.c       |    6 +++---
- 3 files changed, 8 insertions(+), 8 deletions(-)
-
-Index: ofed_kernel/drivers/infiniband/core/uverbs_main.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/core/uverbs_main.c
-+++ ofed_kernel/drivers/infiniband/core/uverbs_main.c
-@@ -565,9 +565,9 @@ struct file *ib_uverbs_alloc_event_file(
- 	 * module reference.
- 	 */
- 	filp->f_op 	   = fops_get(&uverbs_event_fops);
--	filp->f_path.mnt 	   = mntget(uverbs_event_mnt);
--	filp->f_path.dentry 	   = dget(uverbs_event_mnt->mnt_root);
--	filp->f_mapping    = filp->f_path.dentry->d_inode->i_mapping;
-+	filp->f_vfsmnt 	   = mntget(uverbs_event_mnt);
-+	filp->f_dentry 	   = dget(uverbs_event_mnt->mnt_root);
-+	filp->f_mapping    = filp->f_dentry->d_inode->i_mapping;
- 	filp->f_flags      = O_RDONLY;
- 	filp->f_mode       = FMODE_READ;
- 	filp->private_data = ev_file;
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_file_ops.c
-@@ -1868,9 +1868,9 @@ static int ipath_assign_port(struct file
- 		goto done_chk_sdma;
- 	}
- 
--	i_minor = iminor(fp->f_path.dentry->d_inode) - IPATH_USER_MINOR_BASE;
-+	i_minor = iminor(fp->f_dentry->d_inode) - IPATH_USER_MINOR_BASE;
- 	ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n",
--		   (long)fp->f_path.dentry->d_inode->i_rdev, i_minor);
-+		   (long)fp->f_dentry->d_inode->i_rdev, i_minor);
- 
- 	if (i_minor)
- 		ret = find_free_port(i_minor - 1, fp, uinfo);
-Index: ofed_kernel/drivers/infiniband/hw/ipath/ipath_fs.c
-===================================================================
---- ofed_kernel.orig/drivers/infiniband/hw/ipath/ipath_fs.c
-+++ ofed_kernel/drivers/infiniband/hw/ipath/ipath_fs.c
-@@ -113,7 +113,7 @@ static ssize_t atomic_counters_read(stru
- 	struct infinipath_counters counters;
- 	struct ipath_devdata *dd;
- 
--	dd = file->f_path.dentry->d_inode->i_private;
-+	dd = file->f_dentry->d_inode->i_private;
- 	dd->ipath_f_read_counters(dd, &counters);
- 
- 	return simple_read_from_buffer(buf, count, ppos, &counters,
-@@ -153,7 +153,7 @@ static ssize_t flash_read(struct file *f
- 		goto bail;
- 	}
- 
--	dd = file->f_path.dentry->d_inode->i_private;
-+	dd = file->f_dentry->d_inode->i_private;
- 	if (ipath_eeprom_read(dd, pos, tmp, count)) {
- 		ipath_dev_err(dd, "failed to read from flash\n");
- 		ret = -ENXIO;
-@@ -206,7 +206,7 @@ static ssize_t flash_write(struct file *
- 		goto bail_tmp;
- 	}
- 
--	dd = file->f_path.dentry->d_inode->i_private;
-+	dd = file->f_dentry->d_inode->i_private;
- 	if (ipath_eeprom_write(dd, pos, tmp, count)) {
- 		ret = -ENXIO;
- 		ipath_dev_err(dd, "failed to write to flash\n");



More information about the ewg mailing list