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

« back to all changes in this revision

Viewing changes to drivers/gpu/pvr/deviceclass.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 "services_headers.h"
28
 
#include "buffer_manager.h"
29
 
#include "kernelbuffer.h"
30
 
#include "kerneldisplay.h"
31
 
#include "pvr_bridge_km.h"
32
 
#include "pdump_km.h"
33
 
#include "deviceid.h"
34
 
 
35
 
#include "lists.h"
36
 
 
37
 
PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
38
 
PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
39
 
 
40
 
#if defined(SUPPORT_MISR_IN_THREAD)
41
 
void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
42
 
#endif
43
 
 
44
 
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
45
 
IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE   hCmdCookie,
46
 
                                                                                   IMG_BOOL             bScheduleMISR);
47
 
#endif
48
 
typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
49
 
 
50
 
typedef struct PVRSRV_DC_BUFFER_TAG
51
 
{
52
 
        
53
 
        PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
54
 
 
55
 
        struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
56
 
        struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
57
 
} PVRSRV_DC_BUFFER;
58
 
 
59
 
typedef struct PVRSRV_DC_SWAPCHAIN_TAG
60
 
{
61
 
        IMG_HANDLE                                                      hExtSwapChain;
62
 
        IMG_UINT32                                                      ui32SwapChainID;
63
 
        IMG_UINT32                                                      ui32RefCount;
64
 
        IMG_UINT32                                                      ui32Flags;
65
 
        PVRSRV_QUEUE_INFO                                       *psQueue;
66
 
        PVRSRV_DC_BUFFER                                        asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
67
 
        IMG_UINT32                                                      ui32BufferCount;
68
 
        PVRSRV_DC_BUFFER                                        *psLastFlipBuffer;
69
 
        IMG_UINT32                                                      ui32MinSwapInterval;
70
 
        IMG_UINT32                                                      ui32MaxSwapInterval;
71
 
        struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
72
 
        struct PVRSRV_DC_SWAPCHAIN_TAG          *psNext;
73
 
} PVRSRV_DC_SWAPCHAIN;
74
 
 
75
 
 
76
 
typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG
77
 
{
78
 
        struct PVRSRV_DC_SWAPCHAIN_TAG          *psSwapChain;
79
 
        IMG_HANDLE                                                      hResItem;       
80
 
} PVRSRV_DC_SWAPCHAIN_REF;
81
 
 
82
 
 
83
 
typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG
84
 
{
85
 
        IMG_UINT32                                                      ui32RefCount;
86
 
        IMG_UINT32                                                      ui32DeviceID;
87
 
        IMG_HANDLE                                                      hExtDevice;
88
 
        PPVRSRV_DC_SRV2DISP_KMJTABLE            psFuncTable;
89
 
        IMG_HANDLE                                                      hDevMemContext;
90
 
        PVRSRV_DC_BUFFER                                        sSystemBuffer;
91
 
        struct PVRSRV_DC_SWAPCHAIN_TAG          *psDCSwapChainShared;
92
 
} PVRSRV_DISPLAYCLASS_INFO;
93
 
 
94
 
 
95
 
typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
96
 
{
97
 
        PVRSRV_DISPLAYCLASS_INFO                        *psDCInfo;
98
 
        PRESMAN_ITEM                                            hResItem;
99
 
} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
100
 
 
101
 
 
102
 
typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
103
 
 
104
 
typedef struct PVRSRV_BC_BUFFER_TAG
105
 
{
106
 
        
107
 
        PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
108
 
 
109
 
        struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
110
 
} PVRSRV_BC_BUFFER;
111
 
 
112
 
 
113
 
typedef struct PVRSRV_BUFFERCLASS_INFO_TAG
114
 
{
115
 
        IMG_UINT32                                                      ui32RefCount;
116
 
        IMG_UINT32                                                      ui32DeviceID;
117
 
        IMG_HANDLE                                                      hExtDevice;
118
 
        PPVRSRV_BC_SRV2BUFFER_KMJTABLE          psFuncTable;
119
 
        IMG_HANDLE                                                      hDevMemContext;
120
 
        
121
 
        IMG_UINT32                                                      ui32BufferCount;
122
 
        PVRSRV_BC_BUFFER                                        *psBuffer;
123
 
 
124
 
} PVRSRV_BUFFERCLASS_INFO;
125
 
 
126
 
 
127
 
typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
128
 
{
129
 
        PVRSRV_BUFFERCLASS_INFO                         *psBCInfo;
130
 
        IMG_HANDLE                                                      hResItem;
131
 
} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
132
 
 
133
 
 
134
 
static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM)
135
 
{
136
 
        PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
137
 
 
138
 
        psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
139
 
 
140
 
        return psDCPerContextInfo->psDCInfo;
141
 
}
142
 
 
143
 
 
144
 
static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM)
145
 
{
146
 
        PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
147
 
 
148
 
        psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
149
 
 
150
 
        return psBCPerContextInfo->psBCInfo;
151
 
}
152
 
 
153
 
static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
154
 
{
155
 
        IMG_UINT *pui32DevCount;
156
 
        IMG_UINT32 **ppui32DevID;
157
 
        PVRSRV_DEVICE_CLASS peDeviceClass;
158
 
 
159
 
        pui32DevCount = va_arg(va, IMG_UINT*);
160
 
        ppui32DevID = va_arg(va, IMG_UINT32**);
161
 
        peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS);
162
 
 
163
 
        if      ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass)
164
 
        &&      (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT))
165
 
        {
166
 
                (*pui32DevCount)++;
167
 
                if(*ppui32DevID)
168
 
                {
169
 
                        *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex;
170
 
                }
171
 
        }
172
 
}
173
 
 
174
 
 
175
 
IMG_EXPORT
176
 
PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass,
177
 
                                                                  IMG_UINT32 *pui32DevCount,
178
 
                                                                  IMG_UINT32 *pui32DevID )
179
 
{
180
 
        
181
 
        IMG_UINT                        ui32DevCount = 0;
182
 
        SYS_DATA                        *psSysData;
183
 
 
184
 
        SysAcquireData(&psSysData);
185
 
 
186
 
        
187
 
        List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
188
 
                                                                                &PVRSRVEnumerateDCKM_ForEachVaCb,
189
 
                                                                                &ui32DevCount,
190
 
                                                                                &pui32DevID,
191
 
                                                                                DeviceClass);
192
 
 
193
 
        if(pui32DevCount)
194
 
        {
195
 
                *pui32DevCount = ui32DevCount;
196
 
        }
197
 
        else if(pui32DevID == IMG_NULL)
198
 
        {
199
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters"));
200
 
                return (PVRSRV_ERROR_INVALID_PARAMS);
201
 
        }
202
 
 
203
 
        return PVRSRV_OK;
204
 
}
205
 
 
206
 
 
207
 
static
208
 
PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
209
 
                                                                           IMG_UINT32 *pui32DeviceID)
210
 
{
211
 
        PVRSRV_DISPLAYCLASS_INFO        *psDCInfo = IMG_NULL;
212
 
        PVRSRV_DEVICE_NODE                      *psDeviceNode;
213
 
        SYS_DATA                                        *psSysData;
214
 
 
215
 
        
216
 
 
217
 
 
218
 
 
219
 
 
220
 
 
221
 
 
222
 
 
223
 
 
224
 
 
225
 
 
226
 
 
227
 
 
228
 
 
229
 
 
230
 
        SysAcquireData(&psSysData);
231
 
 
232
 
        
233
 
 
234
 
 
235
 
        
236
 
        if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
237
 
                                         sizeof(*psDCInfo),
238
 
                                         (IMG_VOID **)&psDCInfo, IMG_NULL,
239
 
                                         "Display Class Info") != PVRSRV_OK)
240
 
        {
241
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
242
 
                return PVRSRV_ERROR_OUT_OF_MEMORY;
243
 
        }
244
 
        OSMemSet (psDCInfo, 0, sizeof(*psDCInfo));
245
 
 
246
 
        
247
 
        if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
