257 if(!device) \ |
259 if(!device) \ |
258 return KErrNoMemory; \ |
260 return KErrNoMemory; \ |
259 r = Kern::InstallPhysicalDevice(device); \ |
261 r = Kern::InstallPhysicalDevice(device); \ |
260 if(r != KErrNone) \ |
262 if(r != KErrNone) \ |
261 return r; \ |
263 return r; \ |
262 TDfc* resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \ |
264 resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \ |
263 if(!resourceInitDfc) \ |
265 if(!resourceInitDfc) \ |
264 return KErrNoMemory; \ |
266 return KErrNoMemory; \ |
265 resourceInitDfc->Enque(); \ |
267 resourceInitDfc->Enque(); \ |
266 return KErrNone; \ |
268 return KErrNone; \ |
267 } \ |
269 } \ |
268 GLDEF_C void CreateController() |
270 GLDEF_C void CreateController() |
269 |
|
270 /* Macro defintion for handling dependency resource state change. This is used only in extended version */ |
|
271 #define HANDLE_CHANGE_PROPAGATION(TheController, resourceTypePointer, traceEnabled, originatorId, originatorName) \ |
|
272 switch(aProp) \ |
|
273 { \ |
|
274 case EChangeStart: \ |
|
275 { \ |
|
276 if(!pDR->iDependencyList) /*No dependents so change state of the resource*/ \ |
|
277 { \ |
|
278 aRequest.ReturnCode() = pDR->DoRequest(aRequest); \ |
|
279 if(aRequest.ReturnCode() == KErrNone) \ |
|
280 { \ |
|
281 iCachedLevel = aRequest.Level(); \ |
|
282 iLevelOwnerId = aRequest.ClientId(); \ |
|
283 if(iIdleListEntry) \ |
|
284 { \ |
|
285 iIdleListEntry->iCurrentLevel = aRequest.Level(); \ |
|
286 iIdleListEntry->iLevelOwnerId = aRequest.ClientId(); \ |
|
287 } \ |
|
288 TheController->CompleteNotifications(aRequest.ClientId(), pDR, \ |
|
289 aRequest.Level(), aRequest.ReturnCode(), aRequest.ClientId()); \ |
|
290 } \ |
|
291 break; \ |
|
292 } \ |
|
293 depRequest.ResourceId() = aRequest.ResourceId(); \ |
|
294 depRequest.ClientId() = aRequest.ResourceId(); \ |
|
295 depRequest.Level() = aRequest.Level(); \ |
|
296 depRequest.Resource() = pDR; \ |
|
297 result = pDR->HandleChangePropagation(depRequest, ECheckChangeAllowed, originatorId, originatorName); \ |
|
298 if(result != KErrNone) \ |
|
299 return result; \ |
|
300 /*Adjust resource client level*/ \ |
|
301 if(clientLevelCount) \ |
|
302 { \ |
|
303 result = TheController->ReserveClientLevelPoolCount(clientLevelCount); \ |
|
304 if(result != KErrNone) \ |
|
305 return result; \ |
|
306 } \ |
|
307 /*Resource change of dependents */ \ |
|
308 pDR->HandleChangePropagation(aRequest, ERequestStateChange, originatorId, originatorName); \ |
|
309 /*Notification to dependents */ \ |
|
310 pDR->HandleChangePropagation(aRequest, EIssueNotifications, originatorId, originatorName); \ |
|
311 break; \ |
|
312 } \ |
|
313 case ECheckChangeAllowed: \ |
|
314 { \ |
|
315 TChangePropagationStatus status; \ |
|
316 for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext) \ |
|
317 { \ |
|
318 pDepRes = (resourceTypePointer)depNode->iResource; \ |
|
319 if((aRequest.ClientId() & KIdMaskResourceWithDependencies) && \ |
|
320 (pDepRes->iResourceId == (TUint)aRequest.ClientId())) \ |
|
321 continue; \ |
|
322 /*Resource need not change if it is already in that state, so continue with \ |
|
323 another dependent state.*/ \ |
|
324 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
325 status = ((DDynamicPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(), \ |
|
326 aRequest.Level(), resState); \ |
|
327 else \ |
|
328 status = ((DStaticPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(), \ |
|
329 aRequest.Level(), resState); \ |
|
330 if((status == ENoChange) || (pDepRes->iCachedLevel == resState)) \ |
|
331 { \ |
|
332 depNode->iRequiresChange = EFalse; \ |
|
333 continue; \ |
|
334 } \ |
|
335 if(status == EChangeNotAccepted) \ |
|
336 return KErrPermissionDenied; \ |
|
337 depRequest.ResourceId() = pDepRes->iResourceId; \ |
|
338 depRequest.ClientId() = aRequest.ResourceId(); /*ID of the dependent resource */ \ |
|
339 depRequest.Level() = resState; \ |
|
340 depRequest.Resource() = pDepRes; \ |
|
341 /*Check resource client list and resource list to see whether change is allowed.*/ \ |
|
342 if(pDepRes->Sense() == DStaticPowerResource::ECustom) \ |
|
343 { \ |
|
344 /*Call custom function to check whether change is allowed.*/ \ |
|
345 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
346 depRequest.RequiresChange() = ((DDynamicPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(), \ |
|
347 originatorName, depRequest.ResourceId(), EClientChangeLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList, \ |
|
348 (TAny*)&((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, NULL); \ |
|
349 else \ |
|
350 depRequest.RequiresChange() = ((DStaticPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(), \ |
|
351 originatorName, depRequest.ResourceId(), EClientChangeLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList, \ |
|
352 (TAny*)&((DStaticPowerResourceD*)pDepRes)->iResourceClientList, NULL); \ |
|
353 if(!depRequest.RequiresChange()) \ |
|
354 return KErrPermissionDenied; \ |
|
355 } \ |
|
356 SPowerResourceClientLevel*pN=NULL; \ |
|
357 for(SDblQueLink* pNL=pDepRes->iClientList.First();pNL!=&pDepRes->iClientList.iA; pNL=pNL->iNext) \ |
|
358 { \ |
|
359 pN = (SPowerResourceClientLevel*)pNL; \ |
|
360 if(pDepRes->Sense() == DStaticPowerResource::EPositive) \ |
|
361 { \ |
|
362 if(pN->iLevel > depRequest.Level()) \ |
|
363 return KErrPermissionDenied; \ |
|
364 } \ |
|
365 else if(pDepRes->Sense() == DStaticPowerResource::ENegative) \ |
|
366 { \ |
|
367 if(pN->iLevel < depRequest.Level()) \ |
|
368 return KErrPermissionDenied; \ |
|
369 } \ |
|
370 } \ |
|
371 \ |
|
372 /*check through the resource client level */ \ |
|
373 SPowerResourceClientLevel*pCL = NULL; \ |
|
374 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
375 pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
376 else \ |
|
377 pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
378 for(; pCL != NULL; pCL = pCL->iNextInList) \ |
|
379 { \ |
|
380 if(pCL->iClientId == pDR->iResourceId) \ |
|
381 break; \ |
|
382 } \ |
|
383 if(!pCL) \ |
|
384 clientLevelCount++; \ |
|
385 /*check dependent resource client list & resource list to see whether change is allowed */ \ |
|
386 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
387 result = ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, \ |
|
388 ECheckChangeAllowed, originatorId, originatorName); \ |
|
389 else \ |
|
390 result = ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, \ |
|
391 ECheckChangeAllowed, originatorId, originatorName); \ |
|
392 if(result != KErrNone) \ |
|
393 return result; \ |
|
394 depNode->iPropagatedLevel = resState; \ |
|
395 depNode->iRequiresChange = ETrue; \ |
|
396 } \ |
|
397 break; \ |
|
398 } \ |
|
399 case ERequestStateChange: \ |
|
400 { \ |
|
401 SPowerResourceClientLevel* pCL = NULL; \ |
|
402 for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext) \ |
|
403 { \ |
|
404 pDepRes = (resourceTypePointer)depNode->iResource; \ |
|
405 if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId())) \ |
|
406 continue; \ |
|
407 depRequest.ResourceId() = pDepRes->iResourceId; \ |
|
408 depRequest.ClientId() = aRequest.ResourceId(); \ |
|
409 depRequest.Level() = depNode->iPropagatedLevel; \ |
|
410 depRequest.Resource() = pDepRes; \ |
|
411 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
412 ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange, \ |
|
413 originatorId, originatorName); \ |
|
414 else \ |
|
415 ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange, \ |
|
416 originatorId, originatorName); \ |
|
417 /*Update level if resource client level is already present for this resource.*/ \ |
|
418 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
419 pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
420 else \ |
|
421 pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
422 for(; pCL != NULL; pCL = pCL->iNextInList) \ |
|
423 { \ |
|
424 if(pCL->iClientId == pDR->iResourceId) \ |
|
425 { \ |
|
426 pCL->iLevel = depNode->iPropagatedLevel; \ |
|
427 break; \ |
|
428 } \ |
|
429 } \ |
|
430 if(!pCL) /*Create a new resource client level*/ \ |
|
431 { \ |
|
432 TheController->RemoveClientLevelFromPool(pCL); \ |
|
433 pCL->iClientId = pDR->iResourceId; \ |
|
434 pCL->iResourceId = pDepRes->iResourceId; \ |
|
435 pCL->iLevel = depNode->iPropagatedLevel; \ |
|
436 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
437 { \ |
|
438 LIST_PUSH(((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList); \ |
|
439 } \ |
|
440 else \ |
|
441 { \ |
|
442 LIST_PUSH(((DStaticPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList); \ |
|
443 } \ |
|
444 clientLevelCount--; \ |
|
445 } \ |
|
446 } \ |
|
447 if(traceEnabled && (aRequest.ClientId() & KIdMaskResourceWithDependencies)) \ |
|
448 { \ |
|
449 SPowerResourceClient res; \ |
|
450 SPowerResourceClient* pC = &res; \ |
|
451 pC->iClientId = aRequest.ClientId(); \ |
|
452 pC->iName = &KParentResource; \ |
|
453 DStaticPowerResource*pR = (DStaticPowerResource*)pDR; \ |
|
454 TUint aResourceId = pDR->iResourceId; \ |
|
455 TInt aNewState = aRequest.Level(); \ |
|
456 PRM_CLIENT_CHANGE_STATE_START_TRACE \ |
|
457 } \ |
|
458 DoRequest(aRequest); \ |
|
459 if(traceEnabled && (aRequest.ClientId() & KIdMaskResourceWithDependencies)) \ |
|
460 { \ |
|
461 SPowerResourceClient res; \ |
|
462 SPowerResourceClient* pC = &res; \ |
|
463 pC->iClientId = aRequest.ClientId(); \ |
|
464 pC->iName = &KParentResource; \ |
|
465 DStaticPowerResource*pR = (DStaticPowerResource*)pDR; \ |
|
466 TUint aResourceId = pDR->iResourceId; \ |
|
467 TInt aNewState = aRequest.Level(); \ |
|
468 TInt r = KErrNone; \ |
|
469 PRM_CLIENT_CHANGE_STATE_END_TRACE \ |
|
470 } \ |
|
471 pDR->iCachedLevel = aRequest.Level(); \ |
|
472 pDR->iLevelOwnerId = aRequest.ClientId(); \ |
|
473 if(pDR->iIdleListEntry) \ |
|
474 { \ |
|
475 pDR->iIdleListEntry->iCurrentLevel = aRequest.Level(); \ |
|
476 pDR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId(); \ |
|
477 } \ |
|
478 break; \ |
|
479 } \ |
|
480 case EIssueNotifications: \ |
|
481 { \ |
|
482 for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext) \ |
|
483 { \ |
|
484 pDepRes = (resourceTypePointer)depNode->iResource; \ |
|
485 if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId())) \ |
|
486 continue; \ |
|
487 depRequest.ResourceId() = pDepRes->iResourceId; \ |
|
488 depRequest.ClientId() = pDepRes->iLevelOwnerId; \ |
|
489 depRequest.Level() = pDepRes->iCachedLevel; \ |
|
490 depRequest.Resource() = pDepRes; \ |
|
491 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
492 ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications, \ |
|
493 originatorId, originatorName); \ |
|
494 else \ |
|
495 ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications, \ |
|
496 originatorId, originatorName); \ |
|
497 } \ |
|
498 TheController->CompleteNotifications(aRequest.ClientId(), pDR, aRequest.Level(), KErrNone, \ |
|
499 aRequest.ClientId()); \ |
|
500 break; \ |
|
501 } \ |
|
502 default: \ |
|
503 return KErrNotSupported; \ |
|
504 } \ |
|
505 return result; |
|
506 |
271 |
507 struct SPowerResourceClient; |
272 struct SPowerResourceClient; |
508 struct TPowerRequest; |
273 struct TPowerRequest; |
509 struct SPowerRequest; |
274 struct SPowerRequest; |
510 struct SPowerResourceClientLevel; |
275 struct SPowerResourceClientLevel; |