os/kernelhwsrv/kerneltest/f32test/smassstorage/scsiprot/t_ms_scsi.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @internalTechnology
    19 */
    20 
    21 
    22 #include <f32file.h>
    23 #include <e32test.h>
    24 #include <f32fsys.h>
    25 #include <e32std.h>
    26 #include <e32std_private.h>		// Caps.iMediaAtt
    27 
    28 #include "massstoragedebug.h"
    29 
    30 #include "t_ms_main.h"
    31 #include "t_ms_scsi.h"
    32 #include "drivepublisher.h"
    33 
    34 
    35 //
    36 //	TTestScsiTransport
    37 //
    38 /** c'tor */
    39 TTestScsiTransport::TTestScsiTransport ()
    40 : iProtocol(NULL),
    41   iBufWrite(NULL, 0)
    42 	{
    43 	}
    44 
    45 /** InitialiseReadBuf */
    46 void TTestScsiTransport::InitialiseReadBuf ()
    47 	{
    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++)
    52 		{
    53 		iBufRead[i] = static_cast<TInt8>(i%0x08);
    54 		}
    55 	}
    56 
    57 //
    58 //	CTestMassStorageDrive
    59 //
    60 /**
    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
    65  */
    66 CMassStorageDrive::CMassStorageDrive(
    67 	RCriticalSection& aCritSec,
    68 	RDriveStateChangedPublisher& aDriveStateChangedPublisher)
    69 	: 
    70 	iCritSec(aCritSec),
    71 	iMountState(EDisconnected),
    72 	iDriveStateChangedPublisher(aDriveStateChangedPublisher)
    73 	{
    74 	}
    75 
    76 CMassStorageDrive::~CMassStorageDrive()
    77 	{
    78 	delete iLocalDrive;
    79 	}
    80 
    81 /** Read data from the drive */
    82 TInt CMassStorageDrive::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia)
    83 	{
    84 	TInt err = KErrUnknown;
    85 	
    86 	if( iMountState != EConnected )
    87 		{
    88 		err = KErrDisconnected;
    89 		}
    90 	else
    91 		{
    92 		ASSERT(iLocalDrive);
    93 		if(aWholeMedia)
    94 			{
    95 			err = iLocalDrive->iProxyDrive.Read(aPos, aLength, &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
    96 			}
    97 		else
    98 			{
    99 			err = iLocalDrive->iProxyDrive.Read(aPos,aLength,aBuf);
   100 			}
   101 		}
   102 
   103 	return err;
   104 	}
   105 
   106 /** Write data to the drive */
   107 TInt CMassStorageDrive::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia)
   108 	{
   109 	TInt err = KErrUnknown;
   110 	
   111 	if( iMountState != EConnected )
   112 		{
   113 		err = KErrDisconnected;
   114 		}
   115 	else
   116 		{
   117 		ASSERT(iLocalDrive);
   118 		if(aWholeMedia)
   119 			{
   120 			err = iLocalDrive->iProxyDrive.Write(aPos, aBuf.Length(), &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
   121 			}
   122 		else
   123 			{
   124 			err = iLocalDrive->iProxyDrive.Write(aPos,aBuf);
   125 			}
   126 		}
   127 
   128 	return err;
   129 	}
   130 
   131 /** Get CAPs */
   132 TInt CMassStorageDrive::Caps(TLocalDriveCapsV4& aInfo)
   133 	{
   134 	TInt err = KErrUnknown;
   135 	
   136 	if( iMountState != EConnected )
   137 		{
   138 		err = KErrDisconnected;
   139 		}
   140 	else
   141 		{
   142 		err = DoCaps(aInfo);
   143 		}
   144 	
   145 	return err;
   146 	}
   147 
   148 /** Get CAPs helper */
   149 TInt CMassStorageDrive::DoCaps(TLocalDriveCapsV4& aInfo)
   150 	{
   151 	if (!iLocalDrive)
   152 		{ return KErrBadHandle; }
   153 
   154 	TLocalDriveCapsV4Buf buf;
   155 	TInt err = iLocalDrive->iProxyDrive.Caps(buf);
   156 	
   157 	// Invoke function call operator to cast to TLocalDriveCapsV4&
   158 	aInfo = buf();
   159 	
   160 	return err;
   161 	}
   162 
   163 /**
   164 Set the mount state
   165 */
   166 TInt CMassStorageDrive::SetMountConnected(CProxyDrive& aProxyDrive, TBool& aMediaChanged)
   167 	{
   168 		__FNLOG("CMassStorageDrive::SetMountConnected");
   169 		TInt err = KErrUnknown; //Never return this
   170 	
   171 		if(iMountState == EConnected)
   172 			{
   173 			err = KErrNone;
   174 			}
   175 		else
   176 			{
   177 			CLocalDriveRef* localDrive = new CLocalDriveRef(aProxyDrive, aMediaChanged);
   178 			err = (localDrive==NULL) 
   179 				? KErrNoMemory
   180 				: SetMountState(EConnected, localDrive);
   181 			}
   182 
   183 		return err;
   184 	}
   185 
   186 /**
   187 @return KErrNone on success, KErrArgument if arguments are illegal
   188 @param aNewState
   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.
   191 */
   192 TInt CMassStorageDrive::SetMountState(TMountState aNewState, CLocalDriveRef* aLocalDrive/*=NULL*/)
   193 	{
   194 	__FNLOG("CMassStorageDrive::SetMountState");
   195 	TInt err = KErrUnknown; //Never return this
   196 	
   197 	if(iMountState != aNewState)
   198 		{
   199 
   200 		if 	(iMountState == EConnected 		&& aNewState==EConnecting ||
   201 			iMountState == EDisconnected 	&& aNewState==EDisconnecting)
   202 			{
   203 			return KErrNone;
   204 			}
   205 		
   206 		iMountState = aNewState;
   207 		if(aNewState==EDisconnected || aNewState==EConnecting)
   208 			{
   209 			// Reset the drive state on disconnection.
   210 			// Note: This should be called before ProxyDrive is NULLed.
   211 			SetDriveState(EErrDisMounted);
   212 			}
   213 
   214 		// Only mounting and unmounting transitions affect iProxyDrive
   215 		if(aNewState==EConnected || aNewState==EDisconnected)
   216 			{
   217 			delete iLocalDrive;
   218 			iLocalDrive = aLocalDrive;  // possibly NULL
   219 			}
   220 
   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)
   225 			{			
   226 			iBytesWritten = iBytesRead = 0;
   227 			}
   228 #endif			
   229 		
   230 		__PRINT1(_L("SetMountState: state=%d\n"), iMountState);
   231 
   232 		err = KErrNone;
   233 		}
   234 	else if(aLocalDrive != iLocalDrive)
   235 		{
   236 		// Caller is not allowed to change the proxy drive
   237 		err = KErrArgument;
   238 		}
   239 		
   240 	return err;
   241 	}
   242 
   243 /**
   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.
   249 */
   250 TBool CMassStorageDrive::IsMediaChanged(TBool aReset)
   251 	{
   252 	__FNLOG("CMassStorageDrive::IsMediaChanged");
   253 
   254 	TBool mediaChanged = EFalse;
   255 	if(iLocalDrive)
   256 		{
   257 		mediaChanged = iLocalDrive->iMediaChanged;
   258 		if(aReset) 
   259 			{
   260 			iLocalDrive->iMediaChanged = EFalse;
   261 			}
   262 		}
   263 	return mediaChanged;
   264 	}
   265 
   266 /**
   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
   270 */
   271 TInt CMassStorageDrive::SetCritical(TBool aCritical)
   272 	{
   273 	__FNLOG("CMassStorageDrive::SetCritical");
   274 
   275 	TInt err = KErrDisMounted;
   276 	if(iLocalDrive)
   277 		{
   278 		if(iLocalDrive->iDriveState == CMassStorageDrive::EMediaNotPresent)
   279 			{
   280 			err = KErrNotReady;
   281 			}
   282 		else
   283 			{
   284 			iCritSec.Wait();
   285 			
   286 			SetDriveState(
   287 				aCritical 
   288 				? CMassStorageDrive::EActive
   289 				: CMassStorageDrive::EIdle );
   290 				
   291 			iCritSec.Signal();
   292 			err = KErrNone;
   293 			}
   294 		}
   295 	return err;
   296 	}
   297 
   298 /**
   299 @return Current drive media state
   300 */
   301 CMassStorageDrive::TDriveState	CMassStorageDrive::DriveState() const
   302 	{
   303 	return iLocalDrive ? iLocalDrive->iDriveState : EErrDisMounted;
   304 	}
   305 
   306 /**
   307 This test version does not check for media removal
   308 */
   309 CMassStorageDrive::TDriveState	CMassStorageDrive::CheckDriveState()
   310 	{
   311 	return iLocalDrive ? iLocalDrive->iDriveState : EErrDisMounted;
   312 	}
   313 	
   314 /**
   315 @param aNewState
   316 */
   317 void CMassStorageDrive::SetDriveState(TDriveState aNewState)
   318 	{
   319 	if(iLocalDrive)
   320 		{
   321 		__PRINT2(_L("SetDriveState: %d->%d\n"), iLocalDrive->iDriveState, aNewState);
   322 		iLocalDrive->iDriveState = aNewState;
   323 		}
   324 	}
   325 
   326 
   327 
   328 
   329 /////////////////////////////////////////////////////////////////
   330 //
   331 //	CTestDriveManager
   332 //
   333 /** NewL */
   334 CDriveManager* CDriveManager::NewL(const RArray<TInt>& aDriveMap)
   335 	{
   336 	__FNLOG ("CDriveManager::NewL");
   337 	CDriveManager* self = new (ELeave) CDriveManager(aDriveMap);
   338 	CleanupStack::PushL(self);
   339 	self->ConstructL();
   340 	CleanupStack::Pop();
   341 	return self;
   342 	}
   343 
   344 /** construct
   345 */
   346 void CDriveManager::ConstructL()
   347 	{
   348 	__FNLOG("CDriveManager::ConstructL");
   349 	User::LeaveIfError(iDriveCritSec.CreateLocal());
   350 	
   351 	iDriveStateChangedPublisher = new (ELeave) RDriveStateChangedPublisher(iDrives, iDriveMap);
   352 
   353 	for(TInt i = 0; i < iDriveMap.Count(); i++)
   354 		{
   355 		iDrives[i] = new (ELeave) CMassStorageDrive(iDriveCritSec, *iDriveStateChangedPublisher);
   356 		}
   357 
   358 	// Publish initial drive state
   359 	if (iDriveMap.Count() > 0)
   360 		{
   361 		iDriveStateChangedPublisher->DriveStateChanged();
   362 		}
   363 	}
   364 
   365 CDriveManager::CDriveManager(const RArray<TInt>& aDriveMap)
   366 	:
   367 	iDriveMap(aDriveMap)
   368 	{}
   369 
   370 /** d'tor */
   371 CDriveManager::~CDriveManager()
   372 	{
   373 	iDrives.DeleteAll();
   374 	delete iDriveStateChangedPublisher;
   375 	iDriveCritSec.Close();
   376 	}
   377 
   378 /** register drive
   379 @param aDrive - a proxy drive to register
   380 @param aLun - Lun to register to
   381 @return system wide return code
   382 */
   383 TInt CDriveManager::RegisterDrive(CProxyDrive&, TBool&, TUint)
   384 	{
   385 	// not used in test code
   386 	ASSERT(EFalse);
   387 	return KErrNone;
   388 	}
   389 	
   390 /** register drive
   391 @param aDrive - a proxy drive to register
   392 @param aLun - Lun to register to
   393 @return system wide return code
   394 */
   395 TInt CDriveManager::DeregisterDrive(TUint)
   396 	{
   397 	// not used in test code
   398 	ASSERT(EFalse);
   399 	return KErrNone;
   400 	}
   401 
   402 /** get a drive by aLun
   403 @param aLun - lun
   404 @param aError - operation error
   405 @return pointer to drive
   406 */
   407 CMassStorageDrive* CDriveManager::Drive(TUint aLun, TInt& aError) const
   408 	{
   409 	aError = KErrNone;
   410 	CMassStorageDrive* drive = NULL;
   411 
   412 	if(aLun>=static_cast<TUint>(iDrives.Count()))
   413 		{
   414 		aError = KErrArgument;
   415 		}
   416 	else
   417 		{
   418 		drive = iDrives[aLun];
   419 		}
   420 	
   421 	return drive;
   422 	}
   423 
   424 /** 
   425 @return true if media is changed
   426 @param aLun - lun
   427 @param aReset - reset flag
   428 */
   429 TBool CDriveManager::IsMediaChanged(TUint, TBool)
   430 	{
   431 	// not used in test code
   432 	ASSERT(EFalse);
   433 	return EFalse;
   434 	}
   435 
   436 /**
   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
   442 */
   443 TInt CDriveManager::SetCritical(TUint aLun, TBool aCritical)
   444 	{
   445 	__PRINT1(_L("CDriveManager::SetCritical lun=%d\n"), aLun);
   446 	
   447 	TInt err = KErrUnknown; // never return this
   448 	CMassStorageDrive* drive = Drive(aLun, err);
   449 	if(drive)
   450 		{
   451 		err = drive->SetCritical(aCritical);
   452 		}
   453 		
   454 	return err;
   455 	}
   456 
   457 /** connect a drive according to lun
   458 @param aLun - lun
   459 @return system wide error code
   460 */
   461 TInt CDriveManager::Connect(TUint aLun)
   462 	{
   463 	TInt err = KErrNone;
   464 	CMassStorageDrive* drive = Drive(aLun, err);
   465 	
   466 	if(drive)
   467 		{
   468 		drive->SetMountConnecting();
   469 		}
   470 
   471 	return err;
   472 	}
   473 
   474 /** disconnect drive according to lun
   475 @param aLun - lun
   476 @return system wide error code
   477 */
   478 TInt CDriveManager::Disconnect(TUint aLun)
   479 	{
   480 	TInt err = KErrNone;
   481 	CMassStorageDrive* drive = Drive(aLun, err);
   482 	
   483 	if(drive)
   484 		{
   485 		drive->SetMountDisconnecting();
   486 		}
   487 
   488 	return err;
   489 	}
   490 
   491 
   492 // 
   493 // Dummy publishers
   494 //	
   495 #ifdef USB_TRANSFER_PUBLISHER
   496 CUsbWriteTransferPublisher* CUsbWriteTransferPublisher::NewL(
   497 	TRefBytesTransferedList /* aDrives */)
   498 	{
   499 	return NULL;
   500 	}
   501 
   502 
   503 CUsbReadTransferPublisher* CUsbReadTransferPublisher::NewL(
   504 	TRefBytesTransferedList /* aDrives */)
   505 	{
   506 	return NULL;
   507 	}
   508 
   509 
   510 void CUsbTransferPublisher::DoPublishDataTransferredEvent()
   511 	{
   512 	}
   513 
   514 
   515 CUsbTransferPublisher::~CUsbTransferPublisher()
   516 	{
   517 	}
   518 
   519 
   520 void CUsbTransferPublisher::StartTimer()
   521 	{
   522 	}
   523 
   524 
   525 #else
   526 CDriveWriteTransferPublisher* CDriveWriteTransferPublisher::NewL(
   527 	TFixedArray<CMassStorageDrive*,KUsbMsMaxDrives>& /* aDrives */)
   528 	{
   529 	return NULL;
   530 	}
   531 
   532 
   533 CDriveReadTransferPublisher* CDriveReadTransferPublisher::NewL(
   534 	TFixedArray<CMassStorageDrive*,KUsbMsMaxDrives>& /* aDrives */)
   535 	{
   536 	return NULL;
   537 	}
   538 
   539 
   540 void CDriveTransferPublisher::DoPublishDataTransferredEvent()
   541 	{
   542 	}
   543 
   544 
   545 CDriveTransferPublisher::~CDriveTransferPublisher()
   546 	{
   547 	}
   548 
   549 
   550 void CDriveTransferPublisher::StartTimer()
   551 	{
   552 	}
   553 #endif
   554 
   555 
   556 RDriveStateChangedPublisher::RDriveStateChangedPublisher(
   557 	TFixedArray<CMassStorageDrive*,KUsbMsMaxDrives>& aDrives,
   558 	const RArray<TInt>& aDriveMap)
   559 	:
   560 	iDrives(aDrives),
   561 	iDriveMap(aDriveMap)
   562 	{
   563 	}
   564 
   565 	
   566 void RDriveStateChangedPublisher::DriveStateChanged()
   567 	{
   568 	}
   569 
   570 	
   571 RDriveMediaErrorPublisher::RDriveMediaErrorPublisher()
   572 	{
   573 	}
   574 
   575 	
   576 RDriveStateChangedPublisher::~RDriveStateChangedPublisher()
   577 	{
   578 	}
   579 
   580 	
   581 RDriveMediaErrorPublisher::~RDriveMediaErrorPublisher()
   582 	{
   583 	}
   584 
   585 
   586 //
   587 // Proxy Drive
   588 //
   589 /** c'tor */
   590 CProxyDrive::CProxyDrive(CMountCB* aMount)
   591 : iMount(aMount)
   592 	{}
   593 
   594 TInt CProxyDrive::ControlIO(const RMessagePtr2&, TInt, TAny*, TAny*)
   595 	{ return KErrNone; }
   596 
   597 TInt CProxyDrive::Read (TInt64 aPos, TInt aLength, const TAny* aTrg, TInt, TInt, TInt)
   598 	{ return Read(aPos, aLength, *(TDes8*)aTrg); }
   599 
   600 TInt CProxyDrive::Write (TInt64 aPos, TInt, const TAny* aSrc, TInt, TInt, TInt)
   601 	{ return Write(aPos, *(TDesC8*)aSrc); }
   602 
   603 // Implemented the GetInterface method here as this are usually 
   604 // exported by EFILE, but these unit tests don't link to it.
   605 
   606 TInt CProxyDrive::GetInterface(TInt /*aInterfaceId*/, TAny*& /*aInterface*/, TAny* /*aInput*/)
   607 	{ return KErrNotSupported; }
   608 
   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; }
   613 
   614 CProxyDrive::~CProxyDrive()
   615 	{ }
   616 
   617 
   618 TInt CProxyDrive::DeleteNotify(TInt64, TInt)
   619 	{ return KErrNone; }
   620 
   621 
   622 /** c'tor */
   623 CTestProxyDrive::CTestProxyDrive()
   624 : CProxyDrive (NULL)
   625 	{
   626 	// default settings
   627 	iCaps.iSize = KMaxBufSize * 2;
   628 	iCaps.iSectorSizeInBytes = 512;
   629 	iCaps.iNumberOfSectors   = I64LOW(iCaps.iSize / iCaps.iSectorSizeInBytes);
   630 	iCaps.iNumPagesPerBlock  = 1;
   631 	}
   632 
   633 /** d'or */
   634 CTestProxyDrive::~CTestProxyDrive()
   635 	{}
   636 	
   637 /** Initializs test proxy drive by initializing read buffer 
   638 @return KErrNone
   639 */
   640 TInt CTestProxyDrive::Initialise()
   641 	{
   642 	__FNLOG ("CTestProxyDrive::Initialise");
   643 	
   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++)
   648 		{
   649 		iMediaBuf[i] = static_cast<TInt8>(i%0x10);
   650 		}
   651 
   652 	return KErrNone;
   653 	}
   654 
   655 /** Reading data 
   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
   660 */
   661 TInt CTestProxyDrive::Read(TInt64 aPos, TInt aLength, TDes8& aTrg)
   662 	{
   663 	__FNLOG ("CTestProxyDrive::Read");
   664 
   665 	// TInt64 is not supported by Copy()
   666 	ASSERT (I64HIGH(aPos) == 0);
   667 	if(!aLength)
   668 		{ return KErrNone; }
   669 
   670 	if( (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos)) && (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos) + static_cast<TUint>(aLength)) )
   671 		{ return KErrOverflow; }
   672 
   673 	aTrg.Copy(&iMediaBuf[I64LOW(aPos)], aLength);
   674 	return KErrNone;
   675 	}
   676 	
   677 /** Writing data 
   678 @param  aPos position to write
   679 @param  aSrc source buffer
   680 @return KErrNone or KErrOverflow in case of an error
   681 */
   682 TInt CTestProxyDrive::Write (TInt64 aPos, const TDesC8& aSrc)
   683 	{
   684 	__FNLOG ("CTestProxyDrive::Write");
   685 
   686 	// TInt64 is not supported by Copy()
   687 	ASSERT(0 == I64HIGH(aPos));
   688 	if (!aSrc.Length())
   689 		{ return KErrNone; }
   690 
   691 	if ( (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos)) && (static_cast<TUint>(iMediaBuf.Length()) <= I64LOW(aPos) + static_cast<TUint>(aSrc.Length())) )
   692 		{ return KErrOverflow; }
   693 
   694 	TPtr8 ptr (&iMediaBuf[I64LOW(aPos)], aSrc.Length(), aSrc.Length());
   695 	ptr.Copy(aSrc);
   696 	return KErrNone;
   697 	}
   698 
   699 
   700 // 
   701 // Command wrappers
   702 //
   703 
   704 /** c'tor */
   705 TReadWrite10Cmd::TReadWrite10Cmd()
   706 	{
   707 	iCmd.FillZ (iCmd.MaxLength());
   708 	
   709 	// SBC-2 doc, p. 50
   710 	iCmd[0] = static_cast<TInt8>(iCmd.MaxLength()-1);	// size of the Cmd
   711 	}
   712 
   713 /** accessor for BlockAddress 
   714 @param aAddress - new address
   715 */
   716 void TReadWrite10Cmd::SetBlockAddress(TUint32 aAddress)
   717 	{
   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);
   722 	}
   723