248
 
                                         sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
249
 
                                         (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL,
250
 
                                         "Function table for SRVKM->DISPLAY") != PVRSRV_OK)
251
 
        {
252
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
253
 
                goto ErrorExit;
254
 
        }
255
 
        OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
256
 
 
257
 
        
258
 
        *psDCInfo->psFuncTable = *psFuncTable;
259
 
 
260
 
        
261
 
        if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
262
 
                                         sizeof(PVRSRV_DEVICE_NODE),
263
 
                                         (IMG_VOID **)&psDeviceNode, IMG_NULL,
264
 
                                         "Device Node") != PVRSRV_OK)
265
 
        {
266
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc"));
267
 
                goto ErrorExit;
268
 
        }
269
 
        OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
270
 
 
271
 
        psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo;
272
 
        psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo);
273
 
        psDeviceNode->ui32RefCount = 1;
274
 
        psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
275
 
        psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY;
276
 
        psDeviceNode->psSysData = psSysData;
277
 
 
278
 
        
279
 
        if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
280
 
        {
281
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
282
 
                goto ErrorExit;
283
 
        }
284
 
        psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
285
 
        if (pui32DeviceID)
286
 
        {
287
 
                *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
288
 
        }
289
 
 
290
 
        
291
 
        SysRegisterExternalDevice(psDeviceNode);
292
 
 
293
 
        
294
 
        List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
295
 
 
296
 
        return PVRSRV_OK;
297
 
 
298
 
ErrorExit:
299
 
 
300
 
        if(psDCInfo->psFuncTable)
301
 
        {
302
 
                OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
303
 
                psDCInfo->psFuncTable = IMG_NULL;
304
 
        }
305
 
 
306
 
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
307
 
        
308
 
 
309
 
        return PVRSRV_ERROR_OUT_OF_MEMORY;
310
 
}
311
 
 
312
 
static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
313
 
{
314
 
        SYS_DATA                                        *psSysData;
315
 
        PVRSRV_DEVICE_NODE                      *psDeviceNode;
316
 
        PVRSRV_DISPLAYCLASS_INFO        *psDCInfo;
317
 
 
318
 
        SysAcquireData(&psSysData);
319
 
 
320
 
        
321
 
        psDeviceNode = (PVRSRV_DEVICE_NODE*)
322
 
                List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
323
 
                                                                           &MatchDeviceKM_AnyVaCb,
324
 
                                                                           ui32DevIndex,
325
 
                                                                           IMG_FALSE,
326
 
                                                                           PVRSRV_DEVICE_CLASS_DISPLAY);
327
 
        if (!psDeviceNode)
328
 
        {
329
 
                
330
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex));
331
 
                return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
332
 
        }
333
 
 
334
 
        
335
 
        psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
336
 
 
337
 
        
338
 
 
339
 
 
340
 
        if(psDCInfo->ui32RefCount == 0)
341
 
        {
342
 
                
343
 
 
344
 
                List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
345
 
 
346
 
                
347
 
                SysRemoveExternalDevice(psDeviceNode);
348
 
 
349
 
                
350
 
 
351
 
 
352
 
                PVR_ASSERT(psDCInfo->ui32RefCount == 0);
353
 
                (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
354
 
                (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
355
 
                psDCInfo->psFuncTable = IMG_NULL;
356
 
                (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
357
 
                
358
 
                (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
359
 
                
360
 
        }
361
 
        else
362
 
        {
363
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount));
364
 
                return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
365
 
        }
366
 
 
367
 
        return PVRSRV_OK;
368
 
}
369
 
 
370
 
 
371
 
static
372
 
PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
373
 
                                                                           IMG_UINT32   *pui32DeviceID)
374
 
{
375
 
        PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL;
376
 
        PVRSRV_DEVICE_NODE              *psDeviceNode;
377
 
        SYS_DATA                                *psSysData;
378
 
        
379
 
 
380
 
 
381
 
 
382
 
 
383
 
 
384
 
 
385
 
 
386
 
 
387
 
 
388
 
 
389
 
 
390
 
 
391
 
 
392
 
        SysAcquireData(&psSysData);
393
 
 
394
 
        
395
 
 
396
 
 
397
 
        
398
 
        if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
399
 
                                         sizeof(*psBCInfo),
400
 
                                         (IMG_VOID **)&psBCInfo, IMG_NULL,
401
 
                                         "Buffer Class Info") != PVRSRV_OK)
402
 
        {
403
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
404
 
                return PVRSRV_ERROR_OUT_OF_MEMORY;
405
 
        }
406
 
        OSMemSet (psBCInfo, 0, sizeof(*psBCInfo));
407
 
 
408
 
        
409
 
        if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
410
 
                                         sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
411
 
                                         (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL,
412
 
                                         "Function table for SRVKM->BUFFER") != PVRSRV_OK)
413
 
        {
414
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
415
 
                goto ErrorExit;
416
 
        }
417
 
        OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
418
 
 
419
 
        
420
 
        *psBCInfo->psFuncTable = *psFuncTable;
421
 
 
422
 
        
423
 
        if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
424
 
                                         sizeof(PVRSRV_DEVICE_NODE),
425
 
                                         (IMG_VOID **)&psDeviceNode, IMG_NULL,
426
 
                                         "Device Node") != PVRSRV_OK)
427
 
        {
428
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc"));
429
 
                goto ErrorExit;
430
 
        }
431
 
        OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE));
432
 
 
433
 
        psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo;
434
 
        psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo);
435
 
        psDeviceNode->ui32RefCount = 1;
436
 
        psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT;
437
 
        psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER;
438
 
        psDeviceNode->psSysData = psSysData;
439
 
 
440
 
        
441
 
        if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
442
 
        {
443
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
444
 
                goto ErrorExit;
445
 
        }
446
 
        psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
447
 
        if (pui32DeviceID)
448
 
        {
449
 
                *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
450
 
        }
451
 
 
452
 
        
453
 
        List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
454
 
 
455
 
        return PVRSRV_OK;
456
 
 
457
 
ErrorExit:
458
 
 
459
 
        if(psBCInfo->psFuncTable)
460
 
        {
461
 
                OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
462
 
                psBCInfo->psFuncTable = IMG_NULL;
463
 
        }
464
 
 
465
 
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
466
 
        
467
 
 
468
 
        return PVRSRV_ERROR_OUT_OF_MEMORY;
469
 
}
470
 
 
471
 
 
472
 
static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
473
 
{
474
 
        SYS_DATA                                        *psSysData;
475
 
        PVRSRV_DEVICE_NODE                      *psDevNode;
476
 
        PVRSRV_BUFFERCLASS_INFO         *psBCInfo;
477
 
 
478
 
        SysAcquireData(&psSysData);
479
 
 
480
 
        
481
 
        psDevNode = (PVRSRV_DEVICE_NODE*)
482
 
                List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
483
 
                                                                           &MatchDeviceKM_AnyVaCb,
484
 
                                                                           ui32DevIndex,
485
 
                                                                           IMG_FALSE,
486
 
                                                                           PVRSRV_DEVICE_CLASS_BUFFER);
487
 
 
488
 
        if (!psDevNode)
489
 
        {
490
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex));
491
 
                return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
492
 
        }
493
 
 
494
 
        
495
 
        
496
 
        psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice;
497
 
 
498
 
        
499
 
 
500
 
 
501
 
        if(psBCInfo->ui32RefCount == 0)
502
 
        {
503
 
                
504
 
 
505
 
                List_PVRSRV_DEVICE_NODE_Remove(psDevNode);
506
 
 
507
 
                
508
 
 
509
 
 
510
 
                (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
511
 
                
512
 
                
513
 
                (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
514
 
                psBCInfo->psFuncTable = IMG_NULL;
515
 
                (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
516
 
                
517
 
                (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL);
518
 
                
519
 
        }
520
 
        else
521
 
        {
522
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount));
523
 
                return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
524
 
        }
525
 
 
526
 
        return PVRSRV_OK;
527
 
}
528
 
 
529
 
 
530
 
 
531
 
