[openib-general] [PATCH RFC 05/10] ofed_1_2 Backport cxgb3 to2.6.15

Steve Wise swise at opengridcomputing.com
Thu Jan 18 11:23:26 PST 2007


Here is what I've coded up.  It compiles ok on staging.openfabrics.org.
You can pull this from

git://staging.openfabrics.org/~swise/ofed_1_2 ofed_1_2

Steve.

----

commit b46734fae0a7b519ce22569cce4f5ba2df33aa77
Author: Steve Wise <swise at hosting.openfabrics.org>
Date:   Thu Jan 18 11:07:29 2007 -0800

    Backport to 2.6.15_ubuntu606
    
    This is the kernel.org 2.6.15 backport with a few tweaks:
    
    - recasting addr paramater for __set_bit() and __clear_bit()
    - removed backport for __netif_rx_schedule_prep()
    
    Signed-off-by: Steve Wise <swise at opengridcomputing.com>

diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/asm/bitops.h b/kernel_addons/backport/2.6.15_ubuntu606/include/asm/bitops.h
new file mode 100644
index 0000000..58ebe41
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/asm/bitops.h
@@ -0,0 +1,20 @@
+#ifndef BACKPORT_ASM_BITOPS_TO_2_6_15_UBUNTU606
+#define BACKPORT_ASM_BITOPS_TO_2_6_15_UBUNTU606
+
+#include_next <asm/bitops.h>
+
+static __inline__ void __backport_set_bit(int nr, void * addr)
+{
+	__set_bit(nr, (volatile void *)addr);
+}
+
+#define __set_bit __backport_set_bit
+
+static __inline__ void __backport_clear_bit(int nr, void * addr)
+{
+	__clear_bit(nr, (volatile void *)addr);
+}
+
+#define __clear_bit __backport_clear_bit
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/bitops.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/bitops.h
new file mode 100644
index 0000000..d9752fc
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/bitops.h
@@ -0,0 +1,24 @@
+#include_next <linux/bitops.h>
+#ifndef LINUX_BITOPS_BACKPORT_2_6_15
+#define LINUX_BITOPS_BACKPORT_2_6_15
+
+static inline int fls64(__u64 x)
+{
+	__u32 h = x >> 32;
+	if (h)
+		return fls(h) + 32;
+	return fls(x);
+}
+
+#endif
+#ifndef LINUX_BITOPS_BACKPORT_2_6_16
+#define LINUX_BITOPS_BACKPORT_2_6_16
+
+static inline unsigned fls_long(unsigned long l)
+{
+	if (sizeof(l) == 4)
+		return fls(l);
+	return fls64(l);
+}
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/device.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/device.h
new file mode 100644
index 0000000..324f20e
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/device.h
@@ -0,0 +1,9 @@
+#ifndef LINUX_DEVICE_BACKPORT_H
+#define LINUX_DEVICE_BACKPORT_H
+
+#include_next <linux/device.h>
+
+#define add_uevent_var add_hotplug_env_var
+#define uevent hotplug
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/fs.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/fs.h
new file mode 100644
index 0000000..f0631fb
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/fs.h
@@ -0,0 +1,8 @@
+#ifndef BACKPORT_LINUX_FS_H
+#define BACKPORT_LINUX_FS_H
+
+#include_next <linux/fs.h>
+
+#define i_private u.generic_ip
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/genalloc.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/genalloc.h
new file mode 100644
index 0000000..3c23c68
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/genalloc.h
@@ -0,0 +1,42 @@
+/*
+ * Basic general purpose allocator for managing special purpose memory
+ * not managed by the regular kmalloc/kfree interface.
+ * Uses for this includes on-device special memory, uncached memory
+ * etc.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+
+/*
+ *  General purpose special memory pool descriptor.
+ */
+struct gen_pool {
+	rwlock_t lock;
+	struct list_head chunks;	/* list of chunks in this pool */
+	int min_alloc_order;		/* minimum allocation order */
+};
+
+/*
+ *  General purpose special memory pool chunk descriptor.
+ */
+struct gen_pool_chunk {
+	spinlock_t lock;
+	struct list_head next_chunk;	/* next chunk in pool */
+	unsigned long start_addr;	/* starting address of memory chunk */
+	unsigned long end_addr;		/* ending address of memory chunk */
+	unsigned long bits[0];		/* bitmap for allocating memory chunk */
+};
+
+extern struct gen_pool *ib_gen_pool_create(int, int);
+extern int ib_gen_pool_add(struct gen_pool *, unsigned long, size_t, int);
+extern void ib_gen_pool_destroy(struct gen_pool *);
+extern unsigned long ib_gen_pool_alloc(struct gen_pool *, size_t);
+extern void ib_gen_pool_free(struct gen_pool *, unsigned long, size_t);
+
+#define gen_pool_create ib_gen_pool_create
+#define gen_pool_add ib_gen_pool_add
+#define gen_pool_destroy ib_gen_pool_destroy
+#define gen_pool_alloc ib_gen_pool_alloc
+#define gen_pool_free ib_gen_pool_free
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/inetdevice.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/inetdevice.h
new file mode 100644
index 0000000..7a32313
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/inetdevice.h
@@ -0,0 +1,28 @@
+#ifndef _LINUX_INETDEVICE_BACKPORT_TO_2_6_17
+#define _LINUX_INETDEVICE_BACKPORT_TO_2_6_17
+
+#include_next <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+
+static inline struct net_device *xxx_ip_dev_find(u32 addr)
+{
+	struct net_device *dev;
+	u32 ip;
+
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev; dev = dev->next) {
+		ip = inet_select_addr(dev, 0, RT_SCOPE_LINK);
+		if (ip == addr) {
+			dev_hold(dev);
+			break;
+		}
+	}
+	read_unlock(&dev_base_lock);
+
+	return dev;
+}
+
+#define ip_dev_find xxx_ip_dev_find
+
+#endif
+
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/interrupt.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/interrupt.h
new file mode 100644
index 0000000..66e66a9
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/interrupt.h
@@ -0,0 +1,17 @@
+#ifndef BACKPORT_LINUX_INTERRUPT_TO_2_6_18
+#define BACKPORT_LINUX_INTERRUPT_TO_2_6_18
+#include_next <linux/interrupt.h>
+
+static inline int 
+backport_request_irq(unsigned int irq,
+                     irqreturn_t (*handler)(int, void *),
+                     unsigned long flags, const char *dev_name, void *dev_id)
+{
+	return request_irq(irq, 
+		           (irqreturn_t (*)(int, void *, struct pt_regs *))handler, 
+			   flags, dev_name, dev_id);
+}
+
+#define request_irq backport_request_irq
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/kernel.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/kernel.h
new file mode 100644
index 0000000..a37dcd5
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/kernel.h
@@ -0,0 +1,7 @@
+#ifndef BACKPORT_KERNEL_H_2_6_19
+#define BACKPORT_KERNEL_H_2_6_19
+
+#include_next <linux/kernel.h>
+#include <linux/log2.h>
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/lockdep.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/lockdep.h
new file mode 100644
index 0000000..0c34f36
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/lockdep.h
@@ -0,0 +1,355 @@
+/*
+ * Runtime locking correctness validator
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo at redhat.com>
+ *
+ * see Documentation/lockdep-design.txt for more details.
+ */
+#ifndef __LINUX_LOCKDEP_H
+#define __LINUX_LOCKDEP_H
+
+#if 0
+#include <linux/linkage.h>
+#include <linux/list.h>
+#include <linux/debug_locks.h>
+#include <linux/stacktrace.h>
+#endif
+
+#ifdef CONFIG_LOCKDEP
+
+/*
+ * Lock-class usage-state bits:
+ */
+enum lock_usage_bit
+{
+	LOCK_USED = 0,
+	LOCK_USED_IN_HARDIRQ,
+	LOCK_USED_IN_SOFTIRQ,
+	LOCK_ENABLED_SOFTIRQS,
+	LOCK_ENABLED_HARDIRQS,
+	LOCK_USED_IN_HARDIRQ_READ,
+	LOCK_USED_IN_SOFTIRQ_READ,
+	LOCK_ENABLED_SOFTIRQS_READ,
+	LOCK_ENABLED_HARDIRQS_READ,
+	LOCK_USAGE_STATES
+};
+
+/*
+ * Usage-state bitmasks:
+ */
+#define LOCKF_USED			(1 << LOCK_USED)
+#define LOCKF_USED_IN_HARDIRQ		(1 << LOCK_USED_IN_HARDIRQ)
+#define LOCKF_USED_IN_SOFTIRQ		(1 << LOCK_USED_IN_SOFTIRQ)
+#define LOCKF_ENABLED_HARDIRQS		(1 << LOCK_ENABLED_HARDIRQS)
+#define LOCKF_ENABLED_SOFTIRQS		(1 << LOCK_ENABLED_SOFTIRQS)
+
+#define LOCKF_ENABLED_IRQS (LOCKF_ENABLED_HARDIRQS | LOCKF_ENABLED_SOFTIRQS)
+#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
+
+#define LOCKF_USED_IN_HARDIRQ_READ	(1 << LOCK_USED_IN_HARDIRQ_READ)
+#define LOCKF_USED_IN_SOFTIRQ_READ	(1 << LOCK_USED_IN_SOFTIRQ_READ)
+#define LOCKF_ENABLED_HARDIRQS_READ	(1 << LOCK_ENABLED_HARDIRQS_READ)
+#define LOCKF_ENABLED_SOFTIRQS_READ	(1 << LOCK_ENABLED_SOFTIRQS_READ)
+
+#define LOCKF_ENABLED_IRQS_READ \
+		(LOCKF_ENABLED_HARDIRQS_READ | LOCKF_ENABLED_SOFTIRQS_READ)
+#define LOCKF_USED_IN_IRQ_READ \
+		(LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ)
+
+#define MAX_LOCKDEP_SUBCLASSES		8UL
+
+/*
+ * Lock-classes are keyed via unique addresses, by embedding the
+ * lockclass-key into the kernel (or module) .data section. (For
+ * static locks we use the lock address itself as the key.)
+ */
+struct lockdep_subclass_key {
+	char __one_byte;
+} __attribute__ ((__packed__));
+
+struct lock_class_key {
+	struct lockdep_subclass_key	subkeys[MAX_LOCKDEP_SUBCLASSES];
+};
+
+/*
+ * The lock-class itself:
+ */
+struct lock_class {
+	/*
+	 * class-hash:
+	 */
+	struct list_head		hash_entry;
+
+	/*
+	 * global list of all lock-classes:
+	 */
+	struct list_head		lock_entry;
+
+	struct lockdep_subclass_key	*key;
+	unsigned int			subclass;
+
+	/*
+	 * IRQ/softirq usage tracking bits:
+	 */
+	unsigned long			usage_mask;
+	struct stack_trace		usage_traces[LOCK_USAGE_STATES];
+
+	/*
+	 * These fields represent a directed graph of lock dependencies,
+	 * to every node we attach a list of "forward" and a list of
+	 * "backward" graph nodes.
+	 */
+	struct list_head		locks_after, locks_before;
+
+	/*
+	 * Generation counter, when doing certain classes of graph walking,
+	 * to ensure that we check one node only once:
+	 */
+	unsigned int			version;
+
+	/*
+	 * Statistics counter:
+	 */
+	unsigned long			ops;
+
+	const char			*name;
+	int				name_version;
+};
+
+/*
+ * Map the lock object (the lock instance) to the lock-class object.
+ * This is embedded into specific lock instances:
+ */
+struct lockdep_map {
+	struct lock_class_key		*key;
+	struct lock_class		*class_cache;
+	const char			*name;
+};
+
+/*
+ * Every lock has a list of other locks that were taken after it.
+ * We only grow the list, never remove from it:
+ */
+struct lock_list {
+	struct list_head		entry;
+	struct lock_class		*class;
+	struct stack_trace		trace;
+};
+
+/*
+ * We record lock dependency chains, so that we can cache them:
+ */
+struct lock_chain {
+	struct list_head		entry;
+	u64				chain_key;
+};
+
+struct held_lock {
+	/*
+	 * One-way hash of the dependency chain up to this point. We
+	 * hash the hashes step by step as the dependency chain grows.
+	 *
+	 * We use it for dependency-caching and we skip detection
+	 * passes and dependency-updates if there is a cache-hit, so
+	 * it is absolutely critical for 100% coverage of the validator
+	 * to have a unique key value for every unique dependency path
+	 * that can occur in the system, to make a unique hash value
+	 * as likely as possible - hence the 64-bit width.
+	 *
+	 * The task struct holds the current hash value (initialized
+	 * with zero), here we store the previous hash value:
+	 */
+	u64				prev_chain_key;
+	struct lock_class		*class;
+	unsigned long			acquire_ip;
+	struct lockdep_map		*instance;
+
+	/*
+	 * The lock-stack is unified in that the lock chains of interrupt
+	 * contexts nest ontop of process context chains, but we 'separate'
+	 * the hashes by starting with 0 if we cross into an interrupt
+	 * context, and we also keep do not add cross-context lock
+	 * dependencies - the lock usage graph walking covers that area
+	 * anyway, and we'd just unnecessarily increase the number of
+	 * dependencies otherwise. [Note: hardirq and softirq contexts
+	 * are separated from each other too.]
+	 *
+	 * The following field is used to detect when we cross into an
+	 * interrupt context:
+	 */
+	int				irq_context;
+	int				trylock;
+	int				read;
+	int				check;
+	int				hardirqs_off;
+};
+
+/*
+ * Initialization, self-test and debugging-output methods:
+ */
+extern void lockdep_init(void);
+extern void lockdep_info(void);
+extern void lockdep_reset(void);
+extern void lockdep_reset_lock(struct lockdep_map *lock);
+extern void lockdep_free_key_range(void *start, unsigned long size);
+
+extern void lockdep_off(void);
+extern void lockdep_on(void);
+extern int lockdep_internal(void);
+
+/*
+ * These methods are used by specific locking variants (spinlocks,
+ * rwlocks, mutexes and rwsems) to pass init/acquire/release events
+ * to lockdep:
+ */
+
+extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
+			     struct lock_class_key *key);
+
+/*
+ * Reinitialize a lock key - for cases where there is special locking or
+ * special initialization of locks so that the validator gets the scope
+ * of dependencies wrong: they are either too broad (they need a class-split)
+ * or they are too narrow (they suffer from a false class-split):
+ */
+#define lockdep_set_class(lock, key) \
+		lockdep_init_map(&(lock)->dep_map, #key, key)
+#define lockdep_set_class_and_name(lock, key, name) \
+		lockdep_init_map(&(lock)->dep_map, name, key)
+
+/*
+ * Acquire a lock.
+ *
+ * Values for "read":
+ *
+ *   0: exclusive (write) acquire
+ *   1: read-acquire (no recursion allowed)
+ *   2: read-acquire with same-instance recursion allowed
+ *
+ * Values for check:
+ *
+ *   0: disabled
+ *   1: simple checks (freeing, held-at-exit-time, etc.)
+ *   2: full validation
+ */
+extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
+			 int trylock, int read, int check, unsigned long ip);
+
+extern void lock_release(struct lockdep_map *lock, int nested,
+			 unsigned long ip);
+
+# define INIT_LOCKDEP				.lockdep_recursion = 0,
+
+#else /* !LOCKDEP */
+
+static inline void lockdep_off(void)
+{
+}
+
+static inline void lockdep_on(void)
+{
+}
+
+static inline int lockdep_internal(void)
+{
+	return 0;
+}
+
+# define lock_acquire(l, s, t, r, c, i)		do { } while (0)
+# define lock_release(l, n, i)			do { } while (0)
+# define lockdep_init()				do { } while (0)
+# define lockdep_info()				do { } while (0)
+# define lockdep_init_map(lock, name, key)	do { (void)(key); } while (0)
+# define lockdep_set_class(lock, key)		do { (void)(key); } while (0)
+# define lockdep_set_class_and_name(lock, key, name) \
+		do { (void)(key); } while (0)
+# define INIT_LOCKDEP
+# define lockdep_reset()		do { debug_locks = 1; } while (0)
+# define lockdep_free_key_range(start, size)	do { } while (0)
+/*
+ * The class key takes no space if lockdep is disabled:
+ */
+struct lock_class_key { };
+#endif /* !LOCKDEP */
+
+#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS)
+extern void early_init_irq_lock_class(void);
+#else
+# define early_init_irq_lock_class()		do { } while (0)
+#endif
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+extern void early_boot_irqs_off(void);
+extern void early_boot_irqs_on(void);
+#else
+# define early_boot_irqs_off()			do { } while (0)
+# define early_boot_irqs_on()			do { } while (0)
+#endif
+
+/*
+ * For trivial one-depth nesting of a lock-class, the following
+ * global define can be used. (Subsystems with multiple levels
+ * of nesting should define their own lock-nesting subclasses.)
+ */
+#define SINGLE_DEPTH_NESTING			1
+
+/*
+ * Map the dependency ops to NOP or to real lockdep ops, depending
+ * on the per lock-class debug mode:
+ */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+# else
+#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+# endif
+# define spin_release(l, n, i)			lock_release(l, n, i)
+#else
+# define spin_acquire(l, s, t, i)		do { } while (0)
+# define spin_release(l, n, i)			do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 2, i)
+# else
+#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 1, i)
+# endif
+# define rwlock_release(l, n, i)		lock_release(l, n, i)
+#else
+# define rwlock_acquire(l, s, t, i)		do { } while (0)
+# define rwlock_acquire_read(l, s, t, i)	do { } while (0)
+# define rwlock_release(l, n, i)		do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+# else
+#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+# endif
+# define mutex_release(l, n, i)			lock_release(l, n, i)
+#else
+# define mutex_acquire(l, s, t, i)		do { } while (0)
+# define mutex_release(l, n, i)			do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 2, i)
+# else
+#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 1, i)
+# endif
+# define rwsem_release(l, n, i)			lock_release(l, n, i)
+#else
+# define rwsem_acquire(l, s, t, i)		do { } while (0)
+# define rwsem_acquire_read(l, s, t, i)		do { } while (0)
+# define rwsem_release(l, n, i)			do { } while (0)
+#endif
+
+#endif /* __LINUX_LOCKDEP_H */
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/log2.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/log2.h
new file mode 100644
index 0000000..d02e1a5
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/log2.h
@@ -0,0 +1,157 @@
+/* Integer base 2 logarithm calculation
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.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 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_LOG2_H
+#define _LINUX_LOG2_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+/*
+ * deal with unrepresentable constant logarithms
+ */
+extern __attribute__((const, noreturn))
+int ____ilog2_NaN(void);
+
+/*
+ * non-constant log of base 2 calculators
+ * - the arch may override these in asm/bitops.h if they can be implemented
+ *   more efficiently than using fls() and fls64()
+ * - the arch is not required to handle n==0 if implementing the fallback
+ */
+#ifndef CONFIG_ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+	return fls(n) - 1;
+}
+#endif
+
+#ifndef CONFIG_ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+	return fls64(n) - 1;
+}
+#endif
+
+/*
+ * round up to nearest power of two
+ */
+static inline __attribute__((const))
+unsigned long __roundup_pow_of_two(unsigned long n)
+{
+	return 1UL << fls_long(n - 1);
+}
+
+/**
+ * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
+ * @n - parameter
+ *
+ * constant-capable log of base 2 calculation
+ * - this can be used to initialise global variables from constant data, hence
+ *   the massive ternary operator construction
+ *
+ * selects the appropriately-sized optimised version depending on sizeof(n)
+ */
+#define ilog2(n)				\
+(						\
+	__builtin_constant_p(n) ? (		\
+		(n) < 1 ? ____ilog2_NaN() :	\
+		(n) & (1ULL << 63) ? 63 :	\
+		(n) & (1ULL << 62) ? 62 :	\
+		(n) & (1ULL << 61) ? 61 :	\
+		(n) & (1ULL << 60) ? 60 :	\
+		(n) & (1ULL << 59) ? 59 :	\
+		(n) & (1ULL << 58) ? 58 :	\
+		(n) & (1ULL << 57) ? 57 :	\
+		(n) & (1ULL << 56) ? 56 :	\
+		(n) & (1ULL << 55) ? 55 :	\
+		(n) & (1ULL << 54) ? 54 :	\
+		(n) & (1ULL << 53) ? 53 :	\
+		(n) & (1ULL << 52) ? 52 :	\
+		(n) & (1ULL << 51) ? 51 :	\
+		(n) & (1ULL << 50) ? 50 :	\
+		(n) & (1ULL << 49) ? 49 :	\
+		(n) & (1ULL << 48) ? 48 :	\
+		(n) & (1ULL << 47) ? 47 :	\
+		(n) & (1ULL << 46) ? 46 :	\
+		(n) & (1ULL << 45) ? 45 :	\
+		(n) & (1ULL << 44) ? 44 :	\
+		(n) & (1ULL << 43) ? 43 :	\
+		(n) & (1ULL << 42) ? 42 :	\
+		(n) & (1ULL << 41) ? 41 :	\
+		(n) & (1ULL << 40) ? 40 :	\
+		(n) & (1ULL << 39) ? 39 :	\
+		(n) & (1ULL << 38) ? 38 :	\
+		(n) & (1ULL << 37) ? 37 :	\
+		(n) & (1ULL << 36) ? 36 :	\
+		(n) & (1ULL << 35) ? 35 :	\
+		(n) & (1ULL << 34) ? 34 :	\
+		(n) & (1ULL << 33) ? 33 :	\
+		(n) & (1ULL << 32) ? 32 :	\
+		(n) & (1ULL << 31) ? 31 :	\
+		(n) & (1ULL << 30) ? 30 :	\
+		(n) & (1ULL << 29) ? 29 :	\
+		(n) & (1ULL << 28) ? 28 :	\
+		(n) & (1ULL << 27) ? 27 :	\
+		(n) & (1ULL << 26) ? 26 :	\
+		(n) & (1ULL << 25) ? 25 :	\
+		(n) & (1ULL << 24) ? 24 :	\
+		(n) & (1ULL << 23) ? 23 :	\
+		(n) & (1ULL << 22) ? 22 :	\
+		(n) & (1ULL << 21) ? 21 :	\
+		(n) & (1ULL << 20) ? 20 :	\
+		(n) & (1ULL << 19) ? 19 :	\
+		(n) & (1ULL << 18) ? 18 :	\
+		(n) & (1ULL << 17) ? 17 :	\
+		(n) & (1ULL << 16) ? 16 :	\
+		(n) & (1ULL << 15) ? 15 :	\
+		(n) & (1ULL << 14) ? 14 :	\
+		(n) & (1ULL << 13) ? 13 :	\
+		(n) & (1ULL << 12) ? 12 :	\
+		(n) & (1ULL << 11) ? 11 :	\
+		(n) & (1ULL << 10) ? 10 :	\
+		(n) & (1ULL <<  9) ?  9 :	\
+		(n) & (1ULL <<  8) ?  8 :	\
+		(n) & (1ULL <<  7) ?  7 :	\
+		(n) & (1ULL <<  6) ?  6 :	\
+		(n) & (1ULL <<  5) ?  5 :	\
+		(n) & (1ULL <<  4) ?  4 :	\
+		(n) & (1ULL <<  3) ?  3 :	\
+		(n) & (1ULL <<  2) ?  2 :	\
+		(n) & (1ULL <<  1) ?  1 :	\
+		(n) & (1ULL <<  0) ?  0 :	\
+		____ilog2_NaN()			\
+				   ) :		\
+	(sizeof(n) <= 4) ?			\
+	__ilog2_u32(n) :			\
+	__ilog2_u64(n)				\
+ )
+
+/**
+ * roundup_pow_of_two - round the given value up to nearest power of two
+ * @n - parameter
+ *
+ * round the given balue up to the nearest power of two
+ * - the result is undefined when n == 0
+ * - this can be used to initialise global variables from constant data
+ */
+#define roundup_pow_of_two(n)			\
+(						\
+	__builtin_constant_p(n) ? (		\
+		(n == 1) ? 0 :			\
+		(1UL << (ilog2((n) - 1) + 1))	\
+				   ) :		\
+	__roundup_pow_of_two(n)			\
+ )
+
+#endif /* _LINUX_LOG2_H */
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/mutex.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/mutex.h
new file mode 100644
index 0000000..ef5a1b4
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/mutex.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006 Cisco Systems.  All rights reserved.
+ *
+ * This file is released under the GPLv2.
+ */
+
+/* mutex compatibility for pre-2.6.16 kernels */
+
+#ifndef __LINUX_MUTEX_H
+#define __LINUX_MUTEX_H
+
+#include <asm/semaphore.h>
+#include <linux/lockdep.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 /* __LINUX_MUTEX_H */
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/netdevice.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/netdevice.h
new file mode 100644
index 0000000..225eeda
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/netdevice.h
@@ -0,0 +1,22 @@
+#ifndef _LINUX_NETDEVICE_BACKPORT_TO_2_6_16
+#define _LINUX_NETDEVICE_BACKPORT_TO_2_6_16
+
+#include_next <linux/netdevice.h>
+
+static inline void netif_tx_lock(struct net_device *dev)
+{
+	spin_lock(&dev->xmit_lock);
+	dev->xmit_lock_owner = smp_processor_id();
+}
+
+static inline void netif_tx_unlock(struct net_device *dev)
+{
+	dev->xmit_lock_owner = -1;
+	spin_unlock(&dev->xmit_lock);
+}
+
+#undef SET_ETHTOOL_OPS
+#define SET_ETHTOOL_OPS(netdev, ops) \
+	(netdev)->ethtool_ops = (struct ethtool_ops *)(ops)
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/random.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/random.h
new file mode 100644
index 0000000..2ea2e1f
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/random.h
@@ -0,0 +1,15 @@
+#ifndef BACKPORT_LINUX_RANDOM_TO_2_6_18
+#define BACKPORT_LINUX_RANDOM_TO_2_6_18
+#include_next <linux/random.h>
+
+static inline u32 backport_random32(void)
+{
+	u32 v;
+
+	get_random_bytes(&v, sizeof(u32));
+	return v;
+}
+
+#define random32 backport_random32
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/rwsem.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/rwsem.h
new file mode 100644
index 0000000..1ad4e13
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/rwsem.h
@@ -0,0 +1,8 @@
+#ifndef _LINUX_RWSEM_BACKPORT_TO_2_6_17
+#define _LINUX_RWSEM_BACKPORT_TO_2_6_17
+
+#include_next <linux/rwsem.h>
+
+#define down_read_nested(sem, subclass) down_read(sem)
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/signal.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/signal.h
new file mode 100644
index 0000000..78adbab
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/signal.h
@@ -0,0 +1,8 @@
+#ifndef _LINUX_SIGNAL_BACKPORT_2_6_17
+#define _LINUX_SIGNAL_BACKPORT_2_6_17
+
+#include_next <linux/signal.h>
+
+#define IRQF_SHARED SA_SHIRQ
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/skbuff.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/skbuff.h
new file mode 100644
index 0000000..70bf011
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/skbuff.h
@@ -0,0 +1,11 @@
+#ifndef LINUX_SKBUFF_H_BACKPORT
+#define LINUX_SKBUFF_H_BACKPORT
+
+#include_next <linux/skbuff.h>
+
+#define CHECKSUM_PARTIAL CHECKSUM_HW 
+#define CHECKSUM_COMPLETE CHECKSUM_HW 
+
+#define gso_size tso_size
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/slab.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/slab.h
new file mode 100644
index 0000000..46ac6e5
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/slab.h
@@ -0,0 +1,34 @@
+#include_next <linux/slab.h>
+
+#include_next <linux/slab.h>
+
+#ifndef BACKPORT_LINUX_STRING_TO_2_6_18
+#define BACKPORT_LINUX_STRING_TO_2_6_18
+
+static inline
+void *kmemdup(const void *src, size_t len, gfp_t gfp)
+{
+       void *p;
+
+       p = kmalloc(len, gfp);
+       if (p)
+               memcpy(p, src, len);
+       return p;
+}
+
+#endif
+#ifndef BACKPORT_LINUX_STRING_TO_2_6_18
+#define BACKPORT_LINUX_STRING_TO_2_6_18
+
+static inline
+void *kmemdup(const void *src, size_t len, gfp_t gfp)
+{
+       void *p;
+
+       p = kmalloc(len, gfp);
+       if (p)
+               memcpy(p, src, len);
+       return p;
+}
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/spinlock.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/spinlock.h
new file mode 100644
index 0000000..db39389
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/spinlock.h
@@ -0,0 +1,7 @@
+#ifndef BACKPORT_LINUX_SPINLOCK_H
+#define BACKPORT_LINUX_SPINLOCK_H
+
+#include_next <linux/spinlock.h>
+#define spin_lock_nested(lock, subclass) spin_lock(lock)
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/types.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/types.h
new file mode 100644
index 0000000..86e334f
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/types.h
@@ -0,0 +1,6 @@
+#ifndef BACKPORT_LINUX_TYPES_TO_2_6_15
+#define BACKPORT_LINUX_TYPES_TO_2_6_15
+#include_next <linux/types.h>
+
+#define BITS_PER_BYTE 8
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/linux/workqueue.h b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/workqueue.h
new file mode 100644
index 0000000..cc8b2cd
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/linux/workqueue.h
@@ -0,0 +1,50 @@
+#ifndef BACKPORT_LINUX_WORKQUEUE_TO_2_6_19
+#define BACKPORT_LINUX_WORKQUEUE_TO_2_6_19
+
+#include_next <linux/workqueue.h>
+
+struct delayed_work {
+	struct work_struct work;
+};
+
+static inline void
+backport_INIT_WORK(struct work_struct *work, void *func)
+{
+	INIT_WORK(work, func, work);
+}
+
+static inline int backport_queue_delayed_work(struct workqueue_struct *wq,
+					      struct delayed_work *work,
+					      unsigned long delay)
+{
+	return queue_delayed_work(wq, &work->work, delay);
+}
+
+static inline int 
+backport_cancel_delayed_work(struct delayed_work *work)
+{
+	return cancel_delayed_work(&work->work);
+}
+
+static inline void 
+backport_cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, struct delayed_work *work)
+{
+	cancel_rearming_delayed_workqueue(wq, &work->work);
+}
+
+
+#undef INIT_WORK
+#define INIT_WORK(_work, _func) backport_INIT_WORK(_work, _func)
+#define INIT_DELAYED_WORK(_work, _func) INIT_WORK(&(_work)->work, _func)
+
+#undef DECLARE_WORK
+#define DECLARE_WORK(n, f) \
+	struct work_struct n = __WORK_INITIALIZER(n, (void (*)(void *))f, &(n))
+#define DECLARE_DELAYED_WORK(n, f) \
+	struct delayed_work n = { .work = __WORK_INITIALIZER(n.work, f, &(n.work)) }
+
+#define queue_delayed_work backport_queue_delayed_work
+#define cancel_delayed_work backport_cancel_delayed_work
+#define cancel_rearming_delayed_workqueue backport_cancel_rearming_delayed_workqueue
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/net/inet_sock.h b/kernel_addons/backport/2.6.15_ubuntu606/include/net/inet_sock.h
new file mode 100644
index 0000000..962da47
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/net/inet_sock.h
@@ -0,0 +1,6 @@
+#ifndef NET_INET_SOCK_H
+#define NET_INET_SOCK_H
+
+#include <linux/ip.h>
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/net/netevent.h b/kernel_addons/backport/2.6.15_ubuntu606/include/net/netevent.h
new file mode 100644
index 0000000..e5d2162
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/net/netevent.h
@@ -0,0 +1,33 @@
+#ifndef _NET_EVENT_H
+#define _NET_EVENT_H
+
+/*
+ *	Generic netevent notifiers
+ *
+ *	Authors:
+ *      Tom Tucker              <tom at opengridcomputing.com>
+ *      Steve Wise              <swise at opengridcomputing.com>
+ *
+ * 	Changes:
+ */
+#ifdef __KERNEL__
+
+#include <net/dst.h>
+
+struct netevent_redirect {
+	struct dst_entry *old;
+	struct dst_entry *new;
+};
+
+enum netevent_notif_type {
+	NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */
+	NETEVENT_PMTU_UPDATE,	   /* arg is struct dst_entry ptr */
+	NETEVENT_REDIRECT,	   /* arg is struct netevent_redirect ptr */
+};
+
+extern int register_netevent_notifier(struct notifier_block *nb);
+extern int unregister_netevent_notifier(struct notifier_block *nb);
+extern int call_netevent_notifiers(unsigned long val, void *v);
+
+#endif
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/net/sock.h b/kernel_addons/backport/2.6.15_ubuntu606/include/net/sock.h
new file mode 100644
index 0000000..f621a71
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/net/sock.h
@@ -0,0 +1,8 @@
+#ifndef _NET_SOCK_SLES_BACKPORT_H
+#define _NET_SOCK_SLES_BACKPORT_H
+
+#include_next <net/sock.h>
+
+#define sk_eat_skb(a, b, c) sk_eat_skb(a, b)
+
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/scsi/scsi.h b/kernel_addons/backport/2.6.15_ubuntu606/include/scsi/scsi.h
new file mode 100644
index 0000000..352330d
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/scsi/scsi.h
@@ -0,0 +1,7 @@
+#ifndef _SCSI_SCSI_H_BACKPORT
+#define _SCSI_SCSI_H_BACKPORT
+
+#include_next <scsi/scsi.h>
+
+#define SCAN_WILD_CARD	 ~0
+#endif
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/src/genalloc.c b/kernel_addons/backport/2.6.15_ubuntu606/include/src/genalloc.c
new file mode 100644
index 0000000..75ae68c
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/src/genalloc.c
@@ -0,0 +1,198 @@
+/*
+ * Basic general purpose allocator for managing special purpose memory
+ * not managed by the regular kmalloc/kfree interface.
+ * Uses for this includes on-device special memory, uncached memory
+ * etc.
+ *
+ * Copyright 2005 (C) Jes Sorensen <jes at trained-monkey.org>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/genalloc.h>
+
+
+/**
+ * gen_pool_create - create a new special memory pool
+ * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents
+ * @nid: node id of the node the pool structure should be allocated on, or -1
+ *
+ * Create a new special memory pool that can be used to manage special purpose
+ * memory not managed by the regular kmalloc/kfree interface.
+ */
+struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
+{
+	struct gen_pool *pool;
+
+	pool = kmalloc_node(sizeof(struct gen_pool), GFP_KERNEL, nid);
+	if (pool != NULL) {
+		rwlock_init(&pool->lock);
+		INIT_LIST_HEAD(&pool->chunks);
+		pool->min_alloc_order = min_alloc_order;
+	}
+	return pool;
+}
+EXPORT_SYMBOL(gen_pool_create);
+
+/**
+ * gen_pool_add - add a new chunk of special memory to the pool
+ * @pool: pool to add new memory chunk to
+ * @addr: starting address of memory chunk to add to pool
+ * @size: size in bytes of the memory chunk to add to pool
+ * @nid: node id of the node the chunk structure and bitmap should be
+ *       allocated on, or -1
+ *
+ * Add a new chunk of special memory to the specified pool.
+ */
+int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
+		 int nid)
+{
+	struct gen_pool_chunk *chunk;
+	int nbits = size >> pool->min_alloc_order;
+	int nbytes = sizeof(struct gen_pool_chunk) +
+				(nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
+
+	chunk = kmalloc_node(nbytes, GFP_KERNEL, nid);
+	if (unlikely(chunk == NULL))
+		return -1;
+
+	memset(chunk, 0, nbytes);
+	spin_lock_init(&chunk->lock);
+	chunk->start_addr = addr;
+	chunk->end_addr = addr + size;
+
+	write_lock(&pool->lock);
+	list_add(&chunk->next_chunk, &pool->chunks);
+	write_unlock(&pool->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(gen_pool_add);
+
+/**
+ * gen_pool_destroy - destroy a special memory pool
+ * @pool: pool to destroy
+ *
+ * Destroy the specified special memory pool. Verifies that there are no
+ * outstanding allocations.
+ */
+void gen_pool_destroy(struct gen_pool *pool)
+{
+	struct list_head *_chunk, *_next_chunk;
+	struct gen_pool_chunk *chunk;
+	int order = pool->min_alloc_order;
+	int bit, end_bit;
+
+
+	write_lock(&pool->lock);
+	list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
+		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+		list_del(&chunk->next_chunk);
+
+		end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+		bit = find_next_bit(chunk->bits, end_bit, 0);
+		BUG_ON(bit < end_bit);
+
+		kfree(chunk);
+	}
+	kfree(pool);
+	return;
+}
+EXPORT_SYMBOL(gen_pool_destroy);
+
+/**
+ * gen_pool_alloc - allocate special memory from the pool
+ * @pool: pool to allocate from
+ * @size: number of bytes to allocate from the pool
+ *
+ * Allocate the requested number of bytes from the specified pool.
+ * Uses a first-fit algorithm.
+ */
+unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
+{
+	struct list_head *_chunk;
+	struct gen_pool_chunk *chunk;
+	unsigned long addr, flags;
+	int order = pool->min_alloc_order;
+	int nbits, bit, start_bit, end_bit;
+
+	if (size == 0)
+		return 0;
+
+	nbits = (size + (1UL << order) - 1) >> order;
+
+	read_lock(&pool->lock);
+	list_for_each(_chunk, &pool->chunks) {
+		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+
+		end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+		end_bit -= nbits + 1;
+
+		spin_lock_irqsave(&chunk->lock, flags);
+		bit = -1;
+		while (bit + 1 < end_bit) {
+			bit = find_next_zero_bit(chunk->bits, end_bit, bit + 1);
+			if (bit >= end_bit)
+				break;
+
+			start_bit = bit;
+			if (nbits > 1) {
+				bit = find_next_bit(chunk->bits, bit + nbits,
+							bit + 1);
+				if (bit - start_bit < nbits)
+					continue;
+			}
+
+			addr = chunk->start_addr +
+					    ((unsigned long)start_bit << order);
+			while (nbits--)
+				__set_bit(start_bit++, &chunk->bits);
+			spin_unlock_irqrestore(&chunk->lock, flags);
+			read_unlock(&pool->lock);
+			return addr;
+		}
+		spin_unlock_irqrestore(&chunk->lock, flags);
+	}
+	read_unlock(&pool->lock);
+	return 0;
+}
+EXPORT_SYMBOL(gen_pool_alloc);
+
+/**
+ * gen_pool_free - free allocated special memory back to the pool
+ * @pool: pool to free to
+ * @addr: starting address of memory to free back to pool
+ * @size: size in bytes of memory to free
+ *
+ * Free previously allocated special memory back to the specified pool.
+ */
+void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
+{
+	struct list_head *_chunk;
+	struct gen_pool_chunk *chunk;
+	unsigned long flags;
+	int order = pool->min_alloc_order;
+	int bit, nbits;
+
+	nbits = (size + (1UL << order) - 1) >> order;
+
+	read_lock(&pool->lock);
+	list_for_each(_chunk, &pool->chunks) {
+		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+
+		if (addr >= chunk->start_addr && addr < chunk->end_addr) {
+			BUG_ON(addr + size > chunk->end_addr);
+			spin_lock_irqsave(&chunk->lock, flags);
+			bit = (addr - chunk->start_addr) >> order;
+			while (nbits--)
+				__clear_bit(bit++, &chunk->bits);
+			spin_unlock_irqrestore(&chunk->lock, flags);
+			break;
+		}
+	}
+	BUG_ON(nbits > 0);
+	read_unlock(&pool->lock);
+}
+EXPORT_SYMBOL(gen_pool_free);
diff --git a/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c b/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c
new file mode 100644
index 0000000..5ffadd1
--- /dev/null
+++ b/kernel_addons/backport/2.6.15_ubuntu606/include/src/netevent.c
@@ -0,0 +1,71 @@
+/*
+ *	Network event notifiers
+ *
+ *	Authors:
+ *      Tom Tucker             <tom at opengridcomputing.com>
+ *      Steve Wise             <swise at opengridcomputing.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 of the License, or (at your option) any later version.
+ *
+ *	Fixes:
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/notifier.h>
+
+static struct notifier_block *netevent_notif_chain;
+
+/**
+ *	register_netevent_notifier - register a netevent notifier block
+ *	@nb: notifier
+ *
+ *	Register a notifier to be called when a netevent occurs.
+ *	The notifier passed is linked into the kernel structures and must
+ *	not be reused until it has been unregistered. A negative errno code
+ *	is returned on a failure.
+ */
+int register_netevent_notifier(struct notifier_block *nb)
+{
+	int err;
+
+	err = notifier_chain_register(&netevent_notif_chain, nb);
+	return err;
+}
+
+/**
+ *	netevent_unregister_notifier - unregister a netevent notifier block
+ *	@nb: notifier
+ *
+ *	Unregister a notifier previously registered by
+ *	register_neigh_notifier(). The notifier is unlinked into the
+ *	kernel structures and may then be reused. A negative errno code
+ *	is returned on a failure.
+ */
+
+int unregister_netevent_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&netevent_notif_chain, nb);
+}
+
+/**
+ *	call_netevent_notifiers - call all netevent notifier blocks
+ *      @val: value passed unmodified to notifier function
+ *      @v:   pointer passed unmodified to notifier function
+ *
+ *	Call all neighbour notifier blocks.  Parameters and return value
+ *	are as for notifier_call_chain().
+ */
+
+int call_netevent_notifiers(unsigned long val, void *v)
+{
+	return notifier_call_chain(&netevent_notif_chain, val, v);
+}
+
+EXPORT_SYMBOL_GPL(register_netevent_notifier);
+EXPORT_SYMBOL_GPL(unregister_netevent_notifier);
+EXPORT_SYMBOL_GPL(call_netevent_notifiers);
diff --git a/kernel_patches/backport/2.6.15_ubuntu606/1_struct_path_revert_to_2_6_19.patch b/kernel_patches/backport/2.6.15_ubuntu606/1_struct_path_revert_to_2_6_19.patch
new file mode 100644
index 0000000..27eb62e
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/1_struct_path_revert_to_2_6_19.patch
@@ -0,0 +1,82 @@
+diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
+index a617ca7..4e16314 100644
+--- a/drivers/infiniband/core/uverbs_main.c
++++ b/drivers/infiniband/core/uverbs_main.c
+@@ -534,9 +534,9 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_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;
+diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
+index b932bcb..ddbcabd 100644
+--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
++++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
+@@ -1744,9 +1744,9 @@ static int ipath_assign_port(struct file *fp,
+ 		goto done;
+ 	}
+ 
+-	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);
+diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
+index 79a60f0..d9ff283 100644
+--- a/drivers/infiniband/hw/ipath/ipath_fs.c
++++ b/drivers/infiniband/hw/ipath/ipath_fs.c
+@@ -118,7 +118,7 @@ static ssize_t atomic_counters_read(struct file *file, char __user *buf,
+ 	u16 i;
+ 	struct ipath_devdata *dd;
+ 
+-	dd = file->f_path.dentry->d_inode->i_private;
++	dd = file->f_dentry->d_inode->i_private;
+ 
+ 	for (i = 0; i < NUM_COUNTERS; i++)
+ 		counters[i] = ipath_snap_cntr(dd, i);
+@@ -138,7 +138,7 @@ static ssize_t atomic_node_info_read(struct file *file, char __user *buf,
+ 	struct ipath_devdata *dd;
+ 	u64 guid;
+ 
+-	dd = file->f_path.dentry->d_inode->i_private;
++	dd = file->f_dentry->d_inode->i_private;
+ 
+ 	guid = be64_to_cpu(dd->ipath_guid);
+ 
+@@ -177,7 +177,7 @@ static ssize_t atomic_port_info_read(struct file *file, char __user *buf,
+ 	u32 tmp, tmp2;
+ 	struct ipath_devdata *dd;
+ 
+-	dd = file->f_path.dentry->d_inode->i_private;
++	dd = file->f_dentry->d_inode->i_private;
+ 
+ 	/* so we only initialize non-zero fields. */
+ 	memset(portinfo, 0, sizeof portinfo);
+@@ -324,7 +324,7 @@ static ssize_t flash_read(struct file *file, char __user *buf,
+ 		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;
+@@ -377,7 +377,7 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
+ 		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.15_ubuntu606/2_misc_device_to_2_6_19.patch b/kernel_patches/backport/2.6.15_ubuntu606/2_misc_device_to_2_6_19.patch
new file mode 100644
index 0000000..6601371
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/2_misc_device_to_2_6_19.patch
@@ -0,0 +1,33 @@
+diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
+index 81a5cdc..640508d 100644
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -842,7 +842,7 @@ static ssize_t show_abi_version(struct device *dev,
+ {
+ 	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)
+ {
+@@ -852,7 +852,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;
+@@ -865,7 +866,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.15_ubuntu606/addr_1_netevents_revert_to_2_6_17.patch b/kernel_patches/backport/2.6.15_ubuntu606/addr_1_netevents_revert_to_2_6_17.patch
new file mode 100644
index 0000000..316d8d2
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/addr_1_netevents_revert_to_2_6_17.patch
@@ -0,0 +1,76 @@
+commit e795d092507d571d66f2ec98d3efdc7dd284bf80
+Author: Tom Tucker <tom at opengridcomputing.com>
+Date:   Sun Jul 30 20:44:19 2006 -0700
+
+    [NET] infiniband: Cleanup ib_addr module to use the netevents
+    
+    Signed-off-by: Tom Tucker <tom at opengridcomputing.com>
+    Signed-off-by: Steve Wise <swise at opengridcomputing.com>
+    Signed-off-by: David S. Miller <davem at davemloft.net>
+
+diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
+index 1205e80..d294bbc 100644
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -35,7 +35,6 @@ #include <linux/if_arp.h>
+ #include <net/arp.h>
+ #include <net/neighbour.h>
+ #include <net/route.h>
+-#include <net/netevent.h>
+ #include <rdma/ib_addr.h>
+ 
+ MODULE_AUTHOR("Sean Hefty");
+@@ -327,22 +326,25 @@ void rdma_addr_cancel(struct rdma_dev_ad
+ }
+ EXPORT_SYMBOL(rdma_addr_cancel);
+ 
+-static int netevent_callback(struct notifier_block *self, unsigned long event, 
+-	void *ctx)
++static int addr_arp_recv(struct sk_buff *skb, struct net_device *dev,
++			 struct packet_type *pkt, struct net_device *orig_dev)
+ {
+-	if (event == NETEVENT_NEIGH_UPDATE) {  
+-		struct neighbour *neigh = ctx;
++	struct arphdr *arp_hdr;
+ 
+-		if (neigh->dev->type == ARPHRD_INFINIBAND &&
+-		    (neigh->nud_state & NUD_VALID)) {
+-			set_timeout(jiffies);
+-		}
+-	}
++	arp_hdr = (struct arphdr *) skb->nh.raw;
++
++	if (arp_hdr->ar_op == htons(ARPOP_REQUEST) ||
++	    arp_hdr->ar_op == htons(ARPOP_REPLY))
++		set_timeout(jiffies);
++
++	kfree_skb(skb);
+ 	return 0;
+ }
+ 
+-static struct notifier_block nb = {
+-	.notifier_call = netevent_callback
++static struct packet_type addr_arp = {
++	.type           = __constant_htons(ETH_P_ARP),
++	.func           = addr_arp_recv,
++	.af_packet_priv = (void*) 1,
+ };
+ 
+ static int addr_init(void)
+@@ -351,13 +353,13 @@ static int addr_init(void)
+ 	if (!addr_wq)
+ 		return -ENOMEM;
+ 
+-	register_netevent_notifier(&nb);
++	dev_add_pack(&addr_arp);
+ 	return 0;
+ }
+ 
+ static void addr_cleanup(void)
+ {
+-	unregister_netevent_notifier(&nb);
++	dev_remove_pack(&addr_arp);
+ 	destroy_workqueue(addr_wq);
+ }
+ 
+
diff --git a/kernel_patches/backport/2.6.15_ubuntu606/cxgb3_makefile_to_2_6_19.patch b/kernel_patches/backport/2.6.15_ubuntu606/cxgb3_makefile_to_2_6_19.patch
new file mode 100644
index 0000000..ad7e7f4
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/cxgb3_makefile_to_2_6_19.patch
@@ -0,0 +1,12 @@
+diff --git a/drivers/net/cxgb3/Makefile b/drivers/net/cxgb3/Makefile
+index 3434679..bb008b6 100755
+--- a/drivers/net/cxgb3/Makefile
++++ b/drivers/net/cxgb3/Makefile
+@@ -1,6 +1,7 @@
+ #
+ # Chelsio T3 driver
+ #
++NOSTDINC_FLAGS:= $(NOSTDINC_FLAGS) $(LINUXINCLUDE)
+ 
+ obj-$(CONFIG_CHELSIO_T3) += cxgb3.o
+ 
diff --git a/kernel_patches/backport/2.6.15_ubuntu606/ipoib_8111_to_2_6_16.patch b/kernel_patches/backport/2.6.15_ubuntu606/ipoib_8111_to_2_6_16.patch
new file mode 100644
index 0000000..2975774
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/ipoib_8111_to_2_6_16.patch
@@ -0,0 +1,83 @@
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
+index 07deee8..501ee93 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib.h
++++ b/drivers/infiniband/ulp/ipoib/ipoib.h
+@@ -217,6 +219,7 @@ struct ipoib_neigh {
+ 
+ 	struct neighbour   *neighbour;
+ 
++	struct list_head    all_neigh_list;
+ 	struct list_head    list;
+ };
+ 
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+index 705eb1d..56022f5 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -85,6 +85,9 @@ struct workqueue_struct *ipoib_workqueue;
+ 
+ struct ib_sa_client ipoib_sa_client;
+ 
++static DEFINE_SPINLOCK(ipoib_all_neigh_list_lock);
++static LIST_HEAD(ipoib_all_neigh_list);
++
+ static void ipoib_add_one(struct ib_device *device);
+ static void ipoib_remove_one(struct ib_device *device);
+ 
+@@ -773,6 +776,17 @@ static void ipoib_neigh_destructor(struct neighbour *n)
+ 	unsigned long flags;
+ 	struct ipoib_ah *ah = NULL;
+ 
++	struct ipoib_neigh *tn, *nn = NULL;
++	spin_lock(&ipoib_all_neigh_list_lock);
++	list_for_each_entry(tn, &ipoib_all_neigh_list, all_neigh_list)
++		if (tn->neighbour == n) {
++			nn = tn;
++			break;
++		}
++	spin_unlock(&ipoib_all_neigh_list_lock);
++	if (!nn)
++		return;
++
+ 	ipoib_dbg(priv,
+ 		  "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
+ 		  IPOIB_QPN(n->ha),
+@@ -806,6 +820,11 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
+ 	*to_ipoib_neigh(neighbour) = neigh;
+ 	skb_queue_head_init(&neigh->queue);
+ 
++	spin_lock(&ipoib_all_neigh_list_lock);
++	list_add_tail(&neigh->all_neigh_list, &ipoib_all_neigh_list);
++	neigh->neighbour->ops->destructor = ipoib_neigh_destructor;
++	spin_unlock(&ipoib_all_neigh_list_lock);
++
+ 	return neigh;
+ }
+ 
+@@ -813,6 +832,17 @@ void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	struct sk_buff *skb;
++	struct ipoib_neigh *nn;
++	spin_lock(&ipoib_all_neigh_list_lock);
++	list_del(&neigh->all_neigh_list);
++	list_for_each_entry(nn, &ipoib_all_neigh_list, all_neigh_list)
++		if (nn->neighbour->ops == neigh->neighbour->ops)
++			goto found;
++
++	neigh->neighbour->ops->destructor = NULL;
++found:
++	spin_unlock(&ipoib_all_neigh_list_lock);
++
+ 	*to_ipoib_neigh(neigh->neighbour) = NULL;
+ 	while ((skb = __skb_dequeue(&neigh->queue))) {
+ 		++priv->stats.tx_dropped;
+@@ -823,8 +853,6 @@ void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
+ 
+ static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
+ {
+-	parms->neigh_destructor = ipoib_neigh_destructor;
+-
+ 	return 0;
+ }
+ 
diff --git a/kernel_patches/backport/2.6.15_ubuntu606/linux_stuff_to_2_6_17.patch b/kernel_patches/backport/2.6.15_ubuntu606/linux_stuff_to_2_6_17.patch
new file mode 100644
index 0000000..eb2285f
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/linux_stuff_to_2_6_17.patch
@@ -0,0 +1,24 @@
+diff --git a/drivers/infiniband/core/genalloc.c b/drivers/infiniband/core/genalloc.c
+new file mode 100644
+index 0000000..58cf933
+--- /dev/null
++++ b/drivers/infiniband/core/genalloc.c
+@@ -0,0 +1 @@
++#include "src/genalloc.c"
+diff --git a/drivers/infiniband/core/netevent.c b/drivers/infiniband/core/netevent.c
+new file mode 100644
+index 0000000..58cf933
+--- /dev/null
++++ b/drivers/infiniband/core/netevent.c
+@@ -0,0 +1 @@
++#include "src/netevent.c"
+diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
+index 50fb1cd..456bfd0 100644
+--- a/drivers/infiniband/core/Makefile
++++ b/drivers/infiniband/core/Makefile
+@@ -30,3 +30,5 @@ ib_ucm-y :=			ucm.o
+ 
+ ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_mem.o \
+ 				uverbs_marshall.o
++
++ib_core-y +=			genalloc.o netevent.o
diff --git a/kernel_patches/backport/2.6.15_ubuntu606/uverbs_to_2_6_17.patch b/kernel_patches/backport/2.6.15_ubuntu606/uverbs_to_2_6_17.patch
new file mode 100644
index 0000000..497a203
--- /dev/null
+++ b/kernel_patches/backport/2.6.15_ubuntu606/uverbs_to_2_6_17.patch
@@ -0,0 +1,20 @@
+Index: gen2_linux/drivers/infiniband/core/uverbs_main.c
+===================================================================
+--- gen2_linux.orig/drivers/infiniband/core/uverbs_main.c
++++ gen2_linux/drivers/infiniband/core/uverbs_main.c
+@@ -815,12 +815,11 @@ static void ib_uverbs_remove_one(struct 
+ 	kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+ }
+ 
+-static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
+-			       const char *dev_name, void *data,
+-			       struct vfsmount *mnt)
++static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
++			       const char *dev_name, void *data)
+ {
+ 	return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
+-			     INFINIBANDEVENTFS_MAGIC, mnt);
++			     INFINIBANDEVENTFS_MAGIC);
+ }
+ 
+ static struct file_system_type uverbs_event_fs = {
diff --git a/ofed_scripts/configure b/ofed_scripts/configure
index f5e1da4..0618d77 100755
--- a/ofed_scripts/configure
+++ b/ofed_scripts/configure
@@ -195,6 +195,9 @@ get_backport_dir()
         2.6.14*)
                 echo 2.6.14
         ;;
+        2.6.15-*-*)
+                echo 2.6.15_ubuntu606
+        ;;
         2.6.15*)
                 echo 2.6.15
         ;;






More information about the general mailing list