Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 2005-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:
// e32test\multimedia\d_mmcsc.cpp
// The interface to a device driver which creates a shared chunk - for use with the multimedia driver tests.
// This driver uses only generic kernel APIs and so need not be built from each variant.
//
//
/**
@file
@internalComponent
@test
*/
#include <kernel/kern_priv.h>
#include "d_mmcsc.h"
//#define __KTRACE_MMD(s) s;
#define __KTRACE_MMD(s)
class DMmCreateScFactory : public DLogicalDevice
{
public:
DMmCreateScFactory();
virtual TInt Install();
virtual void GetCaps(TDes8 &aDes) const;
virtual TInt Create(DLogicalChannelBase*& aChannel);
};
class DMmCreateSc : public DLogicalChannel
{
public:
DMmCreateSc();
~DMmCreateSc();
protected:
virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
virtual void HandleMsg(TMessageBase* aMsg);
TInt DoControl(TInt aId, TAny* a1, TAny* a2);
private:
TInt CreateChunk(TInt aNumBuffers,TInt aBufferSize);
void CloseChunk();
TInt MakeChunkHandle(DThread* aThread);
private:
DThread* iClient;
TMmSharedChunkBufConfig iBufferConfig;
DChunk* iChunk;
};
DECLARE_STANDARD_LDD()
{
return new DMmCreateScFactory;
}
DMmCreateScFactory::DMmCreateScFactory()
{
// Set version number for this device
iVersion=TVersion(0,1,1);
// Indicate we do support units or a PDD
iParseMask=0;
}
TInt DMmCreateScFactory::Install()
{
return(SetName(&KDevMmCScName));
}
void DMmCreateScFactory::GetCaps(TDes8& aDes) const
{
// Create a capabilities object
TCapsMmCScV01 caps;
caps.iVersion=iVersion;
// Write it back to user memory
Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
}
TInt DMmCreateScFactory::Create(DLogicalChannelBase*& aChannel)
{
aChannel=new DMmCreateSc;
if (!aChannel)
return(KErrNoMemory);
return(KErrNone);
}
DMmCreateSc::DMmCreateSc()
{
// iChunk=NULL;
iClient=&Kern::CurrentThread();
((DObject*)iClient)->Open();
}
DMmCreateSc::~DMmCreateSc()
{
CloseChunk();
Kern::SafeClose((DObject*&)iClient,NULL);
}
TInt DMmCreateSc::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
{
__KTRACE_MMD(Kern::Printf("DMmCreateSc:DoCreate"));
SetDfcQ(Kern::DfcQue0());
iMsgQ.Receive();
TInt r;
r=CreateChunk(KMmCScNumBuffers,KMmCScBufSize); // Contains two 150K buffers
return(r);
}
void DMmCreateSc::HandleMsg(TMessageBase* aMsg)
{
TThreadMessage& m=*(TThreadMessage*)aMsg;
TInt id=m.iValue;
if (id==(TInt)ECloseMsg)
{
m.Complete(KErrNone, EFalse);
return;
}
else if (id==KMaxTInt)
{
m.Complete(KErrNone,ETrue); // DoCancel
return;
}
if (id<0)
{
TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); // DoRequest
Kern::RequestComplete(iClient,pS,KErrNotSupported);
m.Complete(KErrNone,ETrue);
}
else
{
TInt r=DoControl(id,m.Ptr0(),m.Ptr1()); // DoControl
m.Complete(r,ETrue);
}
}
TInt DMmCreateSc::DoControl(TInt aId, TAny* a1, TAny* /*a2*/)
{
__KTRACE_MMD(Kern::Printf("DMmCreateSc:DoControl %x",aId));
TInt r=KErrNone;
switch (aId)
{
case RMmCreateSc::EGetChunkHandle:
{
r=MakeChunkHandle(iClient);
break;
}
case RMmCreateSc::EGetBufInfo:
{
TPtrC8 ptr((const TUint8*)&iBufferConfig,sizeof(iBufferConfig));
r=Kern::ThreadDesWrite(iClient,a1,ptr,0,KTruncateToMaxLength,NULL);
break;
}
default:
r=KErrNotSupported;
}
return(r);
}
TInt DMmCreateSc::CreateChunk(TInt aNumBuffers,TInt aBufferSize)
{
TInt bufferSize=Kern::RoundToPageSize(aBufferSize);
TInt chunkSz=(aNumBuffers*bufferSize);
__KTRACE_MMD(Kern::Printf("DMmCreateSc:CreateChunk %d",chunkSz));
// Thread must be in critical section to create chunks
NKern::ThreadEnterCS();
// Create the shared chunk.
TChunkCreateInfo info;
info.iType = TChunkCreateInfo::ESharedKernelMultiple;
info.iMaxSize = chunkSz;
#if !defined(__WINS__)
info.iMapAttr=EMapAttrFullyBlocking; // No caching
#else
info.iMapAttr=0;
#endif
info.iOwnsMemory = ETrue; // Using RAM pages
info.iDestroyedDfc = NULL; // No chunk destroy DFC
DChunk* chunk;
TLinAddr chunkKernelAddr;
TUint32 mapAttr;
TInt r = Kern::ChunkCreate(info,chunk,chunkKernelAddr,mapAttr);
if (r!=KErrNone)
{
NKern::ThreadLeaveCS();
return(r);
}
// Map the three buffers into the chunk - each containing physically contiguous RAM pages.
TInt bufOffset=0;
TUint32 pa;
r=Kern::ChunkCommitContiguous(chunk,bufOffset,bufferSize,pa);
if (r==KErrNone)
{
bufOffset+=bufferSize;
r=Kern::ChunkCommitContiguous(chunk,bufOffset,bufferSize,pa);
}
if (r==KErrNone)
{
bufOffset+=bufferSize;
r=Kern::ChunkCommitContiguous(chunk,bufOffset,bufferSize,pa);
}
if (r!=KErrNone)
Kern::ChunkClose(chunk); // Commit failed - tidy-up.
else
iChunk=chunk;
NKern::ThreadLeaveCS();
// Update our buffer info. structure to reflect the chunk we have just created.
iBufferConfig.iNumBuffers=aNumBuffers;
iBufferConfig.iBufferSizeInBytes=aBufferSize;
iBufferConfig.iFlags|=KScFlagBufOffsetListInUse;
iBufferConfig.iSpec[0].iBufferOffset=0;
iBufferConfig.iSpec[0].iBufferId=0;
iBufferConfig.iSpec[1].iBufferOffset=bufferSize;
iBufferConfig.iSpec[1].iBufferId=1;
__KTRACE_MMD(Kern::Printf("ChunkCommit %d",r));
return(r);
}
void DMmCreateSc::CloseChunk()
{
__KTRACE_MMD(Kern::Printf("DMmCreateSc:CloseChunk"));
// Thread must be in critical section to close a chunk
NKern::ThreadEnterCS();
// Close chunk
if (iChunk)
Kern::ChunkClose(iChunk);
// Can leave critical section now
NKern::ThreadLeaveCS();
}
TInt DMmCreateSc::MakeChunkHandle(DThread* aThread)
{
TInt r;
// Thread must be in critical section to make a handle
NKern::ThreadEnterCS();
if (iChunk)
r=Kern::MakeHandleAndOpen(aThread,iChunk);
else
r=KErrNotFound;
NKern::ThreadLeaveCS();
__KTRACE_MMD(Kern::Printf("DMmCreateSc:MakeChunkHandle %x %d",aThread,r));
return(r);
}