Update contrib.
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
26 #include <e32std_private.h> // Caps.iMediaAtt
28 #include "massstoragedebug.h"
30 #include "t_ms_main.h"
31 #include "t_ms_scsi.h"
32 #include "drivepublisher.h"
39 TTestScsiTransport::TTestScsiTransport ()
45 /** InitialiseReadBuf */
46 void TTestScsiTransport::InitialiseReadBuf ()
48 // KMaxBufSize is defined in scsiprot.h
49 iBufRead.FillZ(KMaxBufSize * 2);
50 // set some values in 1/2 a buffer for testing
51 for (TInt i = 0; i<(TInt)KMaxBufSize; i++)
53 iBufRead[i] = static_cast<TInt8>(i%0x08);
58 // CTestMassStorageDrive
61 @param aOwner A reference to the drive manager, for use with aDriveStateChanged.
62 @param aDriveStateChanged A pointer to the private callback function CDriveManager::DriveStateChanged.
63 @param aCritSec A Critical Section object shared by all drives.
64 @post Object is fully constructed
66 CMassStorageDrive::CMassStorageDrive(
67 RCriticalSection& aCritSec,
68 RDriveStateChangedPublisher& aDriveStateChangedPublisher)
71 iMountState(EDisconnected),
72 iDriveStateChangedPublisher(aDriveStateChangedPublisher)
76 CMassStorageDrive::~CMassStorageDrive()
81 /** Read data from the drive */
82 TInt CMassStorageDrive::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia)
84 TInt err = KErrUnknown;
86 if( iMountState != EConnected )
88 err = KErrDisconnected;
95 err = iLocalDrive->iProxyDrive.Read(aPos, aLength, &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
99 err = iLocalDrive->iProxyDrive.Read(aPos,aLength,aBuf);
106 /** Write data to the drive */
107 TInt CMassStorageDrive::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia)
109 TInt err = KErrUnknown;
111 if( iMountState != EConnected )
113 err = KErrDisconnected;
120 err = iLocalDrive->iProxyDrive.Write(aPos, aBuf.Length(), &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
124 err = iLocalDrive->iProxyDrive.Write(aPos,aBuf);
132 TInt CMassStorageDrive::Caps(TLocalDriveCapsV4& aInfo)
134 TInt err = KErrUnknown;
136 if( iMountState != EConnected )
138 err = KErrDisconnected;
148 /** Get CAPs helper */
149 TInt CMassStorageDrive::DoCaps(TLocalDriveCapsV4& aInfo)
152 { return KErrBadHandle; }
154 TLocalDriveCapsV4Buf buf;
155 TInt err = iLocalDrive->iProxyDrive.Caps(buf);
157 // Invoke function call operator to cast to TLocalDriveCapsV4&
166 TInt CMassStorageDrive::SetMountConnected(CProxyDrive& aProxyDrive, TBool& aMediaChanged)
168 __FNLOG("CMassStorageDrive::SetMountConnected");
169 TInt err = KErrUnknown; //Never return this
171 if(iMountState == EConnected)
177 CLocalDriveRef* localDrive = new CLocalDriveRef(aProxyDrive, aMediaChanged);
178 err = (localDrive==NULL)
180 : SetMountState(EConnected, localDrive);
187 @return KErrNone on success, KErrArgument if arguments are illegal
189 @param aLocalDrive Only provide this if aNewState is EConnected, in which case it is required.
190 Only sets/clears iLocalDrive if new state is Connected or Disconnected.
192 TInt CMassStorageDrive::SetMountState(TMountState aNewState, CLocalDriveRef* aLocalDrive/*=NULL*/)
194 __FNLOG("CMassStorageDrive::SetMountState");
195 TInt err = KErrUnknown; //Never return this
197 if(iMountState != aNewState)
200 if (iMountState == EConnected && aNewState==EConnecting ||
201 iMountState == EDisconnected && aNewState==EDisconnecting)
206 iMountState = aNewState;
207 if(aNewState==EDisconnected || aNewState==EConnecting)
209 // Reset the drive state on disconnection.
210 // Note: This should be called before ProxyDrive is NULLed.
211 SetDriveState(EErrDisMounted);
214 // Only mounting and unmounting transitions affect iProxyDrive
215 if(aNewState==EConnected || aNewState==EDisconnected)
218 iLocalDrive = aLocalDrive; // possibly NULL
221 #ifndef USB_TRANSFER_PUBLISHER
222 // The data transferred counts are "since the host connected to the drive"
223 // so reset them when going to the connected state.
224 if(aNewState==EConnected)
226 iBytesWritten = iBytesRead = 0;
230 __PRINT1(_L("SetMountState: state=%d\n"), iMountState);
234 else if(aLocalDrive != iLocalDrive)
236 // Caller is not allowed to change the proxy drive
244 Checks the Media Removed flag, and optionally resets it.
245 The media has been changed (reinserted) if this function returns true
246 and the Drive State is not EMediaNotPresent.
247 @return The state of the Media Removed flag.
248 @param aReset If true, the Media Removed flag is reset to EFalse.
250 TBool CMassStorageDrive::IsMediaChanged(TBool aReset)
252 __FNLOG("CMassStorageDrive::IsMediaChanged");
254 TBool mediaChanged = EFalse;
257 mediaChanged = iLocalDrive->iMediaChanged;
260 iLocalDrive->iMediaChanged = EFalse;
267 Set the Drive State to Active or Idle.
268 @return KErrNone on success, KErrNotReady if media not present
269 @param aCritical ETrue for Active, EFalse for Idle
271 TInt CMassStorageDrive::SetCritical(TBool aCritical)
273 __FNLOG("CMassStorageDrive::SetCritical");
275 TInt err = KErrDisMounted;
278 if(iLocalDrive->iDriveState == CMassStorageDrive::EMediaNotPresent)
288 ? CMassStorageDrive::EActive
289 : CMassStorageDrive::EIdle );
299 @return Current drive media state
301 CMassStorageDrive::TDriveState CMassStorageDrive::DriveState() const
303 return iLocalDrive ? iLocalDrive->iDriveState : EErrDisMounted;
307 This test version does not check for media removal
309 CMassStorageDrive::TDriveState CMassStorageDrive::CheckDriveState()
311 return iLocalDrive ? iLocalDrive->iDriveState : EErrDisMounted;
317 void CMassStorageDrive::SetDriveState(TDriveState aNewState)
321 __PRINT2(_L("SetDriveState: %d->%d\n"), iLocalDrive->iDriveState, aNewState);
322 iLocalDrive->iDriveState = aNewState;
329 /////////////////////////////////////////////////////////////////
334 CDriveManager* CDriveManager::NewL(const RArray<TInt>& aDriveMap)
336 __FNLOG ("CDriveManager::NewL");
337 CDriveManager* self = new (ELeave) CDriveManager(aDriveMap);
338 CleanupStack::PushL(self);
346 void CDriveManager::ConstructL()
348 __FNLOG("CDriveManager::ConstructL");
349 User::LeaveIfError(iDriveCritSec.CreateLocal());
351 iDriveStateChangedPublisher = new (ELeave) RDriveStateChangedPublisher(iDrives, iDriveMap);
353 for(TInt i = 0; i < iDriveMap.Count(); i++)
355 iDrives[i] = new (ELeave) CMassStorageDrive(iDriveCritSec, *iDriveStateChangedPublisher);
358 // Publish initial drive state
359 if (iDriveMap.Count() > 0)
361 iDriveStateChangedPublisher->DriveStateChanged();
365 CDriveManager::CDriveManager(const RArray<TInt>& aDriveMap)
371 CDriveManager::~CDriveManager()
374 delete iDriveStateChangedPublisher;
375 iDriveCritSec.Close();
379 @param aDrive - a proxy drive to register
380 @param aLun - Lun to register to
381 @return system wide return code
383 TInt CDriveManager::RegisterDrive(CProxyDrive&, TBool&, TUint)
385 // not used in test code
391 @param aDrive - a proxy drive to register
392 @param aLun - Lun to register to
393 @return system wide return code
395 TInt CDriveManager::DeregisterDrive(TUint)
397 // not used in test code
402 /** get a drive by aLun
404 @param aError - operation error
405 @return pointer to drive
407 CMassStorageDrive* CDriveManager::Drive(TUint aLun, TInt& aError) const
410 CMassStorageDrive* drive = NULL;
412 if(aLun>=static_cast<TUint>(iDrives.Count()))
414 aError = KErrArgument;
418 drive = iDrives[aLun];
425 @return true if media is changed
427 @param aReset - reset flag
429 TBool CDriveManager::IsMediaChanged(TUint, TBool)
431 // not used in test code
437 Set the Drive State to Active or Idle.
438 Ref: 3.6.3.2 - PREVENT_MEDIUM_REMOVAL
439 @return KErrNone on success, otherwise system wide error code
440 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
441 @param aCritical ETrue for Active, EFalse for Idle
443 TInt CDriveManager::SetCritical(TUint aLun, TBool aCritical)
445 __PRINT1(_L("CDriveManager::SetCritical lun=%d\n"), aLun);
447 TInt err = KErrUnknown; // never return this
448 CMassStorageDrive* drive = Drive(aLun, err);
451 err = drive->SetCritical(aCritical);
457 /** connect a drive according to lun
459 @return system wide error code
461 TInt CDriveManager::Connect(TUint aLun)
464 CMassStorageDrive* drive = Drive(aLun, err);
468 drive->SetMountConnecting();
474 /** disconnect drive according to lun
476 @return system wide error code
478 TInt CDriveManager::Disconnect(TUint aLun)
481 CMassStorageDrive* drive = Drive(aLun, err);
485 drive->SetMountDisconnecting();
495 #ifdef USB_TRANSFER_PUBLISHER
496 CUsbWriteTransferPublisher* CUsbWriteTransferPublisher::NewL(
497 TRefBytesTransferedList /* aDrives */)
503 CUsbReadTransferPublisher* CUsbReadTransferPublisher::NewL(
504 TRefBytesTransferedList /* aDrives */)
510 void CUsbTransferPublisher::DoPublishDataTransferredEvent()
515 CUsbTransferPublisher::~CUsbTransferPublisher()
520 void CUsbTransferPublisher::StartTimer()
526 CDriveWriteTransferPublisher* CDriveWriteTransferPublisher::NewL(
527 TFixedArray<CMassStorageDrive*,KUsbMsMaxDrives>& /* aDrives */)
533 CDriveReadTransferPublisher* CDriveReadTransferPublisher::NewL(
534 TFixedArray<CMassStorageDrive*,KUsbMsMaxDrives>& /* aDrives */)
540 void CDriveTransferPublisher::DoPublishDataTransferredEvent()
545 CDriveTransferPublisher::~CDriveTransferPublisher()
550 void CDriveTransferPublisher::StartTimer()
556 RDriveStateChangedPublisher::RDriveStateChangedPublisher(
557 TFixedArray<CMassStorageDrive*,KUsbMsMaxDrives>& aDrives,
558 const RArray<TInt>& aDriveMap)
566 void RDriveStateChangedPublisher::DriveStateChanged()
571 RDriveMediaErrorPublisher::RDriveMediaErrorPublisher()
576 RDriveStateChangedPublisher::~RDriveStateChangedPublisher()
581 RDriveMediaErrorPublisher::~RDriveMediaErrorPublisher()
590 CProxyDrive::CProxyDrive(CMountCB* aMount)
594 TInt CProxyDrive::ControlIO(const RMessagePtr2&, TInt, TAny*, TAny*)
597 TInt CProxyDrive::Read (TInt64 aPos, TInt aLength, const TAny* aTrg, TInt, TInt, TInt)
598 { return Read(aPos, aLength, *(TDes8*)aTrg); }
600 TInt CProxyDrive::Write (TInt64 aPos, TInt, const TAny* aSrc, TInt, TInt, TInt)
601 { return Write(aPos, *(TDesC8*)aSrc); }
603 // Implemented the GetInterface method here as this are usually
604 // exported by EFILE, but these unit tests don't link to it.
606 TInt CProxyDrive::GetInterface(TInt /*aInterfaceId*/, TAny*& /*aInterface*/, TAny* /*aInput*/)
607 { return KErrNotSupported; }
609 // Implemented the GetLastErrorInfo method here as this is usually
610 // exported by EFILE, but these unit tests don't link to it.
611 TInt CProxyDrive::GetLastErrorInfo(TDes8& /*anErrorInfo*/)
612 { return KErrNotSupported; }
614 CProxyDrive::~CProxyDrive()
618 TInt CProxyDrive::DeleteNotify(TInt64, TInt)
623 CTestProxyDrive::CTestProxyDrive()
627 iCaps.iSize = KMaxBufSize * 2;
628 iCaps.iSectorSizeInBytes = 512;
629 iCaps.iNumberOfSectors = I64LOW(iCaps.iSize / iCaps.iSectorSizeInBytes);
630 iCaps.iNumPagesPerBlock = 1;
634 CTestProxyDrive::~CTestProxyDrive()
637 /** Initializs test proxy drive by initializing read buffer
640 TInt CTestProxyDrive::Initialise()
642 __FNLOG ("CTestProxyDrive::Initialise");
644 // KMaxBufSize is defined in scsiprot.h
645 iMediaBuf.FillZ(KMaxBufSize * 2);
646 // initialize 1/2 a buffer for testing
647 for (TInt i = 0; i<(TInt)KMaxBufSize; i++)
649 iMediaBuf[i] = static_cast<TInt8>(i%0x10);
656 @param aPos position to read
657 @param aLength number of bytes to read
658 @param aTrg targer buffer
659 @return KErrNone or KErrOverflow in case of an error
661 TInt CTestProxyDrive::Read(TInt64 aPos, TInt aLength, TDes8& aTrg)
663 __FNLOG ("CTestProxyDrive::Read");
665 // TInt64 is not supported by Copy()
666 ASSERT (I64HIGH(aPos) == 0);
670 if( (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos)) && (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos) + static_cast<TUint>(aLength)) )
671 { return KErrOverflow; }
673 aTrg.Copy(&iMediaBuf[I64LOW(aPos)], aLength);
678 @param aPos position to write
679 @param aSrc source buffer
680 @return KErrNone or KErrOverflow in case of an error
682 TInt CTestProxyDrive::Write (TInt64 aPos, const TDesC8& aSrc)
684 __FNLOG ("CTestProxyDrive::Write");
686 // TInt64 is not supported by Copy()
687 ASSERT(0 == I64HIGH(aPos));
691 if ( (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos)) && (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos) + static_cast<TUint>(aSrc.Length())) )
692 { return KErrOverflow; }
694 TPtr8 ptr (&iMediaBuf[I64LOW(aPos)], aSrc.Length(), aSrc.Length());
705 TReadWrite10Cmd::TReadWrite10Cmd()
707 iCmd.FillZ (iCmd.MaxLength());
710 iCmd[0] = static_cast<TInt8>(iCmd.MaxLength()-1); // size of the Cmd
713 /** accessor for BlockAddress
714 @param aAddress - new address
716 void TReadWrite10Cmd::SetBlockAddress(TUint32 aAddress)
718 iCmd[3] = static_cast<TInt8>((aAddress & 0xFF000000) >> 24);
719 iCmd[4] = static_cast<TInt8>((aAddress & 0x00FF0000) >> 16);
720 iCmd[5] = static_cast<TInt8>((aAddress & 0x0000FF00) >> 8);
721 iCmd[6] = static_cast<TInt8>(aAddress & 0x000000FF);