]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/device-ti-proprietary-open.git/blob - jacinto6/sgx_src/eurasia_km/services4/srvkm/common/resman.c
jacinto6: sgx: update DDK version to 1.12/2701748
[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_
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_
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
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)
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;
220 /*!
221 ******************************************************************************
223  @Function      ResManDeInit
225  @Description de-initialises the resman
227  @Return   none
229 ******************************************************************************/
230 IMG_VOID ResManDeInit(IMG_VOID)
232         if (gpsResList != IMG_NULL)
233         {
234                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
235                 gpsResList = IMG_NULL;
236         }
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)
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;
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)
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);
354                 
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;
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)
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);
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)
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);
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)
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;
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)
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;
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)
647         RESMAN_ITEM             *psItem;
649         psItem = va_arg(va, RESMAN_ITEM*);
651         return (IMG_BOOL)(psCurItem == psItem);
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)
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;
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)
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);
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)
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         }
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)
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;
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)
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         }
982 #endif /* DEBUG */
985 /******************************************************************************
986  End of file (resman.c)
987 ******************************************************************************/