Automatic merge from PDK_3.0.h CompilerCompatibility
authorWilliam Roberts <williamr@symbian.org>
Sun, 14 Mar 2010 13:16:31 +0000
branchCompilerCompatibility
changeset 50 3a9a2481ac1c
parent 47 a3637f7e2d6c (current diff)
parent 48 34cd6bf038ac (diff)
child 59 62a56fb37080
Automatic merge from PDK_3.0.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applications/Symbian_MiniGUI_TestApp/BLD.INF	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,21 @@
+/*******************************************************************************
+* Copyright (c) 2009 Accenture
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Accenture - Johnathan White
+
+*******************************************************************************/
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_EXPORTS
+grid.iby \epoc32\rom\include\grid.iby
+
+PRJ_MMPFILES
+grid
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applications/Symbian_MiniGUI_TestApp/Grid.iby	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,21 @@
+/*******************************************************************************
+* Copyright (c) 2009 Accenture
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Accenture - Johnathan White
+
+*******************************************************************************/
+
+#ifndef __SYMBIANMINIGUI_TESTAPP_IBY__
+#define __SYMBIANMINIGUI_TESTAPP_IBY__
+
+
+//actual logo console app
+file=\epoc32\release\armv5\urel\grid.exe sys\bin\grid.exe
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applications/Symbian_MiniGUI_TestApp/Grid.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,18 @@
+/*******************************************************************************
+* Copyright (c) 2009 Accenture
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Accenture - Johnathan White
+
+*******************************************************************************/
+
+TARGET			grid.EXE
+TARGETTYPE		EXE
+SOURCEPATH		.
+SOURCE			grid.cpp
+SYSTEMINCLUDE		\epoc32\include
+LIBRARY			efsrv.lib euser.lib hal.lib ws32.lib 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applications/Symbian_MiniGUI_TestApp/grid.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,83 @@
+#include <w32std.h> 
+#include "profiler.h"
+
+const TSize KSize(64,60);
+const TInt KRow = 4;
+const TInt KCol = 5; 
+
+void MainL()	
+	{	
+	RWsSession ws;
+	ws.Connect();
+ 	CWsScreenDevice* scr = new(ELeave) CWsScreenDevice(ws);
+	scr->Construct();
+ 	CWindowGc* gc = new(ELeave) CWindowGc(scr);
+	gc->Construct();
+ 	RWindowGroup grp(ws);
+	grp.Construct(0xc0decafe, ETrue);
+ 	RWindow win(ws);
+	win.Construct(grp, 0xbeefcafe);
+	win.SetExtent(TPoint(20,160), TSize(320,240));
+	win.Activate();
+ 	win.Invalidate();
+	win.BeginRedraw();
+	gc->Activate(win);
+ 	gc->SetPenStyle(CGraphicsContext::ENullPen);
+	gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ 	TBool color = EFalse;
+
+if (Profiler::Start() == KErrNotFound)
+	{
+	_LIT(KProfiler,"profiler");
+	_LIT(KStart,"start -noui -drive=S");
+	RProcess p;
+	if (p.Create(KProfiler,KStart) == KErrNone)
+		{
+		p.Resume();
+		p.Close();
+		}
+	}
+
+	for (TInt col=0; col<KCol; ++col)
+		{
+		color = !color;		
+		for (TInt row=0; row<KRow; ++row)
+			{
+			TRect rect;
+			rect.iTl.iX = col * KSize.iWidth;
+			rect.iTl.iY = row * KSize.iHeight;
+			rect.SetSize(KSize);
+			color = !color;
+			gc->SetBrushColor(color? KRgbGray : KRgbBlack);
+			gc->DrawRect(rect);
+			}
+	}
+	gc->Deactivate();
+	win.EndRedraw();
+	ws.Flush();
+ 	User::After(3000000);
+ 	win.Close();
+	grp.Close();
+	delete gc;
+	delete scr;
+	ws.Close();
+
+	Profiler::Stop();
+	Profiler::Close();
+	Profiler::Unload();
+
+	} 
+
+
+GLDEF_C TInt E32Main()	
+{	
+
+	CTrapCleanup* tc = CTrapCleanup::New();	
+	if (!tc)
+		{		
+		return KErrNoMemory;
+		}
+	TRAPD(err, MainL());
+	delete tc;
+ 	return err;	
+}
\ No newline at end of file
--- a/baseport/syborg/bld.inf	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/bld.inf	Sun Mar 14 13:16:31 2010 +0000
@@ -55,9 +55,6 @@
 serial/serial					// Serial / UART ports
 fb/fb							// Framebuffer
 
-fb/fb_landscape
-fb/fb_portrait
-fb/fb_portrait_wvga
 
 keyboard/keyboard				// Keyboard
 pointer/pointer					// Pointer
@@ -85,6 +82,8 @@
 svpsnapdriver/svpsnapdriver
 svpsnapdriver/snapapp
 
+//NGA framebuffer
+svpframebuffer/svpframebuffer
 
 //Add Sound Driver
 soundsc\soundsc
--- a/baseport/syborg/ethernet/pdd/enet.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/ethernet/pdd/enet.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -22,6 +22,7 @@
 TARGETTYPE		pdd
 ROMTARGET       ethernet.pdd
 
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
 SYSTEMINCLUDE	/epoc32/include/drivers
 SYSTEMINCLUDE	AsspNKernIncludePath
 SOURCEPATH	    .
--- a/baseport/syborg/fb/syborg_fb.cpp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/fb/syborg_fb.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -11,6 +11,8 @@
 *
 * Contributors:
 *
+* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements
+*
 * Description: Minimalistic frame buffer driver
 *
 */
@@ -114,10 +116,10 @@
 
 void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
 {
-#if 1
+
   WriteReg(iPortAddr, FB_ENABLED, 0);
   WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys);
-  WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth);
+
   WriteReg(iPortAddr, FB_BLANK, 0);
   WriteReg(iPortAddr, FB_BPP, 32);
   WriteReg(iPortAddr, FB_COLOR_ORDER, 0);
@@ -125,8 +127,9 @@
   WriteReg(iPortAddr, FB_PIXEL_ORDER, 0);
   WriteReg(iPortAddr, FB_INT_MASK, 0);
   WriteReg(iPortAddr, FB_ENABLED, 1);
-  WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight);
-#endif
+
+  // We don't write the Height and Width of the framebuffer, this is controlled by the board model
+
 }
 
 void DLcdPowerHandler::PowerDownLcd()
@@ -202,7 +205,7 @@
 
 	  aInfo.iIsPalettized       = KConfigIsPalettized;
 
-	  aInfo.iOffsetBetweenLines = KConfigOffsetBetweenLines;
+	  aInfo.iOffsetBetweenLines = iVideoInfo.iSizeInPixels.iWidth*4; //Offset depends on width of framebuffer
 
 	  aInfo.iBitsPerPixel       = KConfigBitsPerPixel;
 	}
@@ -211,11 +214,13 @@
 
 TInt DLcdPowerHandler::AllocateFrameBuffer()
 {
-	// Allocate physical RAM for video
-
-// Added only the comments
-	TInt vSize = TSyborg::VideoRamSize(); // Maximum display now 854 x 854
-
+// Allocate physical RAM for video
+	
+	//read width and height of display from board model and allocate size
+	TInt width = ReadReg(iPortAddr, FB_WIDTH);
+	TInt height = ReadReg(iPortAddr, FB_HEIGHT);
+	
+	TInt vSize = 4*width*height; //*4 as 32bits per pixel
 
 	NKern::ThreadEnterCS();
 	TInt r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhys);
@@ -255,13 +260,16 @@
 
 	TUint* pV2 = (TUint*)iSecureChunk->LinearAddress();
 
-	iVideoInfo.iSizeInPixels.iWidth  = KConfigLcdWidth;
-	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
-	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
+	//width and height set by reading board model
+	iVideoInfo.iSizeInPixels.iWidth  = width;
+	iVideoInfo.iSizeInPixels.iHeight = height;
 
+	//offset between lines depends on width of screen
+	iVideoInfo.iOffsetBetweenLines = width*4;
+
+	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
 	iVideoInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel;
-	iVideoInfo.iOffsetBetweenLines = KConfigOffsetBetweenLines;
-
+	
 	iVideoInfo.iIsPalettized = KConfigIsPalettized;
 	iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
 	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
@@ -273,16 +281,6 @@
 
 	iSecureVideoInfo = iVideoInfo;
 	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
-
-#if 0
-	WriteReg(iPortAddr, FB_ENABLED, 0);
-	WriteReg(IPortAddr, FB_INT_MASK, 0);
-	WriteReg(iPortAddr, FB_BASE, iSecureDisplay ? iSecurevRamPhys : ivRamPhys);
-	WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth);
-	WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight);
-	WriteReg(iPortAddr, FB_BLANK, 0);
-	WriteReg(iPortAddr, FB_ENABLED, 1);
-#endif
 	
 	return KErrNone;
 }
@@ -432,45 +430,6 @@
 
 	iPortAddr = KHwBaseClcd;
 
-	// !@!
-#if 0	
-	// Map the video RAM
-	TInt vSize = TSyborg::VideoRamSize();
-	ivRamPhys = TSyborg::VideoRamPhys();
-
-	TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
-	if(r != KErrNone)
-	  return r;
-
-	TUint* pV = (TUint*)iChunk->LinearAddress();
-
-	iSecurevRamPhys = ivRamPhys + vSize;
-	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
-	if(r2 != KErrNone)
-	  return r2;
-
-	TUint* pV2 = (TUint*)iSecureChunk->LinearAddress();
-#endif
-
-	iVideoInfo.iSizeInPixels.iWidth  = KConfigLcdWidth;
-	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
-	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
-
-	iVideoInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel;
-	iVideoInfo.iOffsetBetweenLines = KConfigOffsetBetweenLines;
-
-	iVideoInfo.iIsPalettized = KConfigIsPalettized;
-	iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
-	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
-	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
-	iVideoInfo.iIsMono = KConfigIsMono;
-	// !@!	iVideoInfo.iVideoAddress = (TInt)pV;
-	iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
-	iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
-
-	iSecureVideoInfo = iVideoInfo;
-	// !@! iSecureVideoInfo.iVideoAddress = (TInt)pV2;
-
 	AllocateFrameBuffer();
 	TInt r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this);
 	if(r != KErrNone)
--- a/baseport/syborg/fb/syborg_fb.h	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/fb/syborg_fb.h	Sun Mar 14 13:16:31 2010 +0000
@@ -11,6 +11,8 @@
 *
 * Contributors:
 *
+* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements
+*
 * Description: Minimalistic frame buffer driver
 *
 */
@@ -25,54 +27,10 @@
 #include <system.h>
 
 
-
-// The definition of __portrait_display__ in the MMP file affects
-// both the display and the pointer component, so both must be
-// rebuilt if this setting is changed.
-
-
 _LIT(KLitLcd,"SYBORG_FB");
 
-
-#ifdef __PORTRAIT_DISPLAY__ // portrait display selected
-
-#	ifdef __DISPLAY_WVGA__
-
-#pragma comment(layout,"Portrait display enabled")
-const TUint KConfigLcdWidth            	= 854; // This must be left at 640, even with only 360 used by S60
-const TUint	KConfigLcdHeight	       	= 854;
-const TInt	KConfigLcdHeightInTwips     = 12860;
-const TInt	KConfigLcdWidthInTwips    	= 12860;
-const TUint	KConfigMouseWidth	       	= 480; // Usable width for the mouse driver
-const TUint	KConfigMouseMin			   	= 0;
-
-#	else //__DISPLAY_WVGA__
-
-#pragma comment(layout,"Portrait display enabled")
-const TUint KConfigLcdWidth            = 640; // This must be left at 640, even with only 360 used by S60
-const TUint	KConfigLcdHeight	       = 640;
-const TInt	KConfigLcdHeightInTwips     = 3550;
-const TInt	KConfigLcdWidthInTwips    = 3550;
-const TUint	KConfigMouseWidth	       = 360; // Usable width for the mouse driver
-
-const TUint	KConfigMouseMin			   = 0;
-#	endif //__DISPLAY_WVGA__
-
-
-
-
-#else // __PORTRAIT_DISPLAY__  Landscape display selected
-
-#pragma comment(layout,"Landscape display enabled")
-const TUint  KConfigLcdWidth            = 640;
-const TUint	KConfigLcdHeight	       = 480;
-const TInt	KConfigLcdWidthInTwips     = 3550;
-const TInt	KConfigLcdHeightInTwips    = 2670;
-const TUint	KConfigMouseWidth	       = 640; // Usable width for the mouse driver
-
-const TUint	KConfigMouseMin			   = 120; // mouse range is 120 - 480, not 0 - 360
-#endif // __PORTRAIT_DISPLAY__
-
+const TInt	KConfigLcdWidthInTwips     = 9638;
+const TInt	KConfigLcdHeightInTwips    = 7370;
 
 const TBool KConfigIsMono              = 0;
 const TBool KConfigIsPalettized        = 0;
@@ -82,17 +40,14 @@
 const TBool KConfigPixelOrderRGB       = 0;
 const TBool KConfigPixelOrderLandscape = 1;
 const TInt  KConfigLcdDisplayMode       = 2;
-//const TInt  KConfigLcdDisplayMode       = 1;
+
+
 const TInt  KConfigLcdNumberOfDisplayModes = 3;
 
 
 const TInt  KConfigBitsPerPixel        = 24;
 
-#ifdef __DISPLAY_WVGA__
-const TInt  KConfigOffsetBetweenLines  = 3416;
-#else //__DISPLAY_WVGA__
-const TInt  KConfigOffsetBetweenLines  = 2560;
-#endif //__DISPLAY_WVGA__
+
 
 
 class DLcdPowerHandler : public DPowerHandler
--- a/baseport/syborg/monitor/monap.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/monitor/monap.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -22,6 +22,7 @@
 
 TARGET			VariantTarget(exmondebug,dll)
 
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
 SYSTEMINCLUDE	/epoc32/include/drivers
 SYSTEMINCLUDE   ../serial
 
--- a/baseport/syborg/rom/base_syborg.iby	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/rom/base_syborg.iby	Sun Mar 14 13:16:31 2010 +0000
@@ -69,19 +69,14 @@
 extension[VARID]=	KERNEL_DIR\DEBUG_DIR\evfp.dll			        \sys\bin\evfp.dll
 
 
-// Changes allowing us of either portrait or landscape mode
-//extension[VARID]=	KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcd.dll		\sys\bin\lcd.dll
-#ifdef _PORTRAIT_
+// Either include NGA or Non NGA Framebuffer
+#ifdef SYMBIAN_BASE_USE_GCE
+extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_svpframebuffer.dll	\sys\bin\lcd.dll
+device[VARID]=KERNEL_DIR\DEBUG_DIR\display.ldd				\sys\bin\display0.ldd
+#else
+extension[VARID]=	KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcd.dll		\sys\bin\lcd.dll
+#endif
 
-#	ifdef _WVGA_
-extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcd_portrait_wvga.dll		    \sys\bin\lcd.dll
-#	else //_WVGA_
-extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcd_portrait.dll		    \sys\bin\lcd.dll
-#	endif //_WVGA_
-
-#else
-extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcd_landscape.dll		    \sys\bin\lcd.dll
-#endif
 
 device[VARID]=		KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_eserial.pdd		\sys\bin\euart1.pdd
 device[VARID]=		KERNEL_DIR\DEBUG_DIR\ecomm.ldd				\sys\bin\ecomm.ldd
@@ -133,12 +128,22 @@
 define	ESTART_EXE		_PLATFORM_NAME_e32strt.exe	// customised ESTART
 
 define	KEYMAP_FILE	_PLATFORM_NAME_ekdata
+
+file=ABI_DIR\DEBUG_DIR\KEYMAP_FILE.dll	\sys\bin\ekdata.dll
+
 #define	SCDV_DLL        _PLATFORM_NAME_scdv.dll
 #define	EUSER_DLL	_PLATFORM_NAME_euser.dll
 
+device[VARID] 	=KERNEL_DIR\DEBUG_DIR\pipelib.ldd		\sys\bin\pipelib.ldd
+
 
 device[VARID]	=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_soundsc.pdd	    \sys\bin\soundsc.pdd
 device[VARID]	=KERNEL_DIR\DEBUG_DIR\esoundsc.ldd				            \sys\bin\esoundsc.ldd
 
+//add sampling profiler
+file= KERNEL_DIR\DEBUG_DIR\profiler.exe		\sys\bin\profiler.exe
+device[VARID] =KERNEL_DIR\DEBUG_DIR\sampler.ldd		\sys\bin\sampler.ldd
+
+
 #endif  // __BASE_SYBORG_IBY__
 
--- a/baseport/syborg/serial/serial.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/serial/serial.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -21,6 +21,7 @@
 TARGET			VariantTarget(eserial,pdd)
 TARGETTYPE		pdd
 
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
 SYSTEMINCLUDE	/epoc32/include/drivers
 SYSTEMINCLUDE	AsspNKernIncludePath
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/bld.inf	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,5 @@
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_MMPFILES
+soundsc.mmp
--- a/baseport/syborg/soundsc/shared_sound.h	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/soundsc/shared_sound.h	Sun Mar 14 13:16:31 2010 +0000
@@ -1,6 +1,4 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
@@ -10,8 +8,9 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* Accenture Ltd
 *
-* Description:
+* Description: This file is a part of sound driver for Syborg adaptation.
 *
 */
 
@@ -20,19 +19,36 @@
 
 #include <soundsc.h>
 
-#ifdef _DEBUG
+#ifdef _ENABLE_SYBORG_AUDIO_DRIVER_DEBUG
 #define SYBORG_SOUND_DEBUG(x...) Kern::Printf(x)
 #else
 #define SYBORG_SOUND_DEBUG(x...)
 #endif
 
+#undef ASSERT
+#define ASSERT(x) (x) || (Kern::Printf("Sound.pdd: ASSERTION FAILED: "#x),0);
+
+#include "virtio_audio.h"
+#include "virtio.h"
+#include "virtio_audio_defs.h"
+
+/// @brief defines the maximum size for a single audio data transfer
+static const TInt KMaxTransferLength = 128 * 1024;
+
+namespace VirtIo
+{
+class DIoHandler;
+}
+
 class DDriverSyborgSoundScPddFactory;
 