IMG_EXPORT
532
 
PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE  hDeviceKM,
533
 
                                                                        IMG_BOOL        bResManCallback)
534
 
{
535
 
        PVRSRV_ERROR eError;
536
 
        PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
537
 
 
538
 
        PVR_UNREFERENCED_PARAMETER(bResManCallback);
539
 
 
540
 
        psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
541
 
 
542
 
        
543
 
        eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
544
 
 
545
 
        return eError;
546
 
}
547
 
 
548
 
 
549
 
static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID  pvParam,
550
 
                                                                                  IMG_UINT32 ui32Param,
551
 
                                                                                  IMG_BOOL   bDummy)
552
 
{
553
 
        PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
554
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
555
 
 
556
 
        PVR_UNREFERENCED_PARAMETER(ui32Param);
557
 
        PVR_UNREFERENCED_PARAMETER(bDummy);
558
 
 
559
 
        psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam;
560
 
        psDCInfo = psDCPerContextInfo->psDCInfo;
561
 
 
562
 
        if(psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount != 0)
563
 
        {
564
 
                PVR_DPF((PVR_DBG_ERROR,"CloseDCDeviceCallBack: system buffer (0x%p) still mapped (refcount = %d)",
565
 
                                &psDCInfo->sSystemBuffer.sDeviceClassBuffer,
566
 
                                psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount));
567
 
#if 0
568
 
                
569
 
                return PVRSRV_ERROR_STILL_MAPPED;
570
 
#endif
571
 
        }
572
 
 
573
 
        psDCInfo->ui32RefCount--;
574
 
        if(psDCInfo->ui32RefCount == 0)
575
 
        {
576
 
                
577
 
                psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
578
 
 
579
 
                if (--psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
580
 
                {
581
 
                        PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
582
 
                }
583
 
 
584
 
                psDCInfo->hDevMemContext = IMG_NULL;
585
 
                psDCInfo->hExtDevice = IMG_NULL;
586
 
        }
587
 
 
588
 
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL);
589
 
        
590
 
 
591
 
        return PVRSRV_OK;
592
 
}
593
 
 
594
 
 
595
 
IMG_EXPORT
596
 
PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA      *psPerProc,
597
 
                                                                   IMG_UINT32                           ui32DeviceID,
598
 
                                                                   IMG_HANDLE                           hDevCookie,
599
 
                                                                   IMG_HANDLE                           *phDeviceKM)
600
 
{
601
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
602
 
        PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
603
 
        PVRSRV_DEVICE_NODE      *psDeviceNode;
604
 
        SYS_DATA                        *psSysData;
605
 
        PVRSRV_ERROR eError;
606
 
 
607
 
        if(!phDeviceKM || !hDevCookie)
608
 
        {
609
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
610
 
                return PVRSRV_ERROR_INVALID_PARAMS;
611
 
        }
612
 
 
613
 
        SysAcquireData(&psSysData);
614
 
 
615
 
        
616
 
        psDeviceNode = (PVRSRV_DEVICE_NODE*)
617
 
                        List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
618
 
                                                                                   &MatchDeviceKM_AnyVaCb,
619
 
                                                                                   ui32DeviceID,
620
 
                                                                                   IMG_FALSE,
621
 
                                                                                   PVRSRV_DEVICE_CLASS_DISPLAY);
622
 
        if (!psDeviceNode)
623
 
        {
624
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
625
 
                return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
626
 
        }
627
 
        psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
628
 
 
629
 
        
630
 
 
631
 
 
632
 
        if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
633
 
                                  sizeof(*psDCPerContextInfo),
634
 
                                  (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
635
 
                                  "Display Class per Context Info") != PVRSRV_OK)
636
 
        {
637
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
638
 
                return PVRSRV_ERROR_OUT_OF_MEMORY;
639
 
        }
640
 
        OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));
641
 
 
642
 
        if(psDCInfo->ui32RefCount++ == 0)
643
 
        {
644
 
 
645
 
                psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
646
 
 
647
 
                
648
 
                psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
649
 
 
650
 
                
651
 
                eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
652
 
                                                                        (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext,
653
 
                                                                        &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
654
 
                if(eError != PVRSRV_OK)
655
 
                {
656
 
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
657
 
                        psDCInfo->ui32RefCount--;
658
 
                        return eError;
659
 
                }
660
 
 
661
 
                
662
 
                eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
663
 
                                                                &psDCInfo->hExtDevice,
664
 
                                                                (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM);
665
 
                if(eError != PVRSRV_OK)
666
 
                {
667
 
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
668
 
                        psDCInfo->ui32RefCount--;
669
 
                        PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
670
 
                        return eError;
671
 
                }
672
 
 
673
 
                psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
674
 
                psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0;
675
 
        }
676
 
 
677
 
        psDCPerContextInfo->psDCInfo = psDCInfo;
678
 
        psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
679
 
                                                                                                         RESMAN_TYPE_DISPLAYCLASS_DEVICE,
680
 
                                                                                                         psDCPerContextInfo,
681
 
                                                                                                         0,
682
 
                                                                                                         &CloseDCDeviceCallBack);
683
 
 
684
 
        
685
 
        *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;
686
 
 
687
 
        return PVRSRV_OK;
688
 
}
689
 
 
690
 
 
691
 
IMG_EXPORT
692
 
PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM,
693
 
                                                                        IMG_UINT32 *pui32Count,
694
 
                                                                        DISPLAY_FORMAT *psFormat)
695
 
{
696
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
697
 
 
698
 
        if(!hDeviceKM || !pui32Count || !psFormat)
699
 
        {
700
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters"));
701
 
                return PVRSRV_ERROR_INVALID_PARAMS;
702
 
        }
703
 
 
704
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
705
 
 
706
 
        
707
 
        return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
708
 
}
709
 
 
710
 
 
711
 
 
712
 
IMG_EXPORT
713
 
PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM,
714
 
                                                                 DISPLAY_FORMAT *psFormat,
715
 
                                                                 IMG_UINT32 *pui32Count,
716
 
                                                                 DISPLAY_DIMS *psDim)
717
 
{
718
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
719
 
 
720
 
        if(!hDeviceKM || !pui32Count || !psFormat)      
721
 
        {
722
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters"));
723
 
                return PVRSRV_ERROR_INVALID_PARAMS;
724
 
        }
725
 
 
726
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
727
 
 
728
 
        
729
 
        return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim);
730
 
}
731
 
 
732
 
 
733
 
IMG_EXPORT
734
 
PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
735
 
                                                                                IMG_HANDLE *phBuffer)
736
 
{
737
 
        PVRSRV_ERROR eError;
738
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
739
 
        IMG_HANDLE hExtBuffer;
740
 
 
741
 
        if(!hDeviceKM || !phBuffer)
742
 
        {
743
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
744
 
                return PVRSRV_ERROR_INVALID_PARAMS;
745
 
        }
746
 
 
747
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
748
 
 
749
 
        
750
 
        eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer);
751
 
        if(eError != PVRSRV_OK)
752
 
        {
753
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver"));
754
 
                return eError;
755
 
        }
756
 
 
757
 
        
758
 
        psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
759
 
        psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
760
 
        psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
761
 
        psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer;
762
 
 
763
 
        psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
764
 
 
765
 
        
766
 
        *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
767
 
 
768
 
        return PVRSRV_OK;
769
 
}
770
 
 
771
 
 
772
 
IMG_EXPORT
773
 
PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM,
774
 
                                                                DISPLAY_INFO *psDisplayInfo)
775
 
{
776
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
777
 
        PVRSRV_ERROR eError;
778
 
 
779
 
        if(!hDeviceKM || !psDisplayInfo)
780
 
        {
781
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters"));
782
 
                return PVRSRV_ERROR_INVALID_PARAMS;
783
 
        }
784
 
 
785
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
786
 
 
787
 
        
788
 
        eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo);
789
 
        if (eError != PVRSRV_OK)
790
 
        {
791
 
                return eError;
792
 
        }
