1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
29 #include "services_headers.h"
30 #include "buffer_manager.h"
31 #include "pvr_pdump.h"
32 #include "pvr_bridge_km.h"
34 #include <linux/pagemap.h>
36 static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap,
37 u32 ui32Flags, u32 ui32Size, u32 ui32Alignment,
38 struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
40 struct RESMAN_MAP_DEVICE_MEM_DATA {
41 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
42 struct PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo;
45 static inline void get_page_details(u32 vaddr, size_t byte_size,
46 u32 *page_offset_out, int *page_count_out)
48 size_t host_page_size;
52 host_page_size = PAGE_SIZE;
53 page_offset = vaddr & (host_page_size - 1);
54 page_count = PAGE_ALIGN(byte_size + page_offset) / host_page_size;
56 *page_offset_out = page_offset;
57 *page_count_out = page_count;
60 static inline int get_page_count(u32 vaddr, size_t byte_size)
65 get_page_details(vaddr, byte_size, &page_offset, &page_count);
70 enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapsKM(void *hDevCookie,
71 struct PVRSRV_HEAP_INFO *psHeapInfo)
73 struct PVRSRV_DEVICE_NODE *psDeviceNode;
75 struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
78 if (hDevCookie == NULL) {
79 PVR_DPF(PVR_DBG_ERROR,
80 "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid");
82 return PVRSRV_ERROR_INVALID_PARAMS;
85 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
87 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
88 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
90 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
92 for (i = 0; i < ui32HeapCount; i++) {
93 psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
94 psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
95 psHeapInfo[i].sDevVAddrBase =
96 psDeviceMemoryHeap[i].sDevVAddrBase;
97 psHeapInfo[i].ui32HeapByteSize =
98 psDeviceMemoryHeap[i].ui32HeapSize;
99 psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
102 for (; i < PVRSRV_MAX_CLIENT_HEAPS; i++) {
103 OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
104 psHeapInfo[i].ui32HeapID = (u32) PVRSRV_UNDEFINED_HEAP_ID;
110 enum PVRSRV_ERROR PVRSRVCreateDeviceMemContextKM(void *hDevCookie,
111 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
112 void **phDevMemContext,
113 u32 *pui32ClientHeapCount,
114 struct PVRSRV_HEAP_INFO *psHeapInfo,
115 IMG_BOOL *pbCreated, IMG_BOOL *pbShared)
117 struct PVRSRV_DEVICE_NODE *psDeviceNode;
118 u32 ui32HeapCount, ui32ClientHeapCount = 0;
119 struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
120 void *hDevMemContext;
122 struct IMG_DEV_PHYADDR sPDDevPAddr;
125 if (hDevCookie == NULL) {
126 PVR_DPF(PVR_DBG_ERROR,
127 "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid");
129 return PVRSRV_ERROR_INVALID_PARAMS;
132 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
134 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
135 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
137 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
139 hDevMemContext = BM_CreateContext(psDeviceNode,
140 &sPDDevPAddr, psPerProc, pbCreated);
141 if (hDevMemContext == NULL) {
142 PVR_DPF(PVR_DBG_ERROR,
143 "PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext");
144 return PVRSRV_ERROR_OUT_OF_MEMORY;
147 for (i = 0; i < ui32HeapCount; i++) {
148 switch (psDeviceMemoryHeap[i].DevMemHeapType) {
149 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
150 psHeapInfo[ui32ClientHeapCount].ui32HeapID =
151 psDeviceMemoryHeap[i].ui32HeapID;
152 psHeapInfo[ui32ClientHeapCount].hDevMemHeap =
153 psDeviceMemoryHeap[i].hDevMemHeap;
154 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase =
155 psDeviceMemoryHeap[i].sDevVAddrBase;
156 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize =
157 psDeviceMemoryHeap[i].ui32HeapSize;
158 psHeapInfo[ui32ClientHeapCount].ui32Attribs =
159 psDeviceMemoryHeap[i].ui32Attribs;
160 pbShared[ui32ClientHeapCount] = IMG_TRUE;
161 ui32ClientHeapCount++;
163 case DEVICE_MEMORY_HEAP_PERCONTEXT:
164 hDevMemHeap = BM_CreateHeap(hDevMemContext,
165 &psDeviceMemoryHeap[i]);
167 psHeapInfo[ui32ClientHeapCount].ui32HeapID =
168 psDeviceMemoryHeap[i].ui32HeapID;
169 psHeapInfo[ui32ClientHeapCount].hDevMemHeap =
171 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase =
172 psDeviceMemoryHeap[i].sDevVAddrBase;
173 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize =
174 psDeviceMemoryHeap[i].ui32HeapSize;
175 psHeapInfo[ui32ClientHeapCount].ui32Attribs =
176 psDeviceMemoryHeap[i].ui32Attribs;
177 pbShared[ui32ClientHeapCount] = IMG_FALSE;
179 ui32ClientHeapCount++;
184 *pui32ClientHeapCount = ui32ClientHeapCount;
185 *phDevMemContext = hDevMemContext;
190 enum PVRSRV_ERROR PVRSRVDestroyDeviceMemContextKM(void *hDevCookie,
191 void *hDevMemContext,
192 IMG_BOOL *pbDestroyed)
196 PVR_UNREFERENCED_PARAMETER(hDevCookie);
198 destroyed = pvr_put_ctx(hDevMemContext);
200 *pbDestroyed = destroyed ? IMG_TRUE : IMG_FALSE;
205 enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapInfoKM(void *hDevCookie,
206 void *hDevMemContext,
207 u32 *pui32ClientHeapCount,
208 struct PVRSRV_HEAP_INFO *psHeapInfo,
211 struct PVRSRV_DEVICE_NODE *psDeviceNode;
212 u32 ui32HeapCount, ui32ClientHeapCount = 0;
213 struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
217 if (hDevCookie == NULL) {
218 PVR_DPF(PVR_DBG_ERROR,
219 "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid");
221 return PVRSRV_ERROR_INVALID_PARAMS;
224 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
226 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
227 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
229 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
231 for (i = 0; i < ui32HeapCount; i++) {
232 switch (psDeviceMemoryHeap[i].DevMemHeapType) {
233 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
234 psHeapInfo[ui32ClientHeapCount].ui32HeapID =
235 psDeviceMemoryHeap[i].ui32HeapID;
236 psHeapInfo[ui32ClientHeapCount].hDevMemHeap =
237 psDeviceMemoryHeap[i].hDevMemHeap;
238 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase =
239 psDeviceMemoryHeap[i].sDevVAddrBase;
240 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize =
241 psDeviceMemoryHeap[i].ui32HeapSize;
242 psHeapInfo[ui32ClientHeapCount].ui32Attribs =
243 psDeviceMemoryHeap[i].ui32Attribs;
244 pbShared[ui32ClientHeapCount] = IMG_TRUE;
245 ui32ClientHeapCount++;
247 case DEVICE_MEMORY_HEAP_PERCONTEXT:
248 hDevMemHeap = BM_CreateHeap(hDevMemContext,
249 &psDeviceMemoryHeap[i]);
250 psHeapInfo[ui32ClientHeapCount].ui32HeapID =
251 psDeviceMemoryHeap[i].ui32HeapID;
252 psHeapInfo[ui32ClientHeapCount].hDevMemHeap =
254 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase =
255 psDeviceMemoryHeap[i].sDevVAddrBase;
256 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize =
257 psDeviceMemoryHeap[i].ui32HeapSize;
258 psHeapInfo[ui32ClientHeapCount].ui32Attribs =
259 psDeviceMemoryHeap[i].ui32Attribs;
260 pbShared[ui32ClientHeapCount] = IMG_FALSE;
262 ui32ClientHeapCount++;
266 *pui32ClientHeapCount = ui32ClientHeapCount;
271 static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap,
272 u32 ui32Flags, u32 ui32Size,
274 struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
276 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
279 struct PVRSRV_MEMBLK *psMemBlock;
282 PVR_UNREFERENCED_PARAMETER(hDevCookie);
286 if (OSAllocMem(PVRSRV_PAGEABLE_SELECT,
287 sizeof(struct PVRSRV_KERNEL_MEM_INFO),
288 (void **) &psMemInfo, NULL) != PVRSRV_OK) {
289 PVR_DPF(PVR_DBG_ERROR,
290 "AllocDeviceMem: Failed to alloc memory for block");
291 return PVRSRV_ERROR_OUT_OF_MEMORY;
294 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
296 psMemBlock = &(psMemInfo->sMemBlk);
298 psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
300 bBMError = BM_Alloc(hDevMemHeap, NULL, ui32Size,
301 &psMemInfo->ui32Flags, ui32Alignment, &hBuffer);
304 PVR_DPF(PVR_DBG_ERROR, "AllocDeviceMem: BM_Alloc Failed");
305 OSFreeMem(PVRSRV_PAGEABLE_SELECT,
306 sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
308 return PVRSRV_ERROR_OUT_OF_MEMORY;
311 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
312 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
314 psMemBlock->hBuffer = (void *)hBuffer;
315 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
316 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
317 psMemInfo->ui32AllocSize = ui32Size;
319 psMemInfo->pvSysBackupBuffer = NULL;
321 *ppsMemInfo = psMemInfo;
326 static enum PVRSRV_ERROR FreeDeviceMem(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo)
331 return PVRSRV_ERROR_INVALID_PARAMS;
333 hBuffer = psMemInfo->sMemBlk.hBuffer;
334 BM_Free(hBuffer, psMemInfo->ui32Flags);
336 if (psMemInfo->pvSysBackupBuffer)
337 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize,
338 psMemInfo->pvSysBackupBuffer, NULL);
340 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO),
346 enum PVRSRV_ERROR PVRSRVAllocSyncInfoKM(void *hDevCookie, void *hDevMemContext,
347 struct PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo)
349 void *hSyncDevMemHeap;
350 struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
351 struct BM_CONTEXT *pBMContext;
352 enum PVRSRV_ERROR eError;
353 struct PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
354 struct PVRSRV_SYNC_DATA *psSyncData;
356 eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
357 sizeof(struct PVRSRV_KERNEL_SYNC_INFO),
358 (void **) &psKernelSyncInfo, NULL);
359 if (eError != PVRSRV_OK) {
360 PVR_DPF(PVR_DBG_ERROR,
361 "PVRSRVAllocSyncInfoKM: Failed to alloc memory");
362 return PVRSRV_ERROR_OUT_OF_MEMORY;
365 pBMContext = (struct BM_CONTEXT *)hDevMemContext;
366 psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
368 hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->
369 ui32SyncHeapID].hDevMemHeap;
371 eError = AllocDeviceMem(hDevCookie, hSyncDevMemHeap,
372 PVRSRV_MEM_CACHE_CONSISTENT,
373 sizeof(struct PVRSRV_SYNC_DATA), sizeof(u32),
374 &psKernelSyncInfo->psSyncDataMemInfoKM);
376 if (eError != PVRSRV_OK) {
377 PVR_DPF(PVR_DBG_ERROR,
378 "PVRSRVAllocSyncInfoKM: Failed to alloc memory");
379 OSFreeMem(PVRSRV_PAGEABLE_SELECT,
380 sizeof(struct PVRSRV_KERNEL_SYNC_INFO),
381 psKernelSyncInfo, NULL);
382 return PVRSRV_ERROR_OUT_OF_MEMORY;
385 psKernelSyncInfo->psSyncData =
386 psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
387 psSyncData = psKernelSyncInfo->psSyncData;
389 psSyncData->ui32WriteOpsPending = 0;
390 psSyncData->ui32WriteOpsComplete = 0;
391 psSyncData->ui32ReadOpsPending = 0;
392 psSyncData->ui32ReadOpsComplete = 0;
393 psSyncData->ui32LastOpDumpVal = 0;
394 psSyncData->ui32LastReadOpDumpVal = 0;
397 PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
398 psKernelSyncInfo->psSyncDataMemInfoKM, 0,
399 psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize,
400 0, MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
403 psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr =
404 psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr +
405 offsetof(struct PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
406 psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr =
407 psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr +
408 offsetof(struct PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
410 psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = NULL;
412 *ppsKernelSyncInfo = psKernelSyncInfo;
417 enum PVRSRV_ERROR PVRSRVFreeSyncInfoKM(
418 struct PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
420 FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
421 OSFreeMem(PVRSRV_PAGEABLE_SELECT,
422 sizeof(struct PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo,
429 void get_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo)
431 syncinfo->refcount++;
435 void put_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo)
437 struct PVRSRV_DEVICE_NODE *dev = syncinfo->dev_cookie;
439 syncinfo->refcount--;
441 if (!syncinfo->refcount) {
442 HASH_Remove(dev->sync_table,
443 syncinfo->phys_addr.uiAddr);
444 PVRSRVFreeSyncInfoKM(syncinfo);
449 enum PVRSRV_ERROR alloc_or_reuse_syncinfo(void *dev_cookie,
450 void *mem_context_handle,
451 struct PVRSRV_KERNEL_SYNC_INFO **syncinfo,
452 struct IMG_SYS_PHYADDR *phys_addr)
454 enum PVRSRV_ERROR error;
455 struct PVRSRV_DEVICE_NODE *dev;
457 dev = (struct PVRSRV_DEVICE_NODE *) dev_cookie;
459 *syncinfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
460 HASH_Retrieve(dev->sync_table,
464 /* Dont' have one so create one */
465 error = PVRSRVAllocSyncInfoKM(dev_cookie, mem_context_handle,
468 if (error != PVRSRV_OK)
471 /* Setup our extra data */
472 (*syncinfo)->phys_addr.uiAddr = phys_addr->uiAddr;
473 (*syncinfo)->dev_cookie = dev_cookie;
474 (*syncinfo)->refcount = 1;
476 if (!HASH_Insert(dev->sync_table, phys_addr->uiAddr,
478 PVR_DPF(PVR_DBG_ERROR, "alloc_or_reuse_syncinfo: "
479 "Failed to add syncobject to hash table");
480 return PVRSRV_ERROR_GENERIC;
483 get_syncinfo(*syncinfo);
488 static enum PVRSRV_ERROR FreeDeviceMemCallBack(void *pvParam, u32 ui32Param)
490 enum PVRSRV_ERROR eError = PVRSRV_OK;
491 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam;
493 PVR_UNREFERENCED_PARAMETER(ui32Param);
495 psMemInfo->ui32RefCount--;
497 if (psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) {
498 void *hMemInfo = NULL;
500 if (psMemInfo->ui32RefCount != 0) {
501 PVR_DPF(PVR_DBG_ERROR, "FreeDeviceMemCallBack: "
502 "mappings are open in other processes");
503 return PVRSRV_ERROR_GENERIC;
506 eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
509 PVRSRV_HANDLE_TYPE_MEM_INFO);
510 if (eError != PVRSRV_OK) {
511 PVR_DPF(PVR_DBG_ERROR, "FreeDeviceMemCallBack: "
512 "can't find exported meminfo in the "
513 "global handle list");
517 eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
519 PVRSRV_HANDLE_TYPE_MEM_INFO);
520 if (eError != PVRSRV_OK) {
521 PVR_DPF(PVR_DBG_ERROR, "FreeDeviceMemCallBack: "
522 "PVRSRVReleaseHandle failed for exported meminfo");
527 PVR_ASSERT(psMemInfo->ui32RefCount == 0);
529 if (psMemInfo->psKernelSyncInfo)
530 eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
532 if (eError == PVRSRV_OK)
533 eError = FreeDeviceMem(psMemInfo);
538 enum PVRSRV_ERROR PVRSRVFreeDeviceMemKM(void *hDevCookie,
539 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo)
541 PVR_UNREFERENCED_PARAMETER(hDevCookie);
544 return PVRSRV_ERROR_INVALID_PARAMS;
546 if (psMemInfo->sMemBlk.hResItem != NULL)
547 ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
549 FreeDeviceMemCallBack(psMemInfo, 0);
554 enum PVRSRV_ERROR PVRSRVAllocDeviceMemKM(void *hDevCookie,
555 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
556 void *hDevMemHeap, u32 ui32Flags,
557 u32 ui32Size, u32 ui32Alignment,
558 struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
560 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
561 enum PVRSRV_ERROR eError;
562 struct BM_HEAP *psBMHeap;
563 void *hDevMemContext;
565 if (!hDevMemHeap || (ui32Size == 0))
566 return PVRSRV_ERROR_INVALID_PARAMS;
568 eError = AllocDeviceMem(hDevCookie, hDevMemHeap, ui32Flags, ui32Size,
569 ui32Alignment, &psMemInfo);
571 if (eError != PVRSRV_OK)
574 if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) {
575 psMemInfo->psKernelSyncInfo = NULL;
577 psBMHeap = (struct BM_HEAP *)hDevMemHeap;
578 hDevMemContext = (void *) psBMHeap->pBMContext;
579 eError = PVRSRVAllocSyncInfoKM(hDevCookie,
581 &psMemInfo->psKernelSyncInfo);
582 if (eError != PVRSRV_OK)
586 *ppsMemInfo = psMemInfo;
588 if (ui32Flags & PVRSRV_MEM_NO_RESMAN) {
589 psMemInfo->sMemBlk.hResItem = NULL;
591 psMemInfo->sMemBlk.hResItem =
592 ResManRegisterRes(psPerProc->hResManContext,
593 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
594 psMemInfo, 0, FreeDeviceMemCallBack);
595 if (psMemInfo->sMemBlk.hResItem == NULL) {
596 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
601 psMemInfo->ui32RefCount++;
606 FreeDeviceMem(psMemInfo);
611 enum PVRSRV_ERROR PVRSRVDissociateDeviceMemKM(void *hDevCookie,
612 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo)
614 enum PVRSRV_ERROR eError;
615 struct PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie;
617 PVR_UNREFERENCED_PARAMETER(hDevCookie);
620 return PVRSRV_ERROR_INVALID_PARAMS;
622 eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem,
623 psDeviceNode->hResManContext);
625 PVR_ASSERT(eError == PVRSRV_OK);
630 enum PVRSRV_ERROR PVRSRVGetFreeDeviceMemKM(u32 ui32Flags, u32 *pui32Total,
631 u32 *pui32Free, u32 *pui32LargestBlock)
634 PVR_UNREFERENCED_PARAMETER(ui32Flags);
635 PVR_UNREFERENCED_PARAMETER(pui32Total);
636 PVR_UNREFERENCED_PARAMETER(pui32Free);
637 PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
642 enum PVRSRV_ERROR PVRSRVUnwrapExtMemoryKM(
643 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo)
646 return PVRSRV_ERROR_INVALID_PARAMS;
648 ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
653 static enum PVRSRV_ERROR UnwrapExtMemoryCallBack(void *pvParam, u32 ui32Param)
655 enum PVRSRV_ERROR eError = PVRSRV_OK;
656 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam;
659 PVR_UNREFERENCED_PARAMETER(ui32Param);
661 hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
663 if (psMemInfo->psKernelSyncInfo)
664 put_syncinfo(psMemInfo->psKernelSyncInfo);
666 if (psMemInfo->sMemBlk.psIntSysPAddr) {
669 page_count = get_page_count((u32)psMemInfo->pvLinAddrKM,
670 psMemInfo->ui32AllocSize);
672 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
673 page_count * sizeof(struct IMG_SYS_PHYADDR),
674 psMemInfo->sMemBlk.psIntSysPAddr, NULL);
677 if (eError == PVRSRV_OK) {
678 psMemInfo->ui32RefCount--;
679 eError = FreeDeviceMem(psMemInfo);
683 OSReleasePhysPageAddr(hOSWrapMem);
688 enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie,
689 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
690 void *hDevMemContext, u32 ui32ByteSize,
691 u32 ui32PageOffset, IMG_BOOL bPhysContig,
692 struct IMG_SYS_PHYADDR *psExtSysPAddr,
694 struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
696 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL;
697 struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
698 u32 ui32HostPageSize = HOST_PAGESIZE();
699 void *hDevMemHeap = NULL;
700 struct PVRSRV_DEVICE_NODE *psDeviceNode;
702 struct PVRSRV_MEMBLK *psMemBlock;
704 struct BM_HEAP *psBMHeap;
705 enum PVRSRV_ERROR eError;
706 void *pvPageAlignedCPUVAddr;
707 struct IMG_SYS_PHYADDR *psIntSysPAddr = NULL;
708 void *hOSWrapMem = NULL;
709 struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
713 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
714 PVR_ASSERT(psDeviceNode != NULL);
716 if (!psDeviceNode || (!pvLinAddr && !psExtSysPAddr)) {
717 PVR_DPF(PVR_DBG_ERROR,
718 "PVRSRVWrapExtMemoryKM: invalid parameter");
719 return PVRSRV_ERROR_INVALID_PARAMS;
723 get_page_details((u32)pvLinAddr, ui32ByteSize,
724 &ui32PageOffset, &page_count);
725 pvPageAlignedCPUVAddr = (void *)((u8 *) pvLinAddr -
728 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
729 page_count * sizeof(struct IMG_SYS_PHYADDR),
730 (void **)&psIntSysPAddr, NULL) != PVRSRV_OK) {
731 PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: "
732 "Failed to alloc memory for block");
733 return PVRSRV_ERROR_OUT_OF_MEMORY;
736 eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
737 page_count * ui32HostPageSize,
738 psIntSysPAddr, &hOSWrapMem);
739 if (eError != PVRSRV_OK) {
740 PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM:"
741 " Failed to alloc memory for block");
742 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
743 goto ErrorExitPhase1;
745 psExtSysPAddr = psIntSysPAddr;
746 bPhysContig = IMG_FALSE;
750 &((struct BM_CONTEXT *)hDevMemContext)->psDeviceNode->
752 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
753 for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) {
754 if (HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) ==
755 psDevMemoryInfo->ui32MappingHeapID) {
756 if (psDeviceMemoryHeap[i].DevMemHeapType ==
757 DEVICE_MEMORY_HEAP_PERCONTEXT) {
759 BM_CreateHeap(hDevMemContext,
760 &psDeviceMemoryHeap[i]);
763 psDevMemoryInfo->psDeviceMemoryHeap[i].
770 if (hDevMemHeap == NULL) {
771 PVR_DPF(PVR_DBG_ERROR,
772 "PVRSRVWrapExtMemoryKM: unable to find mapping heap");
773 eError = PVRSRV_ERROR_GENERIC;
774 goto ErrorExitPhase2;
777 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
778 sizeof(struct PVRSRV_KERNEL_MEM_INFO),
779 (void **) &psMemInfo, NULL) != PVRSRV_OK) {
780 PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: "
781 "Failed to alloc memory for block");
782 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
783 goto ErrorExitPhase2;
786 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
787 psMemBlock = &(psMemInfo->sMemBlk);
789 bBMError = BM_Wrap(hDevMemHeap,
794 NULL, &psMemInfo->ui32Flags, &hBuffer);
796 PVR_DPF(PVR_DBG_ERROR,
797 "PVRSRVWrapExtMemoryKM: BM_Wrap Failed");
798 eError = PVRSRV_ERROR_BAD_MAPPING;
799 goto ErrorExitPhase3;
802 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
803 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
804 psMemBlock->hOSWrapMem = hOSWrapMem;
805 psMemBlock->psIntSysPAddr = psIntSysPAddr;
807 psMemBlock->hBuffer = (void *) hBuffer;
809 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
810 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
811 psMemInfo->ui32AllocSize = ui32ByteSize;
813 psMemInfo->pvSysBackupBuffer = NULL;
815 psBMHeap = (struct BM_HEAP *)hDevMemHeap;
816 hDevMemContext = (void *) psBMHeap->pBMContext;
817 eError = alloc_or_reuse_syncinfo(hDevCookie,
819 &psMemInfo->psKernelSyncInfo,
821 if (eError != PVRSRV_OK)
822 goto ErrorExitPhase4;
824 psMemInfo->ui32RefCount++;
826 psMemInfo->sMemBlk.hResItem =
827 ResManRegisterRes(psPerProc->hResManContext,
828 RESMAN_TYPE_DEVICEMEM_WRAP, psMemInfo, 0,
829 UnwrapExtMemoryCallBack);
831 *ppsMemInfo = psMemInfo;
836 FreeDeviceMem(psMemInfo);
841 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
842 sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
848 OSReleasePhysPageAddr(hOSWrapMem);
852 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
853 page_count * sizeof(struct IMG_SYS_PHYADDR),
854 psIntSysPAddr, NULL);
860 enum PVRSRV_ERROR PVRSRVUnmapDeviceMemoryKM(
861 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo)
864 return PVRSRV_ERROR_INVALID_PARAMS;
866 ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
871 static enum PVRSRV_ERROR UnmapDeviceMemoryCallBack(void *pvParam, u32 ui32Param)
873 enum PVRSRV_ERROR eError;
874 struct RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam;
877 PVR_UNREFERENCED_PARAMETER(ui32Param);
879 page_count = get_page_count((u32)psMapData->psMemInfo->pvLinAddrKM,
880 psMapData->psMemInfo->ui32AllocSize);
882 if (psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
883 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
884 page_count * sizeof(struct IMG_SYS_PHYADDR),
885 psMapData->psMemInfo->sMemBlk.psIntSysPAddr, NULL);
887 eError = FreeDeviceMem(psMapData->psMemInfo);
888 if (eError != PVRSRV_OK) {
889 PVR_DPF(PVR_DBG_ERROR, "UnmapDeviceMemoryCallBack: "
890 "Failed to free DST meminfo");
894 psMapData->psSrcMemInfo->ui32RefCount--;
896 PVR_ASSERT(psMapData->psSrcMemInfo->ui32RefCount != (u32) (-1));
898 * Don't free the source MemInfo as we didn't allocate it
899 * and it's not our job as the process the allocated
900 * should also free it when it's finished
902 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
903 sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), psMapData, NULL);
908 static inline int bm_is_continuous(const struct BM_BUF *buf)
910 return buf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr;
913 enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM(
914 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
915 struct PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
916 void *hDstDevMemHeap,
917 struct PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo)
919 enum PVRSRV_ERROR eError;
921 u32 ui32HostPageSize = HOST_PAGESIZE();
924 struct IMG_SYS_PHYADDR *psSysPAddr = NULL;
925 struct IMG_DEV_PHYADDR sDevPAddr;
926 struct BM_BUF *psBuf;
927 struct IMG_DEV_VIRTADDR sDevVAddr;
928 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL;
930 struct PVRSRV_MEMBLK *psMemBlock;
932 struct PVRSRV_DEVICE_NODE *psDeviceNode;
933 void *pvPageAlignedCPUVAddr;
934 struct RESMAN_MAP_DEVICE_MEM_DATA *psMapData = NULL;
936 if (!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) {
937 PVR_DPF(PVR_DBG_ERROR,
938 "PVRSRVMapDeviceMemoryKM: invalid parameters");
939 return PVRSRV_ERROR_INVALID_PARAMS;
942 *ppsDstMemInfo = NULL;
944 get_page_details((u32)psSrcMemInfo->pvLinAddrKM,
945 psSrcMemInfo->ui32AllocSize,
946 &ui32PageOffset, &page_count);
947 pvPageAlignedCPUVAddr =
948 (void *) ((u8 *) psSrcMemInfo->pvLinAddrKM -
951 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
952 page_count * sizeof(struct IMG_SYS_PHYADDR),
953 (void **) &psSysPAddr, NULL) != PVRSRV_OK) {
954 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
955 "Failed to alloc memory for block");
956 return PVRSRV_ERROR_OUT_OF_MEMORY;
959 psBuf = psSrcMemInfo->sMemBlk.hBuffer;
961 psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
963 sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - ui32PageOffset;
964 for (i = 0; i < page_count; i++) {
966 BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
967 if (eError != PVRSRV_OK) {
968 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
969 "Failed to retrieve page list from device");
974 SysDevPAddrToSysPAddr(psDeviceNode->sDevId.eDeviceType,
977 sDevVAddr.uiAddr += ui32HostPageSize;
980 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
981 sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA),
982 (void **)&psMapData, NULL) != PVRSRV_OK) {
983 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
984 "Failed to alloc resman map data");
985 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
989 if (OSAllocMem(PVRSRV_PAGEABLE_SELECT,
990 sizeof(struct PVRSRV_KERNEL_MEM_INFO),
991 (void **)&psMemInfo, NULL) != PVRSRV_OK) {
992 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
993 "Failed to alloc memory for block");
994 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
998 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
1000 psMemBlock = &(psMemInfo->sMemBlk);
1002 bBMError = BM_Wrap(hDstDevMemHeap, psSrcMemInfo->ui32AllocSize,
1003 ui32PageOffset, bm_is_continuous(psBuf), psSysPAddr,
1004 pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags,
1008 PVR_DPF(PVR_DBG_ERROR,
1009 "PVRSRVMapDeviceMemoryKM: BM_Wrap Failed");
1010 eError = PVRSRV_ERROR_BAD_MAPPING;
1014 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
1015 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
1017 psMemBlock->hBuffer = (void *) hBuffer;
1019 psMemBlock->psIntSysPAddr = psSysPAddr;
1021 psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
1023 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
1024 psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize;
1025 psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
1027 psMemInfo->pvSysBackupBuffer = NULL;
1029 psSrcMemInfo->ui32RefCount++;
1031 psMapData->psMemInfo = psMemInfo;
1032 psMapData->psSrcMemInfo = psSrcMemInfo;
1034 psMemInfo->sMemBlk.hResItem =
1035 ResManRegisterRes(psPerProc->hResManContext,
1036 RESMAN_TYPE_DEVICEMEM_MAPPING, psMapData, 0,
1037 UnmapDeviceMemoryCallBack);
1039 *ppsDstMemInfo = psMemInfo;
1046 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1047 sizeof(struct IMG_SYS_PHYADDR), psSysPAddr, NULL);
1051 OSFreeMem(PVRSRV_PAGEABLE_SELECT,
1052 sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
1057 OSFreeMem(PVRSRV_PAGEABLE_SELECT,
1058 sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), psMapData,
1065 enum PVRSRV_ERROR PVRSRVUnmapDeviceClassMemoryKM(
1066 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo)
1069 return PVRSRV_ERROR_INVALID_PARAMS;
1071 ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
1076 static enum PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(void *pvParam,
1079 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam;
1081 PVR_UNREFERENCED_PARAMETER(ui32Param);
1083 return FreeDeviceMem(psMemInfo);
1086 enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM(
1087 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
1088 void *hDevMemContext, void *hDeviceClassBuffer,
1089 struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
1092 enum PVRSRV_ERROR eError;
1093 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
1094 struct PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
1095 struct IMG_SYS_PHYADDR *psSysPAddr;
1096 void *pvCPUVAddr, *pvPageAlignedCPUVAddr;
1097 IMG_BOOL bPhysContig;
1098 struct BM_CONTEXT *psBMContext;
1099 struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
1100 struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
1101 void *hDevMemHeap = NULL;
1104 u32 ui32PageSize = HOST_PAGESIZE();
1106 struct PVRSRV_MEMBLK *psMemBlock;
1110 if (!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo ||
1112 PVR_DPF(PVR_DBG_ERROR,
1113 "PVRSRVMapDeviceClassMemoryKM: invalid parameters");
1114 return PVRSRV_ERROR_INVALID_PARAMS;
1117 psDeviceClassBuffer = (struct PVRSRV_DEVICECLASS_BUFFER *)
1121 psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->
1123 psDeviceClassBuffer->
1124 hExtBuffer, &psSysPAddr,
1126 (void __iomem **)&pvCPUVAddr,
1127 phOSMapInfo, &bPhysContig);
1128 if (eError != PVRSRV_OK) {
1129 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
1130 "unable to get buffer address");
1131 return PVRSRV_ERROR_GENERIC;
1134 psBMContext = (struct BM_CONTEXT *)psDeviceClassBuffer->hDevMemContext;
1135 psDevMemoryInfo = &psBMContext->psDeviceNode->sDevMemoryInfo;
1136 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
1137 for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) {
1138 if (HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) ==
1139 psDevMemoryInfo->ui32MappingHeapID) {
1140 if (psDeviceMemoryHeap[i].DevMemHeapType ==
1141 DEVICE_MEMORY_HEAP_PERCONTEXT)
1143 BM_CreateHeap(hDevMemContext,
1144 &psDeviceMemoryHeap[i]);
1147 psDevMemoryInfo->psDeviceMemoryHeap[i].
1153 if (hDevMemHeap == NULL) {
1154 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
1155 "unable to find mapping heap");
1156 return PVRSRV_ERROR_GENERIC;
1159 ui32Offset = ((u32)pvCPUVAddr) & (ui32PageSize - 1);
1160 pvPageAlignedCPUVAddr = (void *)((u8 *)pvCPUVAddr - ui32Offset);
1162 if (OSAllocMem(PVRSRV_PAGEABLE_SELECT,
1163 sizeof(struct PVRSRV_KERNEL_MEM_INFO),
1164 (void **)&psMemInfo, NULL) != PVRSRV_OK) {
1165 PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
1166 "Failed to alloc memory for block");
1167 return PVRSRV_ERROR_OUT_OF_MEMORY;
1170 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
1172 psMemBlock = &(psMemInfo->sMemBlk);
1174 bBMError = BM_Wrap(hDevMemHeap, ui32ByteSize, ui32Offset, bPhysContig,
1175 psSysPAddr, pvPageAlignedCPUVAddr,
1176 &psMemInfo->ui32Flags, &hBuffer);
1179 PVR_DPF(PVR_DBG_ERROR,
1180 "PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed");
1181 OSFreeMem(PVRSRV_PAGEABLE_SELECT,
1182 sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
1184 return PVRSRV_ERROR_BAD_MAPPING;
1187 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
1188 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
1190 psMemBlock->hBuffer = (void *) hBuffer;
1192 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
1194 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
1195 psMemInfo->ui32AllocSize = ui32ByteSize;
1196 psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
1198 psMemInfo->pvSysBackupBuffer = NULL;
1200 psMemInfo->sMemBlk.hResItem =
1201 ResManRegisterRes(psPerProc->hResManContext,
1202 RESMAN_TYPE_DEVICECLASSMEM_MAPPING, psMemInfo, 0,
1203 UnmapDeviceClassMemoryCallBack);
1205 *ppsMemInfo = psMemInfo;