-class DDriverSyborgSoundScPdd : public DSoundScPdd
+
+class DDriverSyborgSoundScPdd : public DSoundScPdd, VirtIo::MIoCallback
 	{
 public:
 
-	DDriverSyborgSoundScPdd();
+	DDriverSyborgSoundScPdd(DDriverSyborgSoundScPddFactory* aPhysicalDevice, 
+		TInt aUnitType, VirtIo::DIoHandler *aIoHandler, TUint aDataQueueId);
 	~DDriverSyborgSoundScPdd();
 	TInt DoCreate();
 	void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo);
@@ -48,48 +64,35 @@
 	TInt PowerUp();
 	void PowerDown();
 	TInt CustomConfig(TInt aFunction, TAny* aParam);
-	void Callback(TUint aTransferID, TInt aTransferResult, TInt aBytesTransferred);
-
 	void SetCaps();
-        // There was a change in the signature for DfcQ() which
-        // is a pure virtual method in the parent.
-        //  for Symbian^2
-        TDfcQue* DfcQ();
-        //  for Symbian^3
-	TDfcQue* DfcQ(TInt aUnit);
+	TDfcQue* DfcQ();
+	TDfcQue* DfcQ( TInt aUnit );
 	
 	TInt CalculateBufferTime(TInt aNumBytes);
+private:
+
+	// implementation of VirtIo::MIoCallback
+	virtual TBool VirtIoCallback( VirtIo::MIoHandler& aVirtIoHandler, VirtIo::MQueue& aQueue, 
+		VirtIo::Token aToken, TUint aBytesTransferred );
 
 public:
 	
 	DDriverSyborgSoundScPddFactory*	iPhysicalDevice;
 	
-	class TTransferArrayInfo{
+	TInt						iUnitType; //Play or Record
 
-public:
-	TUint 						iTransferID;
-	TLinAddr 					iLinAddr;
-	TInt 						iNumBytes;
-	TInt						iPlayTime;
-	};
+	VirtIo::MIoHandler* iIoHandler;
 	
-	RArray<TTransferArrayInfo> iTransferArray;
-	
-	NTimer						iTimer;
-	
-	TInt						iUnitType; //Play or Record
+	TUint iDataQueueId;
 	
 private:
 
 	TSoundFormatsSupportedV02	iCaps;
 	
 	TCurrentSoundFormatV02		iConfig;
+
+	VirtIo::Audio::DControl* iAudioControl;
 	
-
-
 	};
 
-
-
-
 #endif 
--- a/baseport/syborg/soundsc/shared_txsound.cpp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/soundsc/shared_txsound.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -1,6 +1,4 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
@@ -10,41 +8,91 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* Accenture Ltd
 *
-* Description:
+* Description: This file is a part of sound driver for Syborg adaptation.
 *
 */
 
 #include "shared_sound.h"
 #include "variant_sound.h"
+#include "../specific/syborg.h"
 
-void TimerCallback(TAny* aData)
+#include "virtio.h"
+#include "virtio_audio.h"
+#include "virtio_iohandler.h"
+
+using namespace VirtIo;
+
+static TInt GetSampleRate( TSoundRate aRate)
 	{
-	DDriverSyborgSoundScPdd * soundscpdd = (DDriverSyborgSoundScPdd*) aData;
-		
-	soundscpdd->Callback(soundscpdd->iTransferArray[0].iTransferID, KErrNone, soundscpdd->iTransferArray[0].iNumBytes);
-	
+	switch(aRate)
+		{
+		case ESoundRate7350Hz: 	return 7350;
+		case ESoundRate8000Hz: 	return 8000;
+		case ESoundRate8820Hz: 	return 8820;
+		case ESoundRate9600Hz: 	return 9600;
+		case ESoundRate11025Hz: return 11025;
+		case ESoundRate12000Hz: return 12000;
+		case ESoundRate14700Hz:	return 14700;
+		case ESoundRate16000Hz: return 16000;
+		case ESoundRate22050Hz: return 22050;
+		case ESoundRate24000Hz: return 24000;
+		case ESoundRate29400Hz: return 29400;
+		case ESoundRate32000Hz: return 32000;
+		case ESoundRate44100Hz: return 44100;
+		case ESoundRate48000Hz: return 48000;
+		}
+	return KErrNotFound;
 	}
 
+static TInt GetSoundEncoding( TSoundEncoding aV )
+	{
+	switch (aV)
+		{
+		case ESoundEncoding8BitPCM: return Audio::EFormatS8;
+		case ESoundEncoding16BitPCM: return Audio::EFormatS16;
+		case ESoundEncoding24BitPCM: break; // not supported
+		}
+	return -KErrNotFound;
+	}
+static TInt GetChannels( TInt aV )
+	{
+	switch (aV)
+		{
+		case KSoundMonoChannel: return 1;
+		case KSoundStereoChannel: return 2;
+		}
+	return KErrNotFound;
+	}
 
-DDriverSyborgSoundScPdd::DDriverSyborgSoundScPdd() : iTimer(TimerCallback,this)
+DDriverSyborgSoundScPdd::DDriverSyborgSoundScPdd(DDriverSyborgSoundScPddFactory* aPhysicalDevice, 
+	TInt aUnitType, VirtIo::DIoHandler* aIoHandler, TUint aDataQueueId )
+	: iPhysicalDevice(aPhysicalDevice),  iUnitType(aUnitType), iIoHandler( aIoHandler ), iDataQueueId( aDataQueueId )
 	{
-
 	}
 
 DDriverSyborgSoundScPdd::~DDriverSyborgSoundScPdd()
 	{
-	iTimer.Cancel();
+	SYBORG_SOUND_DEBUG("~DDriverSyborgSoundScPdd()");
+	iIoHandler->UnregisterClient( this );
+	delete iAudioControl;
+	SYBORG_SOUND_DEBUG("~DDriverSyborgSoundScPdd() - done");
 	}
 
-
 TInt DDriverSyborgSoundScPdd::DoCreate()
 	{
-
 	SetCaps();
+	
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::DoCreate TxPdd");
 
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::DoCreate TxPdd");
+	SYBORG_SOUND_DEBUG("Registering with IOHandler %x", iIoHandler );
+	iIoHandler->RegisterClient( this );
+	SYBORG_SOUND_DEBUG("Registered with IoHandler... Done %x", iIoHandler);
 	
+	iAudioControl = new Audio::DControl( *iIoHandler, iDataQueueId );
+	iAudioControl->Construct();
+		
 	return KErrNone;
 	}
 
@@ -60,7 +108,6 @@
 
 void DDriverSyborgSoundScPdd::Caps(TDes8& aCapsBuf) const
 	{
-
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::Caps TxPdd");
 	
 	// Fill the structure with zeros in case it is a newer version than we know about
@@ -73,14 +120,40 @@
 
 TInt DDriverSyborgSoundScPdd::SetConfig(const TDesC8& aConfigBuf)
 	{
-
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig TxPdd");
 	
 	// Read the new configuration from the LDD
 	TCurrentSoundFormatV02 config;
 	TPtr8 ptr((TUint8*) &config, sizeof(config));
 	Kern::InfoCopy(ptr, aConfigBuf);
+	
+	TInt channels = GetChannels(config.iChannels);
+	Audio::FormatId encoding = static_cast<Audio::FormatId>( GetSoundEncoding(config.iEncoding) );
+	TInt freq = GetSampleRate(config.iRate);
+	Audio::StreamDirection direction = static_cast<Audio::StreamDirection>(
+		(iUnitType == KSoundScRxUnit0)?Audio::EDirectionRecord
+		:(iUnitType == KSoundScTxUnit0)?Audio::EDirectionPlayback:-1 );
 
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig c %x, e %x, f %x, d %x",
+		channels, encoding, freq, direction );
+	
+	if ( (channels < 0 )
+		|| ( encoding < 0 )
+		|| ( freq < 0 ) 
+		|| ( direction < 0 )
+		)
+		{
+		SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig failed");		
+		return KErrArgument;
+		}
+	
+	TInt st = iAudioControl->Setup( direction, channels, encoding, freq );
+	if (st !=KErrNone)
+		{
+		SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::SetConfig failed %d", st);				
+		return st;
+		}
+	
 	iConfig = config;
 	
 	return KErrNone;
@@ -89,7 +162,6 @@
 
 TInt DDriverSyborgSoundScPdd::SetVolume(TInt aVolume)
 	{
-	
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::Setvolume TxPdd");
 	
 	return KErrNone;
@@ -98,45 +170,19 @@
 
 TInt DDriverSyborgSoundScPdd::StartTransfer()
 	{
-	
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::starttransfer TxPdd");
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::starttransfer TxPdd S");
+	iAudioControl->SendCommand( Audio::DControl::ERun );
+	return KErrNone;
+	}
 	
-	//Prepare for transfer
-	return KErrNone;
 	
-	}
-
 TInt DDriverSyborgSoundScPdd::CalculateBufferTime(TInt aNumBytes)
 	{
-	
-	TUint samplerate=0;
-
-	// Let the compiler perform an integer division of rates
-	switch(iConfig.iRate)
-		{
-		case ESoundRate7350Hz: 	samplerate = 7350; break;
-		case ESoundRate8000Hz: 	samplerate = 8000; break;
-		case ESoundRate8820Hz: 	samplerate = 8820; break;
-		case ESoundRate9600Hz: 	samplerate = 9600; break;
-		case ESoundRate11025Hz: samplerate = 11025; break;
-		case ESoundRate12000Hz: samplerate = 12000; break;
-		case ESoundRate14700Hz:	samplerate = 14700; break;
-		case ESoundRate16000Hz: samplerate = 16000; break;
-		case ESoundRate22050Hz: samplerate = 22050; break;
-		case ESoundRate24000Hz: samplerate = 24000; break;
-		case ESoundRate29400Hz: samplerate = 29400; break;
-		case ESoundRate32000Hz: samplerate = 32000; break;
-		case ESoundRate44100Hz: samplerate = 44100; break;
-		case ESoundRate48000Hz: samplerate = 48000; break;
-		}
-
+	TUint samplerate=GetSampleRate( iConfig.iRate );
 
 	// integer division by number of channels
 	aNumBytes /= iConfig.iChannels;
 
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::iChannels =%d", iConfig.iChannels);
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::iEncoding =%d", iConfig.iEncoding);
-	
 	// integer division by bytes per sample
 	switch(iConfig.iEncoding)
 		{
@@ -146,55 +192,31 @@
 		}
 
 	return (aNumBytes * 1000) / samplerate; //return time in milliseconds
-	
-
 	}
 
-TInt DDriverSyborgSoundScPdd::TransferData(TUint aTransferID, TLinAddr aLinAddr, TPhysAddr /*aPhysAddr*/, TInt aNumBytes)
+TInt DDriverSyborgSoundScPdd::TransferData(TUint aTransferID, TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aNumBytes)
 	{
-
-	//function wil get called multiple times while transfer is in progress therefore keep fifo queue of requests
-	TTransferArrayInfo transfer;	
-		
-	transfer.iTransferID = aTransferID;
-	transfer.iLinAddr = aLinAddr;
-	transfer.iNumBytes = aNumBytes;
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::TransferData unit %x aTId=%x, linAddr=%x,phAddr=%x,len=%x", 
+		iUnitType, aTransferID, aLinAddr, aPhysAddr, aNumBytes);
 	
-	//calculate the amount of time required to play/record buffer
-	TInt buffer_play_time = CalculateBufferTime(aNumBytes);
-	TInt timerticks = NKern::TimerTicks(buffer_play_time);
-	transfer.iPlayTime = timerticks;
-	
-	iTransferArray.Append(transfer);
-	
-	//Timer will callback when correct time has elapsed, will return KErrInUse if transfer
-	//already active, this is ok becuase will be started again in callback
-	TInt err = iTimer.OneShot(timerticks, ETrue);
-	
-	
+	iAudioControl->SendDataBuffer( 
+		reinterpret_cast<TAny*>( aLinAddr ), aNumBytes, reinterpret_cast<Token>( aTransferID ) );
+
 	return KErrNone;
 	}
 
 void DDriverSyborgSoundScPdd::StopTransfer()
 	{
-	// Stop transfer
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::stoptransfer TxPdd");
 	
-	//If timer is currently active then cancel it and call back buffer
-	if(iTimer.Cancel())
-		{
-		Callback(iTransferArray[0].iTransferID, KErrNone, iTransferArray[0].iNumBytes);
-		}
-		
-
+	iAudioControl->SendCommand( Audio::DControl::EStop );
 	}
 
 
 TInt DDriverSyborgSoundScPdd::PauseTransfer()
 	{
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::pausetransfer TxPdd");
-	//Pause Transfer
-	
+	iAudioControl->SendCommand( Audio::DControl::EPause );
 	return KErrNone;
 	}
 
@@ -202,8 +224,7 @@
 TInt DDriverSyborgSoundScPdd::ResumeTransfer()
 	{
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::resumetransfer TxPdd");
-	//Resume Transfer
-	
+	iAudioControl->SendCommand( Audio::DControl::EResume );
 	return KErrNone;
 	}
 
@@ -220,51 +241,44 @@
 
 TInt DDriverSyborgSoundScPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/)
 	{
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::customconfig TxPdd");
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::CustomConfig TxPdd");
 	return KErrNotSupported;
 	}
 
+TBool DDriverSyborgSoundScPdd::VirtIoCallback( MIoHandler& aVirtIoHandler, MQueue& aQueue, 
+	Token aToken, TUint aBytesTransferred )
+	{
+	if ( &aQueue != &iAudioControl->DataQueue() )
+		{ return ETrue; }
+			
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::VirtIoCallback t%x, s%x", aToken, aBytesTransferred);
+	
+	if ( iCaps.iDirection == ESoundDirPlayback )
+		{
+		Ldd()->PlayCallback( (TUint) aToken, KErrNone, aBytesTransferred );
+		}
+	else
+		{
+		Ldd()->RecordCallback( (TUint) aToken, KErrNone, aBytesTransferred );
+		}
+		
+	return EFalse; // cannot process any more buffers in this go due to a bug in LDD?
+	}
+
+TDfcQue*DDriverSyborgSoundScPdd::DfcQ()
+	{
+	return iPhysicalDevice->iDfcQ;
+	}
+	
+TDfcQue*DDriverSyborgSoundScPdd::DfcQ( TInt /* aUinit */ )
+	{
+	return iPhysicalDevice->iDfcQ;
+	}
+
 
-void DDriverSyborgSoundScPdd::Callback(TUint aTransferID, TInt aTransferResult, TInt aBytesTransferred)
-	{
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::playcallback TxPdd");
-	//Callback when Transfer completes or is stopped
-	
-	iTransferArray.Remove(0);
-	
-	if(iUnitType == KSoundScTxUnit0)
-		{
-		Ldd()->PlayCallback(aTransferID, aTransferResult, aBytesTransferred);
-		}
-	else if(iUnitType == KSoundScRxUnit0)
-		{
-		Ldd()->RecordCallback(aTransferID, aTransferResult, aBytesTransferred);
-		}
-	
-	if(	iTransferArray.Count()>0)
-		{
-		iTimer.OneShot(iTransferArray[0].iPlayTime, ETrue);
-		}
-	
-	}
-
-TDfcQue*DDriverSyborgSoundScPdd::DfcQ(TInt /* aUnit*/ )
-        {
-        return this->DfcQ();
-        }
-
-TDfcQue*DDriverSyborgSoundScPdd::DfcQ()
-        {
-        return iPhysicalDevice->iDfcQ;
-        }
-
 TInt DDriverSyborgSoundScPdd::MaxTransferLen() const
 	{
-	
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPdd::MaxTransferLen TxPdd");
-	
-	TInt maxlength = 200*1024;
-	return maxlength;
+	return KMaxTransferLength; 
 	}
 
 
@@ -279,7 +293,7 @@
 		}
 	else if(iUnitType == KSoundScRxUnit0)
 		{
-		// The data transfer direction for this unit is record 
+		// The data transfer direction for this unit is play
 		iCaps.iDirection = ESoundDirRecord;
 		}
 	
--- a/baseport/syborg/soundsc/soundsc.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/soundsc/soundsc.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -1,6 +1,4 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
@@ -10,14 +8,16 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* Accenture Ltd
 *
-* Description:
+* Description: This file is a part of sound driver for Syborg adaptation.
 *
 */
 
-#include		<variant.mmh>
+#include		"../variant.mmh"
 #include		"kernel/kern_ext.mmh"
 
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
 SYSTEMINCLUDE		/epoc32/include/drivers
 
 
@@ -25,8 +25,17 @@
 TARGETTYPE		pdd
 ROMTARGET		soundsc.pdd
 
+SYSTEMINCLUDE .
+
 SOURCE			shared_txsound.cpp
 SOURCE			variant_sound.cpp
+SOURCE			virtio.cpp
+SOURCE			virtio_io.cpp
+SOURCE			virtio_iohandler.cpp
+SOURCE			virtio_queue.cpp
+SOURCE			virtio_audio.cpp
+
+LIBRARY	    PlatformLib 
 
 CAPABILITY		all
 EPOCALLOWDLLDATA
--- a/baseport/syborg/soundsc/variant_sound.cpp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/soundsc/variant_sound.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -1,6 +1,4 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
@@ -10,25 +8,27 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* Accenture Ltd
 *
-* Description:
+* Description: This file is a part of sound driver for Syborg adaptation.
 *
 */
 
 #include "variant_sound.h"
+#include "virtio_iohandler.h"
+#include "../specific/syborg.h"
 
 _LIT(KSoundScPddName, "SoundSc.Syborg");
 