793
 
 
794
 
        if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
795
 
        {
796
 
                psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS;
797
 
        }
798
 
 
799
 
        return PVRSRV_OK;
800
 
}
801
 
 
802
 
 
803
 
IMG_EXPORT
804
 
PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef)
805
 
{
806
 
        PVRSRV_ERROR eError;
807
 
        PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
808
 
 
809
 
        if(!hSwapChainRef)
810
 
        {
811
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
812
 
                return PVRSRV_ERROR_INVALID_PARAMS;
813
 
        }
814
 
 
815
 
        psSwapChainRef = hSwapChainRef;
816
 
 
817
 
        eError = ResManFreeResByPtr(psSwapChainRef->hResItem, CLEANUP_WITH_POLL);
818
 
 
819
 
        return eError;
820
 
}
821
 
 
822
 
 
823
 
static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
824
 
{
825
 
        PVRSRV_ERROR                            eError;
826
 
        PVRSRV_DISPLAYCLASS_INFO        *psDCInfo = psSwapChain->psDCInfo;
827
 
        IMG_UINT32 i;
828
 
 
829
 
        
830
 
        if( psDCInfo->psDCSwapChainShared )
831
 
        {
832
 
                if( psDCInfo->psDCSwapChainShared == psSwapChain )
833
 
                {
834
 
                        psDCInfo->psDCSwapChainShared = psSwapChain->psNext;
835
 
                }
836
 
                else 
837
 
                {
838
 
                        PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
839
 
                        psCurrentSwapChain = psDCInfo->psDCSwapChainShared;             
840
 
                        while( psCurrentSwapChain->psNext )
841
 
                        {
842
 
                                if( psCurrentSwapChain->psNext != psSwapChain ) 
843
 
                                {
844
 
                                        psCurrentSwapChain = psCurrentSwapChain->psNext;
845
 
                                        continue;
846
 
                                }
847
 
                                psCurrentSwapChain->psNext = psSwapChain->psNext;
848
 
                                break;                          
849
 
                        }
850
 
                }
851
 
        }
852
 
 
853
 
        
854
 
        PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
855
 
 
856
 
        
857
 
        eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice,
858
 
                                                                                                                        psSwapChain->hExtSwapChain);
859
 
 
860
 
        if (eError != PVRSRV_OK)
861
 
        {
862
 
                PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain"));
863
 
                return eError;
864
 
        }
865
 
 
866
 
        
867
 
        for(i=0; i<psSwapChain->ui32BufferCount; i++)
868
 
        {
869
 
                if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
870
 
                {
871
 
                        if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
872
 
                        {
873
 
                                PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
874
 
                        }
875
 
                }
876
 
        }
877
 
 
878
 
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
879
 
        
880
 
 
881
 
        return eError;
882
 
}
883
 
 
884
 
 
885
 
static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam,
886
 
                                                                                                  IMG_UINT32 ui32Param,
887
 
                                                                                                  IMG_BOOL bDummy)
888
 
{
889
 
        PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam;
890
 
        PVRSRV_ERROR eError = PVRSRV_OK;
891
 
        IMG_UINT32 i;
892
 
 
893
 
        PVR_UNREFERENCED_PARAMETER(ui32Param);
894
 
        PVR_UNREFERENCED_PARAMETER(bDummy);
895
 
 
896
 
        for (i = 0; i < psSwapChainRef->psSwapChain->ui32BufferCount; i++)
897
 
        {
898
 
                if (psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
899
 
                {
900
 
                        PVR_DPF((PVR_DBG_ERROR, "DestroyDCSwapChainRefCallBack: swapchain (0x%p) still mapped (ui32MemMapRefCount = %d)",
901
 
                                        &psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer,
902
 
                                        psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
903
 
#if 0
904
 
                        
905
 
                        return PVRSRV_ERROR_STILL_MAPPED;
906
 
#endif
907
 
                }
908
 
        }
909
 
 
910
 
        if(--psSwapChainRef->psSwapChain->ui32RefCount == 0) 
911
 
        {
912
 
                eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain);
913
 
        }
914
 
 
915
 
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL);
916
 
        return eError;
917
 
}
918
 
 
919
 
static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo,
920
 
                                                                                                                 IMG_UINT32 ui32SwapChainID)
921
 
{
922
 
        PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
923
 
 
924
 
        for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared; 
925
 
                psCurrentSwapChain; 
926
 
                psCurrentSwapChain = psCurrentSwapChain->psNext) 
927
 
        {
928
 
                if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID)
929
 
                        return psCurrentSwapChain;
930
 
        }
931
 
        return IMG_NULL;
932
 
}
933
 
 
934
 
static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA        *psPerProc,
935
 
                                                                                                 PVRSRV_DC_SWAPCHAIN            *psSwapChain, 
936
 
                                                                                                 PVRSRV_DC_SWAPCHAIN_REF        **ppsSwapChainRef)
937
 
{
938
 
        PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
939
 
 
940
 
        
941
 
        if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
942
 
                                         sizeof(PVRSRV_DC_SWAPCHAIN_REF),
943
 
                                         (IMG_VOID **)&psSwapChainRef, IMG_NULL,
944
 
                                         "Display Class Swapchain Reference") != PVRSRV_OK)
945
 
        {
946
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc"));
947
 
                return  PVRSRV_ERROR_OUT_OF_MEMORY;
948
 
        }
949
 
        OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF));
950
 
 
951
 
        
952
 
        psSwapChain->ui32RefCount++;
953
 
 
954
 
        
955
 
        psSwapChainRef->psSwapChain = psSwapChain;
956
 
        psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext,
957
 
                                                                                                  RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
958
 
                                                                                                  psSwapChainRef,
959
 
                                                                                                  0,
960
 
                                                                                                  &DestroyDCSwapChainRefCallBack);
961
 
        *ppsSwapChainRef = psSwapChainRef;
962
 
 
963
 
        return PVRSRV_OK;
964
 
}
965
 
 
966
 
 
967
 
IMG_EXPORT
968
 
PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
969
 
                                                                                IMG_HANDLE                              hDeviceKM,
970
 
                                                                                IMG_UINT32                              ui32Flags,
971
 
                                                                                DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
972
 
                                                                                DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
973
 
                                                                                IMG_UINT32                              ui32BufferCount,
974
 
                                                                                IMG_UINT32                              ui32OEMFlags,
975
 
                                                                                IMG_HANDLE                              *phSwapChainRef,
976
 
                                                                                IMG_UINT32                              *pui32SwapChainID)
977
 
{
978
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
979
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
980
 
        PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
981
 
        PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
982
 
        PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
983
 
        PVRSRV_ERROR eError;
984
 
        IMG_UINT32 i;
985
 
        DISPLAY_INFO sDisplayInfo;
986
 
 
987
 
 
988
 
        if(!hDeviceKM
989
 
        || !psDstSurfAttrib
990
 
        || !psSrcSurfAttrib
991
 
        || !phSwapChainRef
992
 
        || !pui32SwapChainID)
993
 
        {
994
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters"));
995
 
                return PVRSRV_ERROR_INVALID_PARAMS;
996
 
        }
997
 
 
998
 
        if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
999
 
        {
1000
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers"));
1001
 
                return PVRSRV_ERROR_TOOMANYBUFFERS;
1002
 
        }
1003
 
 
1004
 
        if (ui32BufferCount < 2)
1005
 
        {
1006
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers"));
1007
 
                return PVRSRV_ERROR_TOO_FEW_BUFFERS;
1008
 
        }
1009
 
 
1010
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1011
 
 
1012
 
        if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY )
1013
 
        {
1014
 
                
1015
 
                psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID );
1016
 
                if( psSwapChain  ) 
1017
 
                {       
1018
 
                                           
1019
 
                        eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, 
1020
 
                                                                                                  psSwapChain, 
1021
 
                                                                                                  &psSwapChainRef);
1022
 
                        if( eError != PVRSRV_OK ) 
1023
 
                        {
1024
 
                                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
1025
 
                                return eError;
1026
 
                        }
