[openfabrics-ewg] [OFED PATCH] Get ipath driver to build on RHEL4 U4
Bryan O'Sullivan
bos at pathscale.com
Tue Sep 19 21:39:22 PDT 2006
This patch is required to build the ipath driver on RHEL4 U4.
It should go into the kernel_patches/backport/2.6.9_U4 directory in the
git tree.
Thanks.
<b
-------------- next part --------------
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/iowrite32_copy_x86_64.S
===================================================================
--- /dev/null
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/iowrite32_copy_x86_64.S
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003, 2004, 2005. PathScale, Inc. 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.
+ */
+
+/**
+ * __iowrite32_copy - copy a memory block using dword multiple writes
+ *
+ * This is primarily for writing to the InfiniPath PIO buffers, which
+ * only support dword multiple writes, and thus can not use memcpy().
+ * For this reason, we use nothing smaller than dword writes.
+ * It is also used as a fast copy routine in some places that have been
+ * measured to win over memcpy, and the performance delta matters.
+ *
+ * Count is number of dwords; might not be a qword multiple.
+ */
+
+ .globl __iowrite32_copy
+ .p2align 4
+/* rdi destination, rsi source, rdx count */
+__iowrite32_copy:
+ movl %edx,%ecx
+ shrl $1,%ecx
+ andl $1,%edx
+ rep
+ movsq
+ movl %edx,%ecx
+ rep
+ movsd
+ ret
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_backport.h
===================================================================
--- /dev/null
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_backport.h
@@ -0,0 +1,112 @@
+#ifndef _IPATH_BACKPORT_H
+#define _IPATH_BACKPORT_H
+/*
+ * Copyright (c) 2006 QLogic, Inc. All rights reserved.
+ * Copyright (c) 2006 PathScale, Inc. 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/version.h>
+#include <linux/fs.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+#include <linux/pci.h> /* needed to avoid struct pci_dev warnings */
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+#include <linux/compiler.h>
+
+#ifndef __nocast
+#define __nocast
+#endif
+
+/*
+ * Work around RHEL4 U3 kernel's backport of random pieces of core
+ * kernel infrastructure. Grrrrrr.
+ */
+#define kzalloc ipath_kzalloc
+#define gfp_t ipath_gfp_t
+
+typedef unsigned int __nocast gfp_t;
+
+static inline void *kzalloc(size_t size, gfp_t flags)
+{
+ void *ret = kmalloc(size, flags);
+ if (ret)
+ memset(ret, 0, size);
+ return ret;
+}
+#endif
+
+// Help me to compile on my laptop -bos
+#if defined(__i386__)
+void writeq(u64, void __iomem *);
+u64 readq(const void __iomem *);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) && !defined(DEFINE_MUTEX)
+#include <asm/semaphore.h>
+
+#define mutex semaphore
+#define DEFINE_MUTEX(foo) DECLARE_MUTEX(foo)
+#define mutex_init(foo) init_MUTEX(foo)
+#define mutex_lock(foo) down(foo)
+#define mutex_lock_interruptible(foo) down_interruptible(foo)
+/* this function follows the spin_trylock() convention, so *
+ * it is negated to the down_trylock() return values! Be careful */
+#define mutex_trylock(foo) !down_trylock(foo)
+#define mutex_unlock(foo) up(foo)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
+#include <linux/interrupt.h>
+#define IRQF_SHARED SA_SHIRQ
+#endif
+
+/*
+ * XXX - This is here for a short time only. See bug 8823.
+ *
+ * optimized word copy; good for rev C and later opterons. Among the best
+ * for short copies, and does as well or slightly better than the
+ * optimizization guide copies 6 and 8 at 2KB.
+ */
+void __iowrite32_copy(void __iomem * dst, const void *src, size_t count);
+
+/*
+ * XXX - Another short-term tenant. See bug 8809.
+ */
+#ifndef BITS_PER_BYTE
+#define BITS_PER_BYTE 8
+#endif
+
+#ifndef DEFINE_SPINLOCK
+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
+#endif
+
+#endif /* _IPATH_BACKPORT_H */
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_diag.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_diag.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -41,7 +41,10 @@
* through the /sys/bus/pci resource mmap interface.
*/
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
#include <linux/io.h>
+#endif
#include <linux/pci.h>
#include <asm/uaccess.h>
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_driver.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_driver.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -38,6 +38,15 @@
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
+/*
+ * InfiniPath only supports message-based interrupts. It has no interrupt
+ * pins. Therefore we require CONFIG_PCI_MSI be enabled. We want a
+ * very visible failure if the support isn't present.
+ */
+#ifndef CONFIG_PCI_MSI
+#warning "Without CONFIG_PCI_MSI, interrupts will be faked"
+#endif
+
#include "ipath_kernel.h"
#include "ipath_verbs.h"
#include "ipath_common.h"
@@ -547,7 +556,12 @@ static int __devinit ipath_init_one(stru
goto bail;
bail_iounmap:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ /* RHEL kernel does not have volatile in declaration */
+ iounmap((void __iomem *) dd->ipath_kregbase);
+#else
iounmap((volatile void __iomem *) dd->ipath_kregbase);
+#endif
bail_regions:
pci_release_regions(pdev);
@@ -584,7 +598,12 @@ static void __devexit ipath_remove_one(s
if (dd->ipath_kregbase) {
ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n",
dd->ipath_kregbase);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+ /* RHEL kernel does not have volatile in declaration */
+ iounmap((void __iomem *) dd->ipath_kregbase);
+#else
iounmap((volatile void __iomem *) dd->ipath_kregbase);
+#endif
dd->ipath_kregbase = NULL;
}
pci_release_regions(pdev);
@@ -1346,6 +1365,13 @@ int ipath_create_rcvhdrq(struct ipath_de
int amt = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize *
sizeof(u32), PAGE_SIZE);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ gfp_flags &= ~__GFP_COMP;
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+ gfp_flags |= __GFP_REPEAT;
+#endif
+
pd->port_rcvhdrq = dma_alloc_coherent(
&dd->pcidev->dev, amt, &pd->port_rcvhdrq_phys,
gfp_flags);
@@ -1368,6 +1394,17 @@ int ipath_create_rcvhdrq(struct ipath_de
}
pd->port_rcvhdrqtailaddr_phys = phys_hdrqtail;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ SetPageReserved(virt_to_page(pd->port_rcvhdrtail_kvaddr));
+ {
+ void *base = pd->port_rcvhdrq;
+ size_t i;
+
+ for (i = 0; i < amt; i+= PAGE_SIZE)
+ SetPageReserved(virt_to_page(base + i));
+ }
+#endif
+
pd->port_rcvhdrq_size = amt;
ipath_cdbg(VERBOSE, "%d pages at %p (phys %lx) size=%lu "
@@ -1837,6 +1874,15 @@ void ipath_free_pddata(struct ipath_devd
return;
if (pd->port_rcvhdrq) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ void *base = pd->port_rcvhdrq;
+ size_t i;
+
+ for (i = 0; i < pd->port_rcvhdrq_size; i += PAGE_SIZE)
+ ClearPageReserved(virt_to_page(base + i));
+ if(pd->port_rcvhdrtail_kvaddr)
+ ClearPageReserved(virt_to_page(pd->port_rcvhdrtail_kvaddr));
+#endif
ipath_cdbg(VERBOSE, "free closed port %d rcvhdrq @ %p "
"(size=%lu)\n", pd->port_port, pd->port_rcvhdrq,
(unsigned long) pd->port_rcvhdrq_size);
@@ -1856,6 +1902,12 @@ void ipath_free_pddata(struct ipath_devd
for (e = 0; e < pd->port_rcvegrbuf_chunks; e++) {
void *base = pd->port_rcvegrbuf[e];
size_t size = pd->port_rcvegrbuf_size;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ size_t i;
+
+ for (i = 0; i < size; i+= PAGE_SIZE)
+ ClearPageReserved(virt_to_page(base + i));
+#endif
ipath_cdbg(VERBOSE, "egrbuf free(%p, %lu), "
"chunk %u/%u\n", base,
@@ -1941,7 +1993,9 @@ bail_pci:
pci_unregister_driver(&ipath_driver);
bail_unit:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
idr_destroy(&unit_table);
+#endif
bail:
return ret;
@@ -1972,6 +2026,9 @@ static void cleanup_device(struct ipath_
}
if (dd->ipath_pioavailregs_dma) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ ClearPageReserved(virt_to_page(dd->ipath_pioavailregs_dma));
+#endif
dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
(void *) dd->ipath_pioavailregs_dma,
dd->ipath_pioavailregs_phys);
@@ -2094,7 +2151,9 @@ static void __exit infinipath_cleanup(vo
ipath_cdbg(VERBOSE, "Unregistering pci driver\n");
pci_unregister_driver(&ipath_driver);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
idr_destroy(&unit_table);
+#endif
}
/**
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_file_ops.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -41,6 +41,11 @@
#include "ipath_kernel.h"
#include "ipath_common.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) && LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,14)
+#define class_device_create(cls, parent, devt, device, fmt, arg...) \
+ class_device_create(cls, devt, device, fmt, ## arg)
+#endif
+
static int ipath_open(struct inode *, struct file *);
static int ipath_close(struct inode *, struct file *);
static ssize_t ipath_write(struct file *, const char __user *, size_t,
@@ -713,7 +718,14 @@ static int ipath_create_user_egr(struct
* heavy filesystem activity makes these fail, and we can
* use compound pages.
*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+ /* RHEL4 2.6.9 really seems to need GFP_REPEAT */
+ gfp_flags = __GFP_WAIT | __GFP_IO | __GFP_REPEAT;
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ gfp_flags = __GFP_WAIT | __GFP_IO;
+#else
gfp_flags = __GFP_WAIT | __GFP_IO | __GFP_COMP;
+#endif
egrcnt = dd->ipath_rcvegrcnt;
/* TID number offset for this port */
@@ -761,6 +773,15 @@ static int ipath_create_user_egr(struct
ret = -ENOMEM;
goto bail_rcvegrbuf_phys;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ {
+ void *base = pd->port_rcvegrbuf[e];
+ size_t i;
+
+ for (i = 0; i < size; i+= PAGE_SIZE)
+ SetPageReserved(virt_to_page(base + i));
+ }
+#endif
}
pd->port_rcvegr_phys = pd->port_rcvegrbuf_phys[0];
@@ -786,6 +807,13 @@ static int ipath_create_user_egr(struct
bail_rcvegrbuf_phys:
for (e = 0; e < pd->port_rcvegrbuf_chunks &&
pd->port_rcvegrbuf[e]; e++) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ void *base = pd->port_rcvegrbuf[e];
+ size_t i;
+
+ for (i = 0; i < size; i+= PAGE_SIZE)
+ ClearPageReserved(virt_to_page(base + i));
+#endif
dma_free_coherent(&dd->pcidev->dev, size,
pd->port_rcvegrbuf[e],
pd->port_rcvegrbuf_phys[e]);
@@ -882,6 +910,15 @@ done:
return ret;
}
+#ifndef io_remap_pfn_range
+#define io_remap_pfn_range(vma, addr, pfn, size, prot) \
+ io_remap_page_range((vma), (addr), (unsigned long)(pfn) << PAGE_SHIFT, (size), \
+ (prot))
+#define remap_pfn_range(vma, addr, pfn, size, prot) \
+ remap_page_range((vma), (addr), (unsigned long)(pfn) << PAGE_SHIFT, (size), \
+ (prot))
+#endif
+
/* common code for the mappings on dma_alloc_coherent mem */
static int ipath_mmap_mem(struct vm_area_struct *vma,
@@ -1671,6 +1708,171 @@ bail:
return ret;
}
+#define NEW_REDHAT
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) && !defined(NEW_REDHAT)
+/**
+ * The following 6 static functions were added in kernel 2.6.13.
+ * They are added here as static functions, with one change --
+ * in function create_class(), there is no owner field in
+ * struct class in this kernel release, so the "owner" parameter
+ * in the function is unused.
+ */
+
+static void class_create_release(struct class *cls)
+{
+ kfree(cls);
+}
+
+static void class_device_create_release(struct class_device *class_dev)
+{
+ kfree(class_dev);
+}
+
+/**
+ * class_create - create a struct class structure
+ * @owner: pointer to the module that is to "own" this struct class
+ * @name: pointer to a string for the name of this class.
+ *
+ * This is used to create a struct class pointer that can then be used
+ * in calls to class_device_create().
+ *
+ * Note, the pointer created here is to be destroyed when finished by
+ * making a call to class_destroy().
+ */
+static struct class *class_create(struct module *owner, char *name)
+{
+ struct class *cls;
+ int retval;
+
+ cls = kzalloc(sizeof(*cls), GFP_KERNEL);
+ if (!cls) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ cls->name = name;
+ /* cls->owner = owner; */
+ cls->class_release = class_create_release;
+ cls->release = class_device_create_release;
+
+ retval = class_register(cls);
+ if (retval)
+ goto error;
+
+ return cls;
+
+error:
+ kfree(cls);
+ return ERR_PTR(retval);
+}
+
+/**
+ * class_destroy - destroys a struct class structure
+ * @cs: pointer to the struct class that is to be destroyed
+ *
+ * Note, the pointer to be destroyed must have been created with a call
+ * to class_create().
+ */
+static void class_destroy(struct class *cls)
+{
+ if ((cls == NULL) || (IS_ERR(cls)))
+ return;
+
+ class_unregister(cls);
+}
+
+/**
+ * class_device_create - creates a class device and registers it with sysfs
+ * @cs: pointer to the struct class that this device should be registered to.
+ * @dev: the dev_t for the char device to be added.
+ * @device: a pointer to a struct device that is assiociated with this class device.
+ * @fmt: string for the class device's name
+ *
+ * This function can be used by char device classes. A struct
+ * class_device will be created in sysfs, registered to the specified
+ * class. A "dev" file will be created, showing the dev_t for the
+ * device. The pointer to the struct class_device will be returned from
+ * the call. Any further sysfs files that might be required can be
+ * created using this pointer.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+static struct class_device *class_device_create(struct class *cls, void *parent, dev_t devt,
+ struct device *device, char *fmt, ...)
+{
+ va_list args;
+ struct class_device *class_dev = NULL;
+ int retval = -ENODEV;
+
+ if (cls == NULL || IS_ERR(cls))
+ goto error;
+
+ class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
+ if (!class_dev) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
+ class_dev->devt = devt;
+#endif
+ class_dev->dev = device;
+ class_dev->class = cls;
+
+ va_start(args, fmt);
+ vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
+ va_end(args);
+ retval = class_device_register(class_dev);
+ if (retval)
+ goto error;
+
+ return class_dev;
+
+error:
+ kfree(class_dev);
+ return ERR_PTR(retval);
+}
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11)
+/**
+ * class_device_destroy - removes a class device that was created with class_device_create()
+ * @cls: the pointer to the struct class that this device was registered * with.
+ * @dev: the dev_t of the device that was previously registered.
+ *
+ * This call unregisters and cleans up a class device that was created with a
+ * call to class_device_create()
+ */
+static void class_device_destroy(struct class *cls, dev_t devt)
+{
+ struct class_device *class_dev = NULL;
+ struct class_device *class_dev_tmp;
+
+ down(&cls->sem);
+ list_for_each_entry(class_dev_tmp, &cls->children, node) {
+ if (class_dev_tmp->devt == devt) {
+ class_dev = class_dev_tmp;
+ break;
+ }
+ }
+ up(&cls->sem);
+
+ if (class_dev)
+ class_device_unregister(class_dev);
+}
+#endif
+#endif
+
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9)
+static ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+ struct cdev *dev= class_get_devdata(class_dev);
+
+ return print_dev_t(buf, dev->dev);
+}
+static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+#endif
+
static struct class *ipath_class;
static int init_cdev(int minor, char *name, struct file_operations *fops,
@@ -1702,7 +1904,11 @@ static int init_cdev(int minor, char *na
goto err_cdev;
}
+#if defined(NEW_REDHAT)
+ class_dev = class_device_create(ipath_class, dev, NULL, name);
+#else
class_dev = class_device_create(ipath_class, NULL, dev, NULL, name);
+#endif
if (IS_ERR(class_dev)) {
ret = PTR_ERR(class_dev);
@@ -1712,8 +1918,24 @@ static int init_cdev(int minor, char *na
goto err_cdev;
}
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9)
+ class_set_devdata(class_dev, cdev);
+
+ if (class_device_create_file(class_dev, &class_device_attr_dev))
+ goto err_class;
+#endif
+
goto done;
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9)
+err_class:
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
+ class_device_unregister(class_dev);
+#else
+ class_device_destroy(ipath_class, dev);
+#endif
+
err_cdev:
cdev_del(cdev);
cdev = NULL;
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_fs.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_fs.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -32,6 +32,7 @@
*/
#include <linux/version.h>
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mount.h>
@@ -40,6 +41,10 @@
#include <linux/namei.h>
#include <linux/pci.h>
+#ifdef DEFINE_MUTEX
+#define USING_MUTEXES
+#endif
+
#include "ipath_kernel.h"
#define IPATHFS_MAGIC 0x726a77
@@ -87,14 +92,22 @@ static int create_file(const char *name,
int error;
*dentry = NULL;
+#if !defined(USING_MUTEXES)
+ down(&parent->d_inode->i_sem);
+#else
mutex_lock(&parent->d_inode->i_mutex);
+#endif
*dentry = lookup_one_len(name, parent, strlen(name));
if (!IS_ERR(dentry))
error = ipathfs_mknod(parent->d_inode, *dentry,
mode, fops, data);
else
error = PTR_ERR(dentry);
+#if !defined(USING_MUTEXES)
+ up(&parent->d_inode->i_sem);
+#else
mutex_unlock(&parent->d_inode->i_mutex);
+#endif
return error;
}
@@ -483,7 +496,11 @@ static int remove_device_files(struct su
int ret;
root = dget(sb->s_root);
+#if !defined(USING_MUTEXES)
+ down(&root->d_inode->i_sem);
+#else
mutex_lock(&root->d_inode->i_mutex);
+#endif
snprintf(unit, sizeof unit, "%02d", dd->ipath_unit);
dir = lookup_one_len(unit, root, strlen(unit));
@@ -501,7 +518,11 @@ static int remove_device_files(struct su
ret = simple_rmdir(root->d_inode, dir);
bail:
+#if !defined(USING_MUTEXES)
+ up(&root->d_inode->i_sem);
+#else
mutex_unlock(&root->d_inode->i_mutex);
+#endif
dput(root);
return ret;
}
@@ -542,6 +563,7 @@ bail:
return ret;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
static int ipathfs_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
{
@@ -551,6 +573,16 @@ static int ipathfs_get_sb(struct file_sy
ipath_super = mnt->mnt_sb;
return ret;
}
+#else
+static struct super_block *ipathfs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+ void *data)
+{
+ ipath_super = get_sb_single(fs_type, flags, data,
+ ipathfs_fill_super);
+ return ipath_super;
+}
+#endif
static void ipathfs_kill_super(struct super_block *s)
{
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_iba6110.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -742,6 +742,45 @@ static int ipath_setup_ht_reset(struct i
return 0;
}
+#define NEW_REDHAT
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) && !defined(NEW_REDHAT)
+/*
+ * pci_find_next_capability is new in 2.6.15, so we define it
+ * here for older kernels.
+ */
+/*
+ * pci_find_next_capability - Find next capability after current position
+ * @dev: PCI device to query
+ * @pos: Position to search from
+ * @cap: capability code
+ */
+static int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
+{
+ u8 id;
+ int ttl = 48;
+ int ret;
+
+ while (ttl--) {
+ pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
+ pos &= ~3;
+ if (pos < 0x40)
+ break;
+ pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
+ if (id == 0xff)
+ break;
+ if (id == cap) {
+ ret = pos;
+ goto bail;
+ }
+ }
+
+ ret = 0;
+
+bail:
+ return ret;
+}
+#endif
+
#define HT_CAPABILITY_ID 0x08 /* HT capabilities not defined in kernel */
#define HT_INTR_DISC_CONFIG 0x80 /* HT interrupt and discovery cap */
#define HT_INTR_REG_INDEX 2 /* intconfig requires indirect accesses */
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_iba6120.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -39,6 +39,9 @@
#include <linux/pci.h>
#include <linux/delay.h>
+#ifndef PCI_EXP_LNKSTA
+#define PCI_EXP_LNKSTA 0x12 /* not defined in RHEL4 2.6.9 */
+#endif
#include "ipath_kernel.h"
#include "ipath_registers.h"
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_init_chip.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -389,6 +389,9 @@ static int init_pioavailregs(struct ipat
dd->ipath_pioavailregs_dma = dma_alloc_coherent(
&dd->pcidev->dev, PAGE_SIZE, &dd->ipath_pioavailregs_phys,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+ __GFP_REPEAT |
+#endif
GFP_KERNEL);
if (!dd->ipath_pioavailregs_dma) {
ipath_dev_err(dd, "failed to allocate PIOavail reg area "
@@ -397,6 +400,10 @@ static int init_pioavailregs(struct ipat
goto done;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ SetPageReserved(virt_to_page(dd->ipath_pioavailregs_dma));
+#endif
+
/*
* we really want L2 cache aligned, but for current CPUs of
* interest, they are the same.
@@ -842,6 +849,12 @@ int ipath_init_chip(struct ipath_devdata
if (!ret && !reinit) {
/* used when we close a port, for DMA already in flight at close */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ gfp_flags &= ~__GFP_COMP;
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+ gfp_flags |= __GFP_REPEAT;
+#endif
dd->ipath_dummy_hdrq = dma_alloc_coherent(
&dd->pcidev->dev, pd->port_rcvhdrq_size,
&dd->ipath_dummy_hdrq_phys,
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_kernel.h
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -41,6 +41,7 @@
#include <linux/interrupt.h>
#include <asm/io.h>
+#include "ipath_backport.h"
#include "ipath_common.h"
#include "ipath_debug.h"
#include "ipath_registers.h"
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_layer.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_layer.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_layer.c
@@ -36,7 +36,10 @@
* layered ethernet driver and verbs layer.
*/
+#include <linux/version.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
#include <linux/io.h>
+#endif
#include <linux/pci.h>
#include <asm/byteorder.h>
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_sysfs.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_sysfs.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_sysfs.c
@@ -85,7 +85,9 @@ static ssize_t show_num_units(struct dev
}
static ssize_t show_status(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -118,7 +120,9 @@ static const char *ipath_status_str[] =
};
static ssize_t show_status_str(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -156,7 +160,9 @@ bail:
}
static ssize_t show_boardversion(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -165,7 +171,9 @@ static ssize_t show_boardversion(struct
}
static ssize_t show_lid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -174,7 +182,9 @@ static ssize_t show_lid(struct device *d
}
static ssize_t store_lid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -201,7 +211,9 @@ bail:
}
static ssize_t show_mlid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -210,7 +222,9 @@ static ssize_t show_mlid(struct device *
}
static ssize_t store_mlid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -235,7 +249,9 @@ bail:
}
static ssize_t show_guid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -250,7 +266,9 @@ static ssize_t show_guid(struct device *
}
static ssize_t store_guid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -289,7 +307,9 @@ bail:
}
static ssize_t show_nguid(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -298,7 +318,9 @@ static ssize_t show_nguid(struct device
}
static ssize_t show_serial(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -310,7 +332,9 @@ static ssize_t show_serial(struct device
}
static ssize_t show_unit(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -318,6 +342,7 @@ static ssize_t show_unit(struct device *
return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_unit);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
#define DEVICE_COUNTER(name, attr) \
static ssize_t show_counter_##name(struct device *dev, \
struct device_attribute *attr, \
@@ -331,6 +356,20 @@ static ssize_t show_unit(struct device *
attr) / sizeof(u64))); \
} \
static DEVICE_ATTR(name, S_IRUGO, show_counter_##name, NULL);
+#else
+#define DEVICE_COUNTER(name, attr) \
+ static ssize_t show_counter_##name(struct device *dev, \
+ char *buf) \
+ { \
+ struct ipath_devdata *dd = dev_get_drvdata(dev); \
+ return scnprintf(\
+ buf, PAGE_SIZE, "%llu\n", (unsigned long long) \
+ ipath_snap_cntr( \
+ dd, offsetof(struct infinipath_counters, \
+ attr) / sizeof(u64))); \
+ } \
+ static DEVICE_ATTR(name, S_IRUGO, show_counter_##name, NULL);
+#endif
DEVICE_COUNTER(ib_link_downeds, IBLinkDownedCnt);
DEVICE_COUNTER(ib_link_err_recoveries, IBLinkErrRecoveryCnt);
@@ -425,7 +464,9 @@ static struct attribute_group dev_counte
};
static ssize_t store_reset(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -453,7 +494,9 @@ bail:
}
static ssize_t store_link_state(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -479,7 +522,9 @@ bail:
}
static ssize_t show_mtu(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -487,7 +532,9 @@ static ssize_t show_mtu(struct device *d
}
static ssize_t store_mtu(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -512,7 +559,9 @@ bail:
}
static ssize_t show_enabled(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
char *buf)
{
struct ipath_devdata *dd = dev_get_drvdata(dev);
@@ -521,7 +570,9 @@ static ssize_t show_enabled(struct devic
}
static ssize_t store_enabled(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
@@ -562,7 +613,9 @@ bail:
}
static ssize_t store_rx_pol_inv(struct device *dev,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
struct device_attribute *attr,
+#endif
const char *buf,
size_t count)
{
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_user_pages.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -58,8 +58,13 @@ static int __get_user_pages(unsigned lon
size_t got;
int ret;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+ lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur >>
+ PAGE_SHIFT;
+#else
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
PAGE_SHIFT;
+#endif
if (num_pages > lock_limit) {
ret = -ENOMEM;
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_verbs.c
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -33,7 +33,10 @@
#include <rdma/ib_mad.h>
#include <rdma/ib_user_verbs.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
#include <linux/io.h>
+#endif
#include <linux/utsname.h>
#include "ipath_kernel.h"
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_verbs.h
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -40,6 +40,7 @@
#include <linux/interrupt.h>
#include <rdma/ib_pack.h>
+#include "ipath_backport.h"
#include "ipath_layer.h"
#define QPN_MAX (1 << 24)
Index: gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/Makefile
===================================================================
--- gen2_linux-20060907-1103_check.orig/drivers/infiniband/hw/ipath/Makefile
+++ gen2_linux-20060907-1103_check/drivers/infiniband/hw/ipath/Makefile
@@ -30,6 +30,7 @@ ib_ipath-y := \
ipath_verbs_mcast.o \
ipath_verbs.o
-ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
+ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o \
+ iowrite32_copy_x86_64.o
ib_ipath-$(CONFIG_X86_64) += memcpy_cachebypass_x86_64.o
ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o
More information about the ewg
mailing list