[ewg] [PATCH] IB/ehca: Backport for RHEL 4.6

Joachim Fenkes fenkes at de.ibm.com
Tue Jul 15 07:27:44 PDT 2008


Also, fix atomic64_t backport on powerpc64.

Signed-off-by: Joachim Fenkes <fenkes at de.ibm.com>
---
 .../2.6.9_U6/include/asm-powerpc/atomic64.h        |   61 +++++++
 .../backport/2.6.9_U6/include/asm/atomic.h         |    4 +
 .../2.6.9_U6/ehca_01_ibmebus_loc_code.patch        |  186 ++++++++++++++++++++
 3 files changed, 251 insertions(+), 0 deletions(-)
 create mode 100644 kernel_addons/backport/2.6.9_U6/include/asm-powerpc/atomic64.h
 create mode 100644 kernel_patches/backport/2.6.9_U6/ehca_01_ibmebus_loc_code.patch

diff --git a/kernel_addons/backport/2.6.9_U6/include/asm-powerpc/atomic64.h b/kernel_addons/backport/2.6.9_U6/include/asm-powerpc/atomic64.h
new file mode 100644
index 0000000..8036dbe
--- /dev/null
+++ b/kernel_addons/backport/2.6.9_U6/include/asm-powerpc/atomic64.h
@@ -0,0 +1,61 @@
+#ifndef __ATOMIC64_INC_BACKPORT_2_6_9__
+#define __ATOMIC64_INC_BACKPORT_2_6_9__
+
+typedef struct { volatile long counter; } atomic64_t;
+
+#define ATOMIC64_INIT(i)        { (i) }
+
+#define atomic64_read(v)        ((v)->counter)
+#define atomic64_set(v,i)       (((v)->counter) = (i))
+
+static __inline__ void atomic64_add(long a, atomic64_t *v)
+{
+  long t;
+
+  __asm__ __volatile__(
+"1:	ldarx   %0,0,%3         # atomic64_add\n\
+	add     %0,%2,%0\n\
+	stdcx.  %0,0,%3 \n\
+	bne-    1b"
+: "=&r" (t), "=m" (v->counter)
+: "r" (a), "r" (&v->counter), "m" (v->counter)
+: "cc");
+}
+
+static __inline__ long atomic64_add_return(long a, atomic64_t *v)
+{
+  long t;
+
+  __asm__ __volatile__(
+#ifdef CONFIG_SMP
+"	lwsync\n"
+#endif
+"1:	ldarx   %0,0,%2         # atomic64_add_return\n\
+	add     %0,%1,%0\n\
+	stdcx.  %0,0,%2 \n\
+	bne-    1b"
+#ifdef CONFIG_SMP
+"	isync\n"
+#endif
+	: "=&r" (t)
+	: "r" (a), "r" (&v->counter)
+	: "cc", "memory");
+
+  return t;
+}
+
+static __inline__ void atomic64_inc(atomic64_t *v)
+{
+  long t;
+
+  __asm__ __volatile__(
+"1:	ldarx   %0,0,%2         # atomic64_inc\n\
+	addic   %0,%0,1\n\
+	stdcx.  %0,0,%2 \n\
+	bne-    1b"
+: "=&r" (t), "=m" (v->counter)
+: "r" (&v->counter), "m" (v->counter)
+: "cc");
+}
+
+#endif
diff --git a/kernel_addons/backport/2.6.9_U6/include/asm/atomic.h b/kernel_addons/backport/2.6.9_U6/include/asm/atomic.h
index 11de648..2823278 100644
--- a/kernel_addons/backport/2.6.9_U6/include/asm/atomic.h
+++ b/kernel_addons/backport/2.6.9_U6/include/asm/atomic.h
@@ -3,6 +3,10 @@
 
 #include_next <asm/atomic.h>
 
+#ifdef __powerpc64__
+#include <asm-powerpc/atomic64.h>
+#endif
+
 # if defined(__x86_64__)
 
 /**
diff --git a/kernel_patches/backport/2.6.9_U6/ehca_01_ibmebus_loc_code.patch b/kernel_patches/backport/2.6.9_U6/ehca_01_ibmebus_loc_code.patch
new file mode 100644
index 0000000..8737b79
--- /dev/null
+++ b/kernel_patches/backport/2.6.9_U6/ehca_01_ibmebus_loc_code.patch
@@ -0,0 +1,186 @@
+diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
+index 1e9e99a..fbf6e58 100644
+--- a/drivers/infiniband/hw/ehca/ehca_classes.h
++++ b/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;
+diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
+index 49660df..aab80e9 100644
+--- a/drivers/infiniband/hw/ehca/ehca_eq.c
++++ b/drivers/infiniband/hw/ehca/ehca_eq.c
+@@ -122,7 +122,7 @@ int ehca_create_eq(struct ehca_shca *shca,
+ 
+ 	/* 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 *shca,
+ 
+ 		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 *shca, struct ehca_eq *eq)
+ 	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);
+ 
+diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
+index 482103e..666aafe 100644
+--- a/drivers/infiniband/hw/ehca/ehca_main.c
++++ b/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 *shca)
+ 	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_attr_grp = {
+ 	.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_attr_grp = {
+ 	.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 of_device *dev,
+ 	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 of_device *dev,
+ 	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 of_device *dev,
+ 		}
+ 	}
+ 
+-	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;
+@@ -924,14 +919,11 @@ static struct of_device_id 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)
+@@ -990,6 +982,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.");
+@@ -1015,6 +1011,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();
+ 
-- 
1.5.5





More information about the ewg mailing list