1027
 
 
1028
 
                        *phSwapChainRef = (IMG_HANDLE)psSwapChainRef;
1029
 
                        return PVRSRV_OK;
1030
 
                }
1031
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query"));
1032
 
                return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;          
1033
 
        }
1034
 
 
1035
 
        
1036
 
        if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
1037
 
                                         sizeof(PVRSRV_DC_SWAPCHAIN),
1038
 
                                         (IMG_VOID **)&psSwapChain, IMG_NULL,
1039
 
                                         "Display Class Swapchain") != PVRSRV_OK)
1040
 
        {
1041
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"));
1042
 
                eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1043
 
                goto ErrorExit;
1044
 
        }
1045
 
        OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN));
1046
 
 
1047
 
        
1048
 
        eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
1049
 
        if(eError != PVRSRV_OK)
1050
 
        {
1051
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
1052
 
                goto ErrorExit;
1053
 
        }
1054
 
 
1055
 
        
1056
 
        psSwapChain->psQueue = psQueue;
1057
 
 
1058
 
        
1059
 
        for(i=0; i<ui32BufferCount; i++)
1060
 
        {
1061
 
                eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
1062
 
                                                                                psDCInfo->hDevMemContext,
1063
 
                                                                                &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1064
 
                if(eError != PVRSRV_OK)
1065
 
                {
1066
 
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain"));
1067
 
                        goto ErrorExit;
1068
 
                }
1069
 
 
1070
 
                psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
1071
 
 
1072
 
                
1073
 
                psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
1074
 
                psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
1075
 
                psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
1076
 
 
1077
 
                
1078
 
                psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
1079
 
                psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
1080
 
 
1081
 
                
1082
 
                apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
1083
 
        }
1084
 
 
1085
 
        psSwapChain->ui32BufferCount = ui32BufferCount;
1086
 
        psSwapChain->psDCInfo = psDCInfo;
1087
 
 
1088
 
#if defined(PDUMP)
1089
 
        PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)",
1090
 
                        *pui32SwapChainID,
1091
 
                        ui32BufferCount);
1092
 
        PDUMPCOMMENT("  Src surface dimensions == %u x %u",
1093
 
                        psSrcSurfAttrib->sDims.ui32Width,
1094
 
                        psSrcSurfAttrib->sDims.ui32Height);
1095
 
        PDUMPCOMMENT("  Dst surface dimensions == %u x %u",
1096
 
                        psDstSurfAttrib->sDims.ui32Width,
1097
 
                        psDstSurfAttrib->sDims.ui32Height);
1098
 
#endif
1099
 
 
1100
 
        eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo);
1101
 
        if (eError != PVRSRV_OK)
1102
 
        {
1103
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info"));
1104
 
                return eError;
1105
 
        }
1106
 
        
1107
 
        psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval;
1108
 
        psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval;
1109
 
 
1110
 
        
1111
 
        eError =  psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
1112
 
                                                                                                                ui32Flags,
1113
 
                                                                                                                psDstSurfAttrib,
1114
 
                                                                                                                psSrcSurfAttrib,
1115
 
                                                                                                                ui32BufferCount,
1116
 
                                                                                                                apsSyncData,
1117
 
                                                                                                                ui32OEMFlags,
1118
 
                                                                                                                &psSwapChain->hExtSwapChain,
1119
 
                                                                                                                &psSwapChain->ui32SwapChainID);
1120
 
        if(eError != PVRSRV_OK)
1121
 
        {
1122
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
1123
 
                PDUMPCOMMENT("Swapchain allocation failed.");
1124
 
                goto ErrorExit;
1125
 
        }
1126
 
 
1127
 
                           
1128
 
        eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, 
1129
 
                                                                                  psSwapChain, 
1130
 
                                                                                  &psSwapChainRef);
1131
 
        if( eError != PVRSRV_OK ) 
1132
 
        {
1133
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
1134
 
                PDUMPCOMMENT("Swapchain allocation failed.");
1135
 
                goto ErrorExit;
1136
 
        }
1137
 
 
1138
 
        psSwapChain->ui32RefCount = 1;
1139
 
        psSwapChain->ui32Flags = ui32Flags;
1140
 
 
1141
 
        
1142
 
        if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED )
1143
 
        {
1144
 
                if(! psDCInfo->psDCSwapChainShared ) 
1145
 
                {
1146
 
                        psDCInfo->psDCSwapChainShared = psSwapChain;
1147
 
                } 
1148
 
                else 
1149
 
                {       
1150
 
                        PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared;
1151
 
                        psDCInfo->psDCSwapChainShared = psSwapChain;
1152
 
                        psSwapChain->psNext = psOldHead;
1153
 
                }
1154
 
        }
1155
 
 
1156
 
        
1157
 
        *pui32SwapChainID = psSwapChain->ui32SwapChainID;
1158
 
 
1159
 
        
1160
 
        *phSwapChainRef= (IMG_HANDLE)psSwapChainRef;
1161
 
 
1162
 
        return eError;
1163
 
 
1164
 
ErrorExit:
1165
 
 
1166
 
        for(i=0; i<ui32BufferCount; i++)
1167
 
        {
1168
 
                if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
1169
 
                {
1170
 
                        if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
1171
 
                        {
1172
 
                                PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1173
 
                        }
1174
 
                }
1175
 
        }
1176
 
 
1177
 
        if(psQueue)
1178
 
        {
1179
 
                PVRSRVDestroyCommandQueueKM(psQueue);
1180
 
        }
1181
 
 
1182
 
        if(psSwapChain)
1183
 
        {
1184
 
                OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
1185
 
                
1186
 
        }
1187
 
 
1188
 
        return eError;
1189
 
}
1190
 
 
1191
 
 
1192
 
 
1193
 
 
1194
 
IMG_EXPORT
1195
 
PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE    hDeviceKM,
1196
 
                                                                  IMG_HANDLE    hSwapChainRef,
1197
 
                                                                  IMG_RECT              *psRect)
1198
 
{
1199
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1200
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain;
1201
 
 
1202
 
        if(!hDeviceKM || !hSwapChainRef)
1203
 
        {
1204
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
1205
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1206
 
        }
1207
 
 
1208
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1209
 
        psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1210
 
 
1211
 
        return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
1212
 
                                                                                                        psSwapChain->hExtSwapChain,
1213
 
                                                                                                        psRect);
1214
 
}
1215
 
 
1216
 
 
1217
 
IMG_EXPORT
1218
 
PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE    hDeviceKM,
1219
 
                                                                  IMG_HANDLE    hSwapChainRef,
1220
 
                                                                  IMG_RECT              *psRect)
1221
 
{
1222
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1223
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain;
1224
 
 
1225
 
        if(!hDeviceKM || !hSwapChainRef)
1226
 
        {
1227
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters"));
1228
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1229
 
        }
1230
 
 
1231
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1232
 
        psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1233
 
 
1234
 
        return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
1235
 
                                                                                                        psSwapChain->hExtSwapChain,
1236
 
                                                                                                        psRect);
1237
 
}
1238
 
 
1239
 
 
1240
 
IMG_EXPORT
1241
 
PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE       hDeviceKM,
1242
 
                                                                           IMG_HANDLE   hSwapChainRef,
1243
 
                                                                           IMG_UINT32   ui32CKColour)
1244
 
{
1245
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1246
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain;
1247
 
 
1248
 
        if(!hDeviceKM || !hSwapChainRef)
1249
 
        {
1250
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
1251
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1252
 
        }
1253
 
 
1254
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1255
 
        psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1256
 
 
1257
 
        return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
1258
 
                                                                                                                psSwapChain->hExtSwapChain,
1259
 
                                                                                                                ui32CKColour);
1260
 
}
1261
 
 
1262
 
 
1263
 
IMG_EXPORT
1264
 
PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE       hDeviceKM,
1265
 
                                                                           IMG_HANDLE   hSwapChainRef,
1266
 
                                                                           IMG_UINT32   ui32CKColour)
1267
 