-
 DECLARE_STANDARD_PDD()
 	{
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory created\n");
 	return new DDriverSyborgSoundScPddFactory;
 	}
 
 
 DDriverSyborgSoundScPddFactory::DDriverSyborgSoundScPddFactory()
 	{
-
 	iUnitsMask = ((1 << KSoundScTxUnit0) | (1 << KSoundScRxUnit0));
 
 	iVersion = RSoundSc::VersionRequired();
@@ -38,20 +38,61 @@
 TInt DDriverSyborgSoundScPddFactory::Install()
 	{
 	_LIT(KAudioDFC, "AUDIO DFC");
-	// Get a pointer to the the McBSP's DFC Queue so that handling of both McBSP callbacks and requests
-	// made to the LDD from user mode can be processed in the same thread, to avoid the use of semaphores
-	TInt r = Kern::DfcQCreate(iDfcQ, 26, &KAudioDFC);
+	
+	// LDD driver is going to use the same queue.
+	TInt r = Kern::DynamicDfcQCreate(iDfcQ, KAudioDfcQueuePriority, KAudioDFC);
 
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::PDD install");
 
-	if(r==KErrNone)
+	if(r!=KErrNone)
+		{
+		SYBORG_SOUND_DEBUG("Creating audio DFC failed %d",r);
+		return r;
+		}
+	// All PDD factories must have a unique name
+	r = SetName(&KSoundScPddName);
+	if (r!=KErrNone)
 		{
-		// All PDD factories must have a unique name
-		TInt r = SetName(&KSoundScPddName);
+		SYBORG_SOUND_DEBUG("Setting name %x",r);
+		return r;
+		}
+	iIoHandler = new VirtIo::DIoHandler(	
+		(TAny*)KHwSVPAudioDevice, 
+		EIntAudio0,
+		iDfcQ );
+	
+	if (iIoHandler == NULL)
+		{
+		iDfcQ->Destroy();
+		return KErrNoMemory;
 		}
-
+	
+	SYBORG_SOUND_DEBUG("Constructing IoHandler");
+	
+	r = iIoHandler->Construct();
+	
+	if ( r != KErrNone)
+		{
+		iDfcQ->Destroy();		
+		delete iIoHandler;
+		}
+		
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::PDD installed");
+	
 	return r;
 	}
+	
+DDriverSyborgSoundScPddFactory::~DDriverSyborgSoundScPddFactory()
+	{
+	if (iIoHandler)
+		{
+		delete iIoHandler;
+		iIoHandler = NULL;
+		}
+	if (iDfcQ)
+		iDfcQ->Destroy();
+	}
+	
 
 void DDriverSyborgSoundScPddFactory::GetCaps(TDes8& /*aDes*/) const
 	{
@@ -81,8 +122,6 @@
 TInt DDriverSyborgSoundScPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
 	{
 
-	DSoundScPdd* pD = NULL;
-
 	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::PDD create aUnit %d TxUnitId %d", aUnit, KSoundScTxUnit0);
 
 	// Assume failure
@@ -90,21 +129,14 @@
 	aChannel = NULL;
 
 				
-	DDriverSyborgSoundScPdd* pTxD = new DDriverSyborgSoundScPdd;
+	DDriverSyborgSoundScPdd* pTxD = new DDriverSyborgSoundScPdd( this, aUnit, 
+		iIoHandler, aUnit == KSoundScTxUnit0?1:2 );
 
-	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd %d", pTxD);
+	SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd %x", pTxD);
 		
 	if (pTxD)
 		{
-		pD = pTxD;
-
-		// Save a pointer to the factory so that it is accessible by the PDD and call the PDD's
-		// second stage constructor
-		pTxD->iPhysicalDevice = this;
-			
-		pTxD->iUnitType = aUnit; // Either KSoundScTxUnit0 or KSoundScRxUnit0 (play or record)
-			
-		SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd2 %d", pTxD);
+		SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd2 %x", pTxD);
 			
 		r = pTxD->DoCreate();
 			
@@ -116,13 +148,19 @@
 	// as some LDDs have been known to access this pointer even if Create() returns an error!
 	if (r == KErrNone)
 		{
-		aChannel = pD;
-		SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd set AChannel %d", aChannel);
+		aChannel = pTxD;
+		SYBORG_SOUND_DEBUG("DDriverSyborgSoundScPddFactory::TxPdd set AChannel %x", aChannel);
 		}
 	else
 		{
-		delete pD;
+		delete pTxD;
 		}
 
 	return r;
 	}
+
+	
+VirtIo::MIoHandler* DDriverSyborgSoundScPddFactory::IoHandler()
+	{
+	return iIoHandler;
+	}
--- a/baseport/syborg/soundsc/variant_sound.h	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/soundsc/variant_sound.h	Sun Mar 14 13:16:31 2010 +0000
@@ -1,6 +1,4 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
@@ -10,8 +8,9 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* Accenture Ltd
 *
-* Description:
+* Description: This file is a part of sound driver for Syborg adaptation.
 *
 */
 
@@ -20,21 +19,28 @@
 
 #include "shared_sound.h"
 
+static const TUint KAudioDfcQueuePriority = 28;
+
 class DDriverSyborgSoundScPddFactory : public DPhysicalDevice
 	{
 public:
 
 	DDriverSyborgSoundScPddFactory();
+	~DDriverSyborgSoundScPddFactory();
 	TInt Install();
 	void GetCaps(TDes8 &aDes) const;
 	TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
 	TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
+	
+	VirtIo::MIoHandler* IoHandler();
 
 public:
 
 	/** The DFC queue to be used by both the LDD and the PDD to serialise access to the PDD */
-	TDfcQue*		iDfcQ;
-
+	TDynamicDfcQue*		iDfcQ;
+	
+	VirtIo::DIoHandler *iIoHandler;
+	
 	};
 
 #endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,58 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#include "virtio.h"
+
+namespace VirtIo 
+{
+
+#define MIN(x,y) (((x)<=(y))?(x):(y))
+#define INVALID_PHYSADDR(x) ((x)==TPhysAddr(-1))
+
+TInt LinearToSGL( TAny* aVirtual, TUint aSize, TAddrLen aSGL[], TUint& aSGLCount )
+	{
+	const TUint pageSize = Kern::RoundToPageSize(1);
+	TUint8* virtAddr = reinterpret_cast<TUint8*>( aVirtual );
+	TPhysAddr physAddr = Epoc::LinearToPhysical( TLinAddr(virtAddr) );
+	if (INVALID_PHYSADDR(physAddr))
+		{ return KErrArgument; }
+	TUint sglLimit = aSGLCount;
+	aSGLCount = 0;
+	TUint left = aSize;
+	while (left)
+		{
+		TPhysAddr startPhysAddr = physAddr;
+		TUint8* startVirtAddr = virtAddr;
+		while ( (left) 
+			&& ( Epoc::LinearToPhysical( TLinAddr(virtAddr) ) == physAddr ) )
+			{
+			TUint size = MIN(left, pageSize);
+			physAddr += size;
+			virtAddr += size;
+			left -= size;
+			}
+		if (INVALID_PHYSADDR(physAddr))
+			{ return KErrArgument; }
+		if ((aSGL) && (aSGLCount<sglLimit))
+			{
+			aSGL[aSGLCount].iAddr = (TUint32) startPhysAddr;
+			aSGL[aSGLCount].iLen = virtAddr - startVirtAddr;
+			}
+		aSGLCount++;
+		}
+	return (aSGLCount<=sglLimit)?KErrNone:KErrNoMemory;
+	}
+	
+} // namespace VirtIo	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,160 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_H
+#define VIRTIO_H
+
+/// @file virtio.h
+/// @brief Delivers the API for dealing with VirtIo device.
+///
+/// Mainly a VirtIo device functionality is accessed through the following entities.
+/// <li> MIo that deals with basic io space access
+/// <li> MQueue that represents a device's transaction queue, which is usually more then one per device
+/// <li> MIoHandler that represents a device, takes care of resource management, device initialisation and MIo and MQueue derived objects' lifetime.
+///
+/// @p The idea is that MIo, MQueue and MIoHandler comes as a specific set. On top of which it is possible to build various drivers (e.g. Audio or Ethernet) that are agnostic to these virtio specifics (e.g. flat device tree or full PCI).
+///
+/// Currently the implementation is not multithread safe. The assumption is that all the routines are driven from a single DFC.
+
+#include "virtio_defs.h"
+
+#include <e32lang.h>
+#include <assp.h>
+
+
+#ifdef _ENABLE_SYBORG_VIRTIO_DEBUG
+#define SYBORG_VIRTIO_DEBUG(x...) Kern::Printf(x)
+#else
+#define SYBORG_VIRTIO_DEBUG(x...)
+#endif
+
+#undef ASSERT
+#define ASSERT(x) (x) || (Kern::Printf("VirtIo: ASSERTION FAILED: "#x),0);
+
+
+namespace VirtIo
+{
+
+/// @brief type of a buffer token.
+typedef TAny* Token;
+
+/// @brief represents a virtual queue's API.
+///
+class MQueue
+	{
+public:
+
+	/// @brief Adds a buffer at the end of the queue
+	///
+	/// @param aScatterList - physical address scatter list
+	/// @param aOutNum - number of scatter buffers to be sent to the device
+	/// @param aInNum - number of scatter buffers to be received from the device (starting at aOutNum index of scatter list)
+	/// @param aToken - a value associated with buffer to be returned by getBuf or used with detachBuf
+	virtual TInt AddBuf( const TAddrLen aScatterList[], TUint32 aOutNum, 
+		TUint32 aInNum, Token aToken) = 0;
+
+	/// @brief Returns buffer associated with the least recent completed transaction
+	/// @return transaction's Token with \a len set to reflect amount of processed bytes or 
+	/// 0 if no completed transaction was found. 
+	virtual Token GetBuf( TUint& len ) = 0;
+	
+	/// @brief Posts queued buffers to the device
+	virtual void Sync() = 0;
+	
+	/// @brief Cancels a specified buffer (if it is not yet posted)
+	/// To be used at shutdown
+	virtual TInt DetachBuf( Token aToken ) = 0;
+	
+	/// @brief reenable callbacks
+	/// @return ETrue - callbacks reenabled, EFalse - callbacks not reenabled as there are pending buffers in
+	/// the DQueue.
+	virtual TBool Restart() = 0;
+	
+	/// @brief returns number of buffers that are posted to the DQueue 
+	/// but not yet completed
+	virtual TInt Processing() = 0;
+	
+	/// @brief returns number of times the GetBuf function could be called returning a buffer
+	virtual TInt Completed() = 0;
+	
+	/// Returns Id of the queue
+	virtual TUint Id() = 0;
+	
+	};
+
+
+/// @brief API wrapping the VirtIo IO space access.
+class MIo
+	{
+public:
+	virtual void SetQueueBase( TUint aId, TAny* iDescRegion ) = 0;
+	virtual TAny* GetQueueBase( TUint aId ) = 0;
+	virtual void PostQueue( TUint aId ) = 0;
+	virtual void GetDeviceIds( TUint32 &aPeripheralId, TUint32 &aDeviceId ) = 0;
+	virtual TUint GetQueueCount( TUint aQId ) = 0;
+	virtual TBool EnableInterrupt( TBool aEnable ) = 0;
+	virtual void SetStatus( TUint status ) = 0;
+	virtual void ClearInteruptStatus() = 0;
+	virtual TBool InteruptStatus() = 0;
+	
+	};
+
+
+class MIoCallback;
+
+/// @brief represents a VirtIo device's API.
+///
+/// An API for a handler that takes care of resources, state and asyncrhonous communication of a VirtIo device. Allocates Queues.
+class MIoHandler
+	{
+public:
+	/// returns one of the device's queues.
+	virtual MQueue& Queue( TUint aId ) = 0;
+	
+	/// registers a client for buffer notifications.
+	virtual void RegisterClient( MIoCallback* aListener ) = 0;	
+	
+	/// unregisters a client for buffer notifications.
+	virtual void UnregisterClient( MIoCallback* aListener )	= 0;
+	};
+
+/// an interface for a MIoHandler's client to implement.
+class MIoCallback
+	{
+public:
+	/// Notifies MIoHandler's client that that a buffer processing has been completed.
+	///
+	/// @return EFalse to defer subsequent buffer processing in the same callback.
+	virtual TBool VirtIoCallback( 
+		MIoHandler& aVirtIoHandler, MQueue& aQueue, 
+		Token aToken, TUint aBytesTransferred ) = 0;
+	};
+
+/// @brief turns virtual address range into a phys scatter gather list
+///
+/// If virtual buffer contains a linear buffer then the 
+/// function will create one SGL entry.
+///
+/// If function is called with aSGL=0 then it will count the linear physical
+/// fragments the buffer is build of. 
+///
+///
+/// @return KErrArgument if the virtual buffer contains nonconvertible addresses)
+TInt LinearToSGL( TAny* aLinear, TUint aSize, TAddrLen aSGL[], TUint& aSGLCount );
+
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_audio.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,158 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#include "virtio_audio.h"
+
+namespace VirtIo
+{
+namespace Audio
+{
+
+DControl::~DControl()
+	{
+	if (iCmdMem)
+		{ Kern::Free( iCmdMem ); }
+	}
+
+TInt DControl::Construct()
+	{
+	TUint cmdSize = sizeof(iCmd[0])*KCmdMaxBufCount;
+	TUint size = cmdSize + sizeof(*iBufferInfo);
+	// as we are going to align the allocated memory
+	// we add extra alignment size minus 1
+	iCmdMem = reinterpret_cast<TUint8*>( Kern::Alloc( size + sizeof(iCmd[0])-1 ) );
+	if (!iCmdMem)
+		{ return KErrNoMemory; }
+		
+	// let us align the memory address 
+	// note: sizeof(iCmd[0]) is a power of 2
+	ASSERT( sizeof(iCmd[0]) == POW2ALIGN(sizeof(iCmd[0])) );
+	TUint8* alignedMem = iCmdMem 
+		+ ( (-(TUint32)iCmdMem)&(sizeof(iCmd[0])-1) ); // adding missing amount of bytes
+	
+	iCmd = reinterpret_cast<TCommandPadded*>( alignedMem );
+	iBufferInfo = reinterpret_cast<TBufferInfo*>( alignedMem + cmdSize );
+	
+	for (TUint i = 0; i< KCmdMaxBufCount; ++i)
+		{
+		iCmd[i].iStream = iDataQueueId - 1;
+		}	
+	iCmd[0].iCommand = Audio::ECmdSetEndian;
+	iCmd[1].iCommand = Audio::ECmdSetChannels;
+	iCmd[2].iCommand = Audio::ECmdSetFormat;
+	iCmd[3].iCommand = Audio::ECmdSetFrequency;
+	iCmd[4].iCommand = Audio::ECmdInit;
+	iCmd[5].iCommand = Audio::ECmdRun;
+	iCmd[5].iArg = Audio::EDoRun; //start stream
+	iCmd[6].iCommand = Audio::ECmdRun;
+	iCmd[6].iArg = Audio::EDoStop; //stop stream		
+	iCmd[7].iCommand = Audio::ECmdRun;
+	iCmd[7].iArg = Audio::EDoStop; //kind of pause
+	iCmd[8].iCommand = Audio::ECmdRun;
+	iCmd[8].iArg = Audio::EDoRun; //kind of resume
+	return KErrNone;
+	}
+
+TInt DControl::Setup( StreamDirection aDirection, TInt aChannelNum, 
+	FormatId aFormat, TInt aFreq)
+	{
+	iCmd[1].iArg = aChannelNum;
+	iCmd[2].iArg = aFormat;
+	iCmd[3].iArg = aFreq;		
+	iCmd[4].iArg = iDirection = aDirection;		
+	AddCommand(&iCmd[0],(Token)0);
+	AddCommand(&iCmd[1],(Token)1);
+	AddCommand(&iCmd[2],(Token)2);
+	AddCommand(&iCmd[3],(Token)3);
+	AddCommand(&iCmd[4],(Token)4, iBufferInfo, sizeof(*iBufferInfo) );
+	ControlQueue().Sync();
+	return KErrNone;
+	}
+	
+void DControl::AddCommand( TCommandPadded* aCmd, Token aToken )
+	{
+	TAddrLen list;
+	list.iLen = sizeof(TCommand);
+	list.iAddr = Epoc::LinearToPhysical((TUint32)aCmd);
+	SYBORG_VIRTIO_DEBUG("AddCommand %x %x %x", aCmd->iCommand, aCmd->iStream, aCmd->iArg);
+	ControlQueue().AddBuf(&list, 1, 0, aToken );
+	}
+
+void DControl::AddCommand( TCommandPadded* aCmd, Token aToken, 
+	TAny* aMem, TUint aSize )
+	{
+	TAddrLen list[2];
+	list[0].iLen = sizeof(TCommand);
+	list[0].iAddr = Epoc::LinearToPhysical((TUint32)aCmd);
+	list[1].iLen = aSize;
+	list[1].iAddr = Epoc::LinearToPhysical((TUint32)aMem);
+	ControlQueue().AddBuf(list, 1, 1, aToken );
+	}
+	
+	
+// Waits until device processes all pending requests
+// there would be no need to have it here at all 
+// if there was no bug in qemu:
+// once you send stop command the buffers processing stops... but the buffers are never returned.
+
+void DControl::WaitForCompletion()
+	{
+	SYBORG_VIRTIO_DEBUG("DControl::WaitForCompletion : {");
+
+	TInt st = Kern::PollingWait( &DControl::CheckProcessing, this, 10, 100 );
+	ASSERT ( (st == KErrNone) && "Polling problem" )
+	
+	SYBORG_VIRTIO_DEBUG("DControlWaitForCompletion : }");
+	}
+
+TBool DControl::CheckProcessing( TAny* aSelf )
+	{
+	DControl* self = reinterpret_cast<DControl*>( aSelf );
+	return self->DataQueue().Processing() == 0;
+	}
+	
+void DControl::AddCommand( Command aCmd )
+	{
+	TUint idx = aCmd;
+	if (aCmd == EStop)
+		{
+		// due to bug on qemu's side we need to stop sending buffers
+		// and wait for all pending buffers to get filled...
+		WaitForCompletion();
+		}
+	AddCommand(&iCmd[idx], (Token)idx );
+	}
+
+TInt DControl::SendDataBuffer( TAny* virtaulAddr, TUint aSize, Token aToken )
+	{
+	TAddrLen sgl[KMaxSGLItemCountPerAudioBuffer];
+	TUint sglCount = KMaxSGLItemCountPerAudioBuffer;
+	TInt st = LinearToSGL(virtaulAddr, aSize, sgl, sglCount );
+	ASSERT( st != KErrNoMemory ); // failure means our fixed lenght sgl table is too small
+	if (st!=KErrNone)
+		{ return st; }
+	st = DataQueue().AddBuf( sgl, 
+		iDirection == EDirectionPlayback ? sglCount : 0,
+		iDirection == EDirectionRecord ? sglCount : 0,
+		aToken );
+	if (st!=KErrNone)
+		{ return st; }
+	DataQueue().Sync();
+	return KErrNone;
+	}
+	
+
+} // namespace Audio
+} // namespace VirtIo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_audio.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,103 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_AUDIO_H
+#define VIRTIO_AUDIO_H
+
+#include "virtio_audio_defs.h"
+#include "virtio_defs.h"
+#include "virtio.h"
+
+#include <e32def.h>
+
+namespace VirtIo
+{
+
+namespace Audio
+{
+
+/// Encapsulates routines that affect VirtIo Audio device's Stream.
+/// DControl object may share ioHandler with other DControl objects.
+/// especially Control Queue.
+class DControl : public DBase
+	{
+	static const TUint KCmdMaxBufCount = 8;
+	static const TUint KControlQueueId = 0;
+public:
+	enum Command { ERun = 5, EStop, EPause, EResume };
+	
+	DControl( VirtIo::MIoHandler& aIoHandler, TUint32 aDataQueueId )
+	: iIoHandler( aIoHandler ), iDataQueueId( aDataQueueId)
+		{}
+		
+	~DControl();
+		
+	TInt Construct();
+	
+	/// sets up stream parameters.
+	TInt Setup( StreamDirection aDirection, TInt aChannelNum, 
+		FormatId aFormat, TInt aFreq );
+		
+	/// @brief posts a data buffer. 
+	///
+	/// The virtaulAddr is going to be turned into 
+	/// a physical address scatter gather list.
+	TInt SendDataBuffer( TAny* virtaulAddr, TUint aSize, Token aToken );
+	
+	/// Sends a specific command
+	void SendCommand( Command aCmd )
+		{ AddCommand( aCmd ); ControlQueue().Sync(); }
+
+	/// Return Data Queue of the stream.
+	MQueue& DataQueue()
+		{ return iIoHandler.Queue(iDataQueueId); }
+
+	/// Returns Control Queue of the associated device.
+	MQueue& ControlQueue()
+		{ return iIoHandler.Queue(KControlQueueId); }	
+
+private:
+	// size of this struct needs to be power2 aligned
+	// we extend original TCommand with padding to ensure this
+	struct TCommandPadded: public TCommand
+		{
+		static const TUint KPaddingSize = POW2ALIGN(sizeof(TCommand))-sizeof(TCommand);
+		TUint8 iPadding[KPaddingSize];
+		};
+	
+	void AddCommand( TCommandPadded* aCmd, Token aToken );
+	
+	void AddCommand( TCommandPadded* aCmd, Token aToken, TAny* mem, TUint size );
+
+	void AddCommand( Command aCmd );
+
+	void WaitForCompletion();
+	static TBool CheckProcessing( TAny* aSelf );
+	
+	VirtIo::MIoHandler& iIoHandler;
+	TUint iDataQueueId;
+	
+	TUint8* iCmdMem; // managed
+	TCommandPadded* iCmd; // unmanaged
+	TBufferInfo* iBufferInfo; // unmanaged
+	
+	StreamDirection iDirection;
+	};
+
+} // namespace Audio
+} // namespace VirtIo
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_audio_defs.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,85 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_AUDIO_DEFS_H //x
+#define VIRTIO_AUDIO_DEFS_H
+
+#include <e32def.h>
+
+/// @file virtio_audio_defs.h
+/// most of definitions here come from VirtIo Audio spec
+/// and was made compatible to the qemu backend (which means diverged from spec)
+
+namespace VirtIo
+{
+namespace Audio
+{
+
+static const TUint KMaxSGLItemCountPerAudioBuffer = 64;
+
+enum CommandId
+	{
+	ECmdSetEndian=1,
+	ECmdSetChannels=2,
+	ECmdSetFormat=3,
+	ECmdSetFrequency=4,
+	ECmdInit=5,
+	ECmdRun=6
+	};
+
+enum FormatId
+	{
+	EFormatU8=0,
+	EFormatS8=1,
+	EFormatU16=2,
+	EFormatS16=3,
+	EFormatU32=4,
+	EFormatS32=5
+	};
+
+enum RunType
+	{
+	EDoStop = 0,
+	EDoRun = 1
+	};
+
+// note the values are opposite to what spec says
+enum StreamDirection
+	{
+	EDirectionPlayback = 0,
+	EDirectionRecord = 1
+	};
+
+struct TCommand
+	{
+	TUint32 iCommand;
+	TUint32 iStream;
+	TUint32 iArg;
+	};
+	
+struct TBufferInfo
+	{
+	TUint32 bufferSize;
+	TUint32 iA[3];	// not really documented
+	};	
+
+static const TUint32 KVirtIoPeripheralId = 0xc51d000a;
+static const TUint32 KVirtIoDeviceId = 0xffff;
+
+} // namespace Audio
+} // namespace VirtIo
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_defs.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,117 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_DEFS_H
+#define VIRTIO_DEFS_H
+
+#include <e32def.h>
+#include <kernel.h> // fot TPhysAddr
+
+/// @file virtio_defs.h
+/// most of definitions here come from VirtIo spec
+/// and was made compatible to the qemu backend (which means diverged from spec)
+
+namespace VirtIo
+{
+
+#define POW2ALIGN1(x) ((x)|((x)>>1))
+#define POW2ALIGN2(x) ((x)|((x)>>2))
+#define POW2ALIGN4(x) ((x)|((x)>>4))
+#define POW2ALIGN8(x) ((x)|((x)>>8))
+#define POW2ALIGN16(x) ((x)|((x)>>16))
+
+///@brief Alignes \a x to the closest bigger or equal power2 value
+#define POW2ALIGN(x) (POW2ALIGN16(POW2ALIGN8(POW2ALIGN4(POW2ALIGN2(POW2ALIGN1((x)-1)))))+1)
+
+static const TUint KVirtIoAlignment = 0x1000;
+
+enum 
+	{
+	EStatusReset = 0,
+	EStatusAcknowledge = 1,
+	EStatusDriverFound = 2,
+	EStatusDriverInitialised = 4,
+	EStatusFailed = 0x80
+	};
+
+enum 
+	{
+    EIoID             = 0,
+    EIoDevType        = 1,
+    EIoHostFeatures  = 2,
+    EIoGuestFeatures = 3,
+    EIoQueueBase     = 4,
+    EIoQueueSize      = 5,
+    EIoQueueSelect      = 6,
+    EIoQueueNotify   = 7,
+    EIoStatus	  	  = 8,
+    EIoInterruptEnable     = 9,
+    EIoInterruptStatus     = 10
+	};
+
+struct TRingDesc
+	{
+	enum 
+		{
+		EFlagNext = 1,
+		EFlagWrite = 2
+		};
+
+	TUint64 iAddr;	// physical address
+	TUint32 iLen;
+	TUint16 iFlags;
+	TUint16 iNext;
+	};
+
+struct TRingAvail
+	{
+	enum { EFlagInhibitNotifications = 1 };
+	TUint16 iFlags;
+	TUint16 iIdx;
+	TUint16 iRing[1];
+	};
+
+struct TRingUsed
+	{
+	enum { EFlagInhibitNotifications = 1 };
+	TUint16 iFlags;
+	TUint16 iIdx;
+		struct 
+		{
+		TUint32 iId;
+		TUint32 iLen;
+		} iRing[1];
+	};
+
+/// @brief Represents element of scatter gather list
+struct TAddrLen
+	{
+	TPhysAddr iAddr;
+	TUint32 iLen;
+	};
+
+/// Gives a pointer resulting with aliging \a v with \a a.
+/// @note \a a must be power of 2.
+template <typename T> T* Align( T* v, TUint a )
+	{ return (T*)( ((TUint8*)v) + ((-(TUint)v)&(a-1)) ); }
+	
+/// Gives a pointer resulting with aliging \a v with \a a.
+/// @note \a a must be power of 2.
+template <typename T> T Align( T v, TUint a )
+	{ return (v)+((-v)&(a-1)); }
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_io.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,42 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#include "virtio_io.h"
+
+namespace VirtIo
+{
+
+void DIo::GetDeviceIds( TUint32 &aPeripheralId, TUint32 &aDeviceId )
+	{
+	aPeripheralId = read( EIoID );
+	aDeviceId = read( EIoDevType );
+	}
+	
+void DIo::SetQueueBase( TUint aQId, TAny* iDescRegion )
+	{
+	TUint32 phAddr = iDescRegion?Epoc::LinearToPhysical( reinterpret_cast<TUint32>( iDescRegion ) ):0;
+	write(EIoQueueSelect, aQId);
+	write(EIoQueueBase, phAddr );
+	SYBORG_VIRTIO_DEBUG("SetQueueBase Q%d %x", aQId, phAddr );
+	}		
+	
+	
+TAny* DIo::GetQueueBase( TUint aQId)
+	{
+	write(EIoQueueSelect, aQId);
+	return reinterpret_cast<TAny*>( read(EIoQueueBase) );
+	}
+	
+} // namespace VirtIo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_io.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,83 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_IO_H
+#define VIRTIO_IO_H
+
+#include "virtio.h"
+#include <e32def.h>
+
+namespace VirtIo
+{
+
+class DIo : public DBase, public MIo
+	{
+public:
+	DIo( TAny* aIoBase ): iIoBase( reinterpret_cast<TUint32*>( aIoBase ) )
+		{ }
+	
+	virtual void GetDeviceIds( TUint32 &aPeripheralId, TUint32 &aDeviceId );
+	
+	virtual void SetQueueBase( TUint aQId, TAny* iDescRegion );
+	
+	virtual TAny* GetQueueBase( TUint aQId);
+	
+	virtual TUint GetQueueCount( TUint aQId )
+		{
+		write(EIoQueueSelect, aQId);
+		return read(EIoQueueSize);
+		}
+	
+	virtual void PostQueue( TUint aQId )
+		{ write(EIoQueueNotify, aQId); SYBORG_VIRTIO_DEBUG("PostQueue Q%d", aQId ); }
+		
+	virtual TBool EnableInterrupt( TBool aEnable )
+		{ return swap(EIoInterruptEnable, aEnable?1:0); }
+
+	virtual void SetStatus( TUint status )
+		{ write(EIoStatus, status ); }
+		
+	virtual void ClearInteruptStatus()
+		{ write( EIoInterruptStatus, 1 ); }
+
+	virtual TBool InteruptStatus()
+		{ return read( EIoInterruptStatus ); }
+		
+	
+	void Reset()
+		{ SetStatus( EStatusReset ); };
+	
+	
+private:	
+	void write(TUint idx, TUint32 value )
+		{ iIoBase[idx] = value; }
+		
+	TUint32 read(TUint idx)
+		{ return iIoBase[idx]; }
+		
+	TUint32 swap(TUint idx, TUint32 value )
+		{ 
+		TUint32 t = iIoBase[idx]; 
+		iIoBase[idx] = value; 
+		return t;
+		}
+	
+	volatile TUint32* iIoBase;
+
+	};
+
+} // namespace VirtIo
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_iohandler.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,238 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#include "virtio_iohandler.h"
+#include "virtio_queue.h"
+#include "virtio_io.h"
+
+namespace VirtIo
+{
+
+DIoHandler::DIoHandler( TAny* aVirtIoBase, TUint aIntNum, TDfcQue* aDfcQue )
+	: iVirtIoBase( aVirtIoBase ), iIntNum( aIntNum ), iDfcQue( aDfcQue ),
+	iDfc( ServeDfc, this, 0 ),
+	iVirtIo( 0 ), iQueueCount( 3 ), iQueue( 0 ),
+	iClientCount( 0 )
+	{
+	SYBORG_VIRTIO_DEBUG("DIoHandler IoBase %x DfcQ %x", iVirtIoBase, iDfcQue);
+	}
+
+TInt DIoHandler::Construct()
+	{
+	TInt err = KErrNone;
+	TUint i;
+
+	SYBORG_VIRTIO_DEBUG("Creating DIo");
+
+	InstallIsr();
+
+	iVirtIo = new DIo(iVirtIoBase);
+	if (iVirtIo == NULL )
+		{ return KErrNoMemory; }
+	iVirtIo->SetStatus( EStatusAcknowledge
+			| EStatusDriverFound );
+
+	iQueue = new DQueue*[iQueueCount];
+	
+	if (iQueue == NULL )
+		{ Wipe(); return KErrNoMemory; }
+	
+	// This is to make Wipe work
+	for ( i = 0; i < iQueueCount; ++i )
+		{ iQueue[i] = NULL; }
+	
+	for ( i = 0; i < iQueueCount; ++i )
+		{
+		SYBORG_VIRTIO_DEBUG("Creating DQueue %d",i);
+		DQueue* q = new DQueue(
+			*iVirtIo, i, iVirtIo->GetQueueCount( i ) );
+		if (!q)
+			{ Wipe(); return KErrNoMemory; }
+		err = q->Construct();
+		if (err != KErrNone)
+			{ Wipe(); return err; }
+		iQueue[i] = q;
+		}
+		
+	iVirtIo->SetStatus(
+		EStatusAcknowledge
+		| EStatusDriverFound
+		| EStatusDriverInitialised );
+
+	iVirtIo->EnableInterrupt( ETrue );
+	Interrupt::Enable(iIntNum);
+	return KErrNone;
+	}
+
+void DIoHandler::Wipe()
+	{
+	if (iQueue)
+		{
+		for ( TUint i = 0; i < iQueueCount; ++i )
+			{
+			if (iQueue[i])
+				{ delete iQueue[i]; }
+			}
+		delete[] iQueue;
+		iQueue = NULL;
+		}
+	if (iVirtIo)
+		{
+		delete iVirtIo;
+		iVirtIo = NULL;
+		}
+	}
+
+DIoHandler::~DIoHandler()
+	{
+
+	Interrupt::Disable(iIntNum);
+	UninstallIsr();
+	iVirtIo->EnableInterrupt( EFalse );
+	iDfc.Cancel();
+	iVirtIo->ClearInteruptStatus();
+
+	WaitForCompletion();
+
+	iVirtIo->SetStatus( EStatusAcknowledge
+		| EStatusDriverFound );
+	iVirtIo->SetStatus( EStatusAcknowledge );
+
+	Wipe();
+	}
+	
+MQueue& DIoHandler::Queue( TUint id )
+	{ return *(iQueue[id]); }	
+
+void DIoHandler::ScheduleCallback()
+	{
+	iDfc.Enque();
+	}
+
+
+// Waits until device processes all pending requests
+// This code should be really handled by each queue individually
+void DIoHandler::WaitForCompletion()
+	{
+	SYBORG_VIRTIO_DEBUG("WaitForCompletion : {");
+
+	TInt st = Kern::PollingWait( &DIoHandler::CheckProcessing, this, 10, 100 );
+
+	ASSERT( st == KErrNone );
+
+	for ( TUint i = 0; i < iQueueCount; ++i )
+		{
+		while ( iQueue[i]->Completed() )
+			{ InterruptHandler(); }
+		}
+
+	SYBORG_VIRTIO_DEBUG("WaitForCompletion : }");
+	}
+
+TBool DIoHandler::CheckProcessing( TAny* aSelf )
+	{
+	DIoHandler* self = reinterpret_cast<DIoHandler*>( aSelf );
+	for ( TUint i = 0; i < self->iQueueCount; ++i )
+		{
+		if (self->iQueue[i]->Processing()!=0)
+			{ return EFalse; }
+		}
+	return ETrue;
+	}
+
+void DIoHandler::InstallIsr()
+	{
+	iDfc.SetDfcQ( iDfcQue );
+	Interrupt::Bind(iIntNum,ServeIsr,this);
+	}
+
+void DIoHandler::UninstallIsr()
+	{
+	Interrupt::Unbind(iIntNum);
+	iDfc.Cancel();
+	}
+
+void DIoHandler::ServeIsr( TAny* aSelf )
+	{
+	DIoHandler* self = reinterpret_cast<DIoHandler*>( aSelf );
+	Interrupt::Clear( self->iIntNum );
+	self->iVirtIo->ClearInteruptStatus();
+	self->iDfc.Add();
+	}
+
+void DIoHandler::ServeDfc( TAny* aSelf )
+	{
+	reinterpret_cast<DIoHandler*>( aSelf )->InterruptHandler();
+	}
+
+	
+// Although the function notifies all clients
+// usually only one of them is an adressee
+// the rest would just check flags/compare numbers and return.
+// If at least one client did some crucial processing 
+// (indicating that by returning EFalse from VirtIoCallback)
+// then NotifyClients returns EFalse as well.
+TBool DIoHandler::NotifyClients( MQueue& aQueue, Token aToken, TUint aBytesTransferred )
+	{
+	TBool r = ETrue;
+	for ( TUint i = 0 ; i < iClientCount; ++i )
+		{
+		r &= iClients[i]->VirtIoCallback( *this, aQueue, aToken, aBytesTransferred );
+		}
+	return r;
+	}
+	
+// Here buffers processed by the device are iterated.
+// After the first serious buffer processing (as indicated by NotifyClients)
+// further buffer processing is Deferred in another DFC callback.
+void DIoHandler::InterruptHandler()
+	{
+	for ( TUint q = 0; q < iQueueCount; ++q )
+		{
+		TUint transferred;
+		TUint cnt = ETrue;
+		do 
+			{
+			Token t = Queue(q).GetBuf(transferred);
+			if (t)
+				{ cnt = NotifyClients( Queue(q), t, transferred); }
+			else 
+				{ break; }
+			} while(cnt);
+		if (!cnt)
+			{
+			ScheduleCallback(); 
+			break;
+			}
+		}
+	}
+
+void DIoHandler::UnregisterClient( MIoCallback* aClient )
+	{
+	ASSERT( iClientCount );
+	TUint i;
+	for ( i = 0; i < iClientCount; ++i)
+		{
+		if (iClients[i] == aClient )
+			{ break; }
+		}
+	ASSERT( i < iClientCount );
+	--iClientCount;
+	// move the rest of the table one slot to the front
+	for ( ; i < iClientCount; ++i) 
+		{ iClients[i] = iClients[i+1]; }
+	}	
+
+} // namespace VirtIo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_iohandler.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,93 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_IOHANDLER_H
+#define VIRTIO_IOHANDLER_H
+
+#include "virtio.h"
+#include <e32def.h>
+
+namespace VirtIo
+{
+
+class DQueue;
+
+class DIo;
+
+
+class DIoHandler : public DBase, public MIoHandler
+	{
+	static const TUint KMaxClients = 4;
+public:
+	DIoHandler( TAny* aVirtIoBase, TUint aIntNum, TDfcQue* aDfcQue );
+	
+	virtual void RegisterClient( MIoCallback* aClient )
+		{
+		ASSERT( iClientCount < KMaxClients );
+		iClients[iClientCount++] = aClient;
+		}
+	
+	virtual void UnregisterClient( MIoCallback* aClient );
+
+	TInt Construct();
+	
+	
+	virtual ~DIoHandler();
+	
+	virtual MQueue& Queue( TUint id );
+
+private:	
+	void ScheduleCallback();
+	
+	void WaitForCompletion();
+	
+	void Wipe();
+	
+	static TBool CheckProcessing( TAny* aSelf );
+	
+	void InstallIsr();
+	
+	void UninstallIsr();
+	
+	static void ServeIsr( TAny* aSelf );
+
+	static void ServeDfc( TAny* aSelf );
+	
+	TBool NotifyClients( MQueue& aQueue, Token aToken, TUint aBytesTransferred );
+	
+	void InterruptHandler();
+	
+	TAny* iVirtIoBase;
+	TUint iIntNum;
+	
+	TDfcQue* iDfcQue;
+	TDfc iDfc;
+	
+	//managed
+	DIo* iVirtIo;
+	
+	TUint iQueueCount;
+	//double managed
+	DQueue** iQueue;
+		
+	TUint iClientCount;	
+	MIoCallback* iClients[KMaxClients];
+	
+	};
+
+
+} // namespace VirtIo
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_queue.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,328 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#include "virtio_queue.h"
+
+#define ENABLE_QEMU_AUDIO_MODEL_BUG_WORKAROUND
+#define ENABLE_QEMU_VIRTIO_CLEANUP_BUG_WORKAROUND
+#define PHYS_ADDR(x) Epoc::LinearToPhysical( reinterpret_cast<TUint32>(x))
+	
+namespace VirtIo
+{
+
+
+DQueue::DQueue( MIo& aVirtIo, TUint aId, TUint aCount ) 
+	: iVirtIo( aVirtIo ), iId( aId ), iCount( aCount )
+	{
+	}
+	
+TInt DQueue::Construct()
+	{
+	TInt r = AllocQueue();
+	if (r!=KErrNone)
+		{ return r; }
+	PreInitQueue();
+	iVirtIo.SetQueueBase( iId, iDesc );
+	PostInitQueue();
+	return KErrNone;
+	}
+
+void DQueue::Wipe()
+	{
+	if ( iChunk )
+		{
+		iChunk->Close( NULL );
+		iChunk = NULL;
+		}
+#ifndef ENABLE_QEMU_VIRTIO_CLEANUP_BUG_WORKAROUND		
+	if ( iPhysAddr )
+		{ Epoc::FreePhysicalRam( iPhysAddr ); }
+#endif
+	iPhysAddr = 0;
+	}
+	
+DQueue::~DQueue()
+	{
+	Wipe();
+	}	
+	
+//
+// Implementation here is that descs are allocated from the one starting with lowest index, 
+TInt DQueue::AddBuf( const TAddrLen aScatterList[], TUint32 aOutNum, TUint32 aInNum, Token aToken)
+	{
+	SYBORG_VIRTIO_DEBUG("AddBuf Q%x %x l%x %x,%x %x",
+		iId, aScatterList[0].iAddr, aScatterList[0].iLen, aOutNum, aInNum, aToken );
+	TUint outLeft = aOutNum;
+	TUint inLeft = aInNum;
+	TInt first = -1;
+	TInt last = -1;
+	TUint totalLen = 0;
+	// @TODO maintain freedescs counter to know if the below is going to success from the outset.
+	// alloc and initialise descs
+	for ( TUint i = 0, j = 0; (i < iCount) && (outLeft+inLeft); ++i )
+		{
+		if (iDesc[i].iFlags == KFreeDescriptorMarker)
+			{
+			if (first<0)
+				{ first = i; }
+			iDesc[i].iFlags = ((outLeft)? 0 : TRingDesc::EFlagWrite);
+			iDesc[i].iNext = KFreeDescriptorMarker;
+			iDesc[i].iAddr = aScatterList[j].iAddr;
+			iDesc[i].iLen = aScatterList[j].iLen;
+			totalLen += aScatterList[j].iLen;
+			iToken[i].iToken = aToken;
+			iToken[i].iTotalLen = 0;
+			if ( last >=0 )
+				{ 
+				iDesc[last].iNext = i; 
+				iDesc[last].iFlags |= TRingDesc::EFlagNext;
+				}
+			last = i;
+			if (outLeft) 
+				{ --outLeft; }
+			else 
+				{ --inLeft; }
+			j++;
+			}
+		}
+	if (outLeft+inLeft) // rollback descs if not all could have been claimed
+		{
+		if (first>=0)
+			{ FreeDescs(first); }
+		return KErrNotReady;
+		}
+	iToken[first].iTotalLen = totalLen;
+	
+	// fill a slot in avail ring
+	iAvail->iRing[Slot(iAvail->iIdx)] = first;
+	++iAvail->iIdx;
+	
+	return KErrNone;
+	}	
+	
+// bases on the assumption that the lowest desc index with given aToken value is used (see addBuf)
+// @todo make sure the buffer is not yet posted	
+TInt DQueue::DetachBuf( Token aToken )
+	{
+	TUint myDescId = KFreeDescriptorMarker;
+	for ( TIdx i = iNextAvailToSync; i != iAvail->iIdx ; ++i )
+		{
+		TUint availSlot = Slot( i );
+		TUint descId = iAvail->iRing[availSlot];
+		if ( descId < iCount )
+			{
+			if (iToken[descId].iToken == aToken)
+				{
+				myDescId = descId;
+				break;
+				}
+			}
+		}
+	if ( myDescId != KFreeDescriptorMarker )
+		{ return KErrNotFound; }
+	FreeDescs( myDescId );
+	return KErrNone;
+	}	
+	
+Token DQueue::GetBuf( TUint& aLen )
+	{
+	TIdx usedIdx = iUsed->iIdx;
+	ASSERT( ((TIdx)iNextUsedToRead) <= usedIdx );
+	if (usedIdx == ((TIdx)iNextUsedToRead))
+		{ return 0; }
+	TUint nextUsedSlot = Slot(iNextUsedToRead);
+	TUint len = iUsed->iRing[nextUsedSlot].iLen;
+	TUint descId = iUsed->iRing[nextUsedSlot].iId;
+	ASSERT(descId<iCount);
+	Token token = iToken[descId].iToken;	
+	TUint orderedLen = iToken[descId].iTotalLen;	
+	SYBORG_VIRTIO_DEBUG( "GetBuf Q%x %x ..%x t%x D%x L%x OL%x", iId, iNextUsedToRead, usedIdx, token, descId, len, orderedLen );
+
+	++iNextUsedToRead;
+	FreeDescs( descId );
+	
+#ifdef ENABLE_QEMU_AUDIO_MODEL_BUG_WORKAROUND	
+	aLen = len?len:orderedLen; // @TODO kind of a hack to solve virtio-audio's failure to report len by syborg on the side of qemu
+#endif
+	return token;
+	}	
+	
+TInt DQueue::Processing()
+	{ return  ((TIdx)(iAvail->iIdx - iFirstEverToSync)) 
+		- ((TIdx)(iUsed->iIdx - iFirstEverToRead)); }	
+	
+TInt DQueue::Completed()
+	{ return  ((TIdx)(iUsed->iIdx - iNextUsedToRead)); }		
+
+void DQueue::Sync()
+	{
+	SYBORG_VIRTIO_DEBUG("Sync Q%d, %x..%x",
+		iId, iNextAvailToSync, iAvail->iIdx );	
+	if ( ((TIdx)iNextAvailToSync) == iAvail->iIdx)
+		{ return; }
+	DumpAvailPending();
+
+	iNextAvailToSync = iAvail->iIdx;
+	iVirtIo.PostQueue( iId );
+	}
+	
+void DQueue::DumpUsedPending()
+	{
+	for (TIdx i = iNextUsedToRead; i != iUsed->iIdx; ++i )
+		{ DumpUsed( Slot(i) ); }
+	}	
+	
+void DQueue::DumpUsed(TUint usedSlot)
+	{
+	SYBORG_VIRTIO_DEBUG("Usedslot = %x, aLen = %x, descId=%x", usedSlot, (TUint32) iUsed->iRing[usedSlot].iLen, iUsed->iRing[usedSlot].iId);
+	TUint descId = iUsed->iRing[usedSlot].iId;
+	DumpDescs( descId );
+	}	
+	
+void DQueue::DumpAvailPending()
+	{
+	for (TIdx i = iNextAvailToSync; i != iAvail->iIdx; ++i )
+		{ DumpAvail( Slot(i) ); }
+	}
+	
+void DQueue::DumpAvail(TUint availSlot)
+	{
+	SYBORG_VIRTIO_DEBUG("Q%d, availslot = %x", iId, availSlot);
+	TUint descId = iAvail->iRing[availSlot];
+	DumpDescs( descId );
+	}
+	
+void DQueue::DumpDescs(TUint descId )
+	{
+	do {
+		TRingDesc& d = iDesc[descId];
+		SYBORG_VIRTIO_DEBUG(" Desc %x,addr %x, len %x, flags %x, next %x",
+			(TUint32)descId, (TUint32)d.iAddr, (TUint32)d.iLen, (TUint32)d.iFlags, (TUint32)d.iNext );
+		if ((d.iFlags&TRingDesc::EFlagNext)==0)
+			{ break; }
+		descId = d.iNext;
+		} while (ETrue);
+	}
+	
+void DQueue::DumpAll()
+	{
+	DumpAvailPending();
+	DumpUsedPending();
+	}	
+		
+void DQueue::FreeDescs( TUint firstDescIdx )
+	{
+	TInt i = firstDescIdx;
+	Token token = iToken[firstDescIdx].iToken;
+	while (i>=0)
+		{
+		ASSERT( ( ((TUint)i) < iCount ) );
+		TUint flags = iDesc[i].iFlags;
+		ASSERT( flags != KFreeDescriptorMarker );
+		iDesc[i].iFlags = KFreeDescriptorMarker;
+		ASSERT( iToken[i].iToken == token );
+		iToken[i].iToken = 0;
+		iToken[i].iTotalLen = 0;
+		i = (flags&TRingDesc::EFlagNext)
+			? iDesc[i].iNext : -1;
+		}
+	}		
+	
+TUint8* DQueue::AllocMem( TUint aSize )
+	{
+	TInt r = KErrNone;
+	
+#ifdef ENABLE_QEMU_VIRTIO_CLEANUP_BUG_WORKAROUND		
+	// note this is second part of workaround that deals
+	// with the issue that memory once assigned to queuebase cannot be 
+	// changed,
+	// if queuebase != 0 this is because it was set when the driver
+	// was loaded previous time
+
+	iPhysAddr = (TUint32) iVirtIo.GetQueueBase( iId );
+	iPhysMemReallyAllocated = (iPhysAddr == 0);
+	if (iPhysMemReallyAllocated)
+		{ r = Epoc::AllocPhysicalRam(aSize, iPhysAddr, 0 ); }
+
+#endif
+
+	if (r!=KErrNone ) 
+		{ return NULL; }
+	
+	r = DPlatChunkHw::New( iChunk, iPhysAddr, aSize, 
+		EMapAttrSupRw | EMapAttrL2Uncached | EMapAttrL1Uncached );
+
+	if (r!=KErrNone ) 
+		{
+		if ( iPhysMemReallyAllocated )
+			{ Epoc::FreePhysicalRam( iPhysAddr, aSize ); }
+		iChunk->Close( NULL );
+		return NULL;
+		}
+
+	ASSERT( r == KErrNone );
+	return reinterpret_cast<TUint8*>( iChunk->LinearAddress() );
+	}	
+	
+TInt DQueue::AllocQueue()
+	{
+	iDescSize = iCount * sizeof(TRingDesc);
+	iAvailSize = sizeof(TRingAvail) + (iCount-1) * sizeof(((TRingAvail*)0)->iRing[0]);
+	iTokenSize = iCount * sizeof(TTransactionInfo);
+	TUint usedOffset = Align( iDescSize +  iAvailSize, KVirtIoAlignment );
+	TUint iUsedSize = sizeof(TRingUsed) + (iCount-1) * sizeof(((TRingUsed*)0)->iRing[0]);
+	TUint size = usedOffset + iUsedSize;
+	TUint8* iMemAligned;
+
+	iMemAligned = AllocMem( size );
+	
+	if (!iMemAligned)
+		{ return KErrNoMemory; }
+	
+	iDesc = reinterpret_cast<TRingDesc*>( iMemAligned );
+	iAvail = reinterpret_cast<TRingAvail*>( iMemAligned + iDescSize );
+	iUsed = reinterpret_cast<TRingUsed*>( iMemAligned + usedOffset );
+	iToken = reinterpret_cast<TTransactionInfo*>( Kern::Alloc( iTokenSize ) );
+	SYBORG_VIRTIO_DEBUG("DQueue %d, Virt iDesc=%x,iAvail=%x,iToken=%x,iUsed=%x",
+		iId, iDesc, iAvail, iToken, iUsed );
+	SYBORG_VIRTIO_DEBUG("DQueue %d, Phys iDesc=%x, iUsed=%x",
+		iId, PHYS_ADDR(iDesc), PHYS_ADDR(iUsed) );
+	ASSERT( ((PHYS_ADDR(iUsed)-PHYS_ADDR(iDesc))) == ((TUint32)((TUint8*)iUsed-(TUint8*)iDesc)) );
+	return KErrNone;
+	}	
+	
+void DQueue::PreInitQueue()
+	{
+	memset(iDesc, -1, iDescSize );
+	memset( ((TUint8*) iAvail) + 4, -1, iDescSize - 4 );
+	memset( ((TUint8*) iUsed) + 4, -1, iDescSize - 4 );
+	
+	iAvail->iFlags = 0; // no notifications from control queue
+	iUsed->iFlags = 0;
+	if ( iPhysMemReallyAllocated )
+		{
+		iAvail->iIdx = 0;
+		iUsed->iIdx = 0;
+		}
+	}	
+	
+void DQueue::PostInitQueue()
+	{
+	iFirstEverToSync = iNextAvailToSync = iAvail->iIdx;
+	iFirstEverToRead = iNextUsedToRead = iUsed->iIdx;
+	}		
+
+
+} // namespace VirtIo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/soundsc/virtio_queue.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,139 @@
+/*
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Accenture Ltd
+*
+* Contributors:
+*
+* Description: This file is a part of sound driver for Syborg adaptation.
+*
+*/
+
+#ifndef VIRTIO_QUEUE_H
+#define VIRTIO_QUEUE_H
+
+#include "virtio.h"
+#include <e32def.h>
+
+namespace VirtIo
+{
+
+/// @brief implements VirtIo Queue.
+/// 
+///
+/// @note functions are not enclosed with any synchronisation primitives.
+/// However, implementation is believed to split operations in 3 groups with the following concurrency constraints:
+/// <li> A GetBuf, DetachBuf
+/// <li> B AddBuf
+/// <li> C Processing, Completed, Sync
+/// Group C can be executed concurrently with any other functions.
+/// Group A can be executed concurrently with a group B function.
+/// Group A or B function cannot be executed concurrently with function from the same group.
+///
+/// Memory barries would have to be introduced for SMP.
+///
+class DQueue : public DBase, public MQueue
+	{
+	typedef TUint16 TIdx;
+
+	struct TTransactionInfo
+		{
+		Token iToken;
+		TUint iTotalLen;
+		};
+	
+	static const TUint KFreeDescriptorMarker = 0xFFFF;
+	
+public:
+
+	/// @brief Creates a VirtIo Queue with a MIo object, Queue Id,
+	/// and descriptor count/ring lenght.
+	DQueue( MIo& aVirtIo, TUint aId, TUint aCount );
+	
+	/// Allocates resources
+	TInt Construct();
+		
+	virtual ~DQueue();
+	
+public: // implementation of MQueue
+	
+	virtual TInt AddBuf( const TAddrLen aScatterList[], TUint32 aOutNum, TUint32 aInNum, Token aToken);
+	
+	virtual TInt DetachBuf( Token aToken );
+	
+	virtual Token GetBuf( TUint& aLen );
+	
+	virtual void Sync();
+	
+	virtual TUint Id() 
+		{ return iId; }
+	
+	virtual TBool Restart()
+		{ return ETrue;	}
+	
+	virtual TInt Processing();
+			
+	virtual TInt Completed();	
+	
+public:	// Debug functions 
+	void DumpUsedPending();
+	
+	void DumpUsed(TUint usedSlot);
+	void DumpAvailPending();
+	
+	void DumpAvail(TUint availSlot);
+	void DumpDescs(TUint descId );
+	
+	virtual void DumpAll();
+		
+private:
+	void Wipe();
+
+	TUint Slot( TUint i )
+		{ return i & (iCount - 1); }
+				
+	void FreeDescs( TUint firstDescIdx );
+	
+	TUint8* AllocMem( TUint aSize );
+	
+	TInt AllocQueue();
+	
+	void PreInitQueue();
+	
+	void PostInitQueue();
+	
+private:
+	MIo& iVirtIo;
+	const TUint iId;
+	const TUint iCount;
+	volatile TUint iNextUsedToRead;
+	TUint iFirstEverToRead;
+	volatile TUint iNextAvailToSync;
+	TUint iFirstEverToSync;
+
+	TUint iDescSize;
+	TUint iAvailSize;
+	TUint iTokenSize;
+	TUint iUsedSize;
+	
+	TRingDesc* iDesc;
+	TRingAvail* iAvail;
+	volatile TRingUsed* iUsed;
+	TTransactionInfo* iToken;
+	
+	// managed
+	TUint8* iMem;
+	TPhysAddr iPhysAddr;
+	TBool iPhysMemReallyAllocated;
+	DPlatChunkHw* iChunk;
+	
+	};
+
+
+} // namespace VirtIo
+
+#endif
--- a/baseport/syborg/specific/syborg.h	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/specific/syborg.h	Sun Mar 14 13:16:31 2010 +0000
@@ -64,7 +64,9 @@
   EIntSerial0 = 5,
   EIntSerial1 = 6,
   EIntSerial2 = 7,
-  EIntSerial3 = 8
+  EIntSerial3 = 8,
+  EIntNet0 = 9,
+  EIntAudio0 = 10
 };
 
 // Timer Mode
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.cpp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,1059 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements
+*
+* Description: Minimalistic frame buffer driver
+*
+*/
+#include <videodriver.h>
+#include "platform.h"
+#include <nkern.h>
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <kernel/kpower.h>
+
+#include <syborg_priv.h>
+#include "svpframebuffer.h"
+
+DLcdPowerHandler	*  DLcdPowerHandler::pLcd			= NULL;
+
+TPhysAddr Syborg::VideoRamPhys;
+TPhysAddr Syborg::VideoRamPhysSecure;		// Secure display memory
+
+TPhysAddr TSyborg::VideoRamPhys()
+{
+  __KTRACE_OPT(KEXTENSION,Kern::Printf("TSyborg::VideoRamPhys: VideoRamPhys=0x%x", Syborg::VideoRamPhys));
+  return Syborg::VideoRamPhys;
+}
+
+TPhysAddr TSyborg::VideoRamPhysSecure()
+{
+  return Syborg::VideoRamPhysSecure;
+}
+
+LOCAL_C TInt DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+{
+  DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
+  return pH->HalFunction(aFunction,a1,a2);
+}
+
+static void rxMsg(TAny* aPtr)
+{
+  DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
+  TMessageBase* pM = h.iMsgQ.iMessage;
+  if(pM)
+	h.HandleMsg(pM);
+}
+
+static void power_up_dfc(TAny* aPtr)
+{
+  ((DLcdPowerHandler*)aPtr)->PowerUpDfc();
+}
+
+void power_down_dfc(TAny* aPtr)
+{
+  ((DLcdPowerHandler*)aPtr)->PowerDownDfc();
+}
+
+void DLcdPowerHandler::DisplayOn()
+{ 
+  PowerUpLcd(iSecureDisplay);
+  iDisplayOn = ETrue;
+}
+
+void DLcdPowerHandler::DisplayOff()
+{
+  PowerDownLcd();
+  iDisplayOn = EFalse;
+}
+
+void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
+ {
+   if(aSecure)
+	 {
+	   if(!iSecureDisplay)
+		 {
+		   DisplayOff();
+		   iSecureDisplay = ETrue;
+		   DisplayOn();
+		 }
+	 }
+   else
+	 {
+	   if(iSecureDisplay)
+		 {
+		   DisplayOff();
+		   iSecureDisplay = EFalse;
+		   DisplayOn();
+		 }
+	 }
+ }
+
+void DLcdPowerHandler::PowerUpDfc()
+{
+  DisplayOn();
+  PowerUpDone();
+}
+
+void DLcdPowerHandler::PowerDownDfc()
+{
+  DisplayOff();
+
+  PowerDownDone();
+}
+
+void DLcdPowerHandler::PowerDown(TPowerState)
+{
+  iPowerDownDfc.Enque();
+}
+
+void DLcdPowerHandler::PowerUp()
+{
+  iPowerUpDfc.Enque();
+}
+
+void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
+{
+
+  WriteReg(iPortAddr, FB_ENABLED, 0);
+  WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys);
+
+  WriteReg(iPortAddr, FB_BLANK, 0);
+  WriteReg(iPortAddr, FB_BPP, 32);
+  WriteReg(iPortAddr, FB_COLOR_ORDER, 0);
+  WriteReg(iPortAddr, FB_BYTE_ORDER, 0);
+  WriteReg(iPortAddr, FB_PIXEL_ORDER, 0);
+  WriteReg(iPortAddr, FB_INT_MASK, 0);
+  WriteReg(iPortAddr, FB_ENABLED, 1);
+
+// We don't write the Height and Width of the framebuffer, this is controlled by the board model
+
+}
+
+void DLcdPowerHandler::PowerDownLcd()
+{
+  WriteReg(iPortAddr, FB_BLANK, 1);
+}
+
+DLcdPowerHandler::DLcdPowerHandler()
+	:	DPowerHandler(KLitLcd),
+		iMsgQ(rxMsg,this,NULL,1),
+		iPowerUpDfc(&power_up_dfc,this,6),
+		iPowerDownDfc(&power_down_dfc,this,7)
+{
+}
+
+void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
+{
+  anInfo.iWindowHandleValid = EFalse;
+  anInfo.iWindowHandle = NULL;
+  anInfo.iScreenAddressValid = ETrue;
+  anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress());
+  anInfo.iScreenSize.iWidth = iVideoInfo.iSizeInPixels.iWidth;
+  anInfo.iScreenSize.iHeight = iVideoInfo.iSizeInPixels.iHeight;
+}
+
+void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg)
+{
+  if(aMsg->iValue)
+	DisplayOn();
+  else
+	DisplayOff();
+  aMsg->Complete(KErrNone,ETrue);
+}
+
+void DLcdPowerHandler::WsSwitchOnScreen()
+{
+  TThreadMessage& m = Kern::Message();
+  m.iValue = ETrue;
+  m.SendReceive(&iMsgQ);
+}
+
+void DLcdPowerHandler::WsSwitchOffScreen()
+{
+  TThreadMessage& m = Kern::Message();
+  m.iValue = EFalse;
+  m.SendReceive(&iMsgQ);
+}
+
+TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
+{
+  NKern::FMWait(&iLock);
+  if(aSecure)
+	aInfo = iSecureVideoInfo;
+  else
+	aInfo = iVideoInfo;
+  NKern::FMSignal(&iLock);
+  return KErrNone;
+}
+
+TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
+{
+  if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+	return KErrArgument;
+  
+  NKern::FMWait(&iLock);
+  aInfo = iVideoInfo;
+  NKern::FMSignal(&iLock);
+
+  if(aMode != aInfo.iDisplayMode)
+	{
+	  aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+	  aInfo.iIsPalettized       = KConfigIsPalettized;
+	  aInfo.iOffsetBetweenLines = iVideoInfo.iSizeInPixels.iWidth*4; //Offset depends on width of framebuffer
+	  aInfo.iBitsPerPixel       = KConfigBitsPerPixel;
+	}
+  return KErrNone;
+}
+
+TInt DLcdPowerHandler::AllocateFrameBuffer()
+{
+	// Allocate physical RAM for video
+	
+	//read width and height of display from board model and allocate size
+	TInt width = ReadReg(iPortAddr, FB_WIDTH);
+	TInt height = ReadReg(iPortAddr, FB_HEIGHT);
+	
+	iSize = 4*width*height; //*4 as 32bits per pixel
+
+	NKern::ThreadEnterCS();
+	TInt r = Epoc::AllocPhysicalRam(iSize,Syborg::VideoRamPhys);
+	if (r != KErrNone)
+	{
+	        NKern::ThreadLeaveCS();
+		Kern::Fault("AllocVideoRam",r);
+	}
+
+	// Map the video RAM
+	ivRamPhys = TSyborg::VideoRamPhys();
+
+	r = DPlatChunkHw::New(iChunk,ivRamPhys,iSize,EMapAttrUserRw|EMapAttrBufferedC);
+
+	NKern::ThreadLeaveCS();
+
+	if(r != KErrNone)
+	  return r;
+
+	TUint* pV = (TUint*)iChunk->LinearAddress();
+
+	// Allocate physical RAM for secure display
+	NKern::ThreadEnterCS();
+	r = Epoc::AllocPhysicalRam(iSize,Syborg::VideoRamPhysSecure);
+	if (r != KErrNone)
+	{
+	        NKern::ThreadLeaveCS();
+		Kern::Fault("AllocVideoRam 2",r);
+	}
+	iSecurevRamPhys = ivRamPhys + iSize;
+	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,iSize,EMapAttrUserRw|EMapAttrBufferedC);
+
+	NKern::ThreadLeaveCS();
+
+	if(r2 != KErrNone)
+	  return r2;
+
+	TUint* pV2 = (TUint*)iSecureChunk->LinearAddress();
+
+	//width and height set by reading board model
+	iVideoInfo.iSizeInPixels.iWidth  = width;
+	iVideoInfo.iSizeInPixels.iHeight = height;
+
+	//offset between lines depends on width of screen
+	iVideoInfo.iOffsetBetweenLines = width*4;
+
+	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
+	iVideoInfo.iOffsetToFirstPixel = KConfigOffsetToFirstPixel;
+	
+	iVideoInfo.iIsPalettized = KConfigIsPalettized;
+	iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
+	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
+	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
+	iVideoInfo.iIsMono = KConfigIsMono;
+	iVideoInfo.iVideoAddress = (TInt)pV;
+	iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
+	iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
+
+	iSecureVideoInfo = iVideoInfo;
+	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
+
+	// Alloc Physical RAM for the Composition Buffers used by OpenWF
+	// double and round the page size
+	TUint round = 2*Kern::RoundToPageSize(iSize);
+
+	r=Epoc::AllocPhysicalRam(round , iCompositionPhysical);
+	if(r!=KErrNone)
+		{
+		return r;
+		}
+	
+	return KErrNone;
+}
+
+
+TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
+{
+  if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+	return KErrArgument;
+
+  // store the current mode
+  iVideoInfo.iDisplayMode = aMode;
+
+  // store the current mode for secure screen
+  iSecureVideoInfo.iDisplayMode = aMode;
+
+  return KErrNone;
+}
+
+TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
+{
+  TInt r=KErrNone;
+  switch(aFunction)
+	{
+	case EDisplayHalScreenInfo:
+	  {
+		TPckgBuf<TScreenInfoV01> vPckg;
+		ScreenInfo(vPckg());
+		Kern::InfoCopy(*(TDes8*)a1,vPckg);
+		break;
+	  }
+	case EDisplayHalWsRegisterSwitchOnScreenHandling:
+	  {
+		iWsSwitchOnScreen=(TBool)a1;
+		break;
+	  }
+	case EDisplayHalWsSwitchOnScreen:
+	  {
+		WsSwitchOnScreen();
+		break;
+	  }
+	case EDisplayHalModeCount:
+	  {
+		TInt ndm = KConfigLcdNumberOfDisplayModes;
+		kumemput32(a1, &ndm, sizeof(ndm));
+		break;
+	  }
+	case EDisplayHalSetMode:
+	  {
+		__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode"));
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
+						return KErrPermissionDenied;
+						)
+		  r = SetDisplayMode((TInt)a1);
+		break;
+	  }
+	case EDisplayHalMode:
+	  {
+		kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
+		r = KErrNone;
+		break;
+	  }
+	case EDisplayHalSetPaletteEntry:
+	  {
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
+						return KErrPermissionDenied;
+						)
+		  r = KErrNotSupported;
+		break;
+	  }
+	case EDisplayHalPaletteEntry:
+	  {
+		TInt entry;
+		kumemget32(&entry, a1, sizeof(TInt));
+		r = KErrNotSupported;
+		break;
+	  }
+	case EDisplayHalSetState:
+	  {
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
+						return KErrPermissionDenied;
+						)
+		  if((TBool)a1)
+			WsSwitchOnScreen();
+		  else
+			WsSwitchOffScreen();
+		break;
+	  }
+	case EDisplayHalState:
+	  {
+		kumemput32(a1, &iDisplayOn, sizeof(TBool));
+		break;
+	  }
+	case EDisplayHalColors:
+	  {
+		TInt mdc = 1<<24;
+		kumemput32(a1, &mdc, sizeof(mdc));
+		break;
+	  }
+	case EDisplayHalCurrentModeInfo:
+	  {
+		TPckgBuf<TVideoInfoV01> vPckg;
+		r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
+		if(KErrNone == r)
+		  Kern::InfoCopy(*(TDes8*)a1,vPckg);
+		break;
+	  }
+	case EDisplayHalSpecifiedModeInfo:
+	  {
+		TPckgBuf<TVideoInfoV01> vPckg;
+		TInt mode;
+		kumemget32(&mode, a1, sizeof(mode));
+		r = GetSpecifiedDisplayModeInfo(mode, vPckg());
+		if(KErrNone == r)
+		  Kern::InfoCopy(*(TDes8*)a2,vPckg);
+		break;
+	  }	
+	case EDisplayHalSecure:
+	  {
+		kumemput32(a1, &iSecureDisplay, sizeof(TBool));
+		break;
+	  }
+	case EDisplayHalSetSecure:
+	  {
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
+						return KErrPermissionDenied;
+						)
+		  SwitchDisplay((TBool)a1);
+		break;
+	  }
+	default:
+	  {
+		r = KErrNotSupported;
+		break;
+	  }			
+	}
+  return r;
+}
+
+TInt DLcdPowerHandler::Create()
+{
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create") );
+	pLcd			= this;
+
+	iPortAddr = KHwBaseClcd;
+
+	TInt r = AllocateFrameBuffer();
+	if(r == KErrNone)
+		{
+		r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this);
+		}
+	    
+	if(r != KErrNone)
+		{
+		__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create failed %d", r) );
+		return r;
+		}
+
+	iPowerUpDfc.SetDfcQ(iDfcQ);
+	iPowerDownDfc.SetDfcQ(iDfcQ);
+	iMsgQ.SetDfcQ(iDfcQ);
+	iMsgQ.Receive();
+
+	Add();
+	DisplayOn();
+
+	return KErrNone;
+}
+
+/**
+ * Register the call back function.
+ * Components interested in receiving notification of the Vsync interrupt should register a callback function.
+ */
+EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr)
+{
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) );
+
+	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
+
+	if(aCbPtr != NULL)
+		{
+		if ( pLcd->iAppCallBk[0] == NULL  )
+			{
+			pLcd->iAppCallBk[0] = aCbPtr;
+			}
+		else
+			{
+			if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn))
+				{
+				pLcd->iAppCallBk[1] = aCbPtr;
+				}
+			else
+				{
+				__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+				return KErrInUse;
+				}
+			}
+
+		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+		__KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::RegisterCallBack ok %08x\n",aCbPtr->iCbFn) );
+		return KErrNone;
+		}
+	else
+		{
+		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+		__KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL"));
+		return KErrArgument;
+		}
+}
+
+
+/**
+ *DeRegister the call back function
+ */
+EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr)
+{
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
+
+	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
+	if(aCbPtr != NULL)
+		{
+	    if( pLcd->iAppCallBk[0] != NULL)
+			{
+			if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) )
+				{
+				pLcd->iAppCallBk[0] = NULL;
+				}
+			}
+
+		if( pLcd->iAppCallBk[1] != NULL)
+			{
+			if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) )
+				{
+				pLcd->iAppCallBk[1] = NULL;
+				}
+			}
+		}
+	__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
+}
+
+/**
+	Constructor
+*/
+DDisplayPddSyborg::DDisplayPddSyborg():
+	iPendingBuffer(NULL),
+	iActiveBuffer(NULL),
+	iChunk(NULL),
+	iLcdCallback(NULL),
+	iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority)
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::DDisplayPddSyborg\n");
+
+	iPostFlag = EFalse;
+	}
+
+/**
+	Destructor
+*/
+DDisplayPddSyborg::~DDisplayPddSyborg()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::~DDisplayPddSyborg()  \n");
+
+	if(iLcdCallback)
+		{
+		DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ;
+		delete iLcdCallback;
+		iLcdCallback = NULL;
+		}
+
+	//The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point.
+	if (iDfcQ)
+		{
+		iDfcQ=NULL;
+		}
+
+	DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0);
+
+	if(chunk)
+		{
+		Kern::ChunkClose(chunk);
+		}
+
+	}
+
+/**
+    Set the Legacy Mode by setting the appropriate Frame control value.
+
+*/
+TInt DDisplayPddSyborg::SetLegacyMode()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::SetLegacyMode()\n");
+
+    return KErrNone;
+	}
+
+/**
+    Set the GCE mode by posting a composition buffer.
+
+*/
+TInt DDisplayPddSyborg::SetGceMode()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::SetGceMode()\n");
+
+    PostCompositionBuffer(&iLdd->iCompositionBuffer[0]);
+    return KErrNone;
+	}
+
+/**
+	@param	aDegOfRot  The requested rotation
+	@return KErrNone
+*/
+TInt DDisplayPddSyborg::SetRotation(RDisplayChannel::TDisplayRotation aDegOfRot)
+	{
+	return KErrNone;
+	}
+
+/**
+    Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+    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
+    be posted next. Layer 3 is associated with user buffers.
+
+	@param	aNode  Pointer to the User buffer to post.
+*/
+TInt DDisplayPddSyborg::PostUserBuffer(TBufferNode* aNode)
+	{
+
+	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostUserBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
+
+	if(iPendingBuffer)
+		{
+		iPendingBuffer->iState = EBufferFree;
+		if (!(iPendingBuffer->iType == EBufferTypeUser) )
+			{
+			iPendingBuffer->iFree  = ETrue;
+			}
+		}
+
+	aNode->iState   = EBufferPending;
+	iPendingBuffer	= aNode;
+	iPostFlag		= ETrue;
+	
+  	// Activate the posted buffer
+	TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
+  	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
+	/* Queue a DFC to complete the request*/
+	iVSyncDfc.Enque();
+
+	return KErrNone;
+	}
+
+/**
+    Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+    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
+    be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively.
+
+	@param	aNode  Pointer to the Composition buffer to post.
+*/
+TInt DDisplayPddSyborg::PostCompositionBuffer(TBufferNode* aNode)
+	{
+
+	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostCompositionBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
+
+	if(iPendingBuffer)
+		{
+		iPendingBuffer->iState = EBufferFree;
+		if (iPendingBuffer->iType == EBufferTypeUser)
+			{
+			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
+			}
+		else
+			{
+			iPendingBuffer->iFree  = ETrue;
+			}
+		}
+	aNode->iState	= EBufferPending;
+	aNode->iFree	= EFalse;
+	iPendingBuffer	= aNode;
+	iPostFlag		= ETrue;
+
+  	// Activate the posted buffer
+	TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
+  	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
+	
+	/* Queue a DFC to complete the request*/
+	iVSyncDfc.Enque();
+
+	return KErrNone;
+	}
+
+/**
+    Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+    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
+    be posted next.Layer 0 is associated with legacy buffer.
+
+	@param	aNode  Pointer to the Composition buffer to post.
+*/
+TInt DDisplayPddSyborg::PostLegacyBuffer()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::PostLegacyBuffer() \n");
+
+	if(iPendingBuffer)
+		{
+		iPendingBuffer->iState = EBufferFree;
+		if (iPendingBuffer->iType == EBufferTypeUser)
+			{
+
+			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
+			}
+		else
+			{
+			iPendingBuffer->iFree  = ETrue;
+			}
+		}
+
+
+	iLdd->iLegacyBuffer[0].iState		= EBufferPending;
+	iLdd->iLegacyBuffer[0].iFree		= EFalse;
+	iPendingBuffer						= &iLdd->iLegacyBuffer[0];
+	iPostFlag		= ETrue;
+
+  	// Activate the posted buffer
+  	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, TSyborg::VideoRamPhys() );
+
+	/* Queue a DFC to complete the request*/
+	iVSyncDfc.Enque();
+
+	return KErrNone;
+	}
+
+/**
+    Handles device specific operations when a close message has been sent to the Logical Channel.
+
+*/
+TInt DDisplayPddSyborg::CloseMsg()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::CloseMsg()\n");
+
+	iPendingBuffer  = NULL;
+	iActiveBuffer	= NULL;
+
+	iVSyncDfc.Cancel();
+    return KErrNone;
+	}
+
+/**
+    Called by the LDD's DoCreate function to handle the device specific part of opening the channel.
+    (DoCreate is called by RDisplayChannel::Open)
+
+	@param aUnit	The screen unit
+
+    @return KErrNone if successful; or one of the other system wide error codes.
+*/
+TInt DDisplayPddSyborg::CreateChannelSetup(TInt aUnit)
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::CreateChannelSetup\n");
+
+	iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo;
+	iLdd->iUnit = aUnit;
+
+	iLdd->iDisplayInfo.iAvailableRotations			= RDisplayChannel::ERotationNormal;
+	iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines	= iScreenInfo.iOffsetBetweenLines;
+	iLdd->iDisplayInfo.iNormal.iHeight				= iScreenInfo.iSizeInPixels.iHeight;
+	iLdd->iDisplayInfo.iNormal.iWidth				= iScreenInfo.iSizeInPixels.iWidth;
+	iLdd->iDisplayInfo.iNumCompositionBuffers		= KDisplayCBMax;
+	iLdd->iDisplayInfo.iBitsPerPixel				= iScreenInfo.iBitsPerPixel;
+    iLdd->iDisplayInfo.iRefreshRateHz = 60;
+
+
+	switch (iScreenInfo.iBitsPerPixel)
+		{
+		case 16:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565;
+			break;
+		case 24:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888;
+			break;
+		case 32:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888;
+			break;
+		default:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown;
+			break;
+		}
+
+	iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal;
+
+	// Open shared chunk to the composition framebuffer
+
+	DChunk* chunk = 0;
+	TLinAddr chunkKernelAddr  = 0;
+	TUint32 chunkMapAttr = 0;
+
+	// round to twice the page size
+	TUint round  =  2*Kern::RoundToPageSize(DLcdPowerHandler::pLcd->iSize);
+
+	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::CreateChannelSetup DLcdPowerHandler::pLcd->iSize  = %d\n", DLcdPowerHandler::pLcd->iSize );
+
+	TChunkCreateInfo info;
+	info.iType					 = TChunkCreateInfo::ESharedKernelMultiple;
+	info.iMaxSize				 = round;
+	info.iMapAttr				 = EMapAttrFullyBlocking;
+	info.iOwnsMemory			 = EFalse;
+	info.iDestroyedDfc			 = 0;
+
+	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
+
+	__GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr  = %08x\n", chunkKernelAddr );
+
+	if( r == KErrNone)
+		{
+		// map our chunk
+		r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical);
+		__GCE_DEBUG_PRINT2("Mapping chunk %d", r);
+		if(r != KErrNone)
+			{
+			Kern::ChunkClose(chunk);
+			}
+		}
+
+	if ( r!= KErrNone)
+		{
+		return r;
+		}
+
+	iChunk	= chunk;
+
+	// init CB 0
+	iLdd->iCompositionBuffer[0].iType			= EBufferTypeComposition;
+	iLdd->iCompositionBuffer[0].iBufferId		= 0;
+	iLdd->iCompositionBuffer[0].iFree			= ETrue;
+	iLdd->iCompositionBuffer[0].iState			= EBufferFree;
+	iLdd->iCompositionBuffer[0].iAddress		= chunkKernelAddr;
+	iLdd->iCompositionBuffer[0].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr);
+	iLdd->iCompositionBuffer[0].iChunk			= chunk;
+	iLdd->iCompositionBuffer[0].iHandle			= 0;
+	iLdd->iCompositionBuffer[0].iOffset			= 0;
+	iLdd->iCompositionBuffer[0].iSize			= DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[0].iPendingRequest = 0;
+
+	// init CB 1
+	iLdd->iCompositionBuffer[1].iType			= EBufferTypeComposition;
+	iLdd->iCompositionBuffer[1].iBufferId		= 1;
+	iLdd->iCompositionBuffer[1].iFree			= ETrue;
+	iLdd->iCompositionBuffer[1].iState			= EBufferFree;
+	iLdd->iCompositionBuffer[1].iAddress		= chunkKernelAddr + DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[1].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr + DLcdPowerHandler::pLcd->iSize);
+	iLdd->iCompositionBuffer[1].iChunk			= chunk;
+	iLdd->iCompositionBuffer[1].iHandle			= 0;
+	iLdd->iCompositionBuffer[1].iOffset			= DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[1].iSize			= DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[1].iPendingRequest = 0;
+
+	iLdd->iCompositionBuffIdx					= 0;
+	//Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread.
+	iDfcQ= DLcdPowerHandler::pLcd->iDfcQ;
+
+	// Set the Post DFC.
+	iVSyncDfc.SetDfcQ(iDfcQ);
+
+
+	return KErrNone;
+	}
+
+/**
+Detect whether a post operation is pending
+*/
+TBool DDisplayPddSyborg::PostPending()
+	{
+	return (iPendingBuffer != NULL);
+	}
+
+/**
+	Return the DFC queue to be used for this device.
+ */
+TDfcQue * DDisplayPddSyborg::DfcQ(TInt aUnit)
+	{
+	return iDfcQ;
+	}
+
+void DDisplayPddSyborg::VSyncDfcFn(TAny* aChannel)
+	{
+	DDisplayPddSyborg * channel =(DDisplayPddSyborg*)aChannel;
+
+	if (channel->iPostFlag)
+		{
+		 channel->iPostFlag = EFalse;
+
+		if (channel->iActiveBuffer)
+			{
+			//When a User buffer is registered its iFree member becomes EFalse and Deregister sets it
+			//back to ETrue. Composition and Legacy buffers are not free when they are in the pending or
+			//active state.
+			if (channel->iActiveBuffer->iType == EBufferTypeUser)
+				{
+				channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone);
+				}
+			else
+				{
+				channel->iActiveBuffer->iFree	= ETrue;
+				}
+
+			channel->iActiveBuffer->iState		= EBufferFree;
+
+
+			//If no buffer was available during a call to GetCompositionBuffer the active buffer has
+			//been returned as the next available one, so we must set the buffer to the proper state before we
+			//send the notification.
+			TInt pendingIndex = channel->iLdd->iPendingIndex[RDisplayChannel::EReqGetCompositionBuffer];
+			if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq)
+			{
+				if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq->IsReady())
+				{
+				channel->iActiveBuffer->iState = EBufferCompose;
+				channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer,KErrNone);
+				}
+
+			}
+
+			channel->iActiveBuffer				= NULL;
+			}
+
+		if (channel->iPendingBuffer)
+			{
+			__GCE_DEBUG_PRINT2("DDisplayPddSyborg::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress);
+			channel->iActiveBuffer			= channel->iPendingBuffer;
+			channel->iActiveBuffer->iState	= EBufferActive;
+			channel->iPendingBuffer			= NULL;
+
+			channel->RequestComplete(RDisplayChannel::EReqWaitForPost,  KErrNone);
+			}
+		}
+	}
+//*****************************************************************
+//DDisplayPddFactory
+//*****************************************************************/
+
+
+/**
+	Constructor
+*/
+DDisplayPddFactory::DDisplayPddFactory()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n");
+
+	iVersion		= TVersion(KDisplayChMajorVersionNumber,
+                      KDisplayChMinorVersionNumber,
+                      KDisplayChBuildVersionNumber);
+	}
+
+/**
+	PDD factory function. Creates a PDD object.
+
+	@param  aChannel  A pointer to an PDD channel object which will be initialised on return.
+
+	@return KErrNone  if object successfully allocated, KErrNoMemory if not.
+*/
+TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
+	{
+	DDisplayPddSyborg *device= new DDisplayPddSyborg() ;
+	aChannel=device;
+	if (!device)
+		{
+		return KErrNoMemory;
+		}
+	return KErrNone;
+	}
+
+
+/**
+    Set the Pdd name and return error code
+*/
+TInt DDisplayPddFactory::Install()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n");
+
+	TBuf<32> name(RDisplayChannel::Name());
+	_LIT(KPddExtension,".pdd");
+	name.Append(KPddExtension);
+	return SetName(&name);
+	}
+
+
+void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const
+	{
+	//Not supported
+	}
+
+
+/**
+    Validate version and number of units.
+*/
+TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
+	{
+	if (!Kern::QueryVersionSupported(iVersion,aVer))
+		{
+		return KErrNotSupported;
+		}
+
+	if (aUnit != 0)
+		{
+		return KErrNotSupported;
+		}
+
+	return KErrNone;
+	}
+
+DECLARE_EXTENSION_PDD()
+/**
+	"Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called
+
+	@return pointer to the PDD factory object.
+*/
+	{
+	__GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n");
+	return new DDisplayPddFactory ;
+	}
+
+
+DECLARE_STANDARD_EXTENSION()
+{
+  TInt r = KErrNoMemory;
+  DLcdPowerHandler* pH=new DLcdPowerHandler;
+  if(pH)
+	{
+	r = pH->Create();
+	if ( r == KErrNone)
+		{
+		TInt r = Kern::DfcQCreate(pH->iDfcQ, 29 , &KLitLcd);
+
+		if(r!=KErrNone)
+		{
+			return r;
+		}
+
+		DDisplayPddFactory * device = new DDisplayPddFactory;
+
+		if (device==NULL)
+			{
+			r=KErrNoMemory;
+			}
+		else
+			{
+			r=Kern::InstallPhysicalDevice(device);
+			}
+
+		#ifdef CPU_AFFINITY_ANY
+        NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny);
+		#endif
+
+		__KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r));
+
+		}
+	}
+  
+  return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.h	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,301 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Accenture Ltd - Syborg framebuffer improvements, now auto determines frame size from board model, performance and memory improvements
+*
+* Description: Minimalistic frame buffer driver
+*
+*/
+
+#ifndef _SVPFRAMEBUFFER_H
+#define _SVPFRAMEBUFFER_H
+
+#include <display.h>
+
+#include <videodriver.h>
+#include <system.h>
+
+#define __SVPFRAMEBUFFER_DEBUG
+
+#ifdef __SVPFRAMEBUFFER_DEBUG
+
+#define  __GCE_DEBUG_PRINT(a) 		Kern::Printf(a)
+#define  __GCE_DEBUG_PRINT2(a,b) 	Kern::Printf(a,b)
+
+#else
+
+#define  __GCE_DEBUG_PRINT(a)
+#define  __GCE_DEBUG_PRINT2(a,b)
+
+#endif
+
+// Macro to calculate the screen buffer size
+// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and aLpp number of lines per panel
+#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp)	((aBpp/8)*aPpl*aLpp)	
+
+_LIT(KLitLcd,"SYBORG_FB");
+
+
+const TInt	KConfigLcdWidthInTwips     = 1996;
+const TInt	KConfigLcdHeightInTwips    = 3550;
+
+const TBool KConfigIsMono              = 0;
+const TBool KConfigIsPalettized        = 0;
+const TInt  KCOnfigOffsetToFirstPixel  = 0;
+const TBool KConfigPixelOrderRGB       = 0;
+const TBool KConfigPixelOrderLandscape = 1;
+const TInt  KConfigLcdDisplayMode       = 2;
+
+const TInt KConfigOffsetToFirstPixel =0;
+
+const TInt  KConfigLcdNumberOfDisplayModes = 3;
+
+
+const TInt  KConfigBitsPerPixel        = 32;
+
+
+const TInt   KVSyncDfcPriority							= 7 ;   //priority of DFC within the queue (0 to 7, where 7 is highest)
+
+/********************************************************************/
+/* Class Definition                                                 */
+/********************************************************************/
+/**
+ * This class defines a callback mechanism that is used by a resource user to specify its callback. It contains a
+ * function pointer and data pointer. The function pointer specifies the user callback function to be invoked by the
+ * resource while the data pointer specifies the data to be passed to the callback function.
+ */
+class TLcdUserCallBack
+    {
+public:
+    // The constructor for the callback mechanism.
+    TLcdUserCallBack(TInt (*aFunction)(TUint aResID, TAny* aPtr), TAny* aPtr)
+
+        {
+        iCbFn = aFunction;
+        iDataPtr = aPtr;
+        }
+
+public:
+    // The callback function pointer.
+    TInt (*iCbFn)(TUint aResID, TAny* aPtr);
+
+    // Pointer to the data structure to be passed to the callback function.
+    TAny *iDataPtr;
+    };
+
+class DLcdPowerHandler : public DPowerHandler
+{
+public: // from DPowerHandler
+  void PowerDown(TPowerState);
+  void PowerUp();
+public:	// to prevent a race condition with WServer trying to power up/down at the same time
+  void PowerUpDfc();
+  void PowerDownDfc();
+public:
+  DLcdPowerHandler();
+  TInt Create();
+  void DisplayOn();
+  void DisplayOff();
+  TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
+
+  void PowerUpLcd(TBool aSecure);
+  void PowerDownLcd();
+
+  void ScreenInfo(TScreenInfoV01& aInfo);
+  void WsSwitchOnScreen();
+  void WsSwitchOffScreen();
+  void HandleMsg(TMessageBase* aMsg);
+  void SwitchDisplay(TBool aSecure);
+
+private:
+  TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
+  TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
+  TInt SetDisplayMode(TInt aMode);
+  TInt AllocateFrameBuffer();
+
+public:
+    IMPORT_C static    TInt    RegisterCallback(TLcdUserCallBack* aCbPtr);
+    IMPORT_C static    void    DeRegisterCallback(TLcdUserCallBack* aCbPtr);
+  
+private:
+  TBool iDisplayOn;
+  DPlatChunkHw* iChunk;
+  DPlatChunkHw* iSecureChunk;
+  TBool iWsSwitchOnScreen;
+  TBool iSecureDisplay;
+
+public:
+  TDfcQue* iDfcQ;
+  TMessageQue iMsgQ;					// to prevent a race condition with Power Manager trying to power up/down at the same time
+  TDfc iPowerUpDfc;
+  TDfc iPowerDownDfc;	
+
+private:
+  NFastMutex iLock;
+  TPhysAddr ivRamPhys;
+  TPhysAddr iSecurevRamPhys;
+  TLcdUserCallBack * iAppCallBk[2];
+
+public:
+  TVideoInfoV01 iVideoInfo;
+  TVideoInfoV01 iSecureVideoInfo;
+  TInt			iSize;
+  TLinAddr iPortAddr;
+  TPhysAddr		iCompositionPhysical;
+  static   DLcdPowerHandler 	* pLcd;
+
+enum {
+    FB_ID               = 0,
+    FB_BASE             = 1,
+    FB_HEIGHT           = 2,
+    FB_WIDTH            = 3,
+    FB_ORIENTATION      = 4,
+    FB_BLANK            = 5,
+    FB_INT_MASK         = 6,
+    /* begin new interface */
+    FB_INTERRUPT_CAUSE  = 7,
+    FB_BPP              = 8,
+    FB_COLOR_ORDER      = 9,
+    FB_BYTE_ORDER       = 10,
+    FB_PIXEL_ORDER      = 11,
+    FB_ROW_PITCH        = 12,
+    FB_ENABLED          = 13,
+    FB_PALETTE_START    = 0x400 >> 2,
+    FB_PALETTE_END   = FB_PALETTE_START+256-1,
+    /* end new interface */
+    };
+
+#define FB_INT_VSYNC            (1U << 0)
+#define FB_INT_BASE_UPDATE_DONE (1U << 1)
+
+};
+
+class DDisplayPddSyborg : public DDisplayPdd
+	{
+
+	public:
+	DDisplayPddSyborg();
+	~DDisplayPddSyborg();
+    
+  	/**  
+    Called by the LDD to handle the device specific part of switching to Legacy mode.
+ 
+	@return KErrNone if successful; or one of the other system wide error codes.
+    */    
+    virtual TInt  SetLegacyMode();
+        
+     /**
+     Called by the LDD to handle the device specific part of switching to GCE mode.
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */       
+    virtual TInt  SetGceMode();
+    
+     /**
+     Called by the LDD to handle the device specific part of setting the rotation.
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */       
+	virtual TInt  SetRotation(RDisplayChannel::TDisplayRotation aRotation);
+
+     /**
+     Called by the LDD to handle the device specific part of posting a User Buffer.
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */ 	
+	virtual TInt  PostUserBuffer(TBufferNode* aNode);
+	
+     /**
+     Called by the LDD to handle the device specific part of posting a Composition Buffer
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */ 		
+	virtual TInt  PostCompositionBuffer(TBufferNode* aNode);
+        
+     /**
+     Called by the LDD to handle the device specific part of posting the Legacy Buffuer
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */   
+    virtual TInt  PostLegacyBuffer();
+    
+    /**
+     Called by the LDD to handle device specific cleanup operations when a channel is closed.
+          
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */  
+    virtual TInt  CloseMsg();
+            
+     /**
+     Called by the LDD to handle device specific initialisation tasks when a channel is opened.
+     
+     @param aUnit The screen/hardware unit number.
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */    
+    virtual TInt  CreateChannelSetup(TInt aUnit);
+          
+     /**
+     Called by the LDD in order to detect whether a post operation is pending. This type of 
+     information is specific to the actual physical device.
+     
+     @return ETrue if a Post operation is pending otherwise EFalse.
+     */       
+   	virtual TBool  PostPending();
+    
+    /**
+     Called by the LDD to retrieve the DFC Queue created in the PDD.      
+     
+     @param aUnit The screen/hardware unit number.
+     @return A pointer to the TDfcQue object created in the PDD.
+     */    
+    virtual TDfcQue* DfcQ(TInt  aUnit);    
+            
+public:
+	static void VSyncDfcFn(TAny* aChannel);
+
+private:
+	TDfcQue* 		iDfcQ;
+
+    //generic  display info
+	TVideoInfoV01    	iScreenInfo;
+
+    //Pointer to a buffer in the Pending state
+    TBufferNode*     	iPendingBuffer;
+
+     //Pointer to a buffer in the Active state
+    TBufferNode*     	iActiveBuffer;
+
+    DChunk * 		 	iChunk;
+    TLcdUserCallBack*   iLcdCallback;
+
+ public:
+	TDfc 		     	iVSyncDfc;
+	};
+
+
+/**
+ PDD Factory class
+ */
+
+class DDisplayPddFactory : public DPhysicalDevice
+	{
+public:
+	DDisplayPddFactory();
+
+	virtual TInt Install();
+	virtual void GetCaps(TDes8& aDes) const;
+	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+	virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <variant.mmh>
+#include "kernel/kern_ext.mmh"
+
+TARGET			VariantTarget(svpframebuffer,dll)
+TARGETTYPE		kext
+
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
+SYSTEMINCLUDE	AsspNKernIncludePath
+SYSTEMINCLUDE	.
+
+SOURCEPATH		.
+SOURCE			svpframebuffer.cpp
+
+LIBRARY			PlatformLib
+
+EPOCALLOWDLLDATA
+
+UID			    0x1000008d 0x100039e8
+VENDORID        0x70000001
+
+ROMTARGET		lcd.dll
+
+CAPABILITY		all
--- a/baseport/syborg/svphostfs/svphostfs.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/svphostfs/svphostfs.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -22,6 +22,7 @@
 LIBRARY        euser.lib efsrv.lib efile.lib hal.lib
 SYSTEMINCLUDE  inc	
 SYSTEMINCLUDE  /epoc32/include 
+OS_LAYER_SYSTEMINCLUDE
 
 CAPABILITY		DISKADMIN ALLFILES
 VENDORID 0x70000001
--- a/baseport/syborg/svphostfs/svphostfsdriver.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/svphostfs/svphostfsdriver.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -24,6 +24,7 @@
 systeminclude		inc
 systeminclude		../svpplatform/libfdt
 systeminclude 		/epoc32/include/stdapis
+OS_LAYER_LIBC_SYSTEMINCLUDE
 
 target			VariantTarget(svphostfsdriver,ldd)
 linkas			svphostfsdriver.ldd
--- a/baseport/syborg/svphostfs/svphostfsstart.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/svphostfs/svphostfsstart.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -22,6 +22,7 @@
 LIBRARY        euser.lib efsrv.lib efile.lib hal.lib
 SYSTEMINCLUDE  inc	
 SYSTEMINCLUDE  /epoc32/include 
+OS_LAYER_SYSTEMINCLUDE
 
 CAPABILITY		DISKADMIN ALLFILES
 VENDORID 0x70000001
--- a/baseport/syborg/svphostfs/svphostfsy.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/svphostfs/svphostfsy.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -24,6 +24,7 @@
 
 SYSTEMINCLUDE	inc	
 SYSTEMINCLUDE	/epoc32/include 
+OS_LAYER_SYSTEMINCLUDE
 
 LIBRARY			efsrv.lib euser.lib hal.lib
 LIBRARY			efile.lib
--- a/baseport/syborg/svpplatform/fdt.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/svpplatform/fdt.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -20,6 +20,7 @@
 
 systeminclude 		libfdt
 systeminclude 		/epoc32/include/stdapis
+OS_LAYER_LIBC_SYSTEMINCLUDE
 
 sourcepath		libfdt
 
--- a/baseport/syborg/svpsnapdriver/snapapp.mmp	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/svpsnapdriver/snapapp.mmp	Sun Mar 14 13:16:31 2010 +0000
@@ -20,7 +20,7 @@
 SOURCEPATH	   src
 SOURCE         snapapp.cpp rsvpsnapdriver.cpp
 LIBRARY        euser.lib efsrv.lib
-SYSTEMINCLUDE  /epoc32/include 
+OS_LAYER_SYSTEMINCLUDE  
 
 CAPABILITY		TCB DISKADMIN ALLFILES
 VENDORID 0x70000001
Binary file baseport/syborg/syborg.dtb has changed
--- a/baseport/syborg/syborg.dts	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/syborg.dts	Sun Mar 14 13:16:31 2010 +0000
@@ -50,6 +50,8 @@
         };
         framebuffer@0 {
             compatible = "syborg,framebuffer";
+	    width = <168>;
+            height = <280>;
             reg = <c0005000>;
             interrupts = <4>;
             interrupt-parent = <&intc>;
--- a/baseport/syborg/variant.mmh	Mon Mar 08 21:42:58 2010 +0000
+++ b/baseport/syborg/variant.mmh	Sun Mar 14 13:16:31 2010 +0000
@@ -15,6 +15,8 @@
 *
 */
 
+#include <platform_paths.hrh>
+
 //macro   __CPU_ARM926J__
 //#define __CPU__ ARM926EJ-S
 
@@ -119,6 +121,11 @@
 systeminclude	/epoc32/include/memmodel/epoc/multiple
 systeminclude	/epoc32/include/memmodel/epoc/multiple/arm
 
+SYMBIAN_BASE_SYSTEMINCLUDE(memmodel/epoc/mmubase)
+SYMBIAN_BASE_SYSTEMINCLUDE(memmodel/epoc/multiple)
+SYMBIAN_BASE_SYSTEMINCLUDE(memmodel/epoc/multiple/arm)
+OS_LAYER_SYSTEMINCLUDE
+
 systeminclude	../../../../os/kernelhwsrv/driversupport/socassp/interface
 
 // Uncomment for T_USERCOMDEB test
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c	Mon Mar 08 21:42:58 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c	Sun Mar 14 13:16:31 2010 +0000
@@ -26,6 +26,7 @@
 #include "devtree.h"
 #include "hw/boards.h"
 #include "libfdt/libfdt.h"
+#include "qemu-char.h"
 
 #define BADF(fmt, args...) \
 do { fprintf(stderr, "error: " fmt , ##args); exit(1);} while (0)
@@ -413,7 +414,15 @@
         if (propstr) {
             i = sscanf(propstr, "serial%d", &n);
             if (i == 1 && n >= 0 && n < MAX_SERIAL_PORTS)
+            {
+                if (!serial_hds[n])
+                {
+                    const char* target = fdt_getprop_string(dt, node, "target");
+                    if (target)
+                        serial_hds[n] = qemu_chr_open(propstr, target);
+                }
                 d->chardev = serial_hds[n];
+            }
         }
     }
     find_properties(d);
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py	Mon Mar 08 21:42:58 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py	Sun Mar 14 13:16:31 2010 +0000
@@ -1,4 +1,6 @@
 import qemu
+import os
+import sys
 
 class syborg_serial(qemu.devclass):
   REG_ID           = 0
@@ -127,6 +129,57 @@
   regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)]
   irqs = 1
   name = "syborg,serial"
