--- /dev/null
+/*
+
+Copyright (C) 2005 Frank Mori Hess <fmhess@users.sourceforge.net>
+2.4 compat code is based on kernel's lib/kref.c which was:
+Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+Copyright (C) 2004 IBM Corp.
+Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org>
+
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _KREF_COMPAT_H_
+#define _KREF_COMPAT_H_
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#include <linux/types.h>
+#include <asm/atomic.h>
+
+struct kref {
+ atomic_t refcount;
+};
+
+static inline void kref_init(struct kref *kref)
+{
+ atomic_set(&kref->refcount,1);
+}
+
+static inline void kref_get(struct kref *kref)
+{
+ atomic_inc(&kref->refcount);
+}
+
+static inline int kref_put(struct kref *kref, void (*release) (struct kref *kref))
+{
+ if (atomic_dec_and_test(&kref->refcount)) {
+ release(kref);
+ return 1;
+ }
+ return 0;
+}
+
+static inline void KREF_INIT(struct kref *kref, void (*release) (struct kref *kref))
+{
+ kref_init(kref);
+}
+
+static inline int KREF_PUT(struct kref *kref, void (*release) (struct kref *kref))
+{
+ return kref_put(kref, release);
+}
+
+#else
+
+#include_next <linux/kref.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
+
+static inline void KREF_INIT(struct kref *kref, void (*release) (struct kref *kref))
+{
+ kref_init(kref, release);
+}
+
+static inline int KREF_PUT(struct kref *kref, void (*release) (struct kref *kref))
+{
+ int retval;
+ if(atomic_read(&kref->refcount) == 1)
+ {
+ retval = 1;
+ }else
+ {
+ retval = 0;
+ }
+ kref_put(kref);
+ return retval;
+}
+
+#else
+
+static inline void KREF_INIT(struct kref *kref, void (*release) (struct kref *kref))
+{
+ kref_init(kref);
+}
+
+static inline int KREF_PUT(struct kref *kref, void (*release) (struct kref *kref))
+{
+ return kref_put(kref, release);
+}
+
+#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
+
+#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#endif /* _KREF_COMPAT_H_ */