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 ******************************************************************************/
27 #include "services_headers.h"
31 static int QueuePrintCommands(struct PVRSRV_QUEUE_INFO *psQueue, char *buffer,
36 u32 ui32ReadOffset = psQueue->ui32ReadOffset;
37 u32 ui32WriteOffset = psQueue->ui32WriteOffset;
38 struct PVRSRV_COMMAND *psCmd;
40 while (ui32ReadOffset != ui32WriteOffset) {
41 psCmd = (struct PVRSRV_COMMAND *)((u32) psQueue->pvLinQueueKM +
44 off = printAppend(buffer, size, off,
45 "%p %p %5u %6u %3u %5u %2u %2u %3u \n",
46 psQueue, psCmd, psCmd->ui32ProcessID,
47 psCmd->CommandType, psCmd->ui32CmdSize,
48 psCmd->ui32DevIndex, psCmd->ui32DstSyncCount,
49 psCmd->ui32SrcSyncCount, psCmd->ui32DataSize);
51 ui32ReadOffset += psCmd->ui32CmdSize;
52 ui32ReadOffset &= psQueue->ui32QueueSize - 1;
56 off = printAppend(buffer, size, off, "%p <empty>\n", psQueue);
60 off_t QueuePrintQueues(char *buffer, size_t size, off_t off)
62 struct SYS_DATA *psSysData;
63 struct PVRSRV_QUEUE_INFO *psQueue;
65 if (SysAcquireData(&psSysData) != PVRSRV_OK)
69 return printAppend(buffer, size, 0,
70 "Command Queues\nQueue CmdPtr "
71 "Pid Command Size DevInd DSC SSC #Data ...\n");
73 for (psQueue = psSysData->psQueueList; --off && psQueue;
74 psQueue = psQueue->psNextKM)
78 QueuePrintCommands(psQueue, buffer, size) : END_OF_FILE;
81 #define GET_SPACE_IN_CMDQ(psQueue) \
82 (((psQueue->ui32ReadOffset - psQueue->ui32WriteOffset) + \
83 (psQueue->ui32QueueSize - 1)) & (psQueue->ui32QueueSize - 1))
85 #define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \
86 psQueue->ui32WriteOffset = (psQueue->ui32WriteOffset + ui32Size) & \
87 (psQueue->ui32QueueSize - 1);
89 #define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \
90 (ui32OpsComplete >= ui32OpsPending)
92 static u32 NearestPower2(u32 ui32Value)
94 u32 ui32Temp, ui32Result = 1;
99 ui32Temp = ui32Value - 1;
108 enum PVRSRV_ERROR PVRSRVCreateCommandQueueKM(u32 ui32QueueSize,
109 struct PVRSRV_QUEUE_INFO **ppsQueueInfo)
111 struct PVRSRV_QUEUE_INFO *psQueueInfo;
112 u32 ui32Power2QueueSize = NearestPower2(ui32QueueSize);
113 struct SYS_DATA *psSysData;
114 enum PVRSRV_ERROR eError;
117 eError = SysAcquireData(&psSysData);
118 if (eError != PVRSRV_OK)
121 if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
122 sizeof(struct PVRSRV_QUEUE_INFO),
123 (void **) &psQueueInfo, &hMemBlock) != PVRSRV_OK) {
124 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateCommandQueueKM: "
125 "Failed to alloc queue struct");
128 OSMemSet(psQueueInfo, 0, sizeof(struct PVRSRV_QUEUE_INFO));
130 psQueueInfo->hMemBlock[0] = hMemBlock;
131 psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
133 if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
134 ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
135 &psQueueInfo->pvLinQueueKM, &hMemBlock) != PVRSRV_OK) {
136 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateCommandQueueKM: "
137 "Failed to alloc queue buffer");
141 psQueueInfo->hMemBlock[1] = hMemBlock;
142 psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
144 PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
145 PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
147 psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
149 psQueueInfo->psNextKM = psSysData->psQueueList;
150 psSysData->psQueueList = psQueueInfo;
152 *ppsQueueInfo = psQueueInfo;
159 if (psQueueInfo->pvLinQueueKM)
160 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
161 psQueueInfo->ui32QueueSize,
162 psQueueInfo->pvLinQueueKM,
163 psQueueInfo->hMemBlock[1]);
165 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
166 sizeof(struct PVRSRV_QUEUE_INFO),
167 psQueueInfo, psQueueInfo->hMemBlock[0]);
170 return PVRSRV_ERROR_GENERIC;
173 enum PVRSRV_ERROR PVRSRVDestroyCommandQueueKM(
174 struct PVRSRV_QUEUE_INFO *psQueueInfo)
176 struct PVRSRV_QUEUE_INFO *psQueue;
177 struct SYS_DATA *psSysData;
178 enum PVRSRV_ERROR eError;
179 IMG_BOOL bTimeout = IMG_TRUE;
181 eError = SysAcquireData(&psSysData);
182 if (eError != PVRSRV_OK)
185 psQueue = psSysData->psQueueList;
187 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
188 if (psQueueInfo->ui32ReadOffset ==
189 psQueueInfo->ui32WriteOffset) {
190 bTimeout = IMG_FALSE;
193 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
195 END_LOOP_UNTIL_TIMEOUT();
198 PVR_DPF(PVR_DBG_ERROR,
199 "PVRSRVDestroyCommandQueueKM : Failed to empty queue");
200 eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
204 if (psQueue == psQueueInfo) {
205 psSysData->psQueueList = psQueueInfo->psNextKM;
207 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
208 psQueueInfo->ui32QueueSize,
209 psQueueInfo->pvLinQueueKM, psQueueInfo->hMemBlock[1]);
210 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
211 sizeof(struct PVRSRV_QUEUE_INFO),
212 psQueueInfo, psQueueInfo->hMemBlock[0]);
215 if (psQueue->psNextKM == psQueueInfo) {
216 psQueue->psNextKM = psQueueInfo->psNextKM;
218 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
219 psQueueInfo->ui32QueueSize,
220 psQueueInfo->pvLinQueueKM,
221 psQueueInfo->hMemBlock[1]);
222 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
223 sizeof(struct PVRSRV_QUEUE_INFO),
225 psQueueInfo->hMemBlock[0]);
228 psQueue = psQueue->psNextKM;
232 eError = PVRSRV_ERROR_INVALID_PARAMS;
242 enum PVRSRV_ERROR PVRSRVGetQueueSpaceKM(struct PVRSRV_QUEUE_INFO *psQueue,
243 u32 ui32ParamSize, void **ppvSpace)
245 IMG_BOOL bTimeout = IMG_TRUE;
247 ui32ParamSize = (ui32ParamSize + 3) & 0xFFFFFFFC;
249 if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE) {
250 PVR_DPF(PVR_DBG_WARNING,
251 "PVRSRVGetQueueSpace: max command size is %d bytes",
252 PVRSRV_MAX_CMD_SIZE);
253 return PVRSRV_ERROR_CMD_TOO_BIG;
256 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) {
257 if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize) {
258 bTimeout = IMG_FALSE;
261 OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT);
263 END_LOOP_UNTIL_TIMEOUT();
265 if (bTimeout == IMG_TRUE) {
268 return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
270 *ppvSpace = (void *)(psQueue->ui32WriteOffset +
271 (u32)psQueue->pvLinQueueUM);
277 enum PVRSRV_ERROR PVRSRVInsertCommandKM(struct PVRSRV_QUEUE_INFO *psQueue,
278 struct PVRSRV_COMMAND **ppsCommand,
279 u32 ui32DevIndex, u16 CommandType,
280 u32 ui32DstSyncCount,
281 struct PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
282 u32 ui32SrcSyncCount,
283 struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
284 u32 ui32DataByteSize)
286 enum PVRSRV_ERROR eError;
287 struct PVRSRV_COMMAND *psCommand;
291 ui32DataByteSize = (ui32DataByteSize + 3) & 0xFFFFFFFC;
293 ui32CommandSize = sizeof(struct PVRSRV_COMMAND) +
294 ((ui32DstSyncCount + ui32SrcSyncCount) *
295 sizeof(struct PVRSRV_SYNC_OBJECT)) + ui32DataByteSize;
297 eError = PVRSRVGetQueueSpaceKM(psQueue, ui32CommandSize,
298 (void **) &psCommand);
299 if (eError != PVRSRV_OK)
302 psCommand->ui32ProcessID = OSGetCurrentProcessIDKM();
304 psCommand->ui32CmdSize = ui32CommandSize;
305 psCommand->ui32DevIndex = ui32DevIndex;
306 psCommand->CommandType = CommandType;
307 psCommand->ui32DstSyncCount = ui32DstSyncCount;
308 psCommand->ui32SrcSyncCount = ui32SrcSyncCount;
309 psCommand->psDstSync =
310 (struct PVRSRV_SYNC_OBJECT *)(((u8 *) psCommand) +
311 sizeof(struct PVRSRV_COMMAND));
313 psCommand->psSrcSync =
314 (struct PVRSRV_SYNC_OBJECT *)(((u8 *) psCommand->psDstSync) +
316 sizeof(struct PVRSRV_SYNC_OBJECT)));
319 (struct PVRSRV_SYNC_OBJECT *)(((u8 *) psCommand->psSrcSync) +
321 sizeof(struct PVRSRV_SYNC_OBJECT)));
323 psCommand->ui32DataSize = ui32DataByteSize;
325 for (i = 0; i < ui32DstSyncCount; i++) {
326 psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
327 psCommand->psDstSync[i].ui32WriteOpsPending =
328 PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
329 psCommand->psDstSync[i].ui32ReadOpsPending =
330 PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
333 for (i = 0; i < ui32SrcSyncCount; i++) {
334 psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
335 psCommand->psSrcSync[i].ui32WriteOpsPending =
336 PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
337 psCommand->psSrcSync[i].ui32ReadOpsPending =
338 PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
341 *ppsCommand = psCommand;
346 enum PVRSRV_ERROR PVRSRVSubmitCommandKM(struct PVRSRV_QUEUE_INFO *psQueue,
347 struct PVRSRV_COMMAND *psCommand)
350 if (psCommand->ui32DstSyncCount > 0) {
351 psCommand->psDstSync = (struct PVRSRV_SYNC_OBJECT *)
352 (((u8 *)psQueue->pvLinQueueKM) +
353 psQueue->ui32WriteOffset +
354 sizeof(struct PVRSRV_COMMAND));
357 if (psCommand->ui32SrcSyncCount > 0) {
358 psCommand->psSrcSync = (struct PVRSRV_SYNC_OBJECT *)
359 (((u8 *)psQueue->pvLinQueueKM) +
360 psQueue->ui32WriteOffset +
361 sizeof(struct PVRSRV_COMMAND) +
362 (psCommand->ui32DstSyncCount *
363 sizeof(struct PVRSRV_SYNC_OBJECT)));
366 psCommand->pvData = (struct PVRSRV_SYNC_OBJECT *)
367 (((u8 *)psQueue->pvLinQueueKM) +
368 psQueue->ui32WriteOffset +
369 sizeof(struct PVRSRV_COMMAND) +
370 (psCommand->ui32DstSyncCount *
371 sizeof(struct PVRSRV_SYNC_OBJECT)) +
372 (psCommand->ui32SrcSyncCount *
373 sizeof(struct PVRSRV_SYNC_OBJECT)));
375 UPDATE_QUEUE_WOFF(psQueue, psCommand->ui32CmdSize);
380 static enum PVRSRV_ERROR PVRSRVProcessCommand(struct SYS_DATA *psSysData,
381 struct PVRSRV_COMMAND *psCommand,
384 struct PVRSRV_SYNC_OBJECT *psWalkerObj;
385 struct PVRSRV_SYNC_OBJECT *psEndObj;
387 struct COMMAND_COMPLETE_DATA *psCmdCompleteData;
388 enum PVRSRV_ERROR eError = PVRSRV_OK;
389 u32 ui32WriteOpsComplete;
390 u32 ui32ReadOpsComplete;
392 psWalkerObj = psCommand->psDstSync;
393 psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
394 while (psWalkerObj < psEndObj) {
395 struct PVRSRV_SYNC_DATA *psSyncData =
396 psWalkerObj->psKernelSyncInfoKM->psSyncData;
398 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
399 ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
401 if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
402 || (ui32ReadOpsComplete !=
403 psWalkerObj->ui32ReadOpsPending)) {
405 !SYNCOPS_STALE(ui32WriteOpsComplete,
406 psWalkerObj->ui32WriteOpsPending) ||
407 !SYNCOPS_STALE(ui32ReadOpsComplete,
408 psWalkerObj->ui32ReadOpsPending)) {
409 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
416 psWalkerObj = psCommand->psSrcSync;
417 psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
418 while (psWalkerObj < psEndObj) {
419 struct PVRSRV_SYNC_DATA *psSyncData =
420 psWalkerObj->psKernelSyncInfoKM->psSyncData;
422 ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
423 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
425 if ((ui32WriteOpsComplete !=
426 psWalkerObj->ui32WriteOpsPending) ||
427 (ui32ReadOpsComplete !=
428 psWalkerObj->ui32ReadOpsPending)) {
430 SYNCOPS_STALE(ui32WriteOpsComplete,
431 psWalkerObj->ui32WriteOpsPending) &&
432 SYNCOPS_STALE(ui32ReadOpsComplete,
433 psWalkerObj->ui32ReadOpsPending)) {
434 PVR_DPF(PVR_DBG_WARNING,
435 "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x "
436 "ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
437 psSyncData, ui32WriteOpsComplete,
438 psWalkerObj->ui32WriteOpsPending);
442 !SYNCOPS_STALE(ui32WriteOpsComplete,
443 psWalkerObj->ui32WriteOpsPending) ||
444 !SYNCOPS_STALE(ui32ReadOpsComplete,
445 psWalkerObj->ui32ReadOpsPending)) {
446 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
452 if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT) {
453 PVR_DPF(PVR_DBG_ERROR,
454 "PVRSRVProcessCommand: invalid DeviceType 0x%x",
455 psCommand->ui32DevIndex);
456 return PVRSRV_ERROR_INVALID_PARAMS;
460 psSysData->ppsCmdCompleteData[psCommand->ui32DevIndex][psCommand->
462 if (psCmdCompleteData->bInUse)
464 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
466 psCmdCompleteData->bInUse = IMG_TRUE;
468 psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
469 for (i = 0; i < psCommand->ui32DstSyncCount; i++)
470 psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
472 psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
473 for (i = 0; i < psCommand->ui32SrcSyncCount; i++)
474 psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
476 if (psSysData->ppfnCmdProcList[psCommand->ui32DevIndex]
477 [psCommand->CommandType]((void *)
479 psCommand->ui32DataSize,
480 psCommand->pvData) == IMG_FALSE) {
481 psCmdCompleteData->bInUse = IMG_FALSE;
482 eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
488 enum PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush)
490 struct PVRSRV_QUEUE_INFO *psQueue;
491 struct SYS_DATA *psSysData;
492 struct PVRSRV_COMMAND *psCommand;
493 struct PVRSRV_DEVICE_NODE *psDeviceNode;
494 enum PVRSRV_ERROR eError;
496 eError = SysAcquireData(&psSysData);
497 if (eError != PVRSRV_OK)
500 psQueue = psSysData->psQueueList;
503 PVR_DPF(PVR_DBG_MESSAGE,
504 "No Queues installed - cannot process commands");
508 PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
511 while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset) {
512 psCommand = (struct PVRSRV_COMMAND *)((u32) psQueue->
513 pvLinQueueKM + psQueue->ui32ReadOffset);
515 if (PVRSRVProcessCommand(psSysData, psCommand, bFlush)
517 UPDATE_QUEUE_ROFF(psQueue,
518 psCommand->ui32CmdSize)
524 psQueue = psQueue->psNextKM;
528 PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
530 psDeviceNode = psSysData->psDeviceNodeList;
531 while (psDeviceNode != NULL) {
532 if (psDeviceNode->bReProcessDeviceCommandComplete &&
533 psDeviceNode->pfnDeviceCommandComplete != NULL) {
535 pfnDeviceCommandComplete) (psDeviceNode);
537 psDeviceNode = psDeviceNode->psNext;
543 void PVRSRVCommandCompleteKM(void *hCmdCookie, IMG_BOOL bScheduleMISR)
546 struct COMMAND_COMPLETE_DATA *psCmdCompleteData =
547 (struct COMMAND_COMPLETE_DATA *)hCmdCookie;
548 struct SYS_DATA *psSysData;
550 if (SysAcquireData(&psSysData) != PVRSRV_OK)
553 for (i = 0; i < psCmdCompleteData->ui32DstSyncCount; i++) {
554 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->
555 ui32WriteOpsComplete++;
558 for (i = 0; i < psCmdCompleteData->ui32SrcSyncCount; i++) {
559 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->
560 ui32ReadOpsComplete++;
563 psCmdCompleteData->bInUse = IMG_FALSE;
565 PVRSRVCommandCompleteCallbacks();
568 OSScheduleMISR(psSysData);
571 void PVRSRVCommandCompleteCallbacks(void)
573 struct SYS_DATA *psSysData;
574 struct PVRSRV_DEVICE_NODE *psDeviceNode;
576 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
577 PVR_DPF(PVR_DBG_ERROR, "PVRSRVCommandCompleteCallbacks: "
578 "SysAcquireData failed");
582 psDeviceNode = psSysData->psDeviceNodeList;
583 while (psDeviceNode != NULL) {
584 if (psDeviceNode->pfnDeviceCommandComplete != NULL)
585 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
586 psDeviceNode = psDeviceNode->psNext;
590 enum PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(u32 ui32DevIndex,
591 IMG_BOOL (**ppfnCmdProcList)(void *, u32, void *),
592 u32 ui32MaxSyncsPerCmd[][2], u32 ui32CmdCount)
594 struct SYS_DATA *psSysData;
595 enum PVRSRV_ERROR eError;
598 IMG_BOOL (**ppfnCmdProc)(void *, u32, void *);
599 struct COMMAND_COMPLETE_DATA *psCmdCompleteData;
601 if (ui32DevIndex >= SYS_DEVICE_COUNT) {
602 PVR_DPF(PVR_DBG_ERROR,
603 "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
605 return PVRSRV_ERROR_INVALID_PARAMS;
608 eError = SysAcquireData(&psSysData);
609 if (eError != PVRSRV_OK) {
610 PVR_DPF(PVR_DBG_ERROR,
611 "PVRSRVRegisterCmdProcListKM: SysAcquireData failed");
615 eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32CmdCount *
616 sizeof(IMG_BOOL (*)(void *, u32, void *)),
617 (void **)&psSysData->ppfnCmdProcList[ui32DevIndex],
619 if (eError != PVRSRV_OK) {
620 PVR_DPF(PVR_DBG_ERROR,
621 "PVRSRVRegisterCmdProcListKM: Failed to alloc queue");
625 ppfnCmdProc = psSysData->ppfnCmdProcList[ui32DevIndex];
627 for (i = 0; i < ui32CmdCount; i++)
628 ppfnCmdProc[i] = ppfnCmdProcList[i];
630 ui32AllocSize = ui32CmdCount * sizeof(struct COMMAND_COMPLETE_DATA *);
631 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
633 (void **) &psSysData->
634 ppsCmdCompleteData[ui32DevIndex], NULL);
635 if (eError != PVRSRV_OK) {
636 PVR_DPF(PVR_DBG_ERROR,
637 "PVRSRVRegisterCmdProcListKM: Failed to alloc CC data");
641 /* clear the list to ensure that we don't try to access uninitialised
642 * pointer in the 'error' execution path */
643 OSMemSet(psSysData->ppsCmdCompleteData[ui32DevIndex], 0x00,
646 for (i = 0; i < ui32CmdCount; i++) {
647 ui32AllocSize = sizeof(struct COMMAND_COMPLETE_DATA)
648 + ((ui32MaxSyncsPerCmd[i][0] + ui32MaxSyncsPerCmd[i][1])
649 * sizeof(struct PVRSRV_SYNC_OBJECT));
651 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
653 (void **)&psSysData->
654 ppsCmdCompleteData[ui32DevIndex][i],
656 if (eError != PVRSRV_OK) {
657 PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterCmdProcListKM: "
658 "Failed to alloc cmd %d",
663 OSMemSet(psSysData->ppsCmdCompleteData[ui32DevIndex][i], 0x00,
667 psSysData->ppsCmdCompleteData[ui32DevIndex][i];
669 psCmdCompleteData->psDstSync = (struct PVRSRV_SYNC_OBJECT *)
670 (((u32) psCmdCompleteData) +
671 sizeof(struct COMMAND_COMPLETE_DATA));
672 psCmdCompleteData->psSrcSync = (struct PVRSRV_SYNC_OBJECT *)
673 (((u32) psCmdCompleteData->psDstSync) +
674 (sizeof(struct PVRSRV_SYNC_OBJECT) *
675 ui32MaxSyncsPerCmd[i][0]));
676 psCmdCompleteData->ui32AllocSize = ui32AllocSize;
683 if (psSysData->ppsCmdCompleteData[ui32DevIndex] != NULL) {
684 for (i = 0; i < ui32CmdCount; i++) {
685 if (psSysData->ppsCmdCompleteData[ui32DevIndex][i] !=
689 ppsCmdCompleteData[ui32DevIndex][i];
690 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
691 psCmdCompleteData->ui32AllocSize,
692 psCmdCompleteData, NULL);
696 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
697 ui32CmdCount * sizeof(struct COMMAND_COMPLETE_DATA *),
698 psSysData->ppsCmdCompleteData[ui32DevIndex],
702 if (psSysData->ppfnCmdProcList[ui32DevIndex] != NULL) {
703 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0,
704 psSysData->ppfnCmdProcList[ui32DevIndex], NULL);
710 enum PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(u32 ui32DevIndex, u32 ui32CmdCount)
712 struct SYS_DATA *psSysData;
713 enum PVRSRV_ERROR eError;
716 if (ui32DevIndex >= SYS_DEVICE_COUNT) {
717 PVR_DPF(PVR_DBG_ERROR,
718 "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
720 return PVRSRV_ERROR_INVALID_PARAMS;
723 eError = SysAcquireData(&psSysData);
724 if (eError != PVRSRV_OK) {
725 PVR_DPF(PVR_DBG_ERROR,
726 "PVRSRVRemoveCmdProcListKM: SysAcquireData failed");
730 if (psSysData->ppsCmdCompleteData[ui32DevIndex] == NULL) {
731 PVR_DPF(PVR_DBG_ERROR,
732 "PVRSRVRemoveCmdProcListKM: Invalid command array");
733 return PVRSRV_ERROR_INVALID_PARAMS;
735 for (i = 0; i < ui32CmdCount; i++) {
737 if (psSysData->ppsCmdCompleteData[ui32DevIndex][i] !=
739 struct COMMAND_COMPLETE_DATA *
740 psCmdCompleteData = psSysData->
741 ppsCmdCompleteData[ui32DevIndex][i];
742 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
743 psCmdCompleteData->ui32AllocSize,
744 psCmdCompleteData, NULL);
748 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
749 ui32CmdCount * sizeof(struct COMMAND_COMPLETE_DATA *),
750 psSysData->ppsCmdCompleteData[ui32DevIndex], NULL);
753 if (psSysData->ppfnCmdProcList[ui32DevIndex] != NULL) {
754 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
756 sizeof(IMG_BOOL (*)(void *, u32, void *)),
757 psSysData->ppfnCmdProcList[ui32DevIndex], NULL);