-  properties = {"fifo-size":16, "chardev":None}
+  properties = {"fifo-size":16, "chardev":None, "target": ""}
 
 qemu.register_device(syborg_serial)
+
+class syborg_modem(syborg_serial):
+  
+  def create(self):
+    syborg_serial.create(self)
+    
+    # Find the path of the emulator executable
+    path = os.path.dirname(sys.executable)
+    executable = os.getenv("SVP_MODEM_EXECUTABLE")
+    if None == executable:
+      executable = self.modem_executable
+    
+    executable_name = executable
+    fq_executable = os.path.join(path, executable_name)
+    print(fq_executable)
+    
+    if not os.path.exists(fq_executable):
+      executable_name = executable + ".exe"
+      fq_executable = os.path.join(path, executable_name)
+      
+      if not os.path.exists(fq_executable):
+        sys.exit("Could not locate modem executable '" + executable + "' in '" + path + "'!\n")
+    
+    # Attempt to find the correct port from the target spec
+    target = self.properties["target"]
+    
+    if not(target.startswith("tcp:") or target.startswith("udp:")):
+      sys.exit("Modem device is not accessed via an acceptable socket.")
+    
+    target = target[4:]
+    port_start_idx = target.find(":");
+    port_end_idx = target.find(",")
+    if -1 == port_start_idx:
+      sys.exit("Could not extract port number from modem target spec!")
+    
+    port = ""
+    if -1 == port_end_idx:
+      port = target[port_start_idx + 1:]
+    else:
+      port = target[port_start_idx + 1:port_end_idx]
+    
+    os.spawnl(os.P_NOWAIT, fq_executable, executable_name, "-p", port)
+    self.chardev.handle_connect()
+  
+  # Name property override.
+  name = "syborg,serial,modem"
+  
+  # Default modem executable
+  modem_executable = "phonesim"
+
+qemu.register_device(syborg_modem)
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c	Mon Mar 08 21:42:58 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c	Sun Mar 14 13:16:31 2010 +0000
@@ -1072,6 +1072,17 @@
     return 0;
 }
 
