1/*-
2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
5 * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice unmodified, this list of conditions, and the following
13 *    disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#ifndef	_LINUXKPI_LINUX_COMPLETION_H_
30#define	_LINUXKPI_LINUX_COMPLETION_H_
31
32#include "los_sys.h"
33
34#ifdef __cplusplus
35#if __cplusplus
36extern "C" {
37#endif /* __cplusplus */
38#endif /* __cplusplus */
39
40enum CompletionState {
41    COMPLETION_ONE,
42    COMPLETION_ALL
43};
44
45#define COMPLETION_EVT 0x1
46
47typedef struct completion {
48    LOS_DL_LIST comList;
49    UINT32 comCount;
50    enum CompletionState state;
51} completion_t;
52
53#define init_completion(x) \
54    linux_init_completion(x)
55
56/* This inline function should be used to reinitialize a completion structure so it can
57 * be reused. This is especially important after complete_all() is used.
58 */
59#define reinit_completion(x) \
60        do { (x)->comCount = 0; } while (0)
61
62#define complete(x) \
63    linux_complete(x)
64
65#define wait_for_completion(x) \
66    linux_wait_for_completion(x)
67
68#define wait_for_completion_timeout(x, timeout) \
69    linux_wait_for_completion_timeout(x, timeout)
70
71#define complete_all(x) \
72    linux_complete_all(x)
73
74#define completion_done(x) \
75    linux_completion_done(x)
76
77/**
78 * @ingroup completion
79 * @brief Initialize a completion.
80 *
81 * @par Description:
82 * This API is used to initialize a specified completion.
83 * @attention
84 * <ul>
85 * <li>The input parameter x must point to valid memory, otherwise, initilize a completion would failed.</li>
86 * </ul>
87 *
88 * @param x   [IN] Pointer to the completion to be initialized,which must point to valid memory.
89 *
90 * @retval None.
91 * @par Dependency: none
92 * <ul><li>completion.h: the header file that contains the API declaration.</li></ul>
93 * @see
94 */
95extern void linux_init_completion(struct completion *x);
96
97/**
98 * @ingroup completion
99 * @brief Wake up a task that is waiting on this completion.
100 *
101 * @par Description:
102 * This API is used to wake up a task that is waiting on the completion.
103 * @attention
104 * <ul>
105 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li>
106 * <li>It suggested that calling complete() after wait_for_completion() or wait_for_completion_timeout(),
107 * otherwise, wait_for_completion() or wait_for_completion_timeout() would not block
108 * because there is already a completion completed.</li>
109 * </ul>
110 *
111 * @param x [IN] Pointer to the completion on which the task to be woken up is waiting,
112 * which must point to valid memory.
113 *
114 * @retval None.
115 * @par Dependency:
116 * <ul>
117 * <li>this function should be used after init_completion() be called.</li>
118 * <li>completion.h: the header file that contains the API declaration.</li>
119 * </ul>
120 * @see
121 */
122extern void linux_complete(struct completion *x);
123
124/**
125 * @ingroup completion
126 * @brief Wait on a completion forever.
127 *
128 * @par Description:
129 * This API is used to wait on a completion forever.
130 * @attention
131 * <ul>
132 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li>
133 * <li>Can not be used in interrupt.</li>
134 * <li>DO NOT call this API in system tasks. </li>
135 * </ul>
136 *
137 * @param x [IN] Pointer to the completion to be waited on, which must point to valid memory.
138 *
139 * @retval None.
140 * @par Dependency:
141 * <ul>
142 * <li>this function should be used after init_completion() be called.</li>
143 * <li>completion.h: the header file that contains the API declaration.</li>
144 * </ul>
145 * @see
146 */
147extern void linux_wait_for_completion(struct completion *x);
148
149/**
150 * @ingroup completion
151 * @brief Wait on a completion within a certain time period.
152 *
153 * @par Description:
154 * This API is used to wait on a completion within a certain time period (timeout).
155 * @attention
156 * <ul>
157 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li>
158 * <li>Timeout interval timeout should be in [1 , 0xFFFFFFFF], otherwise,
159 *  it would return OS_WAIT_COMPLETION_ERROR but not wait for completion.</li>
160 * <li>Can not be used in interrupt.</li>
161 * <li>DO NOT call this API in software timer callback. </li>
162 * </ul>
163 *
164 * @param x       [IN] Pointer to the  completion to be waited on, which must point to valid memory.
165 * @param timeout [IN] Timeout interval for waiting on the completion (unit: Tick).
166 *
167 * @retval 0 The timeout period expires before the task is blocked or scheduled, or that timeout period is 0.
168 * @retval [1,0xFFFFFFFF] Remaining waiting time.
169 * @par Dependency:
170 * <ul>
171 * <li>this function should be used after init_completion() be called.</li>
172 * <li>completion.h: the header file that contains the API declaration.</li>
173 * </ul>
174 * @see
175 */
176extern unsigned long linux_wait_for_completion_timeout(struct completion *x, unsigned long timeout);
177
178/**
179 * @ingroup completion
180 * @brief Wake up all tasks that are waiting on this completion.
181 *
182 * @par Description:
183 * This API is used to wake up all tasks that are waiting on the completion.
184 * @attention
185 * <ul>
186 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li>
187 * <li>It suggested that calling complete_all() after wait_for_completion() or wait_for_completion_timeout(),
188 * otherwise, wait_for_completion() or wait_for_completion_timeout() would not block
189 * because there is already a completion completed.</li>
190 * </ul>
191 *
192 * @param x [IN] Pointer to the completion on which the task to be woken up is waiting,
193 * which must point to valid memory.
194 *
195 * @retval None.
196 * @par Dependency:
197 * <ul>
198 * <li>this function should be used after init_completion() be called.</li>
199 * <li>completion.h: the header file that contains the API declaration.</li>
200 * </ul>
201 * @see
202 */
203extern void linux_complete_all(struct completion *x);
204extern int linux_completion_done(struct completion *x);
205
206#ifdef __cplusplus
207#if __cplusplus
208}
209#endif /* __cplusplus */
210#endif /* __cplusplus */
211
212#endif /* _LINUXKPI_LINUX_COMPLETION_H_ */
213