gpu: pvr: kick: check for duplicate src syncs
[sgx.git] / pvr / sgxkick.c
1 /**********************************************************************
2  *
3  * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful but, except
10  * as otherwise stated in writing, without any warranty; without even the
11  * implied warranty of merchantability or fitness for a particular purpose.
12  * See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * The full GNU General Public License is included in this distribution in
19  * the file called "COPYING".
20  *
21  * Contact Information:
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24  *
25  ******************************************************************************/
26
27 #include <stddef.h>
28 #include "services_headers.h"
29 #include "sgxinfo.h"
30 #include "sgxinfokm.h"
31 #if defined(PDUMP)
32 #include "sgxapi_km.h"
33 #include "pvr_pdump.h"
34 #endif
35 #include "sgx_bridge_km.h"
36 #include "osfunc.h"
37 #include "pvr_debug.h"
38 #include "sgxutils.h"
39 #include "perproc.h"
40 #include "pvr_trace_cmd.h"
41
42 enum PVRSRV_ERROR SGXDoKickKM(void *hDevHandle, struct SGX_CCB_KICK *psCCBKick,
43                               struct PVRSRV_PER_PROCESS_DATA *proc)
44 {
45         enum PVRSRV_ERROR eError;
46         struct PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
47         struct PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo =
48             (struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hCCBKernelMemInfo;
49         struct SGXMKIF_CMDTA_SHARED *psTACmd;
50         u32 i;
51         struct PVRSRV_DEVICE_NODE *psDeviceNode;
52         struct PVRSRV_SGXDEV_INFO *psDevInfo;
53         struct pvr_trcmd_sgxkick *ktrace;
54         int trcmd_type;
55
56         psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevHandle;
57         psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
58
59         if (psCCBKick->bKickRender)
60                 ++psDevInfo->ui32KickTARenderCounter;
61         ++psDevInfo->ui32KickTACounter;
62
63         if (!CCB_OFFSET_IS_VALID
64             (struct SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick,
65              ui32CCBOffset)) {
66                 PVR_DPF(PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset");
67                 return PVRSRV_ERROR_INVALID_PARAMS;
68         }
69         psTACmd =
70             CCB_DATA_FROM_OFFSET(struct SGXMKIF_CMDTA_SHARED, psCCBMemInfo,
71                                  psCCBKick, ui32CCBOffset);
72
73         trcmd_type = psCCBKick->bFirstKickOrResume ?
74                                 PVR_TRCMD_SGX_FIRSTKICK : PVR_TRCMD_SGX_KICK;
75         pvr_trcmd_lock();
76         ktrace = pvr_trcmd_alloc(trcmd_type, proc->ui32PID, proc->name,
77                                  sizeof(*ktrace));
78
79         if (psCCBKick->hTA3DSyncInfo) {
80                 psSyncInfo =
81                     (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
82                 psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr =
83                     psSyncInfo->sWriteOpsCompleteDevVAddr;
84
85                 psTACmd->sTA3DDependency.ui32WriteOpsPendingVal =
86                     psSyncInfo->psSyncData->ui32WriteOpsPending;
87
88                 if (psCCBKick->bTADependency)
89                         psSyncInfo->psSyncData->ui32WriteOpsPending++;
90
91                 pvr_trcmd_set_syn(&ktrace->ta3d_syn, psSyncInfo);
92         } else {
93                 pvr_trcmd_clear_syn(&ktrace->ta3d_syn);
94         }
95
96         if (psCCBKick->hTASyncInfo != NULL) {
97                 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
98                                                 psCCBKick->hTASyncInfo;
99
100                 psTACmd->sTATQSyncReadOpsCompleteDevVAddr =
101                     psSyncInfo->sReadOpsCompleteDevVAddr;
102                 psTACmd->sTATQSyncWriteOpsCompleteDevVAddr =
103                     psSyncInfo->sWriteOpsCompleteDevVAddr;
104
105                 psTACmd->ui32TATQSyncReadOpsPendingVal =
106                     psSyncInfo->psSyncData->ui32ReadOpsPending++;
107                 psTACmd->ui32TATQSyncWriteOpsPendingVal =
108                     psSyncInfo->psSyncData->ui32WriteOpsPending;
109
110                 pvr_trcmd_set_syn(&ktrace->tatq_syn, psSyncInfo);
111         } else {
112                 pvr_trcmd_clear_syn(&ktrace->tatq_syn);
113         }
114
115         if (psCCBKick->h3DSyncInfo != NULL) {
116                 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
117                                                         psCCBKick->h3DSyncInfo;
118
119                 psTACmd->s3DTQSyncReadOpsCompleteDevVAddr =
120                     psSyncInfo->sReadOpsCompleteDevVAddr;
121                 psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr =
122                     psSyncInfo->sWriteOpsCompleteDevVAddr;
123
124                 psTACmd->ui323DTQSyncReadOpsPendingVal =
125                     psSyncInfo->psSyncData->ui32ReadOpsPending++;
126                 psTACmd->ui323DTQSyncWriteOpsPendingVal =
127                     psSyncInfo->psSyncData->ui32WriteOpsPending;
128
129                 pvr_trcmd_set_syn(&ktrace->_3dtq_syn, psSyncInfo);
130         } else {
131                 pvr_trcmd_clear_syn(&ktrace->_3dtq_syn);
132         }
133
134         psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals;
135         if (psCCBKick->ui32NumTAStatusVals != 0) {
136                 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) {
137                         psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
138                                 psCCBKick->ahTAStatusSyncInfo[i];
139
140                         psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr =
141                                 psSyncInfo->sReadOpsCompleteDevVAddr;
142
143                         psTACmd->sCtlTAStatusInfo[i].ui32StatusValue =
144                                 psSyncInfo->psSyncData->ui32ReadOpsPending;
145                 }
146         }
147
148         psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals;
149         if (psCCBKick->ui32Num3DStatusVals != 0) {
150                 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) {
151                         psSyncInfo =
152                             (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
153                             ah3DStatusSyncInfo[i];
154
155                         psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr =
156                             psSyncInfo->sReadOpsCompleteDevVAddr;
157
158                         psTACmd->sCtl3DStatusInfo[i].ui32StatusValue =
159                             psSyncInfo->psSyncData->ui32ReadOpsPending;
160                 }
161         }
162
163         /* check for duplicates while creating the new list */
164         psTACmd->ui32NumSrcSyncs = 0;
165         for (i = 0; ((i < SGX_MAX_SRC_SYNCS) &&
166                      (i < psCCBKick->ui32NumSrcSyncs)); i++) {
167                 int j;
168
169                 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
170                         psCCBKick->ahSrcKernelSyncInfo[i];
171
172                 for (j = 0; j < i; j++) {
173                         struct PVRSRV_KERNEL_SYNC_INFO *tmp =
174                                 psCCBKick->ahSrcKernelSyncInfo[j];
175                         if (tmp->psSyncData == psSyncInfo->psSyncData) {
176                                 pr_err("%s: Duplicate SRC Sync detected: %p\n",
177                                        __func__, tmp->psSyncData);
178                                 break;
179                         }
180                 }
181                 if (j != i)
182                         continue;
183
184                 /* beat the 80 char limit. */
185                 j = psTACmd->ui32NumSrcSyncs;
186
187                 psTACmd->asSrcSyncs[j].sWriteOpsCompleteDevVAddr =
188                         psSyncInfo->sWriteOpsCompleteDevVAddr;
189                 psTACmd->asSrcSyncs[j].sReadOpsCompleteDevVAddr =
190                         psSyncInfo->sReadOpsCompleteDevVAddr;
191
192                 psTACmd->asSrcSyncs[j].ui32ReadOpsPendingVal =
193                         psSyncInfo->psSyncData->ui32ReadOpsPending++;
194
195                 psTACmd->asSrcSyncs[j].ui32WriteOpsPendingVal =
196                         psSyncInfo->psSyncData->ui32WriteOpsPending;
197
198                 pvr_trcmd_set_syn(&ktrace->src_syn[j], psSyncInfo);
199
200                 psTACmd->ui32NumSrcSyncs++;
201         }
202
203         /* clear the remaining src syncs */
204         for (i = psTACmd->ui32NumSrcSyncs; i < SGX_MAX_SRC_SYNCS; i++)
205                 pvr_trcmd_clear_syn(&ktrace->src_syn[i]);
206
207         if (psCCBKick->bFirstKickOrResume &&
208             psCCBKick->ui32NumDstSyncObjects > 0) {
209                 struct PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
210                     (struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->
211                     hKernelHWSyncListMemInfo;
212                 struct SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList =
213                     psHWDstSyncListMemInfo->pvLinAddrKM;
214                 u32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects;
215
216                 PVR_ASSERT(((struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->
217                             hKernelHWSyncListMemInfo)->ui32AllocSize >=
218                            (sizeof(struct SGXMKIF_HWDEVICE_SYNC_LIST) +
219                             (sizeof(struct PVRSRV_DEVICE_SYNC_OBJECT) *
220                              ui32NumDstSyncs)));
221
222                 psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs;
223 #if defined(PDUMP)
224                 if (PDumpIsCaptureFrameKM()) {
225                         PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n");
226                         PDUMPMEM(NULL,
227                                  psHWDstSyncListMemInfo, 0,
228                                  sizeof(struct SGXMKIF_HWDEVICE_SYNC_LIST),
229                                  0, MAKEUNIQUETAG(psHWDstSyncListMemInfo));
230                 }
231 #endif
232                 psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
233                             sDstSyncHandle;
234                 i = 0;
235                 if (psSyncInfo) {
236                         psHWDeviceSyncList->asSyncData[i].
237                             sWriteOpsCompleteDevVAddr =
238                                         psSyncInfo->sWriteOpsCompleteDevVAddr;
239
240                         psHWDeviceSyncList->asSyncData[i].
241                             sReadOpsCompleteDevVAddr =
242                                         psSyncInfo->sReadOpsCompleteDevVAddr;
243
244                         psHWDeviceSyncList->asSyncData[i].
245                             ui32ReadOpsPendingVal =
246                                 psSyncInfo->psSyncData->ui32ReadOpsPending;
247
248                         psHWDeviceSyncList->asSyncData[i].
249                             ui32WriteOpsPendingVal =
250                                     psSyncInfo->psSyncData->
251                                                         ui32WriteOpsPending++;
252
253                         pvr_trcmd_set_syn(&ktrace->dst_syn, psSyncInfo);
254
255 #if defined(PDUMP)
256                         if (PDumpIsCaptureFrameKM()) {
257                                 u32 ui32ModifiedValue;
258                                 u32 ui32SyncOffset = offsetof(
259                                         struct SGXMKIF_HWDEVICE_SYNC_LIST,
260                                         asSyncData) + (i *
261                                         sizeof(
262                                         struct PVRSRV_DEVICE_SYNC_OBJECT));
263                                 u32 ui32WOpsOffset = ui32SyncOffset +
264                                         offsetof(
265                                         struct PVRSRV_DEVICE_SYNC_OBJECT,
266                                         ui32WriteOpsPendingVal);
267                                 u32 ui32ROpsOffset = ui32SyncOffset +
268                                         offsetof(
269                                         struct PVRSRV_DEVICE_SYNC_OBJECT,
270                                         ui32ReadOpsPendingVal);
271
272                                 PDUMPCOMMENT("HWDeviceSyncObject for RT: "
273                                              "%i\r\n", i);
274
275                                 PDUMPMEM(NULL, psHWDstSyncListMemInfo,
276                                         ui32SyncOffset, sizeof(
277                                         struct PVRSRV_DEVICE_SYNC_OBJECT),
278                                         0, MAKEUNIQUETAG(
279                                                 psHWDstSyncListMemInfo));
280
281                                 if ((psSyncInfo->psSyncData->
282                                                 ui32LastOpDumpVal == 0) &&
283                                     (psSyncInfo->psSyncData->
284                                                 ui32LastReadOpDumpVal == 0)) {
285
286                                         PDUMPCOMMENT("Init RT ROpsComplete\r\n",
287                                                          i);
288                                         PDUMPMEM(&psSyncInfo->psSyncData->
289                                                         ui32LastReadOpDumpVal,
290                                                 psSyncInfo->psSyncDataMemInfoKM,
291                                                 offsetof(struct
292                                                         PVRSRV_SYNC_DATA,
293                                                         ui32ReadOpsComplete),
294                                                 sizeof(psSyncInfo->psSyncData->
295                                                            ui32ReadOpsComplete),
296                                                 0,
297                                                 MAKEUNIQUETAG(psSyncInfo->
298                                                         psSyncDataMemInfoKM));
299
300                                 PDUMPCOMMENT("Init RT WOpsComplete\r\n");
301                                 PDUMPMEM(&psSyncInfo->psSyncData->
302                                                 ui32LastOpDumpVal,
303                                          psSyncInfo->psSyncDataMemInfoKM,
304                                          offsetof(struct PVRSRV_SYNC_DATA,
305                                                         ui32WriteOpsComplete),
306                                          sizeof(psSyncInfo->psSyncData->
307                                                         ui32WriteOpsComplete),
308                                          0, MAKEUNIQUETAG(psSyncInfo->
309                                                         psSyncDataMemInfoKM));
310                                 }
311
312                                 psSyncInfo->psSyncData->ui32LastOpDumpVal++;
313
314                                 ui32ModifiedValue = psSyncInfo->psSyncData->
315                                             ui32LastOpDumpVal - 1;
316
317                                 PDUMPCOMMENT("Modify RT %d WOpPendingVal "
318                                              "in HWDevSyncList\r\n", i);
319
320                                 PDUMPMEM(&ui32ModifiedValue,
321                                          psHWDstSyncListMemInfo, ui32WOpsOffset,
322                                          sizeof(u32), 0,
323                                          MAKEUNIQUETAG(psHWDstSyncListMemInfo));
324
325                                 PDUMPCOMMENT("Modify RT %d ROpsPendingVal "
326                                              "in HWDevSyncList\r\n", i);
327
328                                 PDUMPMEM(&psSyncInfo->psSyncData->
329                                                  ui32LastReadOpDumpVal,
330                                          psHWDstSyncListMemInfo,
331                                          ui32ROpsOffset, sizeof(u32), 0,
332                                          MAKEUNIQUETAG(psHWDstSyncListMemInfo));
333                         }
334 #endif
335                 } else {
336                         psHWDeviceSyncList->asSyncData[i].
337                             sWriteOpsCompleteDevVAddr.uiAddr = 0;
338                         psHWDeviceSyncList->asSyncData[i].
339                             sReadOpsCompleteDevVAddr.uiAddr = 0;
340
341                         psHWDeviceSyncList->asSyncData[i].
342                             ui32ReadOpsPendingVal = 0;
343                         psHWDeviceSyncList->asSyncData[i].
344                             ui32WriteOpsPendingVal = 0;
345
346                         pvr_trcmd_clear_syn(&ktrace->dst_syn);
347                 }
348         } else {
349                 pvr_trcmd_clear_syn(&ktrace->dst_syn);
350         }
351 #if defined(PDUMP)
352         if (PDumpIsCaptureFrameKM()) {
353                 PDUMPCOMMENT("Shared part of TA command\r\n");
354
355                 PDUMPMEM(psTACmd, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff,
356                          sizeof(struct SGXMKIF_CMDTA_SHARED), 0,
357                          MAKEUNIQUETAG(psCCBMemInfo));
358
359                 for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
360                         u32 ui32ModifiedValue;
361                         psSyncInfo =
362                             (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
363                             ahSrcKernelSyncInfo[i];
364
365                         if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
366                             (psSyncInfo->psSyncData->ui32LastReadOpDumpVal ==
367                              0)) {
368                                 PDUMPCOMMENT("Init RT ROpsComplete\r\n", i);
369                                 PDUMPMEM(&psSyncInfo->psSyncData->
370                                          ui32LastReadOpDumpVal,
371                                          psSyncInfo->psSyncDataMemInfoKM,
372                                          offsetof(struct PVRSRV_SYNC_DATA,
373                                                   ui32ReadOpsComplete),
374                                          sizeof(psSyncInfo->psSyncData->
375                                                 ui32ReadOpsComplete), 0,
376                                          MAKEUNIQUETAG(psSyncInfo->
377                                                        psSyncDataMemInfoKM));
378                                 PDUMPCOMMENT("Init RT WOpsComplete\r\n");
379                                 PDUMPMEM(&psSyncInfo->psSyncData->
380                                          ui32LastOpDumpVal,
381                                          psSyncInfo->psSyncDataMemInfoKM,
382                                          offsetof(struct PVRSRV_SYNC_DATA,
383                                                   ui32WriteOpsComplete),
384                                          sizeof(psSyncInfo->psSyncData->
385                                                 ui32WriteOpsComplete), 0,
386                                          MAKEUNIQUETAG(psSyncInfo->
387                                                        psSyncDataMemInfoKM));
388                         }
389
390                         psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
391
392                         ui32ModifiedValue =
393                             psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1;
394
395                         PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i);
396
397                         PDUMPMEM(&ui32ModifiedValue,
398                                  psCCBMemInfo,
399                                  psCCBKick->ui32CCBDumpWOff +
400                                  offsetof(struct SGXMKIF_CMDTA_SHARED,
401                                           asSrcSyncs) +
402                                  (i *
403                                   sizeof(struct PVRSRV_DEVICE_SYNC_OBJECT)) +
404                                  offsetof(struct PVRSRV_DEVICE_SYNC_OBJECT,
405                                           ui32ReadOpsPendingVal), sizeof(u32),
406                                  0, MAKEUNIQUETAG(psCCBMemInfo));
407
408                         PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i);
409
410                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
411                                  psCCBMemInfo,
412                                  psCCBKick->ui32CCBDumpWOff +
413                                  offsetof(struct SGXMKIF_CMDTA_SHARED,
414                                           asSrcSyncs) +
415                                  (i *
416                                   sizeof(struct PVRSRV_DEVICE_SYNC_OBJECT)) +
417                                  offsetof(struct PVRSRV_DEVICE_SYNC_OBJECT,
418                                           ui32WriteOpsPendingVal), sizeof(u32),
419                                  0, MAKEUNIQUETAG(psCCBMemInfo));
420
421                 }
422
423                 for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) {
424                         psSyncInfo =
425                             (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
426                             ahTAStatusSyncInfo[i];
427                         PDUMPCOMMENT("Modify TA status value in TA cmd\r\n");
428                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
429                                  psCCBMemInfo,
430                                  psCCBKick->ui32CCBDumpWOff +
431                                  offsetof(struct SGXMKIF_CMDTA_SHARED,
432                                           sCtlTAStatusInfo[i].ui32StatusValue),
433                                  sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo));
434                 }
435
436                 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) {
437                         psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
438                                 psCCBKick->ah3DStatusSyncInfo[i];
439
440                         PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n");
441
442                         PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
443                                  psCCBMemInfo,
444                                  psCCBKick->ui32CCBDumpWOff +
445                                  offsetof(struct SGXMKIF_CMDTA_SHARED,
446                                           sCtl3DStatusInfo[i].ui32StatusValue),
447                                  sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo));
448                 }
449         }
450 #endif
451
452         pvr_trcmd_set_data(&ktrace->ctx, psCCBKick->sCommand.ui32Data[1]);
453         pvr_trcmd_unlock();
454
455         /* to aid in determining the next power down delay */
456         sgx_mark_new_command(psDeviceNode);
457
458         eError = SGXScheduleCCBCommandKM(hDevHandle, psCCBKick->eCommand,
459                                     &psCCBKick->sCommand, KERNEL_ID, 0);
460         if (eError == PVRSRV_ERROR_RETRY) {
461                 if (psCCBKick->bFirstKickOrResume &&
462                     psCCBKick->ui32NumDstSyncObjects > 0) {
463                         psSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
464                                     psCCBKick->sDstSyncHandle;
465                         if (psSyncInfo) {
466                                 psSyncInfo->psSyncData->ui32WriteOpsPending--;
467 #if defined(PDUMP)
468                                 if (PDumpIsCaptureFrameKM())
469                                         psSyncInfo->psSyncData->
470                                                         ui32LastOpDumpVal--;
471 #endif
472                         }
473                 }
474
475                 for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
476                         psSyncInfo =
477                             (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
478                             ahSrcKernelSyncInfo[i];
479                         psSyncInfo->psSyncData->ui32ReadOpsPending--;
480                 }
481
482                 return eError;
483         } else if (PVRSRV_OK != eError) {
484                 PVR_DPF(PVR_DBG_ERROR,
485                          "SGXDoKickKM: SGXScheduleCCBCommandKM failed.");
486                 return eError;
487         }
488
489 #if defined(NO_HARDWARE)
490
491         if (psCCBKick->hTA3DSyncInfo) {
492                 psSyncInfo =
493                     (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
494
495                 if (psCCBKick->bTADependency) {
496                         psSyncInfo->psSyncData->ui32WriteOpsComplete =
497                             psSyncInfo->psSyncData->ui32WriteOpsPending;
498                 }
499         }
500
501         if (psCCBKick->hTASyncInfo != NULL) {
502                 psSyncInfo =
503                     (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
504
505                 psSyncInfo->psSyncData->ui32ReadOpsComplete =
506                     psSyncInfo->psSyncData->ui32ReadOpsPending;
507         }
508
509         if (psCCBKick->h3DSyncInfo != NULL) {
510                 psSyncInfo =
511                     (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
512
513                 psSyncInfo->psSyncData->ui32ReadOpsComplete =
514                     psSyncInfo->psSyncData->ui32ReadOpsPending;
515         }
516
517         for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) {
518                 psSyncInfo =
519                     (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
520                     ahTAStatusSyncInfo[i];
521                 psSyncInfo->psSyncData->ui32ReadOpsComplete =
522                     psTACmd->sCtlTAStatusInfo[i].ui32StatusValue;
523         }
524
525         for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) {
526                 psSyncInfo =
527                     (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
528                     ahSrcKernelSyncInfo[i];
529
530                 psSyncInfo->psSyncData->ui32ReadOpsComplete =
531                     psSyncInfo->psSyncData->ui32ReadOpsPending;
532
533         }
534
535         if (psCCBKick->bTerminateOrAbort) {
536                 if (psCCBKick->ui32NumDstSyncObjects > 0) {
537                         struct PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo =
538                             (struct PVRSRV_KERNEL_MEM_INFO *)psCCBKick->
539                             hKernelHWSyncListMemInfo;
540                         struct SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList =
541                             psHWDstSyncListMemInfo->pvLinAddrKM;
542
543                         psSyncInfo =
544                             (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
545                             sDstSyncHandle;
546                         if (psSyncInfo)
547                                 psSyncInfo->psSyncData->ui32WriteOpsComplete =
548                                     psHWDeviceSyncList->asSyncData[0].
549                                     ui32WriteOpsPendingVal + 1;
550                 }
551
552                 for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) {
553                         psSyncInfo =
554                             (struct PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->
555                             ah3DStatusSyncInfo[i];
556                         psSyncInfo->psSyncData->ui32ReadOpsComplete =
557                             psTACmd->sCtl3DStatusInfo[i].ui32StatusValue;
558                 }
559         }
560 #endif
561
562         return eError;
563 }