+static PyObject *qemu_py_chardev_handle_connect(qemu_py_chardev *self,
+                                     PyObject *args)
+{
+    if (!self->chr)
+        Py_RETURN_NONE;
+    
+    qemu_chr_connect(self->chr);
+    
+    Py_RETURN_NONE; 
+}
+
 static PyObject *qemu_py_chardev_set_handlers(qemu_py_chardev *self,
                                               PyObject *args, PyObject *kwds)
 {
@@ -1147,6 +1158,9 @@
 };
 
 static PyMethodDef qemu_py_chardev_methods[] = {
+    {"handle_connect", (PyCFunction)qemu_py_chardev_handle_connect,
+      METH_NOARGS,
+      "Handle character device connect if required"},
     {"set_handlers", (PyCFunction)qemu_py_chardev_set_handlers,
       METH_VARARGS|METH_KEYWORDS,
      "Set event handlers"},
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c	Mon Mar 08 21:42:58 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c	Sun Mar 14 13:16:31 2010 +0000
@@ -123,6 +123,12 @@
     }
 }
 
+void qemu_chr_connect(CharDriverState *s)
+{
+    if (s->chr_connect)
+        s->chr_connect(s);
+}
+
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
 {
     return s->chr_write(s, buf, len);
@@ -605,6 +611,20 @@
     return qemu_chr_open_fd(-1, fd_out);
 }
 
