1
/*********************************************************
2
* Copyright (C) 2002 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation version 2 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*********************************************************/
19
#ifndef __COMPAT_WAIT_H__
20
# define __COMPAT_WAIT_H__
23
#include <linux/wait.h>
24
#include <linux/poll.h>
25
#include <linux/file.h>
27
#include "compat_file.h"
31
* The DECLARE_WAITQUEUE() API appeared in 2.3.1
32
* It was back ported in 2.2.18
37
#ifndef DECLARE_WAITQUEUE
39
typedef struct wait_queue *wait_queue_head_t;
40
# define init_waitqueue_head(_headPtr) *(_headPtr) = NULL
41
# define DECLARE_WAITQUEUE(_var, _task) \
42
struct wait_queue _var = {_task, NULL, }
44
typedef struct wait_queue wait_queue_t;
45
# define init_waitqueue_entry(_wait, _task) ((_wait)->task = (_task))
50
* The 'struct poll_wqueues' appeared in 2.5.48, when global
51
* /dev/epoll interface was added. It was backported to the
55
#ifdef VMW_HAVE_EPOLL // {
56
#define compat_poll_wqueues struct poll_wqueues
58
#define compat_poll_wqueues poll_table
61
#ifdef VMW_HAVE_EPOLL // {
63
/* If prototype does not match, build will abort here */
64
extern void poll_initwait(compat_poll_wqueues *);
66
#define compat_poll_initwait(wait, table) ( \
67
poll_initwait((table)), \
68
(wait) = &(table)->pt \
71
#define compat_poll_freewait(wait, table) ( \
72
poll_freewait((table)) \
75
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) // {
77
/* If prototype does not match, build will abort here */
78
extern void poll_initwait(compat_poll_wqueues *);
80
#define compat_poll_initwait(wait, table) ( \
85
#define compat_poll_freewait(wait, table) ( \
86
poll_freewait((table)) \
91
#define compat_poll_initwait(wait, table) ( \
92
(wait) = (table), /* confuse compiler */ \
93
(wait) = (poll_table *) __get_free_page(GFP_KERNEL), \
95
(wait)->entry = (struct poll_table_entry *)((wait) + 1), \
100
poll_freewait(poll_table *wait)
103
struct poll_table_entry * entry;
106
entry = wait->entry + wait->nr;
107
while (wait->nr > 0) {
110
remove_wait_queue(entry->wait_address, &entry->wait);
111
compat_fput(entry->filp);
115
free_page((unsigned long) old);
119
#define compat_poll_freewait(wait, table) ( \
120
poll_freewait((wait)) \
126
* The wait_event_interruptible_timeout() interface is not
127
* defined in pre-2.6 kernels.
129
#ifndef wait_event_interruptible_timeout
130
#define __wait_event_interruptible_timeout(wq, condition, ret) \
132
wait_queue_t __wait; \
133
init_waitqueue_entry(&__wait, current); \
135
add_wait_queue(&wq, &__wait); \
137
set_current_state(TASK_INTERRUPTIBLE); \
140
if (!signal_pending(current)) { \
141
ret = schedule_timeout(ret); \
146
ret = -ERESTARTSYS; \
149
set_current_state(TASK_RUNNING); \
150
remove_wait_queue(&wq, &__wait); \
153
#define wait_event_interruptible_timeout(wq, condition, timeout) \
155
long __ret = timeout; \
157
__wait_event_interruptible_timeout(wq, condition, __ret); \
163
* The wait_event_timeout() interface is not
164
* defined in pre-2.6 kernels.
166
#ifndef wait_event_timeout
167
#define __wait_event_timeout(wq, condition, ret) \
169
wait_queue_t __wait; \
170
init_waitqueue_entry(&__wait, current); \
172
add_wait_queue(&wq, &__wait); \
174
set_current_state(TASK_UNINTERRUPTIBLE); \
177
ret = schedule_timeout(ret); \
181
set_current_state(TASK_RUNNING); \
182
remove_wait_queue(&wq, &__wait); \
185
#define wait_event_timeout(wq, condition, timeout) \
187
long __ret = timeout; \
189
__wait_event_timeout(wq, condition, __ret); \
195
* DEFINE_WAIT() and friends were added in 2.5.39 and backported to 2.4.28.
197
* Unfortunately it is not true. While some distros may have done it the
198
* change has never made it into vanilla 2.4 kernel. Instead of testing
199
* particular kernel versions let's just test for presence of DEFINE_WAIT
200
* when figuring out whether we need to provide replacement implementation
201
* or simply alias existing one.
206
# define COMPAT_DEFINE_WAIT(_wait) \
207
DECLARE_WAITQUEUE(_wait, current)
208
# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
210
__set_current_state(_state); \
211
add_wait_queue(_sleep, _wait); \
213
# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
214
set_current_state(_state)
215
# define compat_finish_wait(_sleep, _wait, _state) \
217
__set_current_state(_state); \
218
remove_wait_queue(_sleep, _wait); \
223
# define COMPAT_DEFINE_WAIT(_wait) \
225
# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
226
prepare_to_wait(_sleep, _wait, _state)
227
# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
228
prepare_to_wait(_sleep, _wait, _state)
229
# define compat_finish_wait(_sleep, _wait, _state) \
230
finish_wait(_sleep, _wait)
232
#endif /* #ifndef DEFINE_WAIT */
234
#endif /* __COMPAT_WAIT_H__ */