{
1268
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1269
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain;
1270
 
 
1271
 
        if(!hDeviceKM || !hSwapChainRef)
1272
 
        {
1273
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
1274
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1275
 
        }
1276
 
 
1277
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1278
 
        psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1279
 
 
1280
 
        return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
1281
 
                                                                                                                psSwapChain->hExtSwapChain,
1282
 
                                                                                                                ui32CKColour);
1283
 
}
1284
 
 
1285
 
 
1286
 
IMG_EXPORT
1287
 
PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE    hDeviceKM,
1288
 
                                                                  IMG_HANDLE    hSwapChainRef,
1289
 
                                                                  IMG_UINT32    *pui32BufferCount,
1290
 
                                                                  IMG_HANDLE    *phBuffer)
1291
 
{
1292
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1293
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain;
1294
 
        IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
1295
 
        PVRSRV_ERROR eError;
1296
 
        IMG_UINT32 i;
1297
 
 
1298
 
        if(!hDeviceKM || !hSwapChainRef || !phBuffer)
1299
 
        {
1300
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));
1301
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1302
 
        }
1303
 
 
1304
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1305
 
        psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
1306
 
 
1307
 
        
1308
 
        eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
1309
 
                                                                                                        psSwapChain->hExtSwapChain,
1310
 
                                                                                                        pui32BufferCount,
1311
 
                                                                                                        ahExtBuffer);
1312
 
 
1313
 
        PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
1314
 
 
1315
 
        
1316
 
 
1317
 
 
1318
 
        for(i=0; i<*pui32BufferCount; i++)
1319
 
        {
1320
 
                psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
1321
 
                phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
1322
 
        }
1323
 
 
1324
 
        return eError;
1325
 
}
1326
 
 
1327
 
 
1328
 
IMG_EXPORT
1329
 
PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE  hDeviceKM,
1330
 
                                                                        IMG_HANDLE      hBuffer,
1331
 
                                                                        IMG_UINT32      ui32SwapInterval,
1332
 
                                                                        IMG_HANDLE      hPrivateTag,
1333
 
                                                                        IMG_UINT32      ui32ClipRectCount,
1334
 
                                                                        IMG_RECT        *psClipRect)
1335
 
{
1336
 
        PVRSRV_ERROR eError;
1337
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1338
 
        PVRSRV_DC_BUFFER *psBuffer;
1339
 
        PVRSRV_QUEUE_INFO *psQueue;
1340
 
        DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1341
 
        IMG_UINT32 i;
1342
 
        IMG_BOOL bAddReferenceToLast = IMG_TRUE;
1343
 
        IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
1344
 
        IMG_UINT32 ui32NumSrcSyncs = 1;
1345
 
        PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1346
 
        PVRSRV_COMMAND *psCommand;
1347
 
        SYS_DATA *psSysData;
1348
 
 
1349
 
        if(!hDeviceKM || !hBuffer || !psClipRect)
1350
 
        {
1351
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters"));
1352
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1353
 
        }
1354
 
 
1355
 
        psBuffer = (PVRSRV_DC_BUFFER*)hBuffer;
1356
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1357
 
 
1358
 
        
1359
 
        if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval ||
1360
 
                ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval)
1361
 
        {
1362
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u",
1363
 
                                 ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval));
1364
 
                return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
1365
 
        }
1366
 
 
1367
 
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
1368
 
 
1369
 
        if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
1370
 
        {
1371
 
                psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
1372
 
                                                                                                         psBuffer->psSwapChain->hExtSwapChain,
1373
 
                                                                                                         psBuffer->sDeviceClassBuffer.hExtBuffer, 
1374
 
                                                                                                         hPrivateTag, 
1375
 
                                                                                                         &ui16SwapCommandID,
1376
 
                                                                                                         &bAddReferenceToLast);
1377
 
                
1378
 
        }
1379
 
 
1380
 
#endif
1381
 
 
1382
 
        
1383
 
        psQueue = psBuffer->psSwapChain->psQueue;
1384
 
 
1385
 
        
1386
 
        apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1387
 
        
1388
 
 
1389
 
 
1390
 
        if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer &&
1391
 
                psBuffer != psBuffer->psSwapChain->psLastFlipBuffer)
1392
 
        {
1393
 
                apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1394
 
                
1395
 
 
1396
 
 
1397
 
                ui32NumSrcSyncs++;
1398
 
        }
1399
 
 
1400
 
        
1401
 
        eError = PVRSRVInsertCommandKM (psQueue,
1402
 
                                                                        &psCommand,
1403
 
                                                                        psDCInfo->ui32DeviceID,
1404
 
                                                                        ui16SwapCommandID,
1405
 
                                                                        0,
1406
 
                                                                        IMG_NULL,
1407
 
                                                                        ui32NumSrcSyncs,
1408
 
                                                                        apsSrcSync,
1409
 
                                                                        sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount));
1410
 
        if(eError != PVRSRV_OK)
1411
 
        {
1412
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
1413
 
                goto Exit;
1414
 
        }
1415
 
 
1416
 
        
1417
 
        psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
1418
 
 
1419
 
        
1420
 
        psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1421
 
 
1422
 
        
1423
 
        psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
1424
 
 
1425
 
        
1426
 
        psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
1427
 
 
1428
 
        
1429
 
        psFlipCmd->hPrivateTag = hPrivateTag;
1430
 
 
1431
 
        
1432
 
        psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
1433
 
        
1434
 
        psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND)); 
1435
 
        
1436
 
        for(i=0; i<ui32ClipRectCount; i++)
1437
 
        {
1438
 
                psFlipCmd->psClipRect[i] = psClipRect[i];
1439
 
        }
1440
 
 
1441
 
        
1442
 
        psFlipCmd->ui32SwapInterval = ui32SwapInterval;
1443
 
 
1444
 
        
1445
 
        eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
1446
 
        if (eError != PVRSRV_OK)
1447
 
        {
1448
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command"));
1449
 
                goto Exit;
1450
 
        }
1451
 
 
1452
 
        
1453
 
 
1454
 
        SysAcquireData(&psSysData);
1455
 
    eError = OSScheduleMISR(psSysData);
1456
 
 
1457
 
        if (eError != PVRSRV_OK)
1458
 
        {
1459
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to schedule MISR"));
1460
 
                goto Exit;
1461
 
        }
1462
 
 
1463
 
        
1464
 
        psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
1465
 
 
1466
 
Exit:
1467
 
 
1468
 
        if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
1469
 
        {
1470
 
                eError = PVRSRV_ERROR_RETRY;
1471
 
        }
1472
 
 
1473
 
        return eError;
1474
 
}
1475
 
 
1476
 
 
1477
 
IMG_EXPORT
1478
 
PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE  hDeviceKM,
1479
 
                                                                        IMG_HANDLE      hSwapChainRef)
1480
 
{
1481
 
        PVRSRV_ERROR eError;
1482
 
        PVRSRV_QUEUE_INFO *psQueue;
1483
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1484
 
        PVRSRV_DC_SWAPCHAIN *psSwapChain;
1485
 
        PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
1486
 
        DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
1487
 
        IMG_UINT32 ui32NumSrcSyncs = 1;
1488
 
        PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
1489
 
        PVRSRV_COMMAND *psCommand;
1490
 
        IMG_BOOL bAddReferenceToLast = IMG_TRUE;
1491
 
        IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
1492
 
    SYS_DATA *psSysData;
1493
 
 
1494
 
        if(!hDeviceKM || !hSwapChainRef)
1495
 
        {
1496
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
1497
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1498
 
        }
1499
 
 
1500
 
        psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
1501
 
        psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef;
1502
 
        psSwapChain = psSwapChainRef->psSwapChain;
1503
 
 
1504
 
        
1505
 
        psQueue = psSwapChain->psQueue;
1506
 
 
1507
 
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
1508
 
 
1509
 
        if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
1510
 
        {
1511
 
                psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
1512
 
                                                                                                         psSwapChain->hExtSwapChain,
1513
 
                                                                                                         psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer, 
1514
 
                                                                                                         0, 
1515
 
                                                                                                         &ui16SwapCommandID,
1516
 
                                                                                                         &bAddReferenceToLast);
1517
 
                
1518
 
        }
