~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/gpu/pvr/pvrsrv.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

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