aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/pvrsrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/pvrsrv.c')
-rw-r--r--drivers/gpu/pvr/pvrsrv.c1253
1 files changed, 1253 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/pvrsrv.c b/drivers/gpu/pvr/pvrsrv.c
new file mode 100644
index 00000000000..98aeb23d745
--- /dev/null
+++ b/drivers/gpu/pvr/pvrsrv.c
@@ -0,0 +1,1253 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
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.
8 *
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.
13 *
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.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "buffer_manager.h"
29#include "pvr_bridge_km.h"
30#include "handle.h"
31#include "perproc.h"
32#include "pdump_km.h"
33#include "deviceid.h"
34#include "ra.h"
35
36#include "pvrversion.h"
37
38#include "lists.h"
39
40IMG_UINT32 g_ui32InitFlags;
41
42#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
43
44PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID)
45{
46 SYS_DEVICE_ID* psDeviceWalker;
47 SYS_DEVICE_ID* psDeviceEnd;
48
49 psDeviceWalker = &psSysData->sDeviceID[0];
50 psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
51
52
53 while (psDeviceWalker < psDeviceEnd)
54 {
55 if (!psDeviceWalker->bInUse)
56 {
57 psDeviceWalker->bInUse = IMG_TRUE;
58 *pui32DevID = psDeviceWalker->uiID;
59 return PVRSRV_OK;
60 }
61 psDeviceWalker++;
62 }
63
64 PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!"));
65
66
67 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
68
69 return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
70}
71
72
73PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID)
74{
75 SYS_DEVICE_ID* psDeviceWalker;
76 SYS_DEVICE_ID* psDeviceEnd;
77
78 psDeviceWalker = &psSysData->sDeviceID[0];
79 psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices;
80
81
82 while (psDeviceWalker < psDeviceEnd)
83 {
84
85 if (
86 (psDeviceWalker->uiID == ui32DevID) &&
87 (psDeviceWalker->bInUse)
88 )
89 {
90 psDeviceWalker->bInUse = IMG_FALSE;
91 return PVRSRV_OK;
92 }
93 psDeviceWalker++;
94 }
95
96 PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!"));
97
98
99 PVR_ASSERT(psDeviceWalker < psDeviceEnd);
100
101 return PVRSRV_ERROR_INVALID_DEVICEID;
102}
103
104
105#ifndef ReadHWReg
106IMG_EXPORT
107IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
108{
109 return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
110}
111#endif
112
113
114#ifndef WriteHWReg
115IMG_EXPORT
116IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
117{
118 PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",
119 (IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
120
121 *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
122}
123#endif
124
125
126#ifndef WriteHWRegs
127IMG_EXPORT
128IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
129{
130 while (ui32Count)
131 {
132 WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
133 psHWRegs++;
134 ui32Count--;
135 }
136}
137#endif
138
139static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
140{
141 IMG_UINT *pui32DevCount;
142 PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
143
144 pui32DevCount = va_arg(va, IMG_UINT*);
145 ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
146
147 if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
148 {
149 *(*ppsDevIdList) = psDeviceNode->sDevId;
150 (*ppsDevIdList)++;
151 (*pui32DevCount)++;
152 }
153}
154
155
156
157IMG_EXPORT
158PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
159 PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
160{
161 SYS_DATA *psSysData;
162 IMG_UINT32 i;
163
164 if (!pui32NumDevices || !psDevIdList)
165 {
166 PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params"));
167 return PVRSRV_ERROR_INVALID_PARAMS;
168 }
169
170 SysAcquireData(&psSysData);
171
172
173
174 for (i=0; i<PVRSRV_MAX_DEVICES; i++)
175 {
176 psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
177 }
178
179
180 *pui32NumDevices = 0;
181
182
183
184
185
186 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
187 &PVRSRVEnumerateDevicesKM_ForEachVaCb,
188 pui32NumDevices,
189 &psDevIdList);
190
191
192 return PVRSRV_OK;
193}
194
195
196PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
197{
198 PVRSRV_ERROR eError;
199
200
201 eError = ResManInit();
202 if (eError != PVRSRV_OK)
203 {
204 goto Error;
205 }
206
207 eError = PVRSRVPerProcessDataInit();
208 if(eError != PVRSRV_OK)
209 {
210 goto Error;
211 }
212
213
214 eError = PVRSRVHandleInit();
215 if(eError != PVRSRV_OK)
216 {
217 goto Error;
218 }
219
220
221 eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
222 if (eError != PVRSRV_OK)
223 {
224 goto Error;
225 }
226
227
228 psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
229 psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
230
231
232 if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
233 sizeof(PVRSRV_EVENTOBJECT) ,
234 (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
235 "Event Object") != PVRSRV_OK)
236 {
237
238 goto Error;
239 }
240
241 if(OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
242 {
243 goto Error;
244 }
245
246
247 PDUMPINIT();
248 g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
249
250 return eError;
251
252Error:
253 PVRSRVDeInit(psSysData);
254 return eError;
255}
256
257
258
259IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData)
260{
261 PVRSRV_ERROR eError;
262
263 PVR_UNREFERENCED_PARAMETER(psSysData);
264
265 if (psSysData == IMG_NULL)
266 {
267 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param"));
268 return;
269 }
270
271
272 if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
273 {
274 PDUMPDEINIT();
275 }
276
277
278 if(psSysData->psGlobalEventObject)
279 {
280 OSEventObjectDestroy(psSysData->psGlobalEventObject);
281 OSFreeMem( PVRSRV_PAGEABLE_SELECT,
282 sizeof(PVRSRV_EVENTOBJECT),
283 psSysData->psGlobalEventObject,
284 0);
285 psSysData->psGlobalEventObject = IMG_NULL;
286 }
287
288 eError = PVRSRVHandleDeInit();
289 if (eError != PVRSRV_OK)
290 {
291 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed"));
292 }
293
294 eError = PVRSRVPerProcessDataDeInit();
295 if (eError != PVRSRV_OK)
296 {
297 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed"));
298 }
299
300 ResManDeInit();
301}
302
303
304PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData,
305 PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*),
306 IMG_UINT32 ui32SOCInterruptBit,
307 IMG_UINT32 *pui32DeviceIndex)
308{
309 PVRSRV_ERROR eError;
310 PVRSRV_DEVICE_NODE *psDeviceNode;
311
312
313 if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
314 sizeof(PVRSRV_DEVICE_NODE),
315 (IMG_VOID **)&psDeviceNode, IMG_NULL,
316 "Device Node") != PVRSRV_OK)
317 {
318 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode"));
319 return (PVRSRV_ERROR_OUT_OF_MEMORY);
320 }
321 OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
322
323 eError = pfnRegisterDevice(psDeviceNode);
324 if (eError != PVRSRV_OK)
325 {
326 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
327 sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
328
329 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
330 return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
331 }
332
333
334
335
336
337
338 psDeviceNode->ui32RefCount = 1;
339 psDeviceNode->psSysData = psSysData;
340 psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
341
342
343 AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
344
345
346 List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
347
348
349 *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
350
351 return PVRSRV_OK;
352}
353
354
355PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
356{
357 PVRSRV_DEVICE_NODE *psDeviceNode;
358 SYS_DATA *psSysData;
359 PVRSRV_ERROR eError;
360
361 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
362
363 SysAcquireData(&psSysData);
364
365
366 psDeviceNode = (PVRSRV_DEVICE_NODE*)
367 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
368 &MatchDeviceKM_AnyVaCb,
369 ui32DevIndex,
370 IMG_TRUE);
371 if(!psDeviceNode)
372 {
373
374 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
375 return PVRSRV_ERROR_INIT_FAILURE;
376 }
377 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
378
379
380
381 eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
382 if (eError != PVRSRV_OK)
383 {
384 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
385 return eError;
386 }
387
388
389 if(psDeviceNode->pfnInitDevice != IMG_NULL)
390 {
391 eError = psDeviceNode->pfnInitDevice(psDeviceNode);
392 if (eError != PVRSRV_OK)
393 {
394 PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call"));
395 return eError;
396 }
397 }
398
399 return PVRSRV_OK;
400}
401
402
403static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
404{
405 PVRSRV_ERROR eError;
406 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
407 PVRSRV_DEV_POWER_STATE_DEFAULT,
408 KERNEL_ID, IMG_FALSE);
409 if (eError != PVRSRV_OK)
410 {
411 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
412 }
413 return eError;
414}
415
416static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
417{
418 PVRSRV_ERROR eError;
419 eError = PVRSRVDevInitCompatCheck(psDeviceNode);
420 if (eError != PVRSRV_OK)
421 {
422 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
423 }
424 return eError;
425}
426
427
428PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
429{
430 SYS_DATA *psSysData;
431 PVRSRV_ERROR eError;
432
433 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
434
435 SysAcquireData(&psSysData);
436
437 if (bInitSuccessful)
438 {
439 eError = SysFinalise();
440 if (eError != PVRSRV_OK)
441 {
442 PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
443 return eError;
444 }
445
446
447 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
448 &PVRSRVFinaliseSystem_SetPowerState_AnyCb);
449 if (eError != PVRSRV_OK)
450 {
451 return eError;
452 }
453
454
455 eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
456 &PVRSRVFinaliseSystem_CompatCheck_AnyCb);
457 if (eError != PVRSRV_OK)
458 {
459 return eError;
460 }
461 }
462
463
464
465
466
467 PDUMPENDINITPHASE();
468
469 return PVRSRV_OK;
470}
471
472
473PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
474{
475
476 if (psDeviceNode->pfnInitDeviceCompatCheck)
477 return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
478 else
479 return PVRSRV_OK;
480}
481
482static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
483{
484 PVRSRV_DEVICE_TYPE eDeviceType;
485 IMG_UINT32 ui32DevIndex;
486
487 eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
488 ui32DevIndex = va_arg(va, IMG_UINT32);
489
490 if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
491 psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
492 (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
493 psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
494 {
495 return psDeviceNode;
496 }
497 else
498 {
499 return IMG_NULL;
500 }
501}
502
503IMG_EXPORT
504PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
505 PVRSRV_DEVICE_TYPE eDeviceType,
506 IMG_HANDLE *phDevCookie)
507{
508 PVRSRV_DEVICE_NODE *psDeviceNode;
509 SYS_DATA *psSysData;
510
511 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
512
513 SysAcquireData(&psSysData);
514
515
516 psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
517 &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
518 eDeviceType,
519 ui32DevIndex);
520
521
522 if (!psDeviceNode)
523 {
524
525 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
526 return PVRSRV_ERROR_INIT_FAILURE;
527 }
528
529 PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
530
531
532 if (phDevCookie)
533 {
534 *phDevCookie = (IMG_HANDLE)psDeviceNode;
535 }
536
537 return PVRSRV_OK;
538}
539
540
541PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
542{
543 PVRSRV_DEVICE_NODE *psDeviceNode;
544 SYS_DATA *psSysData;
545 PVRSRV_ERROR eError;
546
547 SysAcquireData(&psSysData);
548
549 psDeviceNode = (PVRSRV_DEVICE_NODE*)
550 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
551 &MatchDeviceKM_AnyVaCb,
552 ui32DevIndex,
553 IMG_TRUE);
554
555 if (!psDeviceNode)
556 {
557 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
558 return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
559 }
560
561
562
563 eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
564 PVRSRV_DEV_POWER_STATE_OFF,
565 KERNEL_ID,
566 IMG_FALSE);
567 if (eError != PVRSRV_OK)
568 {
569 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
570 return eError;
571 }
572
573
574
575 eError = ResManFreeResByCriteria(psDeviceNode->hResManContext,
576 RESMAN_CRITERIA_RESTYPE,
577 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
578 IMG_NULL, 0);
579 if (eError != PVRSRV_OK)
580 {
581 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call"));
582 return eError;
583 }
584
585
586
587 if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
588 {
589 eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
590 if (eError != PVRSRV_OK)
591 {
592 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
593 return eError;
594 }
595 }
596
597
598
599 PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
600 psDeviceNode->hResManContext = IMG_NULL;
601
602
603 List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
604
605
606 (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
607 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
608 sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
609
610
611 return (PVRSRV_OK);
612}
613
614
615IMG_EXPORT
616PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
617 IMG_UINT32 ui32Value,
618 IMG_UINT32 ui32Mask,
619 IMG_UINT32 ui32Waitus,
620 IMG_UINT32 ui32Tries)
621{
622 {
623 IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU;
624 IMG_UINT32 uiMaxTime = ui32Tries * ui32Waitus;
625
626
627 LOOP_UNTIL_TIMEOUT(uiMaxTime)
628 {
629 ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
630 if(ui32ActualValue == ui32Value)
631 {
632 return PVRSRV_OK;
633 }
634 OSWaitus(ui32Waitus);
635 } END_LOOP_UNTIL_TIMEOUT();
636
637 PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
638 ui32Value, ui32ActualValue, ui32Mask));
639 }
640
641
642 return PVRSRV_ERROR_TIMEOUT;
643}
644
645
646static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
647{
648 IMG_CHAR **ppszStr;
649 IMG_UINT32 *pui32StrLen;
650 IMG_UINT32 ui32Mode;
651 PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
652
653 ppszStr = va_arg(va, IMG_CHAR**);
654 pui32StrLen = va_arg(va, IMG_UINT32*);
655 ui32Mode = va_arg(va, IMG_UINT32);
656
657
658 switch(ui32Mode)
659 {
660 case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
661 pfnGetStats = &RA_GetStats;
662 break;
663 case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
664 pfnGetStats = &RA_GetStatsFreeMem;
665 break;
666 default:
667 return;
668 }
669
670 if(psBMHeap->pImportArena)
671 {
672 pfnGetStats(psBMHeap->pImportArena,
673 ppszStr,
674 pui32StrLen);
675 }
676
677 if(psBMHeap->pVMArena)
678 {
679 pfnGetStats(psBMHeap->pVMArena,
680 ppszStr,
681 pui32StrLen);
682 }
683}
684
685static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
686{
687
688 IMG_UINT32 *pui32StrLen;
689 IMG_INT32 *pi32Count;
690 IMG_CHAR **ppszStr;
691 IMG_UINT32 ui32Mode;
692
693 pui32StrLen = va_arg(va, IMG_UINT32*);
694 pi32Count = va_arg(va, IMG_INT32*);
695 ppszStr = va_arg(va, IMG_CHAR**);
696 ui32Mode = va_arg(va, IMG_UINT32);
697
698 CHECK_SPACE(*pui32StrLen);
699 *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
700 (IMG_HANDLE)psBMContext);
701 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
702
703 List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
704 &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
705 ppszStr,
706 pui32StrLen,
707 ui32Mode);
708 return PVRSRV_OK;
709}
710
711
712static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
713{
714 IMG_UINT32 *pui32StrLen;
715 IMG_INT32 *pi32Count;
716 IMG_CHAR **ppszStr;
717 IMG_UINT32 ui32Mode;
718
719 pui32StrLen = va_arg(va, IMG_UINT32*);
720 pi32Count = va_arg(va, IMG_INT32*);
721 ppszStr = va_arg(va, IMG_CHAR**);
722 ui32Mode = va_arg(va, IMG_UINT32);
723
724 CHECK_SPACE(*pui32StrLen);
725 *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
726 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
727
728
729 if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
730 {
731 CHECK_SPACE(*pui32StrLen);
732 *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
733 UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
734
735 List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
736 &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
737 ppszStr,
738 pui32StrLen,
739 ui32Mode);
740 }
741
742
743 return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
744 &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
745 pui32StrLen,
746 pi32Count,
747 ppszStr,
748 ui32Mode);
749}
750
751
752IMG_EXPORT
753PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
754{
755 SYS_DATA *psSysData;
756
757 if(!psMiscInfo)
758 {
759 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
760 return PVRSRV_ERROR_INVALID_PARAMS;
761 }
762
763 psMiscInfo->ui32StatePresent = 0;
764
765
766 if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT
767 |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT
768 |PVRSRV_MISC_INFO_MEMSTATS_PRESENT
769 |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT
770 |PVRSRV_MISC_INFO_DDKVERSION_PRESENT
771 |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
772 |PVRSRV_MISC_INFO_RESET_PRESENT
773 |PVRSRV_MISC_INFO_FREEMEM_PRESENT))
774 {
775 PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
776 return PVRSRV_ERROR_INVALID_PARAMS;
777 }
778
779 SysAcquireData(&psSysData);
780
781
782 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) &&
783 (psSysData->pvSOCTimerRegisterKM != IMG_NULL))
784 {
785 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT;
786 psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM;
787 psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle;
788 }
789 else
790 {
791 psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL;
792 psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL;
793 }
794
795
796 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) &&
797 (psSysData->pvSOCClockGateRegsBase != IMG_NULL))
798 {
799 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT;
800 psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase;
801 psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize;
802 }
803
804
805 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) &&
806 (psMiscInfo->pszMemoryStr != IMG_NULL))
807 {
808 RA_ARENA **ppArena;
809 IMG_CHAR *pszStr;
810 IMG_UINT32 ui32StrLen;
811 IMG_INT32 i32Count;
812
813 pszStr = psMiscInfo->pszMemoryStr;
814 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
815
816 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT;
817
818
819 ppArena = &psSysData->apsLocalDevMemArena[0];
820 while(*ppArena)
821 {
822 CHECK_SPACE(ui32StrLen);
823 i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n");
824 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
825
826 RA_GetStats(*ppArena,
827 &pszStr,
828 &ui32StrLen);
829
830 ppArena++;
831 }
832
833
834
835 List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
836 &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
837 &ui32StrLen,
838 &i32Count,
839 &pszStr,
840 PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
841
842
843 i32Count = OSSNPrintf(pszStr, 100, "\n");
844 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
845 }
846
847
848 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT)
849 && psMiscInfo->pszMemoryStr)
850 {
851 IMG_CHAR *pszStr;
852 IMG_UINT32 ui32StrLen;
853 IMG_INT32 i32Count;
854
855 pszStr = psMiscInfo->pszMemoryStr;
856 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
857
858 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
859
860
861 List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
862 &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
863 &ui32StrLen,
864 &i32Count,
865 &pszStr,
866 PVRSRV_MISC_INFO_FREEMEM_PRESENT);
867
868 i32Count = OSSNPrintf(pszStr, 100, "\n");
869 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
870 }
871
872 if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) &&
873 (psSysData->psGlobalEventObject != IMG_NULL))
874 {
875 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT;
876 psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject;
877 }
878
879
880
881 if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL)
882 && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL)
883 && (psMiscInfo->pszMemoryStr != IMG_NULL))
884 {
885 IMG_CHAR *pszStr;
886 IMG_UINT32 ui32StrLen;
887 IMG_UINT32 ui32LenStrPerNum = 12;
888 IMG_INT32 i32Count;
889 IMG_INT i;
890 psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
891
892
893 psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
894 psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
895 psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH;
896 psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD;
897
898 pszStr = psMiscInfo->pszMemoryStr;
899 ui32StrLen = psMiscInfo->ui32MemoryStrLen;
900
901 for (i=0; i<4; i++)
902 {
903 if (ui32StrLen < ui32LenStrPerNum)
904 {
905 return PVRSRV_ERROR_INVALID_PARAMS;
906 }
907
908 i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
909 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
910 if (i != 3)
911 {
912 i32Count = OSSNPrintf(pszStr, 2, ".");
913 UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
914 }
915 }
916 }
917
918 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
919 {
920 if(psMiscInfo->sCacheOpCtl.bDeferOp)
921 {
922
923 psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
924 }
925 else
926 {
927 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
928 PVRSRV_PER_PROCESS_DATA *psPerProc;
929
930 if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
931 {
932 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
933 "Ignoring non-deferred cache op with no meminfo"));
934 return PVRSRV_ERROR_INVALID_PARAMS;
935 }
936
937 if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
938 {
939 PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
940 "Deferred cache op is pending. It is unlikely you want "
941 "to combine deferred cache ops with immediate ones"));
942 }
943
944
945 psPerProc = PVRSRVFindPerProcessData();
946
947 if(PVRSRVLookupHandle(psPerProc->psHandleBase,
948 (IMG_PVOID *)&psKernelMemInfo,
949 psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
950 PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
951 {
952 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
953 "Can't find kernel meminfo"));
954 return PVRSRV_ERROR_INVALID_PARAMS;
955 }
956
957 if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
958 {
959 if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
960 psMiscInfo->sCacheOpCtl.pvBaseVAddr,
961 psMiscInfo->sCacheOpCtl.ui32Length))
962 {
963 return PVRSRV_ERROR_CACHEOP_FAILED;
964 }
965 }
966 else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
967 {
968 if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
969 psMiscInfo->sCacheOpCtl.pvBaseVAddr,
970 psMiscInfo->sCacheOpCtl.ui32Length))
971 {
972 return PVRSRV_ERROR_CACHEOP_FAILED;
973 }
974 }
975 }
976 }
977
978#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
979 if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
980 {
981 PVR_LOG(("User requested OS reset"));
982 OSPanic();
983 }
984#endif
985
986 return PVRSRV_OK;
987}
988
989
990IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode)
991{
992 SYS_DATA *psSysData;
993 IMG_BOOL bStatus = IMG_FALSE;
994 IMG_UINT32 ui32InterruptSource;
995
996 if(!psDeviceNode)
997 {
998 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n"));
999 goto out;
1000 }
1001 psSysData = psDeviceNode->psSysData;
1002
1003
1004 ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
1005 if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1006 {
1007 if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1008 {
1009 bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
1010 }
1011
1012 SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
1013 }
1014
1015out:
1016 return bStatus;
1017}
1018
1019static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1020{
1021
1022 IMG_BOOL *pbStatus;
1023 IMG_UINT32 *pui32InterruptSource;
1024 IMG_UINT32 *pui32ClearInterrupts;
1025
1026 pbStatus = va_arg(va, IMG_BOOL*);
1027 pui32InterruptSource = va_arg(va, IMG_UINT32*);
1028 pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
1029
1030
1031 if(psDeviceNode->pfnDeviceISR != IMG_NULL)
1032 {
1033 if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
1034 {
1035 if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
1036 {
1037
1038 *pbStatus = IMG_TRUE;
1039 }
1040
1041 *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
1042 }
1043 }
1044}
1045
1046IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData)
1047{
1048 SYS_DATA *psSysData = pvSysData;
1049 IMG_BOOL bStatus = IMG_FALSE;
1050 IMG_UINT32 ui32InterruptSource;
1051 IMG_UINT32 ui32ClearInterrupts = 0;
1052 if(!psSysData)
1053 {
1054 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n"));
1055 }
1056 else
1057 {
1058
1059 ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
1060
1061
1062 if(ui32InterruptSource)
1063 {
1064
1065 List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
1066 &PVRSRVSystemLISR_ForEachVaCb,
1067 &bStatus,
1068 &ui32InterruptSource,
1069 &ui32ClearInterrupts);
1070
1071 SysClearInterrupts(psSysData, ui32ClearInterrupts);
1072 }
1073 }
1074 return bStatus;
1075}
1076
1077
1078static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1079{
1080 if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
1081 {
1082 (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
1083 }
1084}
1085
1086IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData)
1087{
1088 SYS_DATA *psSysData = pvSysData;
1089 if(!psSysData)
1090 {
1091 PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n"));
1092 return;
1093 }
1094
1095
1096 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1097 &PVRSRVMISR_ForEachCb);
1098
1099
1100 if (PVRSRVProcessQueues(ISR_ID, IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
1101 {
1102 PVRSRVProcessQueues(ISR_ID, IMG_FALSE);
1103 }
1104
1105
1106 if (psSysData->psGlobalEventObject)
1107 {
1108 IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
1109 if(hOSEventKM)
1110 {
1111 OSEventObjectSignal(hOSEventKM);
1112 }
1113 }
1114}
1115
1116
1117IMG_EXPORT
1118PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID)
1119{
1120 return PVRSRVPerProcessDataConnect(ui32PID);
1121}
1122
1123
1124IMG_EXPORT
1125IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID)
1126{
1127 PVRSRVPerProcessDataDisconnect(ui32PID);
1128}
1129
1130
1131PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
1132 IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
1133{
1134 IMG_SIZE_T uiBytesSaved = 0;
1135 IMG_PVOID pvLocalMemCPUVAddr;
1136 RA_SEGMENT_DETAILS sSegDetails;
1137
1138 if (hArena == IMG_NULL)
1139 {
1140 return (PVRSRV_ERROR_INVALID_PARAMS);
1141 }
1142
1143 sSegDetails.uiSize = 0;
1144 sSegDetails.sCpuPhyAddr.uiAddr = 0;
1145 sSegDetails.hSegment = 0;
1146
1147
1148 while (RA_GetNextLiveSegment(hArena, &sSegDetails))
1149 {
1150 if (pbyBuffer == IMG_NULL)
1151 {
1152
1153 uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1154 }
1155 else
1156 {
1157 if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize)
1158 {
1159 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1160 }
1161
1162 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize));
1163
1164
1165 pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr,
1166 sSegDetails.uiSize,
1167 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1168 IMG_NULL);
1169 if (pvLocalMemCPUVAddr == IMG_NULL)
1170 {
1171 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host"));
1172 return (PVRSRV_ERROR_OUT_OF_MEMORY);
1173 }
1174
1175 if (bSave)
1176 {
1177
1178 OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
1179 pbyBuffer += sizeof(sSegDetails.uiSize);
1180
1181 OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
1182 pbyBuffer += sSegDetails.uiSize;
1183 }
1184 else
1185 {
1186 IMG_UINT32 uiSize;
1187
1188 OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize));
1189
1190 if (uiSize != sSegDetails.uiSize)
1191 {
1192 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error"));
1193 }
1194 else
1195 {
1196 pbyBuffer += sizeof(sSegDetails.uiSize);
1197
1198 OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize);
1199 pbyBuffer += sSegDetails.uiSize;
1200 }
1201 }
1202
1203
1204 uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize;
1205
1206 OSUnMapPhysToLin(pvLocalMemCPUVAddr,
1207 sSegDetails.uiSize,
1208 PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
1209 IMG_NULL);
1210 }
1211 }
1212
1213 if (pbyBuffer == IMG_NULL)
1214 {
1215 *puiBufSize = uiBytesSaved;
1216 }
1217
1218 return (PVRSRV_OK);
1219}
1220
1221
1222IMG_EXPORT
1223const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
1224{
1225
1226#include "pvrsrv_errors.h"
1227}
1228
1229static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
1230{
1231 if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
1232 {
1233
1234 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
1235 }
1236}
1237
1238IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
1239{
1240 SYS_DATA *psSysData;
1241 SysAcquireData(&psSysData);
1242
1243
1244 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
1245 &PVRSRVCommandCompleteCallbacks_ForEachCb);
1246}
1247
1248IMG_EXPORT
1249IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
1250{
1251 PVRSRVScheduleDeviceCallbacks();
1252}
1253