baseport/syborg/svpframebuffer/svpframebuffer.cpp
branchCompilerCompatibility
changeset 50 3a9a2481ac1c
parent 46 b6935a90ca64
child 119 931f2bbaabf7
equal deleted inserted replaced
47:a3637f7e2d6c 50:3a9a2481ac1c
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements
       
    15 *
       
    16 * Description: Minimalistic frame buffer driver
       
    17 *
       
    18 */
       
    19 #include <videodriver.h>
       
    20 #include "platform.h"
       
    21 #include <nkern.h>
       
    22 #include <kernel/kernel.h>
       
    23 #include <kernel/kern_priv.h>
       
    24 #include <kernel/kpower.h>
       
    25 
       
    26 #include <syborg_priv.h>
       
    27 #include "svpframebuffer.h"
       
    28 
       
    29 DLcdPowerHandler	*  DLcdPowerHandler::pLcd			= NULL;
       
    30 
       
    31 TPhysAddr Syborg::VideoRamPhys;
       
    32 TPhysAddr Syborg::VideoRamPhysSecure;		// Secure display memory
       
    33 
       
    34 TPhysAddr TSyborg::VideoRamPhys()
       
    35 {
       
    36   __KTRACE_OPT(KEXTENSION,Kern::Printf("TSyborg::VideoRamPhys: VideoRamPhys=0x%x", Syborg::VideoRamPhys));
       
    37   return Syborg::VideoRamPhys;
       
    38 }
       
    39 
       
    40 TPhysAddr TSyborg::VideoRamPhysSecure()
       
    41 {
       
    42   return Syborg::VideoRamPhysSecure;
       
    43 }
       
    44 
       
    45 LOCAL_C TInt DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
       
    46 {
       
    47   DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
       
    48   return pH->HalFunction(aFunction,a1,a2);
       
    49 }
       
    50 
       
    51 static void rxMsg(TAny* aPtr)
       
    52 {
       
    53   DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
       
    54   TMessageBase* pM = h.iMsgQ.iMessage;
       
    55   if(pM)
       
    56 	h.HandleMsg(pM);
       
    57 }
       
    58 
       
    59 static void power_up_dfc(TAny* aPtr)
       
    60 {
       
    61   ((DLcdPowerHandler*)aPtr)->PowerUpDfc();
       
    62 }
       
    63 
       
    64 void power_down_dfc(TAny* aPtr)
       
    65 {
       
    66   ((DLcdPowerHandler*)aPtr)->PowerDownDfc();
       
    67 }
       
    68 
       
    69 void DLcdPowerHandler::DisplayOn()
       
    70 { 
       
    71   PowerUpLcd(iSecureDisplay);
       
    72   iDisplayOn = ETrue;
       
    73 }
       
    74 
       
    75 void DLcdPowerHandler::DisplayOff()
       
    76 {
       
    77   PowerDownLcd();
       
    78   iDisplayOn = EFalse;
       
    79 }
       
    80 
       
    81 void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
       
    82  {
       
    83    if(aSecure)
       
    84 	 {
       
    85 	   if(!iSecureDisplay)
       
    86 		 {
       
    87 		   DisplayOff();
       
    88 		   iSecureDisplay = ETrue;
       
    89 		   DisplayOn();
       
    90 		 }
       
    91 	 }
       
    92    else
       
    93 	 {
       
    94 	   if(iSecureDisplay)
       
    95 		 {
       
    96 		   DisplayOff();
       
    97 		   iSecureDisplay = EFalse;
       
    98 		   DisplayOn();
       
    99 		 }
       
   100 	 }
       
   101  }
       
   102 
       
   103 void DLcdPowerHandler::PowerUpDfc()
       
   104 {
       
   105   DisplayOn();
       
   106   PowerUpDone();
       
   107 }
       
   108 
       
   109 void DLcdPowerHandler::PowerDownDfc()
       
   110 {
       
   111   DisplayOff();
       
   112 
       
   113   PowerDownDone();
       
   114 }
       
   115 
       
   116 void DLcdPowerHandler::PowerDown(TPowerState)
       
   117 {
       
   118   iPowerDownDfc.Enque();
       
   119 }
       
   120 
       
   121 void DLcdPowerHandler::PowerUp()
       
   122 {
       
   123   iPowerUpDfc.Enque();
       
   124 }
       
   125 
       
   126 void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
       
   127 {
       
   128 
       
   129   WriteReg(iPortAddr, FB_ENABLED, 0);
       
   130   WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys);
       
   131 
       
   132   WriteReg(iPortAddr, FB_BLANK, 0);
       
   133   WriteReg(iPortAddr, FB_BPP, 32);
       
   134   WriteReg(iPortAddr, FB_COLOR_ORDER, 0);
       
   135   WriteReg(iPortAddr, FB_BYTE_ORDER, 0);
       
   136   WriteReg(iPortAddr, FB_PIXEL_ORDER, 0);
       
   137   WriteReg(iPortAddr, FB_INT_MASK, 0);
       
   138   WriteReg(iPortAddr, FB_ENABLED, 1);
       
   139 
       
   140 // We don't write the Height and Width of the framebuffer, this is controlled by the board model
       
   141 
       
   142 }
       
   143 
       
   144 void DLcdPowerHandler::PowerDownLcd()
       
   145 {
       
   146   WriteReg(iPortAddr, FB_BLANK, 1);
       
   147 }
       
   148 
       
   149 DLcdPowerHandler::DLcdPowerHandler()
       
   150 	:	DPowerHandler(KLitLcd),
       
   151 		iMsgQ(rxMsg,this,NULL,1),
       
   152 		iPowerUpDfc(&power_up_dfc,this,6),
       
   153 		iPowerDownDfc(&power_down_dfc,this,7)
       
   154 {
       
   155 }
       
   156 
       
   157 void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
       
   158 {
       
   159   anInfo.iWindowHandleValid = EFalse;
       
   160   anInfo.iWindowHandle = NULL;
       
   161   anInfo.iScreenAddressValid = ETrue;
       
   162   anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress());
       
   163   anInfo.iScreenSize.iWidth = iVideoInfo.iSizeInPixels.iWidth;
       
   164   anInfo.iScreenSize.iHeight = iVideoInfo.iSizeInPixels.iHeight;
       
   165 }
       
   166 
       
   167 void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg)
       
   168 {
       
   169   if(aMsg->iValue)
       
   170 	DisplayOn();
       
   171   else
       
   172 	DisplayOff();
       
   173   aMsg->Complete(KErrNone,ETrue);
       
   174 }
       
   175 
       
   176 void DLcdPowerHandler::WsSwitchOnScreen()
       
   177 {
       
   178   TThreadMessage& m = Kern::Message();
       
   179   m.iValue = ETrue;
       
   180   m.SendReceive(&iMsgQ);
       
   181 }
       
   182 
       
   183 void DLcdPowerHandler::WsSwitchOffScreen()
       
   184 {
       
   185   TThreadMessage& m = Kern::Message();
       
   186   m.iValue = EFalse;
       
   187   m.SendReceive(&iMsgQ);
       
   188 }
       
   189 
       
   190 TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
       
   191 {
       
   192   NKern::FMWait(&iLock);
       
   193   if(aSecure)
       
   194 	aInfo = iSecureVideoInfo;
       
   195   else
       
   196 	aInfo = iVideoInfo;
       
   197   NKern::FMSignal(&iLock);
       
   198   return KErrNone;
       
   199 }
       
   200 
       
   201 TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
       
   202 {
       
   203   if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
       
   204 	return KErrArgument;
       
   205   
       
   206   NKern::FMWait(&iLock);
       
   207   aInfo = iVideoInfo;
       
   208   NKern::FMSignal(&iLock);
       
   209 
       
   210   if(aMode != aInfo.iDisplayMode)
       
   211 	{
       
   212 	  aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
       
   213 	  aInfo.iIsPalettized       = KConfigIsPalettized;
       
   214 	  aInfo.iOffsetBetweenLines = iVideoInfo.iSizeInPixels.iWidth*4; //Offset depends on width of framebuffer
       
   215 	  aInfo.iBitsPerPixel       = KConfigBitsPerPixel;
       
   216 	}
       
   217   return KErrNone;
       
   218 }
       
   219 
       
   220 TInt DLcdPowerHandler::AllocateFrameBuffer()
       
   221 {
       
   222 	// Allocate physical RAM for video
       
   223 	
       
   224 	//read width and height of display from board model and allocate size
       
   225 	TInt width = ReadReg(iPortAddr, FB_WIDTH);
       
   226 	TInt height = ReadReg(iPortAddr, FB_HEIGHT);
       
   227 	
       
   228 	iSize = 4*width*height; //*4 as 32bits per pixel
       
   229 
       
   230 	NKern::ThreadEnterCS();
       
   231 	TInt r = Epoc::AllocPhysicalRam(iSize,Syborg::VideoRamPhys);
       
   232 	if (r != KErrNone)
       
   233 	{
       
   234 	        NKern::ThreadLeaveCS();
       
   235 		Kern::Fault("AllocVideoRam",r);
       
   236 	}
       
   237 
       
   238 	// Map the video RAM
       
   239 	ivRamPhys = TSyborg::VideoRamPhys();
       
   240 
       
   241 	r = DPlatChunkHw::New(iChunk,ivRamPhys,iSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   242 
       
   243 	NKern::ThreadLeaveCS();
       
   244 
       
   245 	if(r != KErrNone)
       
   246 	  return r;
       
   247 
       
   248 	TUint* pV = (TUint*)iChunk->LinearAddress();
       
   249 
       
   250 	// Allocate physical RAM for secure display
       
   251 	NKern::ThreadEnterCS();
       
   252 	r = Epoc::AllocPhysicalRam(iSize,Syborg::VideoRamPhysSecure);
       
   253 	if (r != KErrNone)
       
   254 	{
       
   255 	        NKern::ThreadLeaveCS();
       
   256 		Kern::Fault("AllocVideoRam 2",r);
       
   257 	}
       
   258 	iSecurevRamPhys = ivRamPhys + iSize;
       
   259 	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,iSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   260 
       
   261 	NKern::ThreadLeaveCS();
       
   262 
       
   263 	if(r2 != KErrNone)
       
   264 	  return r2;
       
   265 
       
   266 	TUint* pV2 = (TUint*)iSecureChunk->LinearAddress();
       
   267 
       
   268 	//width and height set by reading board model
       
   269 	iVideoInfo.iSizeInPixels.iWidth  = width;
       
   270 	iVideoInfo.iSizeInPixels.iHeight = height;
       
   271 
       
   272 	//offset between lines depends on width of screen
       
   273 	iVideoInfo.iOffsetBetweenLines = width*4;
       
   274 
       
   275 	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
       
   276 	iVideoInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel;
       
   277 	
       
   278 	iVideoInfo.iIsPalettized = KConfigIsPalettized;
       
   279 	iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
       
   280 	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
       
   281 	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
       
   282 	iVideoInfo.iIsMono = KConfigIsMono;
       
   283 	iVideoInfo.iVideoAddress = (TInt)pV;
       
   284 	iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
       
   285 	iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
       
   286 
       
   287 	iSecureVideoInfo = iVideoInfo;
       
   288 	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
       
   289 
       
   290 	// Alloc Physical RAM for the Composition Buffers used by OpenWF
       
   291 	// double and round the page size
       
   292 	TUint round = 2*Kern::RoundToPageSize(iSize);
       
   293 
       
   294 	r=Epoc::AllocPhysicalRam(round , iCompositionPhysical);
       
   295 	if(r!=KErrNone)
       
   296 		{
       
   297 		return r;
       
   298 		}
       
   299 	
       
   300 	return KErrNone;
       
   301 }
       
   302 
       
   303 
       
   304 TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
       
   305 {
       
   306   if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
       
   307 	return KErrArgument;
       
   308 
       
   309   // store the current mode
       
   310   iVideoInfo.iDisplayMode = aMode;
       
   311 
       
   312   // store the current mode for secure screen
       
   313   iSecureVideoInfo.iDisplayMode = aMode;
       
   314 
       
   315   return KErrNone;
       
   316 }
       
   317 
       
   318 TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
   319 {
       
   320   TInt r=KErrNone;
       
   321   switch(aFunction)
       
   322 	{
       
   323 	case EDisplayHalScreenInfo:
       
   324 	  {
       
   325 		TPckgBuf<TScreenInfoV01> vPckg;
       
   326 		ScreenInfo(vPckg());
       
   327 		Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
   328 		break;
       
   329 	  }
       
   330 	case EDisplayHalWsRegisterSwitchOnScreenHandling:
       
   331 	  {
       
   332 		iWsSwitchOnScreen=(TBool)a1;
       
   333 		break;
       
   334 	  }
       
   335 	case EDisplayHalWsSwitchOnScreen:
       
   336 	  {
       
   337 		WsSwitchOnScreen();
       
   338 		break;
       
   339 	  }
       
   340 	case EDisplayHalModeCount:
       
   341 	  {
       
   342 		TInt ndm = KConfigLcdNumberOfDisplayModes;
       
   343 		kumemput32(a1, &ndm, sizeof(ndm));
       
   344 		break;
       
   345 	  }
       
   346 	case EDisplayHalSetMode:
       
   347 	  {
       
   348 		__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode"));
       
   349 		__SECURE_KERNEL(
       
   350 						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
       
   351 						return KErrPermissionDenied;
       
   352 						)
       
   353 		  r = SetDisplayMode((TInt)a1);
       
   354 		break;
       
   355 	  }
       
   356 	case EDisplayHalMode:
       
   357 	  {
       
   358 		kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
       
   359 		r = KErrNone;
       
   360 		break;
       
   361 	  }
       
   362 	case EDisplayHalSetPaletteEntry:
       
   363 	  {
       
   364 		__SECURE_KERNEL(
       
   365 						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
       
   366 						return KErrPermissionDenied;
       
   367 						)
       
   368 		  r = KErrNotSupported;
       
   369 		break;
       
   370 	  }
       
   371 	case EDisplayHalPaletteEntry:
       
   372 	  {
       
   373 		TInt entry;
       
   374 		kumemget32(&entry, a1, sizeof(TInt));
       
   375 		r = KErrNotSupported;
       
   376 		break;
       
   377 	  }
       
   378 	case EDisplayHalSetState:
       
   379 	  {
       
   380 		__SECURE_KERNEL(
       
   381 						if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
       
   382 						return KErrPermissionDenied;
       
   383 						)
       
   384 		  if((TBool)a1)
       
   385 			WsSwitchOnScreen();
       
   386 		  else
       
   387 			WsSwitchOffScreen();
       
   388 		break;
       
   389 	  }
       
   390 	case EDisplayHalState:
       
   391 	  {
       
   392 		kumemput32(a1, &iDisplayOn, sizeof(TBool));
       
   393 		break;
       
   394 	  }
       
   395 	case EDisplayHalColors:
       
   396 	  {
       
   397 		TInt mdc = 1<<24;
       
   398 		kumemput32(a1, &mdc, sizeof(mdc));
       
   399 		break;
       
   400 	  }
       
   401 	case EDisplayHalCurrentModeInfo:
       
   402 	  {
       
   403 		TPckgBuf<TVideoInfoV01> vPckg;
       
   404 		r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
       
   405 		if(KErrNone == r)
       
   406 		  Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
   407 		break;
       
   408 	  }
       
   409 	case EDisplayHalSpecifiedModeInfo:
       
   410 	  {
       
   411 		TPckgBuf<TVideoInfoV01> vPckg;
       
   412 		TInt mode;
       
   413 		kumemget32(&mode, a1, sizeof(mode));
       
   414 		r = GetSpecifiedDisplayModeInfo(mode, vPckg());
       
   415 		if(KErrNone == r)
       
   416 		  Kern::InfoCopy(*(TDes8*)a2,vPckg);
       
   417 		break;
       
   418 	  }	
       
   419 	case EDisplayHalSecure:
       
   420 	  {
       
   421 		kumemput32(a1, &iSecureDisplay, sizeof(TBool));
       
   422 		break;
       
   423 	  }
       
   424 	case EDisplayHalSetSecure:
       
   425 	  {
       
   426 		__SECURE_KERNEL(
       
   427 						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
       
   428 						return KErrPermissionDenied;
       
   429 						)
       
   430 		  SwitchDisplay((TBool)a1);
       
   431 		break;
       
   432 	  }
       
   433 	default:
       
   434 	  {
       
   435 		r = KErrNotSupported;
       
   436 		break;
       
   437 	  }			
       
   438 	}
       
   439   return r;
       
   440 }
       
   441 
       
   442 TInt DLcdPowerHandler::Create()
       
   443 {
       
   444 	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create") );
       
   445 	pLcd			= this;
       
   446 
       
   447 	iPortAddr = KHwBaseClcd;
       
   448 
       
   449 	TInt r = AllocateFrameBuffer();
       
   450 	if(r == KErrNone)
       
   451 		{
       
   452 		r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this);
       
   453 		}
       
   454 	    
       
   455 	if(r != KErrNone)
       
   456 		{
       
   457 		__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create failed %d", r) );
       
   458 		return r;
       
   459 		}
       
   460 
       
   461 	iPowerUpDfc.SetDfcQ(iDfcQ);
       
   462 	iPowerDownDfc.SetDfcQ(iDfcQ);
       
   463 	iMsgQ.SetDfcQ(iDfcQ);
       
   464 	iMsgQ.Receive();
       
   465 
       
   466 	Add();
       
   467 	DisplayOn();
       
   468 
       
   469 	return KErrNone;
       
   470 }
       
   471 
       
   472 /**
       
   473  * Register the call back function.
       
   474  * Components interested in receiving notification of the Vsync interrupt should register a callback function.
       
   475  */
       
   476 EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr)
       
   477 {
       
   478 	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) );
       
   479 
       
   480 	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
       
   481 
       
   482 	if(aCbPtr != NULL)
       
   483 		{
       
   484 		if ( pLcd->iAppCallBk[0] == NULL  )
       
   485 			{
       
   486 			pLcd->iAppCallBk[0] = aCbPtr;
       
   487 			}
       
   488 		else
       
   489 			{
       
   490 			if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn))
       
   491 				{
       
   492 				pLcd->iAppCallBk[1] = aCbPtr;
       
   493 				}
       
   494 			else
       
   495 				{
       
   496 				__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
   497 				return KErrInUse;
       
   498 				}
       
   499 			}
       
   500 
       
   501 		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
   502 		__KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::RegisterCallBack ok %08x\n",aCbPtr->iCbFn) );
       
   503 		return KErrNone;
       
   504 		}
       
   505 	else
       
   506 		{
       
   507 		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
   508 		__KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL"));
       
   509 		return KErrArgument;
       
   510 		}
       
   511 }
       
   512 
       
   513 
       
   514 /**
       
   515  *DeRegister the call back function
       
   516  */
       
   517 EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr)
       
   518 {
       
   519 	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
       
   520 
       
   521 	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
       
   522 	if(aCbPtr != NULL)
       
   523 		{
       
   524 	    if( pLcd->iAppCallBk[0] != NULL)
       
   525 			{
       
   526 			if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) )
       
   527 				{
       
   528 				pLcd->iAppCallBk[0] = NULL;
       
   529 				}
       
   530 			}
       
   531 
       
   532 		if( pLcd->iAppCallBk[1] != NULL)
       
   533 			{
       
   534 			if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) )
       
   535 				{
       
   536 				pLcd->iAppCallBk[1] = NULL;
       
   537 				}
       
   538 			}
       
   539 		}
       
   540 	__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
   541 	__KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
       
   542 }
       
   543 
       
   544 /**
       
   545 	Constructor
       
   546 */
       
   547 DDisplayPddSyborg::DDisplayPddSyborg():
       
   548 	iPendingBuffer(NULL),
       
   549 	iActiveBuffer(NULL),
       
   550 	iChunk(NULL),
       
   551 	iLcdCallback(NULL),
       
   552 	iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority)
       
   553 	{
       
   554 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::DDisplayPddSyborg\n");
       
   555 
       
   556 	iPostFlag = EFalse;
       
   557 	}
       
   558 
       
   559 /**
       
   560 	Destructor
       
   561 */
       
   562 DDisplayPddSyborg::~DDisplayPddSyborg()
       
   563 	{
       
   564 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::~DDisplayPddSyborg()  \n");
       
   565 
       
   566 	if(iLcdCallback)
       
   567 		{
       
   568 		DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ;
       
   569 		delete iLcdCallback;
       
   570 		iLcdCallback = NULL;
       
   571 		}
       
   572 
       
   573 	//The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point.
       
   574 	if (iDfcQ)
       
   575 		{
       
   576 		iDfcQ=NULL;
       
   577 		}
       
   578 
       
   579 	DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0);
       
   580 
       
   581 	if(chunk)
       
   582 		{
       
   583 		Kern::ChunkClose(chunk);
       
   584 		}
       
   585 
       
   586 	}
       
   587 
       
   588 /**
       
   589     Set the Legacy Mode by setting the appropriate Frame control value.
       
   590 
       
   591 */
       
   592 TInt DDisplayPddSyborg::SetLegacyMode()
       
   593 	{
       
   594 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::SetLegacyMode()\n");
       
   595 
       
   596     return KErrNone;
       
   597 	}
       
   598 
       
   599 /**
       
   600     Set the GCE mode by posting a composition buffer.
       
   601 
       
   602 */
       
   603 TInt DDisplayPddSyborg::SetGceMode()
       
   604 	{
       
   605 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::SetGceMode()\n");
       
   606 
       
   607     PostCompositionBuffer(&iLdd->iCompositionBuffer[0]);
       
   608     return KErrNone;
       
   609 	}
       
   610 
       
   611 /**
       
   612 	@param	aDegOfRot  The requested rotation
       
   613 	@return KErrNone
       
   614 */
       
   615 TInt DDisplayPddSyborg::SetRotation(RDisplayChannel::TDisplayRotation aDegOfRot)
       
   616 	{
       
   617 	return KErrNone;
       
   618 	}
       
   619 
       
   620 /**
       
   621     Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
       
   622     with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
       
   623     be posted next. Layer 3 is associated with user buffers.
       
   624 
       
   625 	@param	aNode  Pointer to the User buffer to post.
       
   626 */
       
   627 TInt DDisplayPddSyborg::PostUserBuffer(TBufferNode* aNode)
       
   628 	{
       
   629 
       
   630 	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostUserBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
       
   631 
       
   632 	if(iPendingBuffer)
       
   633 		{
       
   634 		iPendingBuffer->iState = EBufferFree;
       
   635 		if (!(iPendingBuffer->iType == EBufferTypeUser) )
       
   636 			{
       
   637 			iPendingBuffer->iFree  = ETrue;
       
   638 			}
       
   639 		}
       
   640 
       
   641 	aNode->iState   = EBufferPending;
       
   642 	iPendingBuffer	= aNode;
       
   643 	iPostFlag		= ETrue;
       
   644 	
       
   645   	// Activate the posted buffer
       
   646 	TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
       
   647   	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
       
   648 	/* Queue a DFC to complete the request*/
       
   649 	iVSyncDfc.Enque();
       
   650 
       
   651 	return KErrNone;
       
   652 	}
       
   653 
       
   654 /**
       
   655     Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
       
   656     with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
       
   657     be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively.
       
   658 
       
   659 	@param	aNode  Pointer to the Composition buffer to post.
       
   660 */
       
   661 TInt DDisplayPddSyborg::PostCompositionBuffer(TBufferNode* aNode)
       
   662 	{
       
   663 
       
   664 	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostCompositionBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
       
   665 
       
   666 	if(iPendingBuffer)
       
   667 		{
       
   668 		iPendingBuffer->iState = EBufferFree;
       
   669 		if (iPendingBuffer->iType == EBufferTypeUser)
       
   670 			{
       
   671 			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
       
   672 			}
       
   673 		else
       
   674 			{
       
   675 			iPendingBuffer->iFree  = ETrue;
       
   676 			}
       
   677 		}
       
   678 	aNode->iState	= EBufferPending;
       
   679 	aNode->iFree	= EFalse;
       
   680 	iPendingBuffer	= aNode;
       
   681 	iPostFlag		= ETrue;
       
   682 
       
   683   	// Activate the posted buffer
       
   684 	TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
       
   685   	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
       
   686 	
       
   687 	/* Queue a DFC to complete the request*/
       
   688 	iVSyncDfc.Enque();
       
   689 
       
   690 	return KErrNone;
       
   691 	}
       
   692 
       
   693 /**
       
   694     Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
       
   695     with V Sync so it will take affect in the next V Sync after that) and also set the Legacy Buffer as the buffer to
       
   696     be posted next.Layer 0 is associated with legacy buffer.
       
   697 
       
   698 	@param	aNode  Pointer to the Composition buffer to post.
       
   699 */
       
   700 TInt DDisplayPddSyborg::PostLegacyBuffer()
       
   701 	{
       
   702 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::PostLegacyBuffer() \n");
       
   703 
       
   704 	if(iPendingBuffer)
       
   705 		{
       
   706 		iPendingBuffer->iState = EBufferFree;
       
   707 		if (iPendingBuffer->iType == EBufferTypeUser)
       
   708 			{
       
   709 
       
   710 			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
       
   711 			}
       
   712 		else
       
   713 			{
       
   714 			iPendingBuffer->iFree  = ETrue;
       
   715 			}
       
   716 		}
       
   717 
       
   718 
       
   719 	iLdd->iLegacyBuffer[0].iState		= EBufferPending;
       
   720 	iLdd->iLegacyBuffer[0].iFree		= EFalse;
       
   721 	iPendingBuffer						= &iLdd->iLegacyBuffer[0];
       
   722 	iPostFlag		= ETrue;
       
   723 
       
   724   	// Activate the posted buffer
       
   725   	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, TSyborg::VideoRamPhys() );
       
   726 
       
   727 	/* Queue a DFC to complete the request*/
       
   728 	iVSyncDfc.Enque();
       
   729 
       
   730 	return KErrNone;
       
   731 	}
       
   732 
       
   733 /**
       
   734     Handles device specific operations when a close message has been sent to the Logical Channel.
       
   735 
       
   736 */
       
   737 TInt DDisplayPddSyborg::CloseMsg()
       
   738 	{
       
   739 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::CloseMsg()\n");
       
   740 
       
   741 	iPendingBuffer  = NULL;
       
   742 	iActiveBuffer	= NULL;
       
   743 
       
   744 	iVSyncDfc.Cancel();
       
   745     return KErrNone;
       
   746 	}
       
   747 
       
   748 /**
       
   749     Called by the LDD's DoCreate function to handle the device specific part of opening the channel.
       
   750     (DoCreate is called by RDisplayChannel::Open)
       
   751 
       
   752 	@param aUnit	The screen unit
       
   753 
       
   754     @return KErrNone if successful; or one of the other system wide error codes.
       
   755 */
       
   756 TInt DDisplayPddSyborg::CreateChannelSetup(TInt aUnit)
       
   757 	{
       
   758 	__GCE_DEBUG_PRINT("DDisplayPddSyborg::CreateChannelSetup\n");
       
   759 
       
   760 	iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo;
       
   761 	iLdd->iUnit = aUnit;
       
   762 
       
   763 	iLdd->iDisplayInfo.iAvailableRotations			= RDisplayChannel::ERotationNormal;
       
   764 	iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines	= iScreenInfo.iOffsetBetweenLines;
       
   765 	iLdd->iDisplayInfo.iNormal.iHeight				= iScreenInfo.iSizeInPixels.iHeight;
       
   766 	iLdd->iDisplayInfo.iNormal.iWidth				= iScreenInfo.iSizeInPixels.iWidth;
       
   767 	iLdd->iDisplayInfo.iNumCompositionBuffers		= KDisplayCBMax;
       
   768 	iLdd->iDisplayInfo.iBitsPerPixel				= iScreenInfo.iBitsPerPixel;
       
   769     iLdd->iDisplayInfo.iRefreshRateHz = 60;
       
   770 
       
   771 
       
   772 	switch (iScreenInfo.iBitsPerPixel)
       
   773 		{
       
   774 		case 16:
       
   775 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565;
       
   776 			break;
       
   777 		case 24:
       
   778 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888;
       
   779 			break;
       
   780 		case 32:
       
   781 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888;
       
   782 			break;
       
   783 		default:
       
   784 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown;
       
   785 			break;
       
   786 		}
       
   787 
       
   788 	iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal;
       
   789 
       
   790 	// Open shared chunk to the composition framebuffer
       
   791 
       
   792 	DChunk* chunk = 0;
       
   793 	TLinAddr chunkKernelAddr  = 0;
       
   794 	TUint32 chunkMapAttr = 0;
       
   795 
       
   796 	// round to twice the page size
       
   797 	TUint round  =  2*Kern::RoundToPageSize(DLcdPowerHandler::pLcd->iSize);
       
   798 
       
   799 	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::CreateChannelSetup DLcdPowerHandler::pLcd->iSize  = %d\n", DLcdPowerHandler::pLcd->iSize );
       
   800 
       
   801 	TChunkCreateInfo info;
       
   802 	info.iType					 = TChunkCreateInfo::ESharedKernelMultiple;
       
   803 	info.iMaxSize				 = round;
       
   804 	info.iMapAttr				 = EMapAttrFullyBlocking;
       
   805 	info.iOwnsMemory			 = EFalse;
       
   806 	info.iDestroyedDfc			 = 0;
       
   807 
       
   808 	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
       
   809 
       
   810 	__GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr  = %08x\n", chunkKernelAddr );
       
   811 
       
   812 	if( r == KErrNone)
       
   813 		{
       
   814 		// map our chunk
       
   815 		r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical);
       
   816 		__GCE_DEBUG_PRINT2("Mapping chunk %d", r);
       
   817 		if(r != KErrNone)
       
   818 			{
       
   819 			Kern::ChunkClose(chunk);
       
   820 			}
       
   821 		}
       
   822 
       
   823 	if ( r!= KErrNone)
       
   824 		{
       
   825 		return r;
       
   826 		}
       
   827 
       
   828 	iChunk	= chunk;
       
   829 
       
   830 	// init CB 0
       
   831 	iLdd->iCompositionBuffer[0].iType			= EBufferTypeComposition;
       
   832 	iLdd->iCompositionBuffer[0].iBufferId		= 0;
       
   833 	iLdd->iCompositionBuffer[0].iFree			= ETrue;
       
   834 	iLdd->iCompositionBuffer[0].iState			= EBufferFree;
       
   835 	iLdd->iCompositionBuffer[0].iAddress		= chunkKernelAddr;
       
   836 	iLdd->iCompositionBuffer[0].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr);
       
   837 	iLdd->iCompositionBuffer[0].iChunk			= chunk;
       
   838 	iLdd->iCompositionBuffer[0].iHandle			= 0;
       
   839 	iLdd->iCompositionBuffer[0].iOffset			= 0;
       
   840 	iLdd->iCompositionBuffer[0].iSize			= DLcdPowerHandler::pLcd->iSize;
       
   841 	iLdd->iCompositionBuffer[0].iPendingRequest = 0;
       
   842 
       
   843 	// init CB 1
       
   844 	iLdd->iCompositionBuffer[1].iType			= EBufferTypeComposition;
       
   845 	iLdd->iCompositionBuffer[1].iBufferId		= 1;
       
   846 	iLdd->iCompositionBuffer[1].iFree			= ETrue;
       
   847 	iLdd->iCompositionBuffer[1].iState			= EBufferFree;
       
   848 	iLdd->iCompositionBuffer[1].iAddress		= chunkKernelAddr + DLcdPowerHandler::pLcd->iSize;
       
   849 	iLdd->iCompositionBuffer[1].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr + DLcdPowerHandler::pLcd->iSize);
       
   850 	iLdd->iCompositionBuffer[1].iChunk			= chunk;
       
   851 	iLdd->iCompositionBuffer[1].iHandle			= 0;
       
   852 	iLdd->iCompositionBuffer[1].iOffset			= DLcdPowerHandler::pLcd->iSize;
       
   853 	iLdd->iCompositionBuffer[1].iSize			= DLcdPowerHandler::pLcd->iSize;
       
   854 	iLdd->iCompositionBuffer[1].iPendingRequest = 0;
       
   855 
       
   856 	iLdd->iCompositionBuffIdx					= 0;
       
   857 	//Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread.
       
   858 	iDfcQ= DLcdPowerHandler::pLcd->iDfcQ;
       
   859 
       
   860 	// Set the Post DFC.
       
   861 	iVSyncDfc.SetDfcQ(iDfcQ);
       
   862 
       
   863 
       
   864 	return KErrNone;
       
   865 	}
       
   866 
       
   867 /**
       
   868 Detect whether a post operation is pending
       
   869 */
       
   870 TBool DDisplayPddSyborg::PostPending()
       
   871 	{
       
   872 	return (iPendingBuffer != NULL);
       
   873 	}
       
   874 
       
   875 /**
       
   876 	Return the DFC queue to be used for this device.
       
   877  */
       
   878 TDfcQue * DDisplayPddSyborg::DfcQ(TInt aUnit)
       
   879 	{
       
   880 	return iDfcQ;
       
   881 	}
       
   882 
       
   883 void DDisplayPddSyborg::VSyncDfcFn(TAny* aChannel)
       
   884 	{
       
   885 	DDisplayPddSyborg * channel =(DDisplayPddSyborg*)aChannel;
       
   886 
       
   887 	if (channel->iPostFlag)
       
   888 		{
       
   889 		 channel->iPostFlag = EFalse;
       
   890 
       
   891 		if (channel->iActiveBuffer)
       
   892 			{
       
   893 			//When a User buffer is registered its iFree member becomes EFalse and Deregister sets it
       
   894 			//back to ETrue. Composition and Legacy buffers are not free when they are in the pending or
       
   895 			//active state.
       
   896 			if (channel->iActiveBuffer->iType == EBufferTypeUser)
       
   897 				{
       
   898 				channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone);
       
   899 				}
       
   900 			else
       
   901 				{
       
   902 				channel->iActiveBuffer->iFree	= ETrue;
       
   903 				}
       
   904 
       
   905 			channel->iActiveBuffer->iState		= EBufferFree;
       
   906 
       
   907 
       
   908 			//If no buffer was available during a call to GetCompositionBuffer the active buffer has
       
   909 			//been returned as the next available one, so we must set the buffer to the proper state before we
       
   910 			//send the notification.
       
   911 			TInt pendingIndex = channel->iLdd->iPendingIndex[RDisplayChannel::EReqGetCompositionBuffer];
       
   912 			if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq)
       
   913 			{
       
   914 				if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq->IsReady())
       
   915 				{
       
   916 				channel->iActiveBuffer->iState = EBufferCompose;
       
   917 				channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer,KErrNone);
       
   918 				}
       
   919 
       
   920 			}
       
   921 
       
   922 			channel->iActiveBuffer				= NULL;
       
   923 			}
       
   924 
       
   925 		if (channel->iPendingBuffer)
       
   926 			{
       
   927 			__GCE_DEBUG_PRINT2("DDisplayPddSyborg::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress);
       
   928 			channel->iActiveBuffer			= channel->iPendingBuffer;
       
   929 			channel->iActiveBuffer->iState	= EBufferActive;
       
   930 			channel->iPendingBuffer			= NULL;
       
   931 
       
   932 			channel->RequestComplete(RDisplayChannel::EReqWaitForPost,  KErrNone);
       
   933 			}
       
   934 		}
       
   935 	}
       
   936 //*****************************************************************
       
   937 //DDisplayPddFactory
       
   938 //*****************************************************************/
       
   939 
       
   940 
       
   941 /**
       
   942 	Constructor
       
   943 */
       
   944 DDisplayPddFactory::DDisplayPddFactory()
       
   945 	{
       
   946 	__GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n");
       
   947 
       
   948 	iVersion		= TVersion(KDisplayChMajorVersionNumber,
       
   949                       KDisplayChMinorVersionNumber,
       
   950                       KDisplayChBuildVersionNumber);
       
   951 	}
       
   952 
       
   953 /**
       
   954 	PDD factory function. Creates a PDD object.
       
   955 
       
   956 	@param  aChannel  A pointer to an PDD channel object which will be initialised on return.
       
   957 
       
   958 	@return KErrNone  if object successfully allocated, KErrNoMemory if not.
       
   959 */
       
   960 TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
       
   961 	{
       
   962 	DDisplayPddSyborg *device= new DDisplayPddSyborg() ;
       
   963 	aChannel=device;
       
   964 	if (!device)
       
   965 		{
       
   966 		return KErrNoMemory;
       
   967 		}
       
   968 	return KErrNone;
       
   969 	}
       
   970 
       
   971 
       
   972 /**
       
   973     Set the Pdd name and return error code
       
   974 */
       
   975 TInt DDisplayPddFactory::Install()
       
   976 	{
       
   977 	__GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n");
       
   978 
       
   979 	TBuf<32> name(RDisplayChannel::Name());
       
   980 	_LIT(KPddExtension,".pdd");
       
   981 	name.Append(KPddExtension);
       
   982 	return SetName(&name);
       
   983 	}
       
   984 
       
   985 
       
   986 void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const
       
   987 	{
       
   988 	//Not supported
       
   989 	}
       
   990 
       
   991 
       
   992 /**
       
   993     Validate version and number of units.
       
   994 */
       
   995 TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
       
   996 	{
       
   997 	if (!Kern::QueryVersionSupported(iVersion,aVer))
       
   998 		{
       
   999 		return KErrNotSupported;
       
  1000 		}
       
  1001 
       
  1002 	if (aUnit != 0)
       
  1003 		{
       
  1004 		return KErrNotSupported;
       
  1005 		}
       
  1006 
       
  1007 	return KErrNone;
       
  1008 	}
       
  1009 
       
  1010 DECLARE_EXTENSION_PDD()
       
  1011 /**
       
  1012 	"Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called
       
  1013 
       
  1014 	@return pointer to the PDD factory object.
       
  1015 */
       
  1016 	{
       
  1017 	__GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n");
       
  1018 	return new DDisplayPddFactory ;
       
  1019 	}
       
  1020 
       
  1021 
       
  1022 DECLARE_STANDARD_EXTENSION()
       
  1023 {
       
  1024   TInt r = KErrNoMemory;
       
  1025   DLcdPowerHandler* pH=new DLcdPowerHandler;
       
  1026   if(pH)
       
  1027 	{
       
  1028 	r = pH->Create();
       
  1029 	if ( r == KErrNone)
       
  1030 		{
       
  1031 		TInt r = Kern::DfcQCreate(pH->iDfcQ, 29 , &KLitLcd);
       
  1032 
       
  1033 		if(r!=KErrNone)
       
  1034 		{
       
  1035 			return r;
       
  1036 		}
       
  1037 
       
  1038 		DDisplayPddFactory * device = new DDisplayPddFactory;
       
  1039 
       
  1040 		if (device==NULL)
       
  1041 			{
       
  1042 			r=KErrNoMemory;
       
  1043 			}
       
  1044 		else
       
  1045 			{
       
  1046 			r=Kern::InstallPhysicalDevice(device);
       
  1047 			}
       
  1048 
       
  1049 		#ifdef CPU_AFFINITY_ANY
       
  1050         NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny);
       
  1051 		#endif
       
  1052 
       
  1053 		__KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r));
       
  1054 
       
  1055 		}
       
  1056 	}
       
  1057   
       
  1058   return r;
       
  1059 }