1519
 
 
1520
 
#endif
1521
 
 
1522
 
        
1523
 
        apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
1524
 
        
1525
 
 
1526
 
 
1527
 
        if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer)
1528
 
        {
1529
 
                
1530
 
                if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
1531
 
                {
1532
 
                        apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
1533
 
                        
1534
 
 
1535
 
 
1536
 
                        ui32NumSrcSyncs++;
1537
 
                }
1538
 
        }
1539
 
 
1540
 
        
1541
 
        eError = PVRSRVInsertCommandKM (psQueue,
1542
 
                                                                        &psCommand,
1543
 
                                                                        psDCInfo->ui32DeviceID,
1544
 
                                                                        ui16SwapCommandID,
1545
 
                                                                        0,
1546
 
                                                                        IMG_NULL,
1547
 
                                                                        ui32NumSrcSyncs,
1548
 
                                                                        apsSrcSync,
1549
 
                                                                        sizeof(DISPLAYCLASS_FLIP_COMMAND));
1550
 
        if(eError != PVRSRV_OK)
1551
 
        {
1552
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
1553
 
                goto Exit;
1554
 
        }
1555
 
 
1556
 
        
1557
 
        psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
1558
 
 
1559
 
        
1560
 
        psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
1561
 
 
1562
 
        
1563
 
        psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
1564
 
 
1565
 
        
1566
 
        psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
1567
 
 
1568
 
        
1569
 
        psFlipCmd->hPrivateTag = IMG_NULL;
1570
 
 
1571
 
        
1572
 
        psFlipCmd->ui32ClipRectCount = 0;
1573
 
 
1574
 
        psFlipCmd->ui32SwapInterval = 1;
1575
 
 
1576
 
        
1577
 
        eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
1578
 
        if (eError != PVRSRV_OK)
1579
 
        {
1580
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
1581
 
                goto Exit;
1582
 
        }
1583
 
 
1584
 
        
1585
 
        SysAcquireData(&psSysData);
1586
 
    eError = OSScheduleMISR(psSysData);
1587
 
 
1588
 
        if (eError != PVRSRV_OK)
1589
 
        {
1590
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to schedule MISR"));
1591
 
                goto Exit;
1592
 
        }
1593
 
 
1594
 
        
1595
 
        psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
1596
 
 
1597
 
        eError = PVRSRV_OK;
1598
 
 
1599
 
Exit:
1600
 
 
1601
 
        if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
1602
 
        {
1603
 
                eError = PVRSRV_ERROR_RETRY;
1604
 
        }
1605
 
 
1606
 
        return eError;
1607
 
}
1608
 
 
1609
 
 
1610
 
static
1611
 
PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER    pfnISRHandler,
1612
 
                                                                                         IMG_VOID                       *pvISRHandlerData,
1613
 
                                                                                         IMG_UINT32                     ui32ISRSourceMask,
1614
 
                                                                                         IMG_UINT32                     ui32DeviceID)
1615
 
{
1616
 
        SYS_DATA                        *psSysData;
1617
 
        PVRSRV_DEVICE_NODE      *psDevNode;
1618
 
 
1619
 
        PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask);
1620
 
 
1621
 
        SysAcquireData(&psSysData);
1622
 
 
1623
 
        
1624
 
        psDevNode = (PVRSRV_DEVICE_NODE*)
1625
 
                                List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
1626
 
                                                                                                &MatchDeviceKM_AnyVaCb,
1627
 
                                                                                                ui32DeviceID,
1628
 
                                                                                                IMG_TRUE);
1629
 
 
1630
 
        if (psDevNode == IMG_NULL)
1631
 
        {
1632
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode"));
1633
 
                PVR_DBG_BREAK;
1634
 
                return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
1635
 
        }
1636
 
 
1637
 
        
1638
 
        psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData;
1639
 
 
1640
 
        
1641
 
        psDevNode->pfnDeviceISR = pfnISRHandler;
1642
 
 
1643
 
        return PVRSRV_OK;
1644
 
}
1645
 
 
1646
 
static
1647
 
IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
1648
 
{
1649
 
        PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
1650
 
        IMG_UINT32 ui32State;
1651
 
        ui32State = va_arg(va, IMG_UINT32);
1652
 
 
1653
 
        if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
1654
 
        {
1655
 
                psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice;
1656
 
                if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice)
1657
 
                {
1658
 
                        psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State);
1659
 
                }
1660
 
        }
1661
 
}
1662
 
 
1663
 
 
1664
 
IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
1665
 
{
1666
 
        SYS_DATA                                        *psSysData;
1667
 
 
1668
 
        SysAcquireData(&psSysData);
1669
 
 
1670
 
        List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
1671
 
                                                                                &PVRSRVSetDCState_ForEachVaCb,
1672
 
                                                                                ui32State);
1673
 
}
1674
 
 
1675
 
 
1676
 
IMG_EXPORT
1677
 
IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable)
1678
 
{
1679
 
        psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE);
1680
 
        psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM;
1681
 
        psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM;
1682
 
        psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction;
1683
 
        psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM;
1684
 
        psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM;
1685
 
#if defined(SUPPORT_MISR_IN_THREAD)
1686
 
        psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR;
1687
 
#else
1688
 
        psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM;
1689
 
#endif
1690
 
        psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler;
1691
 
        psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice;
1692
 
#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
1693
 
        psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM;
1694
 
#endif
1695
 
 
1696
 
        return IMG_TRUE;
1697
 
}
1698
 
 
1699
 
 
1700
 
 
1701
 
IMG_EXPORT
1702
 
PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE  hDeviceKM,
1703
 
                                                                        IMG_BOOL        bResManCallback)
1704
 
{
1705
 
        PVRSRV_ERROR eError;
1706
 
        PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1707
 
 
1708
 
        PVR_UNREFERENCED_PARAMETER(bResManCallback);
1709
 
 
1710
 
        psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
1711
 
 
1712
 
        
1713
 
        eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
1714
 
 
1715
 
        return eError;
1716
 
}
1717
 
 
1718
 
 
1719
 
static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID  pvParam,
1720
 
                                                                                  IMG_UINT32 ui32Param,
1721
 
                                                                                  IMG_BOOL   bDummy)
1722
 
{
1723
 
        PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
1724
 
        PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1725
 
        IMG_UINT32 i;
1726
 
 
1727
 
        PVR_UNREFERENCED_PARAMETER(ui32Param);
1728
 
        PVR_UNREFERENCED_PARAMETER(bDummy);
1729
 
 
1730
 
        psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam;
1731
 
 
1732
 
        psBCInfo = psBCPerContextInfo->psBCInfo;
1733
 
 
1734
 
        for (i = 0; i < psBCInfo->ui32BufferCount; i++)
1735
 
        {
1736
 
                if (psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
1737
 
                {
1738
 
                        PVR_DPF((PVR_DBG_ERROR, "CloseBCDeviceCallBack: buffer %d (0x%p) still mapped (ui32MemMapRefCount = %d)",
1739
 
                                        i,
1740
 
                                        &psBCInfo->psBuffer[i].sDeviceClassBuffer,
1741
 
                                        psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
1742
 
                        return PVRSRV_ERROR_STILL_MAPPED;
1743
 
                }
1744
 
        }
1745
 
 
1746
 
        psBCInfo->ui32RefCount--;
1747
 
        if(psBCInfo->ui32RefCount == 0)
1748
 
        {
1749
 
                
1750
 
                psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice);
1751
 
 
1752
 
                
1753
 
                for(i=0; i<psBCInfo->ui32BufferCount; i++)
1754
 
                {
1755
 
                        if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
1756
 
                        {
1757
 
                                if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
1758
 
                                {
1759
 
                                        PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1760
 
                                }
1761
 
                        }
1762
 
                }
1763
 
 
1764
 
                
1765
 
                if(psBCInfo->psBuffer)
1766
 
                {
1767
 
                        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * psBCInfo->ui32BufferCount, psBCInfo->psBuffer, IMG_NULL);
1768
 
                        psBCInfo->psBuffer = IMG_NULL;
1769
 
                }
1770
 
        }
1771
 
 
1772
 
        OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL);
1773
 
        
1774
 
 
1775
 
        return PVRSRV_OK;
1776
 
}
1777
 
 
1778
 
 
1779
 
