xref: /freebsd-src/sys/compat/linuxkpi/common/include/linux/iopoll.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1fed248a6SBjoern A. Zeeb /*-
2fed248a6SBjoern A. Zeeb  * SPDX-License-Identifier: BSD-2-Clause
3fed248a6SBjoern A. Zeeb  *
4fed248a6SBjoern A. Zeeb  * Copyright (c) 2020-2021 Bjoern A. Zeeb
5fed248a6SBjoern A. Zeeb  *
6fed248a6SBjoern A. Zeeb  * Redistribution and use in source and binary forms, with or without
7fed248a6SBjoern A. Zeeb  * modification, are permitted provided that the following conditions
8fed248a6SBjoern A. Zeeb  * are met:
9fed248a6SBjoern A. Zeeb  * 1. Redistributions of source code must retain the above copyright
10fed248a6SBjoern A. Zeeb  *    notice, this list of conditions and the following disclaimer.
11fed248a6SBjoern A. Zeeb  * 2. Redistributions in binary form must reproduce the above copyright
12fed248a6SBjoern A. Zeeb  *    notice, this list of conditions and the following disclaimer in the
13fed248a6SBjoern A. Zeeb  *    documentation and/or other materials provided with the distribution.
14fed248a6SBjoern A. Zeeb  *
15fed248a6SBjoern A. Zeeb  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16fed248a6SBjoern A. Zeeb  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17fed248a6SBjoern A. Zeeb  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18fed248a6SBjoern A. Zeeb  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19fed248a6SBjoern A. Zeeb  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20fed248a6SBjoern A. Zeeb  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21fed248a6SBjoern A. Zeeb  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22fed248a6SBjoern A. Zeeb  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23fed248a6SBjoern A. Zeeb  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24fed248a6SBjoern A. Zeeb  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25fed248a6SBjoern A. Zeeb  * SUCH DAMAGE.
26fed248a6SBjoern A. Zeeb  */
27fed248a6SBjoern A. Zeeb 
28*307f78f3SVladimir Kondratyev #ifndef	_LINUXKPI_LINUX_IOPOLL_H
29*307f78f3SVladimir Kondratyev #define	_LINUXKPI_LINUX_IOPOLL_H
30fed248a6SBjoern A. Zeeb 
31fed248a6SBjoern A. Zeeb #include <sys/types.h>
32fed248a6SBjoern A. Zeeb #include <sys/time.h>
33fed248a6SBjoern A. Zeeb #include <linux/delay.h>
34fed248a6SBjoern A. Zeeb 
35fed248a6SBjoern A. Zeeb #define	read_poll_timeout(_pollfp, _var, _cond, _us, _to, _early_sleep, ...)	\
36fed248a6SBjoern A. Zeeb ({										\
37fed248a6SBjoern A. Zeeb 	struct timeval __now, __end;						\
38fed248a6SBjoern A. Zeeb 	if (_to) {								\
39fed248a6SBjoern A. Zeeb 		__end.tv_sec = (_to) / USEC_PER_SEC;				\
40fed248a6SBjoern A. Zeeb 		__end.tv_usec = (_to) % USEC_PER_SEC;				\
41fed248a6SBjoern A. Zeeb 		microtime(&__now);						\
42fed248a6SBjoern A. Zeeb 		timevaladd(&__end, &__now);					\
43fed248a6SBjoern A. Zeeb 	}									\
44fed248a6SBjoern A. Zeeb 										\
45fed248a6SBjoern A. Zeeb 	if ((_early_sleep) && (_us) > 0)					\
46fed248a6SBjoern A. Zeeb 		usleep_range(_us, _us);						\
47fed248a6SBjoern A. Zeeb 	do {									\
48fed248a6SBjoern A. Zeeb 		(_var) = _pollfp(__VA_ARGS__);					\
49fed248a6SBjoern A. Zeeb 		if (_cond)							\
50fed248a6SBjoern A. Zeeb 			break;							\
51fed248a6SBjoern A. Zeeb 		if (_to) {							\
52fed248a6SBjoern A. Zeeb 			microtime(&__now);					\
53fed248a6SBjoern A. Zeeb 			if (timevalcmp(&__now, &__end, >))			\
54fed248a6SBjoern A. Zeeb 				break;						\
55fed248a6SBjoern A. Zeeb 		}								\
56fed248a6SBjoern A. Zeeb 		if ((_us) != 0)							\
57fed248a6SBjoern A. Zeeb 			usleep_range(_us, _us);					\
58fed248a6SBjoern A. Zeeb 	} while (1);								\
59fed248a6SBjoern A. Zeeb 	(_cond) ? 0 : (-ETIMEDOUT);						\
60fed248a6SBjoern A. Zeeb })
61fed248a6SBjoern A. Zeeb 
622e194c20SVladimir Kondratyev #define readx_poll_timeout(_pollfp, _addr, _var, _cond, _us, _to)		\
632e194c20SVladimir Kondratyev 	read_poll_timeout(_pollfp, _var, _cond, _us, _to, false, _addr)
642e194c20SVladimir Kondratyev 
65fed248a6SBjoern A. Zeeb #define	read_poll_timeout_atomic(_pollfp, _var, _cond, _us, _to, _early_sleep, ...)	\
66fed248a6SBjoern A. Zeeb ({										\
67fed248a6SBjoern A. Zeeb 	struct timeval __now, __end;						\
68fed248a6SBjoern A. Zeeb 	if (_to) {								\
69fed248a6SBjoern A. Zeeb 		__end.tv_sec = (_to) / USEC_PER_SEC;				\
70fed248a6SBjoern A. Zeeb 		__end.tv_usec = (_to) % USEC_PER_SEC;				\
71fed248a6SBjoern A. Zeeb 		microtime(&__now);						\
72fed248a6SBjoern A. Zeeb 		timevaladd(&__end, &__now);					\
73fed248a6SBjoern A. Zeeb 	}									\
74fed248a6SBjoern A. Zeeb 										\
75fed248a6SBjoern A. Zeeb 	if ((_early_sleep) && (_us) > 0)					\
76fed248a6SBjoern A. Zeeb 		DELAY(_us);							\
77fed248a6SBjoern A. Zeeb 	do {									\
78fed248a6SBjoern A. Zeeb 		(_var) = _pollfp(__VA_ARGS__);					\
79fed248a6SBjoern A. Zeeb 		if (_cond)							\
80fed248a6SBjoern A. Zeeb 			break;							\
81fed248a6SBjoern A. Zeeb 		if (_to) {							\
82fed248a6SBjoern A. Zeeb 			microtime(&__now);					\
83fed248a6SBjoern A. Zeeb 			if (timevalcmp(&__now, &__end, >))			\
84fed248a6SBjoern A. Zeeb 				break;						\
85fed248a6SBjoern A. Zeeb 		}								\
86fed248a6SBjoern A. Zeeb 		if ((_us) != 0)							\
87fed248a6SBjoern A. Zeeb 			DELAY(_us);						\
88fed248a6SBjoern A. Zeeb 	} while (1);								\
89fed248a6SBjoern A. Zeeb 	(_cond) ? 0 : (-ETIMEDOUT);						\
90fed248a6SBjoern A. Zeeb })
91fed248a6SBjoern A. Zeeb 
92*307f78f3SVladimir Kondratyev #endif	/* _LINUXKPI_LINUX_IOPOLL_H */
93