1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 #include "qat_utils.h"
4
5 #include <sys/types.h>
6 #include <sys/lock.h>
7 #include <sys/sema.h>
8 #include <sys/mutex.h>
9
10 /* Define a 64 bit number */
11 #define QAT_UTILS_MAX_LONG (0x7FFFFFFF)
12
13 /* Max timeout in MS, used to guard against possible overflow */
14 #define QAT_UTILS_MAX_TIMEOUT_MS (QAT_UTILS_MAX_LONG / hz)
15
16 CpaStatus
qatUtilsSemaphoreInit(struct sema ** pSid,uint32_t start_value)17 qatUtilsSemaphoreInit(struct sema **pSid, uint32_t start_value)
18 {
19 if (!pSid)
20 return CPA_STATUS_FAIL;
21
22 *pSid = malloc(sizeof(struct sema), M_QAT, M_WAITOK);
23
24 sema_init(*pSid, start_value, "qat sema");
25
26 return CPA_STATUS_SUCCESS;
27 }
28
29 /**
30 * DESCRIPTION: If the semaphore is unset, the calling thread is blocked.
31 * If the semaphore is set, it is taken and control is returned
32 * to the caller. If the time indicated in 'timeout' is reached,
33 * the thread will unblock and return an error indication. If the
34 * timeout is set to 'QAT_UTILS_WAIT_NONE', the thread will never block;
35 * if it is set to 'QAT_UTILS_WAIT_FOREVER', the thread will block until
36 * the semaphore is available.
37 *
38 *
39 */
40
41 CpaStatus
qatUtilsSemaphoreWait(struct sema ** pSid,int32_t timeout)42 qatUtilsSemaphoreWait(struct sema **pSid, int32_t timeout)
43 {
44
45 CpaStatus Status = CPA_STATUS_SUCCESS;
46 unsigned long timeoutTime;
47
48 if (!pSid)
49 return CPA_STATUS_FAIL;
50 /*
51 * Guard against illegal timeout values
52 */
53 if ((timeout < 0) && (timeout != QAT_UTILS_WAIT_FOREVER)) {
54 QAT_UTILS_LOG(
55 "QatUtilsSemaphoreWait(): illegal timeout value\n");
56 return CPA_STATUS_FAIL;
57 } else if (timeout > QAT_UTILS_MAX_TIMEOUT_MS) {
58 QAT_UTILS_LOG(
59 "QatUtilsSemaphoreWait(): use a smaller timeout value to avoid overflow.\n");
60 return CPA_STATUS_FAIL;
61 }
62
63 if (timeout == QAT_UTILS_WAIT_FOREVER) {
64 sema_wait(*pSid);
65 } else if (timeout == QAT_UTILS_WAIT_NONE) {
66 if (sema_trywait(*pSid)) {
67 Status = CPA_STATUS_FAIL;
68 }
69 } else {
70 /* Convert timeout in milliseconds to HZ */
71 timeoutTime = timeout * hz / 1000;
72 if (sema_timedwait(*pSid, timeoutTime)) {
73 Status = CPA_STATUS_FAIL;
74 }
75 } /* End of if */
76
77 return Status;
78 }
79
80 CpaStatus
qatUtilsSemaphoreTryWait(struct sema ** pSid)81 qatUtilsSemaphoreTryWait(struct sema **pSid)
82 {
83 if (!pSid)
84 return CPA_STATUS_FAIL;
85 if (sema_trywait(*pSid)) {
86 return CPA_STATUS_FAIL;
87 }
88 return CPA_STATUS_SUCCESS;
89 }
90
91 /**
92 *
93 * DESCRIPTION: This function causes the next available thread in the pend queue
94 * to be unblocked. If no thread is pending on this semaphore, the
95 * semaphore becomes 'full'.
96 */
97 CpaStatus
qatUtilsSemaphorePost(struct sema ** pSid)98 qatUtilsSemaphorePost(struct sema **pSid)
99 {
100 if (!pSid)
101 return CPA_STATUS_FAIL;
102 sema_post(*pSid);
103 return CPA_STATUS_SUCCESS;
104 }
105
106 CpaStatus
qatUtilsSemaphoreDestroy(struct sema ** pSid)107 qatUtilsSemaphoreDestroy(struct sema **pSid)
108 {
109 if (!pSid)
110 return CPA_STATUS_FAIL;
111
112 sema_destroy(*pSid);
113 free(*pSid, M_QAT);
114
115 return CPA_STATUS_SUCCESS;
116 }
117
118 /****************************
119 * Mutex
120 ****************************/
121
122 CpaStatus
qatUtilsMutexInit(struct mtx ** pMutex)123 qatUtilsMutexInit(struct mtx **pMutex)
124 {
125 if (!pMutex)
126 return CPA_STATUS_FAIL;
127 *pMutex = malloc(sizeof(struct mtx), M_QAT, M_WAITOK);
128
129 memset(*pMutex, 0, sizeof(struct mtx));
130
131 mtx_init(*pMutex, "qat mtx", NULL, MTX_DEF);
132 return CPA_STATUS_SUCCESS;
133 }
134
135 CpaStatus
qatUtilsMutexLock(struct mtx ** pMutex,int32_t timeout)136 qatUtilsMutexLock(struct mtx **pMutex, int32_t timeout)
137 {
138 if (!pMutex)
139 return CPA_STATUS_FAIL;
140 if (timeout != QAT_UTILS_WAIT_FOREVER) {
141 QAT_UTILS_LOG("QatUtilsMutexLock(): Illegal timeout value\n");
142 return CPA_STATUS_FAIL;
143 }
144
145 mtx_lock(*pMutex);
146 return CPA_STATUS_SUCCESS;
147 }
148
149 CpaStatus
qatUtilsMutexUnlock(struct mtx ** pMutex)150 qatUtilsMutexUnlock(struct mtx **pMutex)
151 {
152 if (!pMutex || !(*pMutex))
153 return CPA_STATUS_FAIL;
154 mtx_unlock(*pMutex);
155 return CPA_STATUS_SUCCESS;
156 }
157
158 CpaStatus
qatUtilsMutexDestroy(struct mtx ** pMutex)159 qatUtilsMutexDestroy(struct mtx **pMutex)
160 {
161 if (!pMutex || !(*pMutex))
162 return CPA_STATUS_FAIL;
163 mtx_destroy(*pMutex);
164 free(*pMutex, M_QAT);
165 *pMutex = NULL;
166
167 return CPA_STATUS_SUCCESS;
168 }
169