+static CharDriverState *qemu_chr_open_tempfile_out(const char *temp_file)
+{
+    CharDriverState *ret = NULL;
+    const char *temp_format = "/tmp/%s";
+    char *fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file)));
+    if (fname)
+    {
+        sprintf(fname, temp_format, temp_file);
+        ret = qemu_chr_open_file_out(fname);
+        qemu_free(fname);
+    }
+    return ret;
+}
+
 static CharDriverState *qemu_chr_open_pipe(const char *filename)
 {
     int fd_in, fd_out;
@@ -1757,6 +1777,29 @@
 
     return qemu_chr_open_win_file(fd_out);
 }
+
+static CharDriverState *qemu_chr_open_win_tempfile_out(const char *temp_file)
+{
+    CharDriverState *ret = NULL;
+    char* fname;
+    const char* temp_format = "%s\\%s";
+    const char* temp_path;
+    
+    temp_path = getenv("TEMP");
+    if (temp_path)
+    {
+        fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file) + strlen(temp_format)));
+        if (fname)
+        {
+            sprintf(fname, temp_format, temp_path, temp_file);
+            ret = qemu_chr_open_win_file_out(fname);
+            qemu_free(fname);
+        }
+    }
+
+    return ret;
+}
+
 #endif /* !_WIN32 */
 
 /***********************************************************/
