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 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 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 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 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 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 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 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 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 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