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