/* $Id: compat22.h,v 1.2 2003/03/09 00:27:46 mikpe Exp $
 * Performance-monitoring counters driver.
 * Compatibility definitions for 2.2 kernels.
 *
 * Copyright (C) 1999-2003  Mikael Pettersson
 */
#include <linux/mm.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,17)
#define EXPORT_SYMBOL_pidhash	EXPORT_SYMBOL(pidhash)
#else
#define EXPORT_SYMBOL_pidhash	/*empty*/
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
#if defined(CONFIG_X86) /* added by perfctr patch for kernels < 2.2.20 */
static inline void rep_nop(void)
{
	__asm__ __volatile__("rep;nop");
}
#endif
#ifdef MODULE
#define module_init(x)	int init_module(void) { return x(); }
#define module_exit(x)	void cleanup_module(void) { x(); }
#define THIS_MODULE	(&__this_module)
#else
#define module_init(x)	/* explicit call is needed */
#define module_exit(x)	/* empty */
#if !defined(__GENKSYMS__)
#define THIS_MODULE	NULL
#endif
#endif /* MODULE */
#if !defined(CONFIG_SMP)
#define cpu_online_map	1
#endif
#define DECLARE_MUTEX(name)	struct semaphore name = MUTEX
#endif /* < 2.2.18 */

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,20)
#define TASK_IS_PTRACED(tsk)	((tsk)->flags & PF_PTRACED)
#else
#define TASK_IS_PTRACED(tsk)	((tsk)->ptrace & PT_PTRACED)
#endif

/* the dummy request_module() returned void before 2.2.20pre10 */
#if !defined(CONFIG_KMOD) && defined(request_module)
#undef request_module
static inline int request_module(const char *name) { return -ENOSYS; }
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,21)
#define MODULE_LICENSE(license)	/*empty*/
#endif

#if defined(CONFIG_X86)
#define cpu_relax()	rep_nop()
#endif

#ifdef MODULE
#define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
#define __exit		/* empty */
#else
#define __exit		__attribute__((unused, __section__("text.init")))
#endif

/* remap_page_range() changed in 2.5.3-pre1 */
static inline int perfctr_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot)
{
	return remap_page_range(from, to, size, prot);
}
#undef remap_page_range
#define remap_page_range(vma,from,to,size,prot) perfctr_remap_page_range((vma),(from),(to),(size),(prot))

#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))
#define ClearPageReserved(page)	clear_bit(PG_reserved, &(page)->flags)
#define EXPORT_SYMBOL___put_task_struct	/* empty */
#define EXPORT_SYMBOL_tasklist_lock	EXPORT_SYMBOL(tasklist_lock)
#define SetPageReserved(page)	set_bit(PG_reserved, &(page)->flags)
#define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
#define fops_get(fops)		(fops)
#define get_cpus_allowed(tsk)	(-1UL)
#define get_task_struct(tsk)	do{}while(0)	/* unsafe no-op */
#define get_zeroed_page(mask)	get_free_page((mask))
#define module_put(MOD)		MOD_DEC_USE_COUNT
#define preempt_disable()	do{}while(0)
#define preempt_enable()	do{}while(0)
#define proc_pid_inode_denotes_task(inode,tsk) ((tsk)->pid == ((inode)->i_ino >> 16))
extern int ptrace_check_attach(struct task_struct *child, int kill);
#define put_task_struct(tsk)	do{}while(0)	/* unsafe no-op */
#define set_cpus_allowed(tsk, mask)	do{}while(0)	/* unused no-op */
#define task_has_cpu(tsk)	((tsk)->has_cpu)
#define task_lock(tsk)		spin_lock_irq(&runqueue_lock)
#define task_thread(tsk)	(&(tsk)->tss)
#define task_unlock(tsk)	spin_unlock_irq(&runqueue_lock)
static inline void try_module_get(void *m) { MOD_INC_USE_COUNT; }
#define virt_to_page(kaddr)	(mem_map + MAP_NR(kaddr))
#define vma_pgoff(vma)	((vma)->vm_offset) /* NOT, but suffices for != 0 */

/* introduced in 2.5.64 */
static inline int on_each_cpu(void (*func) (void *info), void *info,
                              int retry, int wait)
{
        int ret = 0;

        preempt_disable();
        ret = smp_call_function(func, info, retry, wait);
        func(info);
        preempt_enable();
        return ret;
}
