[android-sdk/device-ti-proprietary-open.git] / jacinto6 / sgx_src / eurasia_km / services4 / srvkm / common / resman.c
1 /*************************************************************************/ /*!
2 @Title Resource Manager
3 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4 @Description Provide resource management
5 @License Dual MIT/GPLv2
7 The contents of this file are subject to the MIT license as set out below.
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
19 Alternatively, the contents of this file may be used under the terms of
20 the GNU General Public License Version 2 ("GPL") in which case the provisions
21 of GPL are applicable instead of those above.
23 If you wish to allow use of your version of this file only under the terms of
24 GPL, and not to allow others to use your version of this file under the terms
25 of the MIT license, indicate your decision by deleting the provisions above
26 and replace them with the notice and other provisions required by GPL as set
27 out in the file called "GPL-COPYING" included in this distribution. If you do
28 not delete the provisions above, a recipient may use your version of this file
29 under the terms of either the MIT license or GPL.
31 This License is also included in this distribution in the file called
32 "MIT-COPYING".
34 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
35 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
38 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
39 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 */ /**************************************************************************/
42 #include "services_headers.h"
43 #include "resman.h"
45 #ifdef __linux__
46 #include <linux/version.h>
48 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
49 #ifndef AUTOCONF_INCLUDED
50 #include <linux/config.h>
51 #endif
52 #endif
54 #include <linux/sched.h>
55 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
56 #include <linux/hardirq.h>
57 #else
58 #include <asm/hardirq.h>
59 #endif
61 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
62 #include <linux/mutex.h>
63 #else
64 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
65 #include <linux/semaphore.h>
66 #else
67 #include <asm/semaphore.h>
68 #endif
69 #endif
71 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
72 static DEFINE_MUTEX(lock);
73 #define DOWN(m) mutex_lock(m)
74 #define UP(m) mutex_unlock(m)
75 #else
76 static DECLARE_MUTEX(lock);
77 #define DOWN(m) down(m)
78 #define UP(m) up(m)
79 #endif
81 #define ACQUIRE_SYNC_OBJ do { \
82 if (in_interrupt()) { \
83 printk("ISR cannot take RESMAN mutex\n"); \
84 BUG(); \
85 } \
86 else DOWN(&lock); \
87 } while (0)
88 #define RELEASE_SYNC_OBJ UP(&lock)
90 #else
92 #define ACQUIRE_SYNC_OBJ
93 #define RELEASE_SYNC_OBJ
95 #endif
97 #define RESMAN_SIGNATURE 0x12345678
99 /******************************************************************************
100 * resman structures
101 *****************************************************************************/
103 /* resman item structure */
104 typedef struct _RESMAN_ITEM_
105 {
106 #ifdef DEBUG
107 IMG_UINT32 ui32Signature;
108 #endif
109 struct _RESMAN_ITEM_ **ppsThis; /*!< list navigation */
110 struct _RESMAN_ITEM_ *psNext; /*!< list navigation */
112 IMG_UINT32 ui32Flags; /*!< flags */
113 IMG_UINT32 ui32ResType;/*!< res type */
115 IMG_PVOID pvParam; /*!< param1 for callback */
116 IMG_UINT32 ui32Param; /*!< param2 for callback */
118 RESMAN_FREE_FN pfnFreeResource;/*!< resman item free callback */
119 } RESMAN_ITEM;
122 /* resman context structure */
123 typedef struct _RESMAN_CONTEXT_
124 {
125 #ifdef DEBUG
126 IMG_UINT32 ui32Signature;
127 #endif
128 struct _RESMAN_CONTEXT_ **ppsThis;/*!< list navigation */
129 struct _RESMAN_CONTEXT_ *psNext;/*!< list navigation */
131 PVRSRV_PER_PROCESS_DATA *psPerProc; /* owner of resources */
133 RESMAN_ITEM *psResItemList;/*!< res item list for context */
135 } RESMAN_CONTEXT;
138 /* resman list structure */
139 typedef struct
140 {
141 RESMAN_CONTEXT *psContextList; /*!< resman context list */
143 } RESMAN_LIST, *PRESMAN_LIST; /* PRQA S 3205 */
146 PRESMAN_LIST gpsResList = IMG_NULL;
148 #include "lists.h" /* PRQA S 5087 */ /* include lists.h required here */
150 static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
151 static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
152 static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
153 static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
154 static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM)
156 static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
157 static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
160 #define PRINT_RESLIST(x, y, z)
162 /******************************************************** Forword references */
164 static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup);
166 static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext,
167 IMG_UINT32 ui32SearchCriteria,
168 IMG_UINT32 ui32ResType,
169 IMG_PVOID pvParam,
170 IMG_UINT32 ui32Param,
171 IMG_BOOL bExecuteCallback);
174 #ifdef DEBUG
175 static IMG_VOID ValidateResList(PRESMAN_LIST psResList);
176 #define VALIDATERESLIST() ValidateResList(gpsResList)
177 #else
178 #define VALIDATERESLIST()
179 #endif
186 /*!
187 ******************************************************************************
189 @Function ResManInit
191 @Description initialises the resman
193 @Return none
195 ******************************************************************************/
196 PVRSRV_ERROR ResManInit(IMG_VOID)
197 {
198 if (gpsResList == IMG_NULL)
199 {
200 /* If not already initialised */
201 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
202 sizeof(*gpsResList),
203 (IMG_VOID **)&gpsResList, IMG_NULL,
204 "Resource Manager List") != PVRSRV_OK)
205 {
206 return PVRSRV_ERROR_OUT_OF_MEMORY;
207 }
209 /* Init list, the linked list has dummy entries at both ends */
210 gpsResList->psContextList = IMG_NULL;
212 /* Check resource list */
213 VALIDATERESLIST();
214 }
216 return PVRSRV_OK;
217 }
220 /*!
221 ******************************************************************************
223 @Function ResManDeInit
225 @Description de-initialises the resman
227 @Return none
229 ******************************************************************************/
230 IMG_VOID ResManDeInit(IMG_VOID)
231 {
232 if (gpsResList != IMG_NULL)
233 {
234 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
235 gpsResList = IMG_NULL;
236 }
237 }
240 /*!
241 ******************************************************************************
243 @Function PVRSRVResManConnect
245 @Description Opens a connection to the Resource Manager
247 @input hPerProc - Per-process data (if applicable)
248 @output phResManContext - Resman context
250 @Return error code or PVRSRV_OK
252 ******************************************************************************/
253 PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
254 PRESMAN_CONTEXT *phResManContext)
255 {
256 PVRSRV_ERROR eError;
257 PRESMAN_CONTEXT psResManContext;
259 /*Acquire resource list sync object*/
260 ACQUIRE_SYNC_OBJ;
262 /*Check resource list*/
263 VALIDATERESLIST();
265 /* Allocate memory for the new context. */
266 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
267 (IMG_VOID **)&psResManContext, IMG_NULL,
268 "Resource Manager Context");
269 if (eError != PVRSRV_OK)
270 {
271 PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
273 /* Check resource list */
274 VALIDATERESLIST();
276 /* Release resource list sync object */
277 RELEASE_SYNC_OBJ;
279 return eError;
280 }
282 #ifdef DEBUG
283 psResManContext->ui32Signature = RESMAN_SIGNATURE;
284 #endif /* DEBUG */
285 psResManContext->psResItemList = IMG_NULL;
286 psResManContext->psPerProc = hPerProc;
288 /* Insert new context struct after the dummy first entry */
289 List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
291 /* Check resource list */
292 VALIDATERESLIST();
294 /* Release resource list sync object */
295 RELEASE_SYNC_OBJ;
297 *phResManContext = psResManContext;
299 return PVRSRV_OK;
300 }
303 /*!
304 ******************************************************************************
306 @Function PVRSRVResManDisconnect
308 @Description Closes a Resource Manager connection and frees all resources
310 @input hResManContext - Resman context
311 @input bKernelContext - IMG_TRUE for kernel contexts
313 @Return IMG_VOID
315 ******************************************************************************/
316 IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
317 IMG_BOOL bKernelContext)
318 {
319 /* Acquire resource list sync object */
320 ACQUIRE_SYNC_OBJ;
322 /* Check resource list */
323 VALIDATERESLIST();
325 /* Print and validate resource list */
326 PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
328 /* Free all auto-freed resources in order */
330 if (!bKernelContext)
331 {
332 /* OS specific User-mode Mappings: */
333 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
335 /* VGX types: */
336 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE);
338 /* Event Object */
339 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
341 /* syncobject state (Read/Write Complete values) */
342 /* Must be FIFO, so we reverse the list, twice */
343 List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
344 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
345 List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList); // (could survive without this - all following items would be cleared up "fifo" too)
347 /* SGX types: */
348 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE);
349 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
350 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE);
351 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE);
352 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE);
353 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE);
355 /* COMMON types: */
356 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE);
357 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE);
358 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE);
359 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE);
360 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
361 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE);
362 #if defined(SUPPORT_ION)
363 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ION, 0, 0, IMG_TRUE);
364 #endif
365 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE);
366 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE);
368 /* DISPLAY CLASS types: */
369 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
370 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
372 /* BUFFER CLASS types: */
373 FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
374 }
376 /* Ensure that there are no resources left */
377 PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
379 /* Remove the context struct from the list */
380 List_RESMAN_CONTEXT_Remove(psResManContext);
382 /* Free the context struct */
383 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
384 /*not nulling pointer, copy on stack*/
387 /* Check resource list */
388 VALIDATERESLIST();
390 /* Print and validate resource list */
391 PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
393 /* Release resource list sync object */
394 RELEASE_SYNC_OBJ;
395 }
398 /*!
399 ******************************************************************************
400 @Function ResManRegisterRes
402 @Description : Inform the resource manager that the given resource has
403 been alloacted and freeing of it will be the responsibility
404 of the resource manager
406 @input psResManContext - resman context
407 @input ui32ResType - identify what kind of resource it is
408 @input pvParam - address of resource
409 @input ui32Param - size of resource
410 @input pfnFreeResource - pointer to function that frees this resource
412 @Return On success a pointer to an opaque data structure that represents
413 the allocated resource, else NULL
415 **************************************************************************/
416 PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext,
417 IMG_UINT32 ui32ResType,
418 IMG_PVOID pvParam,
419 IMG_UINT32 ui32Param,
420 RESMAN_FREE_FN pfnFreeResource)
421 {
422 PRESMAN_ITEM psNewResItem;
424 PVR_ASSERT(psResManContext != IMG_NULL);
425 PVR_ASSERT(ui32ResType != 0);
427 if (psResManContext == IMG_NULL)
428 {
429 PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext"));
430 return (PRESMAN_ITEM) IMG_NULL;
431 }
433 /* Acquire resource list sync object */
434 ACQUIRE_SYNC_OBJ;
436 /* Check resource list */
437 VALIDATERESLIST();
439 PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
440 "Context 0x%p, ResType 0x%x, pvParam 0x%p, ui32Param 0x%x, "
441 "FreeFunc %p",
442 psResManContext,
443 ui32ResType,
444 pvParam,
445 ui32Param,
446 pfnFreeResource));
448 /* Allocate memory for the new resource structure */
449 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
450 sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
451 IMG_NULL,
452 "Resource Manager Item") != PVRSRV_OK)
453 {
454 PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
455 "ERROR allocating new resource item"));
457 /* Release resource list sync object */
458 RELEASE_SYNC_OBJ;
460 return((PRESMAN_ITEM)IMG_NULL);
461 }
463 /* Fill in details about this resource */
464 #ifdef DEBUG
465 psNewResItem->ui32Signature = RESMAN_SIGNATURE;
466 #endif /* DEBUG */
467 psNewResItem->ui32ResType = ui32ResType;
468 psNewResItem->pvParam = pvParam;
469 psNewResItem->ui32Param = ui32Param;
470 psNewResItem->pfnFreeResource = pfnFreeResource;
471 psNewResItem->ui32Flags = 0;
473 /* Insert new structure after dummy first entry */
474 List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
476 /* Check resource list */
477 VALIDATERESLIST();
479 /* Release resource list sync object */
480 RELEASE_SYNC_OBJ;
482 return(psNewResItem);
483 }
485 /*!
486 ******************************************************************************
487 @Function ResManFreeResByPtr
489 @Description frees a resource by matching on pointer type
491 @inputs psResItem - pointer to resource item to free
492 bForceCleanup - ignored uKernel re-sync
494 @Return PVRSRV_ERROR
495 **************************************************************************/
496 PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem, IMG_BOOL bForceCleanup)
497 {
498 PVRSRV_ERROR eError;
500 PVR_ASSERT(psResItem != IMG_NULL);
502 if (psResItem == IMG_NULL)
503 {
504 PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do"));
505 return PVRSRV_OK;
506 }
508 PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %p",
509 psResItem));
511 /*Acquire resource list sync object*/
512 ACQUIRE_SYNC_OBJ;
514 /*Check resource list*/
515 VALIDATERESLIST();
517 /*Free resource*/
518 eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup);
520 /*Check resource list*/
521 VALIDATERESLIST();
523 /*Release resource list sync object*/
524 RELEASE_SYNC_OBJ;
526 return(eError);
527 }
530 /*!
531 ******************************************************************************
532 @Function ResManFreeResByCriteria
534 @Description frees a resource by matching on criteria
536 @inputs hResManContext - handle for resman context
537 @inputs ui32SearchCriteria - indicates which parameters should be
538 used in search for resources to free
539 @inputs ui32ResType - identify what kind of resource to free
540 @inputs pvParam - address of resource to be free
541 @inputs ui32Param - size of resource to be free
543 @Return PVRSRV_ERROR
544 **************************************************************************/
545 PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext,
546 IMG_UINT32 ui32SearchCriteria,
547 IMG_UINT32 ui32ResType,
548 IMG_PVOID pvParam,
549 IMG_UINT32 ui32Param)
550 {
551 PVRSRV_ERROR eError;
553 PVR_ASSERT(psResManContext != IMG_NULL);
555 /* Acquire resource list sync object */
556 ACQUIRE_SYNC_OBJ;
558 /* Check resource list */
559 VALIDATERESLIST();
561 PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
562 "Context 0x%p, Criteria 0x%x, Type 0x%x, Addr 0x%p, Param 0x%x",
563 psResManContext, ui32SearchCriteria, ui32ResType,
564 pvParam, ui32Param));
566 /* Free resources by criteria for this context */
567 eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
568 ui32ResType, pvParam, ui32Param,
569 IMG_TRUE);
571 /* Check resource list */
572 VALIDATERESLIST();
574 /* Release resource list sync object */
575 RELEASE_SYNC_OBJ;
577 return eError;
578 }
581 /*!
582 ******************************************************************************
583 @Function ResManDissociateRes
585 @Description Moves a resource from one context to another.
587 @inputs psResItem - pointer to resource item to dissociate
588 @inputs psNewResManContext - new resman context for the resource
590 @Return IMG_VOID
591 **************************************************************************/
592 PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem,
593 PRESMAN_CONTEXT psNewResManContext)
594 {
595 PVRSRV_ERROR eError = PVRSRV_OK;
597 PVR_ASSERT(psResItem != IMG_NULL);
599 if (psResItem == IMG_NULL)
600 {
601 PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem"));
602 PVR_DBG_BREAK;
603 return PVRSRV_ERROR_INVALID_PARAMS;
604 }
606 #ifdef DEBUG /* QAC fix */
607 PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
608 #endif
610 if (psNewResManContext != IMG_NULL)
611 {
612 /* Remove this item from its old resource list */
613 List_RESMAN_ITEM_Remove(psResItem);
615 /* Re-insert into new list */
616 List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
618 }
619 else
620 {
621 eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL);
622 if(eError != PVRSRV_OK)
623 {
624 PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
625 return eError;
626 }
627 }
629 return eError;
630 }
632 /*!
633 ******************************************************************************
634 @Function ResManFindResourceByPtr_AnyVaCb
636 @Description
637 Compares the resman item with a given pointer.
639 @inputs psCurItem - theThe item to check
640 @inputs va - Variable argument list with:
641 psItem - pointer to resource item to find
643 @Return IMG_BOOL
644 **************************************************************************/
645 static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
646 {
647 RESMAN_ITEM *psItem;
649 psItem = va_arg(va, RESMAN_ITEM*);
651 return (IMG_BOOL)(psCurItem == psItem);
652 }
655 /*!
656 ******************************************************************************
657 @Function ResManFindResourceByPtr
659 @Description
660 Attempts to find a resource in the list for this context
662 @inputs hResManContext - handle for resman context
663 @inputs psItem - pointer to resource item to find
665 @Return PVRSRV_ERROR
666 **************************************************************************/
667 IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext,
668 RESMAN_ITEM *psItem)
669 {
670 /* RESMAN_ITEM *psCurItem;*/
672 PVRSRV_ERROR eResult;
674 PVR_ASSERT(psResManContext != IMG_NULL);
675 PVR_ASSERT(psItem != IMG_NULL);
677 if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL))
678 {
679 PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter"));
680 PVR_DBG_BREAK;
681 return PVRSRV_ERROR_INVALID_PARAMS;
682 }
684 #ifdef DEBUG /* QAC fix */
685 PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
686 #endif
688 /* Acquire resource list sync object */
689 ACQUIRE_SYNC_OBJ;
691 PVR_DPF((PVR_DBG_MESSAGE,
692 "FindResourceByPtr: psItem=%p, psItem->psNext=%p",
693 psItem, psItem->psNext));
695 PVR_DPF((PVR_DBG_MESSAGE,
696 "FindResourceByPtr: Resource Ctx 0x%p, Type 0x%x, Addr 0x%p, "
697 "Param 0x%x, FnCall %p, Flags 0x%x",
698 psResManContext,
699 psItem->ui32ResType,
700 psItem->pvParam,
701 psItem->ui32Param,
702 psItem->pfnFreeResource,
703 psItem->ui32Flags));
705 /* Search resource items starting at after the first dummy item */
706 if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
707 &ResManFindResourceByPtr_AnyVaCb,
708 psItem))
709 {
710 eResult = PVRSRV_OK;
711 }
712 else
713 {
714 eResult = PVRSRV_ERROR_NOT_OWNER;
715 }
717 /* Release resource list sync object */
718 RELEASE_SYNC_OBJ;
720 /* return PVRSRV_ERROR_NOT_OWNER;*/
721 return eResult;
722 }
724 /*!
725 ******************************************************************************
726 @Function FreeResourceByPtr
728 @Description
729 Frees a resource and move it from the list
730 NOTE : this function must be called with the resource
731 list sync object held
733 @inputs psItem - pointer to resource item to free
734 bExecuteCallback - execute callback?
735 bForceCleanup - skips uKernel re-sync
737 @Return PVRSRV_ERROR
738 **************************************************************************/
739 static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
740 IMG_BOOL bExecuteCallback,
741 IMG_BOOL bForceCleanup)
742 {
743 PVRSRV_ERROR eError = PVRSRV_OK;
745 PVR_ASSERT(psItem != IMG_NULL);
747 if (psItem == IMG_NULL)
748 {
749 PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter"));
750 return PVRSRV_ERROR_INVALID_PARAMS;
751 }
753 #ifdef DEBUG /* QAC fix */
754 PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
755 #endif
757 PVR_DPF((PVR_DBG_MESSAGE,
758 "FreeResourceByPtr: psItem=%p, psItem->psNext=%p",
759 psItem, psItem->psNext));
761 PVR_DPF((PVR_DBG_MESSAGE,
762 "FreeResourceByPtr: Type 0x%x, Addr 0x%p, "
763 "Param 0x%x, FnCall %p, Flags 0x%x",
764 psItem->ui32ResType,
765 psItem->pvParam,
766 psItem->ui32Param,
767 psItem->pfnFreeResource, psItem->ui32Flags));
769 /* Release resource list sync object just in case the free routine calls the resource manager */
770 RELEASE_SYNC_OBJ;
772 /* Call the freeing routine */
773 if (bExecuteCallback)
774 {
775 eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup);
776 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
777 {
778 PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
779 }
780 }
782 /* Acquire resource list sync object */
783 ACQUIRE_SYNC_OBJ;
785 if (eError != PVRSRV_ERROR_RETRY)
786 {
787 /* Remove this item from the resource list */
788 List_RESMAN_ITEM_Remove(psItem);
790 /* Free memory for the resource item */
791 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
792 }
794 return(eError);
795 }
797 /*!
798 ******************************************************************************
799 @Function FreeResourceByCriteria_AnyVaCb
801 @Description
802 Matches a resource manager item with a given criteria.
804 @inputs psCuItem - the item to be matched
805 @inputs va - a variable argument list with:.
806 ui32SearchCriteria - indicates which parameters should be used
807 search for resources to free
808 ui32ResType - identify what kind of resource to free
809 pvParam - address of resource to be free
810 ui32Param - size of resource to be free
813 @Return psCurItem if matched, IMG_NULL otherwise.
814 **************************************************************************/
815 static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
816 {
817 IMG_UINT32 ui32SearchCriteria;
818 IMG_UINT32 ui32ResType;
819 IMG_PVOID pvParam;
820 IMG_UINT32 ui32Param;
822 ui32SearchCriteria = va_arg(va, IMG_UINT32);
823 ui32ResType = va_arg(va, IMG_UINT32);
824 pvParam = va_arg(va, IMG_PVOID);
825 ui32Param = va_arg(va, IMG_UINT32);
827 /*check that for all conditions are either disabled or eval to true*/
828 if(
829 /* Check resource type */
830 (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
831 (psCurItem->ui32ResType == ui32ResType))
832 &&
833 /* Check address */
834 (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
835 (psCurItem->pvParam == pvParam))
836 &&
837 /* Check size */
838 (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
839 (psCurItem->ui32Param == ui32Param))
840 )
841 {
842 return psCurItem;
843 }
844 else
845 {
846 return IMG_NULL;
847 }
848 }
850 /*!
851 ******************************************************************************
852 @Function FreeResourceByCriteria
854 @Description
855 Frees all resources that match the given criteria for the
856 context.
857 NOTE : this function must be called with the resource
858 list sync object held
860 @inputs psResManContext - pointer to resman context
861 @inputs ui32SearchCriteria - indicates which parameters should be used
862 @inputs search for resources to free
863 @inputs ui32ResType - identify what kind of resource to free
864 @inputs pvParam - address of resource to be free
865 @inputs ui32Param - size of resource to be free
866 @inputs ui32AutoFreeLev - auto free level to free
867 @inputs bExecuteCallback - execute callback?
869 @Return PVRSRV_ERROR
870 **************************************************************************/
871 static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext,
872 IMG_UINT32 ui32SearchCriteria,
873 IMG_UINT32 ui32ResType,
874 IMG_PVOID pvParam,
875 IMG_UINT32 ui32Param,
876 IMG_BOOL bExecuteCallback)
877 {
878 PRESMAN_ITEM psCurItem;
879 PVRSRV_ERROR eError = PVRSRV_OK;
881 /* Search resource items starting at after the first dummy item */
882 /*while we get a match and not an error*/
883 while((psCurItem = (PRESMAN_ITEM)
884 List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
885 &FreeResourceByCriteria_AnyVaCb,
886 ui32SearchCriteria,
887 ui32ResType,
888 pvParam,
889 ui32Param)) != IMG_NULL
890 && eError == PVRSRV_OK)
891 {
892 do
893 {
894 eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
895 if (eError == PVRSRV_ERROR_RETRY)
896 {
897 RELEASE_SYNC_OBJ;
898 OSReleaseBridgeLock();
899 /* Give a chance for other threads to come in and SGX to do more work */
900 OSSleepms(MAX_CLEANUP_TIME_WAIT_US/1000);
901 OSReacquireBridgeLock();
902 ACQUIRE_SYNC_OBJ;
903 }
904 } while (eError == PVRSRV_ERROR_RETRY);
905 }
907 return eError;
908 }
911 #ifdef DEBUG
912 /*!
913 ******************************************************************************
914 @Function ValidateResList
916 @Description
917 Walks the resource list check the pointers
918 NOTE : this function must be called with the resource
919 list sync object held
921 @Return none
922 **************************************************************************/
923 static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
924 {
925 PRESMAN_ITEM psCurItem, *ppsThisItem;
926 PRESMAN_CONTEXT psCurContext, *ppsThisContext;
928 /* check we're initialised */
929 if (psResList == IMG_NULL)
930 {
931 PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
932 return;
933 }
935 psCurContext = psResList->psContextList;
936 ppsThisContext = &psResList->psContextList;
938 /* Walk the context list */
939 while(psCurContext != IMG_NULL)
940 {
941 /* Check current item */
942 PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE);
943 if (psCurContext->ppsThis != ppsThisContext)
944 {
945 PVR_DPF((PVR_DBG_WARNING,
946 "psCC=%p psCC->ppsThis=%p psCC->psNext=%p ppsTC=%p",
947 psCurContext,
948 psCurContext->ppsThis,
949 psCurContext->psNext,
950 ppsThisContext));
951 PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
952 }
954 /* Walk the list for this context */
955 psCurItem = psCurContext->psResItemList;
956 ppsThisItem = &psCurContext->psResItemList;
957 while(psCurItem != IMG_NULL)
958 {
959 /* Check current item */
960 PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE);
961 if (psCurItem->ppsThis != ppsThisItem)
962 {
963 PVR_DPF((PVR_DBG_WARNING,
964 "psCurItem=%p psCurItem->ppsThis=%p psCurItem->psNext=%p ppsThisItem=%p",
965 psCurItem,
966 psCurItem->ppsThis,
967 psCurItem->psNext,
968 ppsThisItem));
969 PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
970 }
972 /* Move to next item */
973 ppsThisItem = &psCurItem->psNext;
974 psCurItem = psCurItem->psNext;
975 }
977 /* Move to next context */
978 ppsThisContext = &psCurContext->psNext;
979 psCurContext = psCurContext->psNext;
980 }
981 }
982 #endif /* DEBUG */
985 /******************************************************************************
986 End of file (resman.c)
987 ******************************************************************************/