void DMediaDriverNVMemory::Disconnect( DLocalDrive* aLocalDrive, TThreadMessage* aMsg ) { __DEBUG_PRINT(">DMediaDriverNVMemory::Disconnect()"); // Complete using the default implementation DMediaDriver::Disconnect(aLocalDrive, aMsg); __DEBUG_PRINT("<DMediaDriverNVMemory::Disconnect()"); }
void DMediaDriverNVMemory::DoTransactionLaunchDfc() { __DEBUG_PRINT(">DMediaDriverNVMemory::DoTransactionLaunchDfc()"); TInt request = iCurrentRequest->Id(); TInt r(KErrNone); switch (request) { case DLocalDrive::ERead: r=Read(); break; case DLocalDrive::EWrite: r=Write(); break; case DLocalDrive::EFormat: r=Format(); break; case DLocalDrive::EEnlarge: case DLocalDrive::EReduce: default: r=KErrNotSupported; break; } if( r != KErrNone ) { // TODO some proper error handling here } __DEBUG_PRINT("<MediaDriverNVMemory::DoTransactionLaunchDfc %d",r); }
DECLARE_STANDARD_EXTENSION() { __DEBUG_PRINT("Registering NVMEM drive"); TInt r=KErrNoMemory; DPrimaryMediaBase* pM=new DPrimaryMediaBase; TDynamicDfcQue* NVMemoryDfcQ; r = Kern::DynamicDfcQCreate( NVMemoryDfcQ, KNVMemDfcThreadPriority, KNVMemDriveName ); if( r == KErrNone ) { pM->iDfcQ = NVMemoryDfcQ; } else { __DEBUG_PRINT("NVMEM DFCQ initialization failed"); } if (pM) { r=LocDrv::RegisterMediaDevice(EFixedMedia1,NVMEM1_DRIVECOUNT,&NVMemDriveNumbers[0],pM,NVMEM1_NUMMEDIA,KNVMemDriveName); } pM->iMsgQ.Receive(); __DEBUG_PRINT("Registering NVMEM drive - return %d",r); return r; }
TInt DMediaDriverNVMemory::Read() { __DEBUG_PRINT(">DMediaDriverNVMemory::Read() pos: %lx, size: %lx", iPos, iTotalLength); // Set our sector offset TUint32 transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); TUint32 transactionLength = 0; TUint32 transactionDirection = NVMEM_TRANSACTION_READ; // Do we have an operation longer than our shared memory? if( iSplitted > 0 ) { transactionLength = KNVMemTransferBufferSize; } else { // Do the whole operation in one go since we have enough room in our memory transactionLength = I64LOW(iTotalLength); // Read the "broken" tail sector if( iTail ) { transactionLength += iTail; iAlignmentOverhead += iTail; } } // Read the "broken" head sector if( iHead > 0 ) { transactionLength += iHead; iAlignmentOverhead += iHead; } // We should be ok to continue ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection ); __DEBUG_PRINT("<DMediaDriverNVMemory::Read()"); return KErrNone; }
TInt DMediaDriverNVMemory::DoCreate(TInt /*aMediaId*/) // // Create the media driver. // { __DEBUG_PRINT(">DMediaDriverNVMemory::DoCreate"); TInt r = KErrNone; // Inform our size Int64 size=GetNVMemSize()<<KDiskSectorShift; if( size<=0 ) { Kern::Fault("DMediaDriverNVMemory zero size nv memory array", 0); } SetTotalSizeInBytes(size); // Some dfc initialization if( r==KErrNone ) { iSessionEndDfc.SetDfcQ( this->iPrimaryMedia->iDfcQ ); iTransactionLaunchDfc.SetDfcQ( this->iPrimaryMedia->iDfcQ ); } // Create our piece of physically contiguous transfer buffer. r = Epoc::AllocPhysicalRam( KNVMemTransferBufferSize, iTransferBufferPhys ); if( r != KErrNone ) { Kern::Fault("DMediaDriverNVMemory Allocate Ram %d",r); } DPlatChunkHw* bufChunk = NULL; // Create HW Memory Chunk r = DPlatChunkHw::New( bufChunk, iTransferBufferPhys, KNVMemTransferBufferSize, EMapAttrUserRw | EMapAttrFullyBlocking ); if( r != KErrNone ) { // Check Physical Memory if( iTransferBufferPhys ) { // Free Physical Memory Epoc::FreePhysicalRam( iTransferBufferPhys, KNVMemTransferBufferSize ); } Kern::Fault("DMediaDriverNVMemory error in creating transfer buffer", r); } // Set Main Buffer Pointer iTransferBufferLin = reinterpret_cast<TUint8*>(bufChunk->LinearAddress()); // Inform "hardware" about the shared memory WriteReg( KHwNVMemoryDevice, R_NVMEM_SHARED_MEMORY_BASE, iTransferBufferPhys ); WriteReg( KHwNVMemoryDevice, R_NVMEM_SHARED_MEMORY_SIZE, KNVMemTransferBufferSize ); WriteReg( KHwNVMemoryDevice, R_NVMEM_ENABLE, 1 ); // Set up interrupt service r = Interrupt::Bind( EIntNVMemoryDevice, Isr, this ); Interrupt::Enable( EIntNVMemoryDevice ); __DEBUG_PRINT("<DMediaDriverNVMemory::DoCreate %d", r); return(r); }
void DPhysicalDeviceMediaNVMemory::GetCaps(TDes8& /*aDes*/) const // // Return the media drivers capabilities. // { __DEBUG_PRINT("DPhysicalDeviceMediaNVMemory::GetCaps()"); }
TInt DMediaDriverStaticRD::ContinueTransaction( TUint32 aTransactionSectorOffset, TUint32 aTransactionSectorCount, TUint32 aTransactionDirection ) { __DEBUG_PRINT("DMediaDriverStaticRD::ContinueTransaction() sectoroffset: %d, sectorcount: %d, direction: %d", aTransactionSectorOffset, aTransactionSectorCount, aTransactionDirection); if( aTransactionDirection != NVMEM_TRANSACTION_UNDEFINED ) { //WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_OFFSET, aTransactionSectorOffset ); //WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_SIZE, aTransactionSectorCount ); //WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_DIRECTION, aTransactionDirection ); //WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_EXECUTE, aTransactionDirection ); if ( aTransactionDirection == NVMEM_TRANSACTION_WRITE ) { memcpy( (TAny *)(iDiscBufferLin+(aTransactionSectorOffset<<9)), iTransferBufferLin, aTransactionSectorCount*512 ); } else if ( aTransactionDirection == NVMEM_TRANSACTION_READ ) { memcpy( iTransferBufferLin, (TAny *)(iDiscBufferLin+(aTransactionSectorOffset<<9)), aTransactionSectorCount*512 ); } iLatestTransferSectorCount = aTransactionSectorCount; Isr(this); // terrible hack, we've yransferred all the sectors and now we pretend to generate an interrupt } else { Kern::Fault("DMediaDriverStaticRD::ContinueTransaction: Undefined transaction!", 0); } return KErrNone; }
TInt DPhysicalDeviceMediaNVMemory::Install() // // Install the Internal NVMem PDD. // { __DEBUG_PRINT("DPhysicalDeviceMediaNVMemory::Install()"); return SetName(&KNVMemPddName); }
int sthread_cond_wait(sthread_cond_t *cond, sthread_mutex_t *mutex) { if(cond->cond) { __DEBUG_PRINT(("tid %d cond 1 \n", __selftid)); setup_sync(); wait_to_enter(); __DEBUG_PRINT(("tid %d cond 2 \n", __selftid)); // if(__threadpool[]) v_next_mutex(mutex->mutex); __threadpool[__selftid].mutex = NULL; __mvspace_commit(); __threadpool[__selftid].state = E_STOPPED; __threadpool[__selftid].cond = cond->cond; __DEBUG_PRINT(("tid %d cond 3 \n", __selftid)); v_next_and_wait(); __DEBUG_PRINT(("tid %d cond 4 \n", __selftid)); __mvspace_pull(); __DEBUG_PRINT(("tid %d cond 5 \n", __selftid)); wait_sem(cond->cond->locks, __selftid); __threadpool[__selftid].mutex = mutex->mutex; __DEBUG_PRINT(("tid %d cond 5.5 \n", __selftid)); wait_sem(mutex->mutex->locks, __selftid); __threadpool[__selftid].state = E_NORMAL; __DEBUG_PRINT(("tid %d cond 6 \n", __selftid)); leave_sync(); return 0; } return -1; }
TInt DPhysicalDeviceMediaNVMemory::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer) { __DEBUG_PRINT("DPhysicalDeviceMediaNVMemory::Validate()"); if (!Kern::QueryVersionSupported(iVersion,aVer)) return KErrNotSupported; if (aDeviceType!=EFixedMedia1) return KErrNotSupported; return KErrNone; }
DPhysicalDeviceMediaNVMemory::DPhysicalDeviceMediaNVMemory() // // Constructor // { __DEBUG_PRINT(">DPhysicalDeviceMediaNVMemory::DPhysicalDeviceMediaNVMemory"); iUnitsMask=0x1; iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion); }
TInt DPhysicalDeviceMediaNVMemory::Info(TInt aFunction, TAny*) // // Return the priority of this media driver // { __DEBUG_PRINT("DPhysicalDeviceMediaNVMemory::Info()"); if (aFunction==EPriority) return KMediaDriverPriorityNormal; return KErrNotSupported; }
DMediaDriverNVMemory::DMediaDriverNVMemory(TInt aMediaId) // // Constructor. // : DMediaDriver(aMediaId), iSessionEndDfc(DMediaDriverNVMemory::SessionEndDfc, this, 1), iTransferBufferPhys(0), iTransactionLaunchDfc(DMediaDriverNVMemory::TransactionLaunchDfc, this, KMaxDfcPriority) { __DEBUG_PRINT("DMediaDriverNVMemory::DMediaDriverNVMemory()"); }
TInt DMediaDriverNVMemory::PartitionInfo(TPartitionInfo& anInfo) // // Return partition information on the media. // { __DEBUG_PRINT("DMediaDriverNVMemory::PartitionInfo()"); anInfo.iPartitionCount=1; anInfo.iEntry[0].iPartitionBaseAddr=0; anInfo.iEntry[0].iPartitionLen=anInfo.iMediaSizeInBytes=TotalSizeInBytes(); anInfo.iEntry[0].iPartitionType=KPartitionTypeFAT16; return KErrCompletion; }
int sthread_cond_signal(sthread_cond_t *cond) { if(cond->cond) { int i; __DEBUG_PRINT(("tid %d signal 1 \n", __selftid)); setup_sync(); __DEBUG_PRINT(("tid %d signal 2 \n", __selftid)); wait_to_enter(); __DEBUG_PRINT(("tid %d signal 3 \n", __selftid)); __mvspace_commit(); v_next_and_wait(); __DEBUG_PRINT(("tid %d signal 3 \n", __selftid)); __mvspace_pull(); for(i=0;i<MAXTHREADS;i++) post_sem(cond->cond->locks, i); __DEBUG_PRINT(("tid %d signal 4 \n", __selftid)); leave_sync(); __DEBUG_PRINT(("tid %d signal 5 \n", __selftid)); return 0; } return -1; }
DDisplayLdd::~DDisplayLdd() { __DEBUG_PRINT("DDisplayLdd::~DDisplayLdd() \n"); // cancel outstanding requests and destroy the queue of TClientRequest objects for(TInt k = 0; k < KPendingReqArraySize ; k++) { for(TInt i = 0; i < KMaxQueuedRequests; i++) { //Method IsReady() returns true if the client’s request SetStatus method has been called but the //coresponding QueueRequestComplete method hasn't. if(iPendingReq[k][i].iTClientReq) { if(iPendingReq[k][i].iTClientReq->IsReady() ) { CompleteRequest(iPendingReq[k][i].iOwningThread,iPendingReq[k][i].iTClientReq,KErrCancel); } } Kern::DestroyClientRequest(iClientRequest[k][i]); } } //Close User Buffer chunks not yet destroyed. for(TInt i = 0; i < KDisplayUBMax; i++) { if(iUserBuffer[i].iChunk != 0) { Kern::ChunkClose(iUserBuffer[i].iChunk); iUserBuffer[i].iChunk= NULL; } } Kern::SafeClose((DObject*&)iClient, NULL); if (iClientRequestMutex != NULL) { iClientRequestMutex->Close(NULL); } __ASSERT_DEBUG(iThreadOpenCount == 0,Kern::Fault(KDisplayLddPanic,__LINE__)); __ASSERT_DEBUG(iAsyncReqCount == 0,Kern::Fault(KDisplayLddPanic,__LINE__)); // Clear the 'units open mask' in the LDD factory. if (iUnit>=0) ((DDisplayLddFactory*)iDevice)->SetUnitOpen(iUnit,EFalse); #ifdef _DEBUG // Close the UDEB user mode chunk, if it exists if (iChunk) Kern::ChunkClose(iChunk); #endif // _DEBUG }
TInt DMediaDriverNVMemory::Format() { __DEBUG_PRINT("DMediaDriverNVMemory::Format() pos: 0x%lx, size: 0x%lx", iPos, iTotalLength); memset( iTransferBufferLin, 0x00, KNVMemTransferBufferSize ); // Stop the nonsense here. Write operations should be used for partial sector data removal operations if( iHead > 0 || iTail > 0 ) { Kern::Fault("DMediaDriverNVMemory::Format: alignment violation!", 0); } Write(); // DoTransaction( m, NVMEM_TRANSACTION_WRITE ); return KErrNone; }
void DMediaDriverNVMemory::CompleteRequest(TInt aReason) // // completes the request which is being currently processed // { __DEBUG_PRINT("DMediaDriverNVMemory::CompleteRequest() reason: %d", aReason); TLocDrvRequest* pR=iCurrentRequest; if (pR) { iCurrentRequest=NULL; DMediaDriver::Complete(*pR,aReason); } }
void DMediaDriverNVMemory::Isr(TAny* aPtr) { __DEBUG_PRINT(">DMediaDriverNVMemory::Isr"); DMediaDriverNVMemory* nvMem = reinterpret_cast<DMediaDriverNVMemory*>(aPtr); // Save the amount of transferred sectors. This clears the interrupt from HW as well nvMem->iLatestTransferSectorCount = ReadReg( KHwNVMemoryDevice, R_NVMEM_STATUS ); // Clear from framework Interrupt::Clear( EIntNVMemoryDevice ); nvMem->iSessionEndDfc.Add(); }
TInt DMediaDriverNVMemory::ContinueTransaction( TUint32 aTransactionSectorOffset, TUint32 aTransactionSectorCount, TUint32 aTransactionDirection ) { __DEBUG_PRINT("DMediaDriverNVMemory::ContinueTransaction() sectoroffset: %d, sectorcount: %d, direction: %d", aTransactionSectorOffset, aTransactionSectorCount, aTransactionDirection); if( aTransactionDirection != NVMEM_TRANSACTION_UNDEFINED ) { WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_OFFSET, aTransactionSectorOffset ); WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_SIZE, aTransactionSectorCount ); WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_DIRECTION, aTransactionDirection ); WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_EXECUTE, aTransactionDirection ); } else { Kern::Fault("DMediaDriverNVMemory::ContinueTransaction: Undefined transaction!", 0); } return KErrNone; }
/************************************************************************************ * DDisplayLdd LDD class implementation ************************************************************************************/ DDisplayLdd::DDisplayLdd() { __DEBUG_PRINT("DDisplayLdd::DDisplayLdd()\n"); // store the pointer to the current thread for request completion iClient = &Kern::CurrentThread(); __NK_ASSERT_DEBUG(iClient); // Open a reference on the client thread so it's control block can't disappear until the driver has finished with it. iClient->Open(); iCurrentPostCount = 0; iRequestedPostCount = 0; iCompositionBuffIdx = 0; iUnit = -1; iThreadOpenCount = 0; iAsyncReqCount = 0; iClientRequestMutex = 0; }
TInt DMediaDriverNVMemory::Caps(TLocDrvRequest& m) { __DEBUG_PRINT("DMediaDriverNVMemory::Caps()"); TLocalDriveCapsV6& caps=*(TLocalDriveCapsV6*)m.RemoteDes(); caps.iType=EMediaHardDisk; caps.iConnectionBusType=EConnectionBusInternal; caps.iDriveAtt=KDriveAttLocal|KDriveAttInternal; caps.iMediaAtt=KMediaAttFormattable; caps.iFileSystemId=KDriveFileSysFAT; caps.iPartitionType=KPartitionTypeFAT16; caps.iSize=m.Drive()->iPartitionLen; caps.iHiddenSectors=0; caps.iEraseBlockSize = KNVMemTransferBufferSize; caps.iBlockSize=KDiskSectorSize; caps.iMaxBytesPerFormat = KNVMemTransferBufferSize; return KErrCompletion; }
void sthread_shared(void *addr, size_t size) { __setup_sync(); // __DEBUG_PRINT(("tid %d shared 0 \n", __selftid)); // __DEBUG_PRINT(("tid %d shared 0.1 barrier %d \n", __selftid, *(__global_barrier1.val))); wait_to_enter(); // __DEBUG_PRINT(("tid %d shared 0.2 barrier %d \n", __selftid, *(__global_barrier1.val))); // __DEBUG_PRINT(("tid %d shared 1 \n", __selftid)); // if(__selftid == 1) { // __acquire_lock(__sharedlist->lock); if(!__in_sharedlist(addr)) { __DEBUG_PRINT(("tid %d shared 1.05 barrier %d \n", __selftid, *(__global_barrier1.val))); void *p = mvshared_malloc(size); void *p2 = mvshared_malloc(size); int __vamsize = __sharedlist->__vamsize; (__sharedlist->__vamap)[__vamsize].addr = addr; // __DEBUG_PRINT(("tid %d shared 1.1 barrier %d \n", __selftid, *(__global_barrier1.val))); (__sharedlist->__vamap)[__vamsize].addr = addr; // __DEBUG_PRINT(("tid %d shared 1.15 barrier %d \n", __selftid, *(__global_barrier1.val))); (__sharedlist->__vamap)[__vamsize].shared = p; // __DEBUG_PRINT(("tid %d shared 1.2 barrier %d \n", __selftid, *(__global_barrier1.val))); (__sharedlist->__vamap)[__vamsize].backup = p2; // __DEBUG_PRINT(("tid %d shared 1.3 barrier %d \n", __selftid, *(__global_barrier1.val))); (__sharedlist->__vamap)[__vamsize].size = size; // __DEBUG_PRINT(("tid %d shared 1.4 p2 %ld p %ld barrierpoint %ld \n", __selftid, p2, p, (__global_barrier1.val))); // memcpy(p2, addr, size); // memcpy(p, addr, size); __mem_copy(p2, addr, size); __mem_copy(p, addr, size); // __DEBUG_PRINT(("tid %d shared 1.5 barrier %d \n", __selftid, *(__global_barrier1.val))); (__sharedlist->__vamsize)++; // __DEBUG_PRINT(("tid %d shared 1.6 barrier %d \n", __selftid, *(__global_barrier1.val))); } // __release_lock(__sharedlist->lock); v_next_and_wait(); // __DEBUG_PRINT(("tid %d shared 2 \n", __selftid)); leave_sync(); // __DEBUG_PRINT(("tid %d shared 3 \n", __selftid)); // } }
TInt DPhysicalDeviceMediaNVMemory::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer) // // Create an Internal Ram media driver. // { __DEBUG_PRINT("DPhysicalDeviceMediaNVMemory::Create()"); if (!Kern::QueryVersionSupported(iVersion,aVer)) return KErrNotSupported; TInt r=KErrNoMemory; DMediaDriverNVMemory* pD=new DMediaDriverNVMemory(aMediaId); aChannel=pD; if (pD) { r=pD->DoCreate(aMediaId); } if( r==KErrNone ) { pD->OpenMediaDriverComplete(KErrNone); } return r; }
int sthread_barrier_wait(sthread_barrier_t *barrier) { if(barrier->barrier) { setup_sync(); //setup_barrier_sync(barrier->barrier); __DEBUG_PRINT(("tid %d barrier1\n", __selftid)); wait_to_enter(); __mvspace_commit(); __threadpool[__selftid].state = E_STOPPED; __threadpool[__selftid].barrier = barrier->barrier; __DEBUG_PRINT(("tid %d barrier2\n", __selftid)); v_next_and_wait(); setup_barrier_sync(barrier->barrier); __sync_fetch_and_add(&(barrier->barrier->num), 1); __DEBUG_PRINT(("tid %d barrier3\n", __selftid)); __mvspace_pull(); if(barrier->barrier->total == barrier->barrier->num) { int i; for(i=0;i<MAXTHREADS;i++) { if(__threadpool[i].barrier == barrier->barrier) __threadpool[i].state = E_NORMAL; } __DEBUG_PRINT(("tid %d barrier3.5\n", __selftid)); barrier->barrier->inited = 0; post_sem(barrier->barrier->sema, 0); } __DEBUG_PRINT(("tid %d barrier4\n", __selftid)); wait_sem(barrier->barrier->sema, 0); __DEBUG_PRINT(("tid %d barrier5\n", __selftid)); post_sem(barrier->barrier->sema, 0); __threadpool[__selftid].barrier = NULL; __threadpool[__selftid].state = E_NORMAL; leave_sync(); return 0; } return -1; }
/** LDD second stage constructor */ TInt DDisplayLdd::DoCreate(TInt aUnit, const TDesC8* /* anInfo*/, const TVersion& aVer) { __DEBUG_PRINT("DDisplayLdd::DoCreate()\n"); if( !Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt, __PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") ) || !Kern::CurrentThreadHasCapability(ECapabilityReadDeviceData, __PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") ) || !Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") ) || !Kern::CurrentThreadHasCapability(ECapabilityProtServ, __PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") ) ) { return KErrPermissionDenied; } // Check that the display driver version specified by the client is compatible. if (!Kern::QueryVersionSupported(RDisplayChannel::VersionRequired(),aVer)) { return(KErrNotSupported); } // Check that a channel hasn't already been opened on this unit. TInt r=((DDisplayLddFactory*)iDevice)->SetUnitOpen(aUnit,ETrue); // Try to update 'units open mask' in the LDD factory. if (r!=KErrNone) return r; iUnit=aUnit; Pdd()->iLdd = this; r = Pdd()->CreateChannelSetup(aUnit); if ( r!= KErrNone) { return r; } // set up user buffer nodes for (TInt node = 0; node < KDisplayUBMax; node++) { iUserBuffer[node].iType = EBufferTypeUser; iUserBuffer[node].iBufferId = (node + 1); iUserBuffer[node].iFree = ETrue; iUserBuffer[node].iState = EBufferFree; iUserBuffer[node].iAddress = 0; iUserBuffer[node].iSize = 0; iUserBuffer[node].iHandle = 0; iUserBuffer[node].iChunk = 0; iUserBuffer[node].iOffset = 0; iUserBuffer[node].iPendingRequest = 0; } //Initialise pending queue for asynchronous requests and queue of TClientRequests for(TInt k = 0; k < KPendingReqArraySize; k++) { iPendingIndex[k]=0; for(TInt i = 0; i < KMaxQueuedRequests; i++) { iPendingReq[k][i].iTClientReq = 0; iPendingReq[k][i].iOwningThread = 0; r = Kern::CreateClientRequest(iClientRequest[k][i]); if (r != KErrNone) { return r; } } } r = Kern::MutexCreate(iClientRequestMutex, KClientRequestMutex, KMutexOrder); if (r != KErrNone) { return r; } Pdd()->SetGceMode(); SetDfcQ(Pdd()->DfcQ(aUnit)); iMsgQ.Receive(); return KErrNone; }
DECLARE_EXTENSION_PDD() { __DEBUG_PRINT(">MediaDriverNVMemory create device"); return new DPhysicalDeviceMediaNVMemory; }
TUint32 DMediaDriverNVMemory::GetNVMemSize( void ) { __DEBUG_PRINT("DMediaDriverNVMemory::GetNVMemSize()"); TUint32 sizeInSectors = ReadReg( KHwNVMemoryDevice, R_NVMEM_NV_MEMORY_SIZE ); return sizeInSectors; }
void DMediaDriverNVMemory::DoSessionEndDfc() { __DEBUG_PRINT(">DMediaDriverNVMemory::DoSessionEndDfc()"); TInt r = KErrNone; // Check that we have a request in process if( iCurrentRequest ) { // Transaction variables TUint32 transactionSectorOffset(0); TUint32 transactionLength(0); TUint32 transactionDirection( NVMEM_TRANSACTION_UNDEFINED ); // How much did we actually transfer? TUint32 latestTransferSize = (iLatestTransferSectorCount * KDiskSectorSize); __DEBUG_PRINT("DMediaDriverNVMemory::DoSessionEndDfc() latestTransferSize: %d", latestTransferSize ); // Subtract alignment overhead latestTransferSize = latestTransferSize - iAlignmentOverhead; // For decision whether the buffer is ready for operation already TBool bufferReady(EFalse); // For decision whether we have finished the latest request TBool sessionComplete(EFalse); // Was there a read-modify-write (RWM) for which we need to do some buffer manipulation before proceeding? // Note that in case of format we triggered to alignment violation in earlier method already and can not enter to following // condition when there is a format operation going on if( iReadModifyWrite ) { bufferReady = ETrue; iReadModifyWrite = EFalse; // Was it a splitted operation for which we only need to take care of the broken head sector. if( iSplitted > 0 ) { // We have a sector here here filled with data from mass memory. Modify with client data. __DEBUG_PRINT("DMediaDriverNVMemory::DoSessionEndDfc() readremote splitted: %d head: %d", latestTransferSize, iHead ); TPtr8 targetDescriptor(&iTransferBufferLin[iHead], KNVMemTransferBufferSize - iHead); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start r = iCurrentRequest->ReadRemote(&targetDescriptor,iSplitLength); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end } // Else we need to take care of both head and tail else { // We have a piece of data read from mass memory. Modify with client data. __DEBUG_PRINT("DMediaDriverNVMemory::DoSessionEndDfc() readremote: %d head: %d", I64LOW(iTotalLength - iProsessedLength), iHead ); TPtr8 targetDescriptor(&iTransferBufferLin[iHead], I64LOW(iTotalLength - iProsessedLength)); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start r = iCurrentRequest->ReadRemote(&targetDescriptor,iSplitLength); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end // latestTransferSize -= (KDiskSectorSize - iTail); iTail = 0; } // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start iSplitLength+= latestTransferSize; // Update split transfer position count // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end } else { // Overhead is processed when we enter here iAlignmentOverhead = 0; // Update position iPos += latestTransferSize; // Save the information on how many bytes we transferred already iProsessedLength += latestTransferSize; // Update the splitted information. We don't take head into account here anymore since it is already taken care of iSplitted = (iTotalLength - iProsessedLength + iTail) / KNVMemTransferBufferSize; // Check if we have done already if( iProsessedLength >= iTotalLength ) { // If this was the final transfer for this request let's take tail into account as well (if not taken already) // iProsessedLength -= iTail; // latestTransferSize -= iTail; if( iProsessedLength > iTotalLength ) { Kern::Fault("DMediaDriverNVMemory: Illegal transfer operation!", 0); } sessionComplete = ETrue; } } TInt request = iCurrentRequest->Id(); // Set our sector offset transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); if( bufferReady ) { // Write as much as we read in RMW operation transactionLength = (iLatestTransferSectorCount * KDiskSectorSize); } else { // Do we have an operation longer than our shared memory? if( iSplitted > 0 ) { transactionLength = KNVMemTransferBufferSize; } else { // Do the whole operation in one go since we have enough room in our memory transactionLength = I64LOW(iTotalLength - iProsessedLength); // Read the "broken" tail sector if( iTail > 0 && request == DLocalDrive::EWrite ) { iReadModifyWrite = ETrue; // Read the "broken" tail sector transactionLength += iTail; iAlignmentOverhead = iTail; } } } // Was there a need to read-modify before writing if( iReadModifyWrite ) { transactionDirection = NVMEM_TRANSACTION_READ; } else { if( request == DLocalDrive::ERead ) { transactionDirection = NVMEM_TRANSACTION_READ; // Write to client __DEBUG_PRINT("DMediaDriverNVMemory::DoSessionEndDfc() WriteRemote: %d head: %d", latestTransferSize, iHead ); TPtrC8 sourceDescriptor(&iTransferBufferLin[iHead], latestTransferSize); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start r = iCurrentRequest->WriteRemote( &sourceDescriptor, iSplitLength ); // Allow for "splitted" operations // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end } // Head is processed iHead = 0; if( request == DLocalDrive::EWrite && !sessionComplete ) { transactionDirection = NVMEM_TRANSACTION_WRITE; if( bufferReady ) { // Actually no need for any actions here } else { // Prepare a buffer for transfer __DEBUG_PRINT("DMediaDriverNVMemory::DoSessionEndDfc() ReadRemote: %d head: %d", latestTransferSize, iHead ); TPtr8 targetDescriptor(iTransferBufferLin, transactionLength); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start r = iCurrentRequest->ReadRemote(&targetDescriptor,iSplitLength); // allow for "splitted" operations // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end } } // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start iSplitLength+= latestTransferSize; // Update split transfer position count // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end if( request == DLocalDrive::EFormat ) { transactionDirection = NVMEM_TRANSACTION_WRITE; } } if( sessionComplete ) { CompleteRequest( r ); } else { ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection ); } } else { // Let's just flow through for now } __DEBUG_PRINT("<DMediaDriverNVMemory::DoSessionEndDfc()" ); }
TInt DMediaDriverNVMemory::Write() { __DEBUG_PRINT("DMediaDriverNVMemory::Write() pos: 0x%lx, size: 0x%lx", iPos, iTotalLength); TInt r = KErrNone; // Set our sector offset TUint32 transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); TUint32 transactionLength = 0; TUint32 transactionDirection = NVMEM_TRANSACTION_WRITE; // Do we have an operation longer than our shared memory? if( iSplitted > 0 ) { transactionLength = KNVMemTransferBufferSize; } else { // Do the whole operation in one go since we have enough room in our memory transactionLength = I64LOW(iTotalLength); if( iTail ) { iReadModifyWrite = ETrue; // Read the "broken" tail sector transactionLength += iTail; iAlignmentOverhead += iTail; } } // Is there a need to read modify write the "broken" head sector of the operation if( iHead > 0 ) { iReadModifyWrite = ETrue; // If splitted operation we only need the broken sector if( iSplitted > 0 ) { transactionLength = KDiskSectorSize; iAlignmentOverhead += iHead; } else { // Read the "broken" head sector in addition to everything else transactionLength += iHead; iAlignmentOverhead += iHead; } } // Was there a need to read-modify before writing if( iReadModifyWrite ) { transactionDirection = NVMEM_TRANSACTION_READ; } else { // Handle format here if( iCurrentRequest->Id() == DLocalDrive::EFormat ) { // Not much handling just flow through since we have filled the shared memory with zeroes already } else { // Read from client TPtr8 targetDescriptor(iTransferBufferLin, transactionLength); // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - start r = iCurrentRequest->ReadRemote(&targetDescriptor,iSplitLength); iSplitLength+= transactionLength; // SF BUG 3759 - NVM drives do not support operations larger than 262144 bytes correctly - end } } // We should be ok to continue ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection ); return r; }