@@ -1886,6 +1929,8 @@
     int do_telnetopt;
     int do_nodelay;
     int is_unix;
+    int wait_connect;
+    int device_handles_connect;
 } TCPCharDriver;
 
 static void tcp_chr_accept(void *opaque);
@@ -2063,6 +2108,26 @@
     tcp_chr_connect(chr);
 }
 
+static void tcp_chr_do_connect(CharDriverState* chr)
+{
+    TCPCharDriver *driver = (TCPCharDriver*)chr->opaque;
+    if (driver->device_handles_connect)
+    {
+        if (-1 != driver->listen_fd)
+        {
+            printf("QEMU waiting for connection...\n");
+            tcp_chr_accept(chr);
+            socket_set_nonblock(driver->listen_fd);
+        }
+        else
+        {
+            driver->connected = 1;
+            socket_set_nodelay(driver->fd);
+            tcp_chr_connect(chr);
+        }
+    }
+}
+
 static void tcp_chr_close(CharDriverState *chr)
 {
     TCPCharDriver *s = chr->opaque;
@@ -2083,6 +2148,7 @@
     int is_listen = 0;
     int is_waitconnect = 1;
     int do_nodelay = 0;
+    int is_device_handles_connect = 0;
     const char *ptr;
 
     ptr = host_str;
@@ -2096,6 +2162,8 @@
             do_nodelay = 1;
         } else if (!strncmp(ptr,"to=",3)) {
             /* nothing, inet_listen() parses this one */;
+        } else if (!strncmp(ptr, "devicehandlesconnect", 20) && !is_unix) {
+            is_device_handles_connect = 1;
         } else {
             printf("Unknown option: %s\n", ptr);
             goto fail;
@@ -2107,6 +2175,7 @@
     chr = qemu_mallocz(sizeof(CharDriverState));
     if (!chr)
         goto fail;
+        
     s = qemu_mallocz(sizeof(TCPCharDriver));
     if (!s)
         goto fail;
@@ -2147,10 +2216,13 @@
     s->listen_fd = -1;
     s->is_unix = is_unix;
     s->do_nodelay = do_nodelay && !is_unix;
+    s->wait_connect = is_waitconnect;
+    s->device_handles_connect = is_device_handles_connect;
 
     chr->opaque = s;
     chr->chr_write = tcp_chr_write;
     chr->chr_close = tcp_chr_close;
+    chr->chr_connect = tcp_chr_do_connect;
 
     if (is_listen) {
         s->listen_fd = fd;
@@ -2158,13 +2230,17 @@
         if (is_telnet)
             s->do_telnetopt = 1;
     } else {
-        s->connected = 1;
         s->fd = fd;
-        socket_set_nodelay(fd);
-        tcp_chr_connect(chr);
+        
+        if (!is_device_handles_connect)
+        {
+            s->connected = 1;
+            socket_set_nodelay(fd);
+            tcp_chr_connect(chr);
+        }
     }
 
-    if (is_listen && is_waitconnect) {
+    if (is_listen && is_waitconnect && !is_device_handles_connect) {
         printf("QEMU waiting for connection on: %s\n",
                chr->filename ? chr->filename : host_str);
         tcp_chr_accept(chr);
@@ -2220,6 +2296,8 @@
 	chr = qemu_chr_open_tcp(p, 0, 1);
     } else if (strstart(filename, "file:", &p)) {
         chr = qemu_chr_open_file_out(p);
+    } else if (strstart(filename, "tempfile:", &p)) {
+        chr = qemu_chr_open_tempfile_out(p);
     } else if (strstart(filename, "pipe:", &p)) {
         chr = qemu_chr_open_pipe(p);
     } else if (!strcmp(filename, "pty")) {
@@ -2252,6 +2330,9 @@
     if (strstart(filename, "file:", &p)) {
         chr = qemu_chr_open_win_file_out(p);
     } else
+    if (strstart(filename, "tempfile:", &p)) {
+        chr = qemu_chr_open_win_tempfile_out(p);
+    } else
     if (strstart(filename, "stdio", &p)) {
         return qemu_chr_open_win_stdio(filename);
     } else
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h	Mon Mar 08 21:42:58 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h	Sun Mar 14 13:16:31 2010 +0000
@@ -46,6 +46,7 @@
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
     void (*chr_update_read_handler)(struct CharDriverState *s);
     int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
+    void (*chr_connect)(struct CharDriverState *s);
     IOEventHandler *chr_event;
     IOCanRWHandler *chr_can_read;
     IOReadHandler *chr_read;
@@ -64,6 +65,7 @@
 CharDriverState *qemu_chr_open(const char *label, const char *filename);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
+void qemu_chr_connect(CharDriverState *s);
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
 void qemu_chr_add_handlers(CharDriverState *s,
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c	Mon Mar 08 21:42:58 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c	Sun Mar 14 13:16:31 2010 +0000
@@ -4666,14 +4666,12 @@
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
     monitor_device = "vc";
-
-    serial_devices[0] = "vc:80Cx24C";
-    for(i = 1; i < MAX_SERIAL_PORTS; i++)
+    
+    for(i = 0; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i] = NULL;
     serial_device_index = 0;
-
-    parallel_devices[0] = "vc:640x480";
-    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
+    
+    for(i = 0; i < MAX_PARALLEL_PORTS; i++)
         parallel_devices[i] = NULL;
     parallel_device_index = 0;