3 * Support for Intel Camera Imaging ISP subsystem.
4 * Copyright (c) 2015, Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 Support for Intel Camera Imaging ISP subsystem.
18 Copyright (c) 2010 - 2015, Intel Corporation.
20 This program is free software; you can redistribute it and/or modify it
21 under the terms and conditions of the GNU General Public License,
22 version 2, as published by the Free Software Foundation.
24 This program is distributed in the hope it will be useful, but WITHOUT
25 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
31 #include "ia_css_rmgr.h"
33 #include <type_support.h>
34 #include <assert_support.h>
35 #include <platform_support.h> /* memset */
36 #include <memory_access.h> /* mmmgr_malloc, mmmgr_free */
37 #include <ia_css_debug.h>
40 * @brief VBUF resource handles
42 #define NUM_HANDLES 1000
43 struct ia_css_rmgr_vbuf_handle handle_table[NUM_HANDLES];
46 * @brief VBUF resource pool - refpool
48 struct ia_css_rmgr_vbuf_pool refpool = {
49 false, /* copy_on_write */
57 * @brief VBUF resource pool - writepool
59 struct ia_css_rmgr_vbuf_pool writepool = {
60 true, /* copy_on_write */
68 * @brief VBUF resource pool - hmmbufferpool
70 struct ia_css_rmgr_vbuf_pool hmmbufferpool = {
71 true, /* copy_on_write */
78 struct ia_css_rmgr_vbuf_pool *vbuf_ref = &refpool;
79 struct ia_css_rmgr_vbuf_pool *vbuf_write = &writepool;
80 struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool = &hmmbufferpool;
83 * @brief Initialize the reference count (host, vbuf)
85 static void rmgr_refcount_init_vbuf(void)
87 /* initialize the refcount table */
88 memset(&handle_table, 0, sizeof(handle_table));
92 * @brief Retain the reference count for a handle (host, vbuf)
94 * @param handle The pointer to the handle
96 void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
99 struct ia_css_rmgr_vbuf_handle *h;
100 if ((handle == NULL) || (*handle == NULL)) {
101 IA_CSS_LOG("Invalid inputs");
104 /* new vbuf to count on */
105 if ((*handle)->count == 0) {
108 for (i = 0; i < NUM_HANDLES; i++) {
109 if (handle_table[i].count == 0) {
110 *handle = &handle_table[i];
114 /* if the loop dus not break and *handle == NULL
115 this is an error handle and report it.
117 if (*handle == NULL) {
118 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
119 "ia_css_i_host_refcount_retain_vbuf() failed to find empty slot!\n");
122 (*handle)->vptr = h->vptr;
123 (*handle)->size = h->size;
129 * @brief Release the reference count for a handle (host, vbuf)
131 * @param handle The pointer to the handle
133 void ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
135 if ((handle == NULL) || ((*handle) == NULL) || (((*handle)->count) == 0)) {
136 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
137 "ia_css_rmgr_refcount_release_vbuf() invalid arguments!\n");
140 /* decrease reference count */
142 /* remove from admin */
143 if ((*handle)->count == 0) {
144 (*handle)->vptr = 0x0;
151 * @brief Initialize the resource pool (host, vbuf)
153 * @param pool The pointer to the pool
155 enum ia_css_err ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
157 enum ia_css_err err = IA_CSS_SUCCESS;
159 rmgr_refcount_init_vbuf();
160 assert(pool != NULL);
162 return IA_CSS_ERR_INVALID_ARGUMENTS;
163 /* initialize the recycle pool if used */
164 if (pool->recycle && pool->size) {
165 /* allocate memory for storing the handles */
169 pool->handles = sh_css_malloc(bytes_needed);
170 if (pool->handles != NULL)
171 memset(pool->handles, 0, bytes_needed);
173 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
175 /* just in case, set the size to 0 */
177 pool->handles = NULL;
183 * @brief Uninitialize the resource pool (host, vbuf)
185 * @param pool The pointer to the pool
187 void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
190 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_rmgr_uninit_vbuf()\n");
192 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_rmgr_uninit_vbuf(): NULL argument\n");
195 if (pool->handles != NULL) {
196 /* free the hmm buffers */
197 for (i = 0; i < pool->size; i++) {
198 if (pool->handles[i] != NULL) {
199 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
200 " freeing/releasing %x (count=%d)\n",
201 pool->handles[i]->vptr,
202 pool->handles[i]->count);
204 mmgr_free(pool->handles[i]->vptr);
205 /* remove from refcount admin */
206 ia_css_rmgr_refcount_release_vbuf(
210 /* now free the pool handles list */
211 sh_css_free(pool->handles);
212 pool->handles = NULL;
217 * @brief Push a handle to the pool
219 * @param pool The pointer to the pool
220 * @param handle The pointer to the handle
223 void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool,
224 struct ia_css_rmgr_vbuf_handle **handle)
228 assert(pool != NULL);
229 assert(pool->recycle);
230 assert(pool->handles != NULL);
231 assert(handle != NULL);
232 for (i = 0; i < pool->size; i++) {
233 if (pool->handles[i] == NULL) {
234 ia_css_rmgr_refcount_retain_vbuf(handle);
235 pool->handles[i] = *handle;
244 * @brief Pop a handle from the pool
246 * @param pool The pointer to the pool
247 * @param handle The pointer to the handle
250 void rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool *pool,
251 struct ia_css_rmgr_vbuf_handle **handle)
255 assert(pool != NULL);
256 assert(pool->recycle);
257 assert(pool->handles != NULL);
258 assert(handle != NULL);
259 assert(*handle != NULL);
260 for (i = 0; i < pool->size; i++) {
261 if ((pool->handles[i] != NULL) &&
262 (pool->handles[i]->size == (*handle)->size)) {
263 *handle = pool->handles[i];
264 pool->handles[i] = NULL;
265 /* dont release, we are returning it...
266 ia_css_rmgr_refcount_release_vbuf(handle); */
274 * @brief Acquire a handle from the pool (host, vbuf)
276 * @param pool The pointer to the pool
277 * @param handle The pointer to the handle
279 void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
280 struct ia_css_rmgr_vbuf_handle **handle)
283 /* KW sees the *handle = h; assignment about 20 lines down
284 and thinks that we are assigning a local to a global.
285 What it does not see is that in ia_css_i_host_rmgr_pop_handle
286 a new value is assigned to handle.
287 So this is a false positive KW issue.
288 To fix that we make the struct static for KW so it will
289 think that h remains alive; we do not want this in our
290 production code though as it breaks reentrancy of the code
293 static struct ia_css_rmgr_vbuf_handle h;
294 #else /* __KLOCWORK__ */
295 struct ia_css_rmgr_vbuf_handle h;
296 #endif /* __KLOCWORK__ */
298 if ((pool == NULL) || (handle == NULL) || (*handle == NULL)) {
299 IA_CSS_LOG("Invalid inputs");
303 if (pool->copy_on_write) {
304 /* only one reference, reuse (no new retain) */
305 if ((*handle)->count == 1)
307 /* more than one reference, release current buffer */
308 if ((*handle)->count > 1) {
309 /* store current values */
311 h.size = (*handle)->size;
312 /* release ref to current buffer */
313 ia_css_rmgr_refcount_release_vbuf(handle);
316 /* get new buffer for needed size */
317 if ((*handle)->vptr == 0x0) {
319 /* try and pop from pool */
320 rmgr_pop_handle(pool, handle);
322 if ((*handle)->vptr == 0x0) {
323 /* we need to allocate */
324 (*handle)->vptr = mmgr_malloc((*handle)->size);
326 /* we popped a buffer */
331 /* Note that handle will change to an internally maintained one */
332 ia_css_rmgr_refcount_retain_vbuf(handle);
336 * @brief Release a handle to the pool (host, vbuf)
338 * @param pool The pointer to the pool
339 * @param handle The pointer to the handle
341 void ia_css_rmgr_rel_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
342 struct ia_css_rmgr_vbuf_handle **handle)
344 if ((pool == NULL) || (handle == NULL) || (*handle == NULL)) {
345 IA_CSS_LOG("Invalid inputs");
348 /* release the handle */
349 if ((*handle)->count == 1) {
350 if (!pool->recycle) {
351 /* non recycling pool, free mem */
352 mmgr_free((*handle)->vptr);
354 /* recycle to pool */
355 rmgr_push_handle(pool, handle);
358 ia_css_rmgr_refcount_release_vbuf(handle);