IMG_EXPORT
1780
 
PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA      *psPerProc,
1781
 
                                                                   IMG_UINT32                           ui32DeviceID,
1782
 
                                                                   IMG_HANDLE                           hDevCookie,
1783
 
                                                                   IMG_HANDLE                           *phDeviceKM)
1784
 
{
1785
 
        PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1786
 
        PVRSRV_BUFFERCLASS_PERCONTEXT_INFO      *psBCPerContextInfo;
1787
 
        PVRSRV_DEVICE_NODE              *psDeviceNode;
1788
 
        SYS_DATA                                *psSysData;
1789
 
        IMG_UINT32                              i;
1790
 
        PVRSRV_ERROR                    eError;
1791
 
 
1792
 
        if(!phDeviceKM || !hDevCookie)
1793
 
        {
1794
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params"));
1795
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1796
 
        }
1797
 
 
1798
 
        SysAcquireData(&psSysData);
1799
 
 
1800
 
        
1801
 
        psDeviceNode = (PVRSRV_DEVICE_NODE*)
1802
 
                        List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
1803
 
                                                                                   &MatchDeviceKM_AnyVaCb,
1804
 
                                                                                   ui32DeviceID,
1805
 
                                                                                   IMG_FALSE,
1806
 
                                                                                   PVRSRV_DEVICE_CLASS_BUFFER);
1807
 
        if (!psDeviceNode)
1808
 
        {
1809
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
1810
 
                return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
1811
 
        }
1812
 
        psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
1813
 
 
1814
 
        
1815
 
 
1816
 
 
1817
 
        if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1818
 
                                  sizeof(*psBCPerContextInfo),
1819
 
                                  (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
1820
 
                                  "Buffer Class per Context Info") != PVRSRV_OK)
1821
 
        {
1822
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
1823
 
                return PVRSRV_ERROR_OUT_OF_MEMORY;
1824
 
        }
1825
 
        OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));
1826
 
 
1827
 
        if(psBCInfo->ui32RefCount++ == 0)
1828
 
        {
1829
 
                BUFFER_INFO sBufferInfo;
1830
 
 
1831
 
                psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
1832
 
 
1833
 
                
1834
 
                psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
1835
 
 
1836
 
                
1837
 
                eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice);
1838
 
                if(eError != PVRSRV_OK)
1839
 
                {
1840
 
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
1841
 
                        return eError;
1842
 
                }
1843
 
 
1844
 
                
1845
 
                eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
1846
 
                if(eError != PVRSRV_OK)
1847
 
                {
1848
 
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
1849
 
                        return eError;
1850
 
                }
1851
 
 
1852
 
                
1853
 
                psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
1854
 
                
1855
 
 
1856
 
                
1857
 
                eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1858
 
                                                          sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
1859
 
                                                          (IMG_VOID **)&psBCInfo->psBuffer,
1860
 
                                                          IMG_NULL,
1861
 
                                                          "Array of Buffer Class Buffer");
1862
 
                if(eError != PVRSRV_OK)
1863
 
                {
1864
 
                        PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
1865
 
                        return eError;
1866
 
                }
1867
 
                OSMemSet (psBCInfo->psBuffer,
1868
 
                                        0,
1869
 
                                        sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount);
1870
 
 
1871
 
                for(i=0; i<psBCInfo->ui32BufferCount; i++)
1872
 
                {
1873
 
                        
1874
 
                        eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
1875
 
                                                                                psBCInfo->hDevMemContext,
1876
 
                                                                                &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1877
 
                        if(eError != PVRSRV_OK)
1878
 
                        {
1879
 
                                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
1880
 
                                goto ErrorExit;
1881
 
                        }
1882
 
 
1883
 
                        psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
1884
 
                        
1885
 
                        
1886
 
 
1887
 
 
1888
 
                        eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice,
1889
 
                                                                                                                        i,
1890
 
                                                                                                                        psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData,
1891
 
                                                                                                                        &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer);
1892
 
                        if(eError != PVRSRV_OK)
1893
 
                        {
1894
 
                                PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
1895
 
                                goto ErrorExit;
1896
 
                        }
1897
 
 
1898
 
                        
1899
 
                        psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
1900
 
                        psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
1901
 
                        psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
1902
 
                        psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount = 0;
1903
 
                }
1904
 
        }
1905
 
 
1906
 
        psBCPerContextInfo->psBCInfo = psBCInfo;
1907
 
        psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
1908
 
                                                                                                         RESMAN_TYPE_BUFFERCLASS_DEVICE,
1909
 
                                                                                                         psBCPerContextInfo,
1910
 
                                                                                                         0,
1911
 
                                                                                                         &CloseBCDeviceCallBack);
1912
 
 
1913
 
        
1914
 
        *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;
1915
 
 
1916
 
        return PVRSRV_OK;
1917
 
 
1918
 
ErrorExit:
1919
 
 
1920
 
        
1921
 
        for(i=0; i<psBCInfo->ui32BufferCount; i++)
1922
 
        {
1923
 
                if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
1924
 
                {
1925
 
                        if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
1926
 
                        {
1927
 
                                PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
1928
 
                        }
1929
 
                }
1930
 
        }
1931
 
 
1932
 
        
1933
 
        if(psBCInfo->psBuffer)
1934
 
        {
1935
 
                OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
1936
 
                psBCInfo->psBuffer = IMG_NULL;
1937
 
        }
1938
 
 
1939
 
        return eError;
1940
 
}
1941
 
 
1942
 
 
1943
 
 
1944
 
 
1945
 
IMG_EXPORT
1946
 
PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM,
1947
 
                                                                BUFFER_INFO *psBufferInfo)
1948
 
{
1949
 
        PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1950
 
        PVRSRV_ERROR                    eError;
1951
 
 
1952
 
        if(!hDeviceKM || !psBufferInfo)
1953
 
        {
1954
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters"));
1955
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1956
 
        }
1957
 
 
1958
 
        psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1959
 
 
1960
 
        eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo);
1961
 
 
1962
 
        if(eError != PVRSRV_OK)
1963
 
        {
1964
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info"));
1965
 
                return eError;
1966
 
        }
1967
 
 
1968
 
        return PVRSRV_OK;
1969
 
}
1970
 
 
1971
 
 
1972
 
IMG_EXPORT
1973
 
PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM,
1974
 
                                                                  IMG_UINT32 ui32BufferIndex,
1975
 
                                                                  IMG_HANDLE *phBuffer)
1976
 
{
1977
 
        PVRSRV_BUFFERCLASS_INFO *psBCInfo;
1978
 
 
1979
 
        if(!hDeviceKM || !phBuffer)
1980
 
        {
1981
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters"));
1982
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1983
 
        }
1984
 
 
1985
 
        psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM);
1986
 
 
1987
 
        if(ui32BufferIndex < psBCInfo->ui32BufferCount)
1988
 
        {
1989
 
                *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex];
1990
 
        }
1991
 
        else
1992
 
        {
1993
 
                PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount));
1994
 
                return PVRSRV_ERROR_INVALID_PARAMS;
1995
 
        }
1996
 
 
1997
 
        return PVRSRV_OK;
1998
 
}
1999
 
 
2000
 
 
2001
 
IMG_EXPORT
2002
 
IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
2003
 
{
2004
 
        psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
2005
 
 
2006
 
        psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM;
2007
 
        psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM;
2008
 
        psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM;
2009
 
 
2010
 
        return IMG_TRUE;
2011
 
}
2012