kernel/eka/drivers/pbus/mmc/stack.cpp
changeset 13 46fffbe7b5a7
parent 9 96e5fb8b040d
child 19 4a8fed1c0ef6
equal deleted inserted replaced
12:0bf4040442f9 13:46fffbe7b5a7
    18 #include <drivers/mmc.h>
    18 #include <drivers/mmc.h>
    19 #include <kernel/kern_priv.h>
    19 #include <kernel/kern_priv.h>
    20 #include <drivers/locmedia.h>
    20 #include <drivers/locmedia.h>
    21 #include "stackbody.h"
    21 #include "stackbody.h"
    22 
    22 
       
    23 #include "OstTraceDefinitions.h"
       
    24 #ifdef OST_TRACE_COMPILER_IN_USE
       
    25 #include "locmedia_ost.h"
       
    26 #ifdef __VC32__
       
    27 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
       
    28 #endif
       
    29 #include "stackTraces.h"
       
    30 #endif
       
    31 
    23 #ifdef __SMP__
    32 #ifdef __SMP__
    24 TSpinLock MMCLock(TSpinLock::EOrderGenericIrqHigh0);
    33 TSpinLock MMCLock(TSpinLock::EOrderGenericIrqHigh0);
    25 #endif
    34 #endif
    26 
    35 
    27 #define ASSERT_NOT_ISR_CONTEXT	__ASSERT_DEBUG(NKern::CurrentContext()!=NKern::EInterrupt,DMMCSocket::Panic(DMMCSocket::EMMCUnblockingInWrongContext));
    36 #define ASSERT_NOT_ISR_CONTEXT	__ASSERT_DEBUG(NKern::CurrentContext()!=NKern::EInterrupt,DMMCSocket::Panic(DMMCSocket::EMMCUnblockingInWrongContext));
   310  * @return ETrue if ready, EFalse otherwise.
   319  * @return ETrue if ready, EFalse otherwise.
   311  */
   320  */
   312 	{
   321 	{
   313 	const TUint state = iStatus.State();
   322 	const TUint state = iStatus.State();
   314 	__KTRACE_OPT(KPBUS1, Kern::Printf("=mcc:ir:%d,0x%08x", IsPresent(), state));
   323 	__KTRACE_OPT(KPBUS1, Kern::Printf("=mcc:ir:%d,0x%08x", IsPresent(), state));
       
   324 	OstTraceExt2( TRACE_INTERNALS, TMMCARD_ISREADY, "IsPresent=%d; state=0x%08x", IsPresent(), state );
       
   325 	
   315 	return IsPresent() && (state == ECardStateStby || state == ECardStateTran || state == ECardStateSlp);
   326 	return IsPresent() && (state == ECardStateStby || state == ECardStateTran || state == ECardStateSlp);
   316 	}
   327 	}
   317 
   328 
   318 EXPORT_C TBool TMMCard::IsLocked() const
   329 EXPORT_C TBool TMMCard::IsLocked() const
   319 /**
   330 /**
   325  * password locking but their CSD reports SPEC_VERS == 1.
   336  * password locking but their CSD reports SPEC_VERS == 1.
   326  *
   337  *
   327  * @return ETrue if locked, EFalse otherwise.
   338  * @return ETrue if locked, EFalse otherwise.
   328  */
   339  */
   329 	{
   340 	{
       
   341 	OstTraceFunctionEntry1( TMMCARD_ISLOCKED_ENTRY, this );
   330 	if ( !IsPresent() ) 
   342 	if ( !IsPresent() ) 
   331 		return( EFalse );
   343 		return( EFalse );
   332 
   344 
   333 	return( (TUint32(iStatus) & KMMCStatCardIsLocked) != 0 );
   345 	return( (TUint32(iStatus) & KMMCStatCardIsLocked) != 0 );
   334 	}
   346 	}
   337 /**
   349 /**
   338  * Returns the size of the MMC card in bytes
   350  * Returns the size of the MMC card in bytes
   339  * @return The size of the MMC card in bytes.
   351  * @return The size of the MMC card in bytes.
   340  */
   352  */
   341 	{
   353 	{
       
   354 	OstTraceFunctionEntry1( TMMCARD_DEVICESIZE64_ENTRY, this );
   342 	const TBool highCapacity = IsHighCapacity();
   355 	const TBool highCapacity = IsHighCapacity();
   343 	const TUint32 sectorCount = ExtendedCSD().SectorCount();
   356 	const TUint32 sectorCount = ExtendedCSD().SectorCount();
   344 	
   357 	
   345 	return ((highCapacity && sectorCount) ? (((TInt64)ExtendedCSD().SectorCount()) * 512) : (TInt64)CSD().DeviceSize());
   358 	return ((highCapacity && sectorCount) ? (((TInt64)ExtendedCSD().SectorCount()) * 512) : (TInt64)CSD().DeviceSize());
   346 	}
   359 	}
   350  * Returns the write group length.  Provided by the variant.
   363  * Returns the write group length.  Provided by the variant.
   351  * Default implementation returns a multiple of the write block length, as indicated by the CSD.
   364  * Default implementation returns a multiple of the write block length, as indicated by the CSD.
   352  * @return The preferred write group length.
   365  * @return The preferred write group length.
   353  */
   366  */
   354 	{
   367 	{
       
   368 	OstTraceFunctionEntry1( TMMCARD_PREFERREDWRITEGROUPLENGTH_ENTRY, this );
   355 	return(CSD().WriteBlockLength() << 5);	// 16K for a standard 512byte block length
   369 	return(CSD().WriteBlockLength() << 5);	// 16K for a standard 512byte block length
   356 	}
   370 	}
   357 
   371 
   358 TInt TMMCard::GetFormatInfo(TLDFormatInfo& /*aFormatInfo*/) const
   372 TInt TMMCard::GetFormatInfo(TLDFormatInfo& /*aFormatInfo*/) const
   359 /**
   373 /**
   398  * Return info. on erase services for this card
   412  * Return info. on erase services for this card
   399  * @param aEraseInfo A reference to the TMMCEraseInfo to be filled in with the erase information.
   413  * @param aEraseInfo A reference to the TMMCEraseInfo to be filled in with the erase information.
   400  * @return Symbian OS error code.
   414  * @return Symbian OS error code.
   401  */
   415  */
   402 	{
   416 	{
       
   417 	OstTraceFunctionEntry1( TMMCARD_GETERASEINFO_ENTRY, this );
   403 	
   418 	
   404 	// Check whether this card supports Erase Class Commands. Also, validate the erase group size
   419 	// Check whether this card supports Erase Class Commands. Also, validate the erase group size
   405 	if ((CSD().CCC() & KMMCCmdClassErase) && IsPowerOfTwo(CSD().EraseGroupSize()))
   420 	if ((CSD().CCC() & KMMCCmdClassErase) && IsPowerOfTwo(CSD().EraseGroupSize()))
   406 		{
   421 		{
   407 		// This card supports erase cmds. Also, all versions of MMC cards support Erase Group commands (i.e. CMD35, CMD36).
   422 		// This card supports erase cmds. Also, all versions of MMC cards support Erase Group commands (i.e. CMD35, CMD36).
       
   423 		OstTrace0( TRACE_INTERNALS, TMMCARD_GETERASEINFO, "Card supports erase class commands" );
   408 		aEraseInfo.iEraseFlags=(KMMCEraseClassCmdsSupported|KMMCEraseGroupCmdsSupported); 
   424 		aEraseInfo.iEraseFlags=(KMMCEraseClassCmdsSupported|KMMCEraseGroupCmdsSupported); 
   409 		
   425 		
   410 		// Return the preferred size to be used as the unit for format operations. We need to return a sensible
   426 		// Return the preferred size to be used as the unit for format operations. We need to return a sensible
   411 		// multiple of the erase group size - as calculated by the CSD. A value around 1/32th of the total disk
   427 		// multiple of the erase group size - as calculated by the CSD. A value around 1/32th of the total disk
   412 		// size generally results in an appropriate number of individual format calls.
   428 		// size generally results in an appropriate number of individual format calls.
   420 		aEraseInfo.iMinEraseSectorSize=CSD().EraseGroupSize();
   436 		aEraseInfo.iMinEraseSectorSize=CSD().EraseGroupSize();
   421 		} 
   437 		} 
   422 	else	
   438 	else	
   423 		aEraseInfo.iEraseFlags=0;
   439 		aEraseInfo.iEraseFlags=0;
   424 	
   440 	
   425 	return(KErrNone);
   441 	OstTraceFunctionExitExt( TMMCARD_GETERASEINFO_EXIT, this, KErrNone );
       
   442 	return KErrNone;
   426 	}
   443 	}
   427 
   444 
   428 TUint TMMCard::MaxTranSpeedInKilohertz() const
   445 TUint TMMCard::MaxTranSpeedInKilohertz() const
   429 /**
   446 /**
   430  * Returns the maximum supported clock rate for the card, in Kilohertz.
   447  * Returns the maximum supported clock rate for the card, in Kilohertz.
   431  * @return Speed, in Kilohertz
   448  * @return Speed, in Kilohertz
   432  */
   449  */
   433 	{
   450 	{
       
   451 	OstTraceFunctionEntry1( TMMCARD_MAXTRANSPEEDINKILOHERTZ_ENTRY, this );
   434 	// Default implementation obtains the transaction speed from the CSD
   452 	// Default implementation obtains the transaction speed from the CSD
   435 	TUint32 highSpeedClock = HighSpeedClock();
   453 	TUint32 highSpeedClock = HighSpeedClock();
   436 	return(highSpeedClock ? highSpeedClock : iCSD.MaxTranSpeedInKilohertz());
   454 	return(highSpeedClock ? highSpeedClock : iCSD.MaxTranSpeedInKilohertz());
   437 	}
   455 	}
   438 
   456 
   443  * Normally this is the same as the READ_BL_LEN field in the CSD register,
   461  * Normally this is the same as the READ_BL_LEN field in the CSD register,
   444  * but for high capacity cards (>- 2GB) this is set to a maximum of 512 bytes,
   462  * but for high capacity cards (>- 2GB) this is set to a maximum of 512 bytes,
   445  * if possible, to try to avoid compatibility issues.
   463  * if possible, to try to avoid compatibility issues.
   446  */
   464  */
   447 	{
   465 	{
       
   466 	OstTraceFunctionEntry1( TMMCARD_MAXREADBLLEN_ENTRY, this );
   448 	const TInt KDefaultReadBlockLen = 9;	// 2^9 = 512 bytes
   467 	const TInt KDefaultReadBlockLen = 9;	// 2^9 = 512 bytes
   449 	const TCSD& csd = CSD();
   468 	const TCSD& csd = CSD();
   450 
   469 
   451 	TInt blkLenLog2 = csd.ReadBlLen();
   470 	TInt blkLenLog2 = csd.ReadBlLen();
   452 
   471 
   453 	if (blkLenLog2 > KDefaultReadBlockLen)
   472 	if (blkLenLog2 > KDefaultReadBlockLen)
   454 		{
   473 		{
   455 		__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl %d", blkLenLog2));
   474 		__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl %d", blkLenLog2));
       
   475 		OstTrace1( TRACE_INTERNALS, TMMCARD_MAXREADBLLEN1, "Block length 1=%d", blkLenLog2 );
       
   476 		
       
   477 		
   456 		if (csd.ReadBlPartial() || CSD().SpecVers() >= 4)
   478 		if (csd.ReadBlPartial() || CSD().SpecVers() >= 4)
   457 			{
   479 			{
   458 			//
   480 			//
   459 			// MMC System Spec 4.2 states that 512 bytes blocks are always supported, 
   481 			// MMC System Spec 4.2 states that 512 bytes blocks are always supported, 
   460 			// regardless of the state of READ_BL_PARTIAL 
   482 			// regardless of the state of READ_BL_PARTIAL 
   461 			//
   483 			//
   462 			blkLenLog2 = KDefaultReadBlockLen;	
   484 			blkLenLog2 = KDefaultReadBlockLen;	
   463 			__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl -> %d", blkLenLog2));
   485 			__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl -> %d", blkLenLog2));
   464 			}
   486 			OstTrace1( TRACE_INTERNALS, TMMCARD_MAXREADBLLEN2, "Block length 2=%d", blkLenLog2 );
   465 		}
   487 			}
   466 
   488 		}
       
   489 
       
   490 	OstTraceFunctionExitExt( TMMCARD_MAXREADBLLEN_EXIT, this, blkLenLog2 );
   467 	return blkLenLog2;
   491 	return blkLenLog2;
   468 
   492 
   469 	}
   493 	}
   470 
   494 
   471 TInt TMMCard::MaxWriteBlLen() const
   495 TInt TMMCard::MaxWriteBlLen() const
   474  * Normally this is the same as the WRITE_BL_LEN field in the CSD register,
   498  * Normally this is the same as the WRITE_BL_LEN field in the CSD register,
   475  * but for high capacity cards (>- 2GB) this is set to a maximum of 512 bytes,
   499  * but for high capacity cards (>- 2GB) this is set to a maximum of 512 bytes,
   476  * if possible, to try to avoid compatibility issues.
   500  * if possible, to try to avoid compatibility issues.
   477  */
   501  */
   478 	{
   502 	{
       
   503 	OstTraceFunctionEntry1( TMMCARD_MAXWRITEBLLEN_ENTRY, this );
   479 	const TInt KDefaultWriteBlockLen = 9;	// 2^9 = 512 bytes
   504 	const TInt KDefaultWriteBlockLen = 9;	// 2^9 = 512 bytes
   480 	const TCSD& csd = CSD();
   505 	const TCSD& csd = CSD();
   481 
   506 
   482 	TInt blkLenLog2 = csd.WriteBlLen();
   507 	TInt blkLenLog2 = csd.WriteBlLen();
   483 
   508 
   484 	if (blkLenLog2 > KDefaultWriteBlockLen)
   509 	if (blkLenLog2 > KDefaultWriteBlockLen)
   485 		{
   510 		{
   486 		__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl %d", blkLenLog2));
   511 		__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl %d", blkLenLog2));
       
   512 		OstTrace1( TRACE_INTERNALS, TMMCARD_MAXWRITEBLLEN1, "Block length 1=%d", blkLenLog2 );
   487 		if (csd.WriteBlPartial() || CSD().SpecVers() >= 4)
   513 		if (csd.WriteBlPartial() || CSD().SpecVers() >= 4)
   488 			{
   514 			{
   489 			//
   515 			//
   490 			// MMC System Spec 4.2 states that 512 bytes blocks are always supported, 
   516 			// MMC System Spec 4.2 states that 512 bytes blocks are always supported, 
   491 			// regardless of the state of READ_BL_PARTIAL 
   517 			// regardless of the state of READ_BL_PARTIAL 
   492 			//
   518 			//
   493 			blkLenLog2 = KDefaultWriteBlockLen;	
   519 			blkLenLog2 = KDefaultWriteBlockLen;	
   494 			__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl -> %d", blkLenLog2));
   520 			__KTRACE_OPT(KPBUS1, Kern::Printf("=mmc:mrbl -> %d", blkLenLog2));
   495 			}
   521 			OstTrace1( TRACE_INTERNALS, TMMCARD_MAXWRITEBLLEN2, "Block length 1=%d", blkLenLog2 );
   496 		}
   522 			}
   497 
   523 		}
       
   524 
       
   525 	OstTraceFunctionExitExt( TMMCARD_MAXWRITEBLLEN_EXIT, this, blkLenLog2 );
   498 	return blkLenLog2;
   526 	return blkLenLog2;
   499 
   527 
   500 	}
   528 	}
   501 
   529 
   502 //	--------  class TMMCardArray  --------
   530 //	--------  class TMMCardArray  --------
   508  * is no cleanup if it fails.
   536  * is no cleanup if it fails.
   509  *
   537  *
   510  * @return KErrNone if successful, Standard Symbian OS error code otherwise.
   538  * @return KErrNone if successful, Standard Symbian OS error code otherwise.
   511  */
   539  */
   512 	{
   540 	{
       
   541 	OstTraceFunctionEntry1( TMMCARDARRAY_ALLOCCARDS_ENTRY, this );
   513 	for (TUint i = 0; i < KMaxMMCardsPerStack; ++i)
   542 	for (TUint i = 0; i < KMaxMMCardsPerStack; ++i)
   514 		{
   543 		{
   515 		// zeroing the card data used to be implicit because embedded in
   544 		// zeroing the card data used to be implicit because embedded in
   516 		// CBase-derived DMMCStack.
   545 		// CBase-derived DMMCStack.
   517 		if ((iCards[i] = new TMMCard) == 0)
   546 		if ((iCards[i] = new TMMCard) == 0)
       
   547 		    {
       
   548 			OstTraceFunctionExitExt( TMMCARDARRAY_ALLOCCARDS_EXIT1, this, KErrNoMemory );
   518 			return KErrNoMemory;
   549 			return KErrNoMemory;
       
   550 		    }
   519 		iCards[i]->iUsingSessionP = 0;
   551 		iCards[i]->iUsingSessionP = 0;
   520 		if ((iNewCards[i] = new TMMCard) == 0)
   552 		if ((iNewCards[i] = new TMMCard) == 0)
       
   553 		    {
       
   554 			OstTraceFunctionExitExt( TMMCARDARRAY_ALLOCCARDS_EXIT2, this, KErrNoMemory );
   521 			return KErrNoMemory;
   555 			return KErrNoMemory;
       
   556 		    }
   522 		iNewCards[i]->iUsingSessionP = 0;
   557 		iNewCards[i]->iUsingSessionP = 0;
   523 		}
   558 		}
   524 
   559 
       
   560 	OstTraceFunctionExitExt( TMMCARDARRAY_ALLOCCARDS_EXIT3, this, KErrNone );
   525 	return KErrNone;
   561 	return KErrNone;
   526 	}
   562 	}
   527 
   563 
   528 void TMMCardArray::InitNewCardScan()
   564 void TMMCardArray::InitNewCardScan()
   529 /**
   565 /**
   530  * Prepare card array for new scan.
   566  * Prepare card array for new scan.
   531  */
   567  */
   532 	{
   568 	{
       
   569 	OstTraceFunctionEntry1( TMMCARDARRAY_INITNEWCARDSCAN_ENTRY, this );
   533 	iNewCardsCount=0;
   570 	iNewCardsCount=0;
       
   571 	OstTraceFunctionExit1( TMMCARDARRAY_INITNEWCARDSCAN_EXIT, this );
   534 	}
   572 	}
   535 
   573 
   536 void TMMCardArray::MoveCardAndLockRCA(TMMCard& aSrcCard,TMMCard& aDestCard,TInt aDestIndex)
   574 void TMMCardArray::MoveCardAndLockRCA(TMMCard& aSrcCard,TMMCard& aDestCard,TInt aDestIndex)
   537 /**
   575 /**
   538  * Copy card object and lock RCA.
   576  * Copy card object and lock RCA.
   539  */
   577  */
   540 	{
   578 	{
       
   579 	OstTraceExt2(TRACE_FLOW, TMMCARDARRAY_MOVECARDANDLOCKRCA_ENTRY, "TMMCardArray::MoveCardAndLockRCA;aDestIndex=%d;this=%x", aDestIndex, (TUint) this);
   541 	__KTRACE_OPT(KPBUS1, Kern::Printf("=mca:mclr:%d", aDestIndex));
   580 	__KTRACE_OPT(KPBUS1, Kern::Printf("=mca:mclr:%d", aDestIndex));
   542 
   581 
   543 	aDestCard.iCID=aSrcCard.iCID;
   582 	aDestCard.iCID=aSrcCard.iCID;
   544 	aDestCard.iRCA=aSrcCard.iRCA;
   583 	aDestCard.iRCA=aSrcCard.iRCA;
   545 	aDestCard.iCSD=aSrcCard.iCSD;
   584 	aDestCard.iCSD=aSrcCard.iCSD;
   554 	aSrcCard.iRCA = aSrcCard.iIndex = aSrcCard.iFlags = 0;
   593 	aSrcCard.iRCA = aSrcCard.iIndex = aSrcCard.iFlags = 0;
   555 	aSrcCard.iBusWidth = 1;
   594 	aSrcCard.iBusWidth = 1;
   556 	aSrcCard.iHighSpeedClock = 0;
   595 	aSrcCard.iHighSpeedClock = 0;
   557 
   596 
   558 	aSrcCard.iUsingSessionP = NULL;
   597 	aSrcCard.iUsingSessionP = NULL;
       
   598 	OstTraceFunctionExit1( TMMCARDARRAY_MOVECARDANDLOCKRCA_EXIT, this );
   559 	}
   599 	}
   560 
   600 
   561 EXPORT_C void TMMCardArray::AddNewCard(const TUint8* aCID,TRCA* aNewRCA)
   601 EXPORT_C void TMMCardArray::AddNewCard(const TUint8* aCID,TRCA* aNewRCA)
   562 /**
   602 /**
   563  * Found a new card to add to the array. Add it to a separate array for now
   603  * Found a new card to add to the array. Add it to a separate array for now
   564  * since we need to know all the cards present before we start replacing old
   604  * since we need to know all the cards present before we start replacing old
   565  * entries.
   605  * entries.
   566  */
   606  */
   567 	{
   607 	{
       
   608 	OstTraceFunctionEntryExt( TMMCARDARRAY_ADDNEWCARD_ENTRY, this );
   568 	// Store the CID in the next free slot
   609 	// Store the CID in the next free slot
   569 	NewCard(iNewCardsCount).iCID = aCID;
   610 	NewCard(iNewCardsCount).iCID = aCID;
   570 
   611 
   571 	*aNewRCA=0;
   612 	*aNewRCA=0;
   572 
   613 
   587 		NewCard(iNewCardsCount).iIndex=0;
   628 		NewCard(iNewCardsCount).iIndex=0;
   588 		__ASSERT_ALWAYS( (*aNewRCA=iOwningStack->iRCAPool.GetFreeRCA())!=0,DMMCSocket::Panic(DMMCSocket::EMMCNoFreeRCA) );
   629 		__ASSERT_ALWAYS( (*aNewRCA=iOwningStack->iRCAPool.GetFreeRCA())!=0,DMMCSocket::Panic(DMMCSocket::EMMCNoFreeRCA) );
   589 		}
   630 		}
   590 
   631 
   591 	__KTRACE_OPT(KPBUS1, Kern::Printf("mca:adn: assigning new card %d rca 0x%04x", iNewCardsCount, TUint16(*aNewRCA) ));
   632 	__KTRACE_OPT(KPBUS1, Kern::Printf("mca:adn: assigning new card %d rca 0x%04x", iNewCardsCount, TUint16(*aNewRCA) ));
       
   633 	OstTraceExt2( TRACE_INTERNALS, TMMCARDARRAY_ADDNEWCARD, "iNewCardsCount=%d; RCA=0x%04x", iNewCardsCount, (TUint) *aNewRCA );
       
   634 	
   592 	NewCard(iNewCardsCount).iRCA=*aNewRCA;
   635 	NewCard(iNewCardsCount).iRCA=*aNewRCA;
   593 	iNewCardsCount++;
   636 	iNewCardsCount++;
       
   637 	OstTraceFunctionExit1( TMMCARDARRAY_ADDNEWCARD_EXIT, this );
   594 	}
   638 	}
   595 
   639 
   596 TInt TMMCardArray::MergeCards(TBool aFirstPass)
   640 TInt TMMCardArray::MergeCards(TBool aFirstPass)
   597 /**
   641 /**
   598  * This function places newly acquired cards from the new card array into free
   642  * This function places newly acquired cards from the new card array into free
   599  * slots of the main card array.
   643  * slots of the main card array.
   600  * Returns KErrNotFound if not able to successfully place all the new cards.
   644  * Returns KErrNotFound if not able to successfully place all the new cards.
   601  */
   645  */
   602 	{
   646 	{
   603 
   647 	OstTraceFunctionEntryExt( TMMCARDARRAY_MERGECARDS_ENTRY, this );
       
   648 
       
   649 	
   604 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mca:mc:%d,%d", aFirstPass, iNewCardsCount));
   650 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mca:mc:%d,%d", aFirstPass, iNewCardsCount));
       
   651 	OstTrace1( TRACE_INTERNALS, TMMCARDARRAY_MERGECARDS1, "iNewCardsCount=%d", iNewCardsCount );
       
   652 	
   605 	TUint i;	// New card index
   653 	TUint i;	// New card index
   606 	TUint j;	// Main card index
   654 	TUint j;	// Main card index
   607 
   655 
   608 	// Only do this on first pass. Setup any new cards which were already there
   656 	// Only do this on first pass. Setup any new cards which were already there
   609 	if (aFirstPass)
   657 	if (aFirstPass)
   610 		{
   658 		{
   611 		for ( i=0 ; i<iNewCardsCount ; i++ )
   659 		for ( i=0 ; i<iNewCardsCount ; i++ )
   612 			{
   660 			{
   613 			__KTRACE_OPT(KPBUS1, Kern::Printf("-mca:fp,i=%d,idx=0x%x", i, NewCard(i).iIndex));
   661 			__KTRACE_OPT(KPBUS1, Kern::Printf("-mca:fp,i=%d,idx=0x%x", i, NewCard(i).iIndex));
       
   662 			OstTraceExt2( TRACE_INTERNALS, TMMCARDARRAY_MERGECARDS2, "i=%d; Index=0x%x", i, NewCard(i).iIndex );
   614 			if( NewCard(i).iIndex != 0 ) // Signifies card was here before (iIndex has old slot number +1)
   663 			if( NewCard(i).iIndex != 0 ) // Signifies card was here before (iIndex has old slot number +1)
   615 				{
   664 				{
   616 				// Put it in the same slot as before
   665 				// Put it in the same slot as before
   617 				j=(NewCard(i).iIndex-1);
   666 				j=(NewCard(i).iIndex-1);
   618 				MoveCardAndLockRCA(NewCard(i),Card(j),(j+1));
   667 				MoveCardAndLockRCA(NewCard(i),Card(j),(j+1));
   626 		if ( NewCard(i).iRCA != 0 )
   675 		if ( NewCard(i).iRCA != 0 )
   627 			{
   676 			{
   628 			// Find a spare slot in main array for this new card
   677 			// Find a spare slot in main array for this new card
   629 			while ( Card(j).IsPresent() )
   678 			while ( Card(j).IsPresent() )
   630 				if ( ++j==iOwningStack->iMaxCardsInStack )
   679 				if ( ++j==iOwningStack->iMaxCardsInStack )
   631 					return(KErrNotFound);
   680 				    {
       
   681 					OstTraceFunctionExitExt( TMMCARDARRAY_MERGECARDS_EXIT1, this, KErrNotFound );
       
   682 					return KErrNotFound;
       
   683 				    }
   632 
   684 
   633 			// Found a free slot; move the card info there
   685 			// Found a free slot; move the card info there
   634 			__KTRACE_OPT(KPBUS1, Kern::Printf("-mca:freej=%d,rca=0x%04x", j, TUint16(Card(j).iRCA) ));
   686 			__KTRACE_OPT(KPBUS1, Kern::Printf("-mca:freej=%d,rca=0x%04x", j, TUint16(Card(j).iRCA) ));
       
   687 			OstTraceExt2( TRACE_INTERNALS, TMMCARDARRAY_MERGECARDS3, "j=%d; RCA=0x%04x", j, (TUint) (Card(j).iRCA) );
   635 			if ( Card(j).iRCA != 0 )
   688 			if ( Card(j).iRCA != 0 )
   636 				iOwningStack->iRCAPool.UnlockRCA(Card(j).iRCA);
   689 				iOwningStack->iRCAPool.UnlockRCA(Card(j).iRCA);
   637 
   690 
   638 			__KTRACE_OPT(KPBUS1, Kern::Printf("merging new card %d to card %d dest index %d", i, j, j+1));
   691 			__KTRACE_OPT(KPBUS1, Kern::Printf("merging new card %d to card %d dest index %d", i, j, j+1));
       
   692 			OstTraceExt3( TRACE_INTERNALS, TMMCARDARRAY_MERGECARDS4, "Merging new card %d to card %d; Destination index=%d", (TInt) i, (TInt) j, (TInt) j+1 );
   639 			MoveCardAndLockRCA(NewCard(i),Card(j),(j+1));
   693 			MoveCardAndLockRCA(NewCard(i),Card(j),(j+1));
   640 			}
   694 			}
   641 		}
   695 		}
   642 	return(KErrNone);
   696 	OstTraceFunctionExitExt( TMMCARDARRAY_MERGECARDS_EXIT2, this, KErrNone );
       
   697 	return KErrNone;
   643 	}
   698 	}
   644 
   699 
   645 void TMMCardArray::UpdateAcquisitions(TUint* aMaxClock)
   700 void TMMCardArray::UpdateAcquisitions(TUint* aMaxClock)
   646 /**
   701 /**
   647  * Called when we have successfully stored a new set of cards in the card array.
   702  * Called when we have successfully stored a new set of cards in the card array.
   648  * This performs final initialisation of the card entries and determines the
   703  * This performs final initialisation of the card entries and determines the
   649  * maximum bus clock that can be employed - by checking the CSD of each card.
   704  * maximum bus clock that can be employed - by checking the CSD of each card.
   650  */
   705  */
   651 	{
   706 	{
   652 
   707 	OstTraceFunctionEntryExt( TMMCARDARRAY_UPDATEACQUISITIONS_ENTRY, this );
       
   708 	
   653 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mca:uda"));
   709 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mca:uda"));
   654 	iCardsPresent=0;
   710 	iCardsPresent=0;
   655 	TUint maxClk = iOwningStack->iMultiplexedBus ? 1 : 800000; // ???
   711 	TUint maxClk = iOwningStack->iMultiplexedBus ? 1 : 800000; // ???
   656 	for ( TUint i=0 ; i < (iOwningStack->iMaxCardsInStack) ; i++ )
   712 	for ( TUint i=0 ; i < (iOwningStack->iMaxCardsInStack) ; i++ )
   657 		{
   713 		{
   678 		}
   734 		}
   679 	// ??? Should also calculate here and return the data timeout and busy timeout 
   735 	// ??? Should also calculate here and return the data timeout and busy timeout 
   680 	// instead of relying on ASSP defaults.
   736 	// instead of relying on ASSP defaults.
   681 
   737 
   682 	*aMaxClock=maxClk;
   738 	*aMaxClock=maxClk;
       
   739 	OstTraceFunctionExit1( TMMCARDARRAY_UPDATEACQUISITIONS_EXIT, this );
   683 	}
   740 	}
   684 
   741 
   685 EXPORT_C void TMMCardArray::DeclareCardAsGone(TUint aCardNumber)
   742 EXPORT_C void TMMCardArray::DeclareCardAsGone(TUint aCardNumber)
   686 /**
   743 /**
   687  * Clears up a card info object in the main card array
   744  * Clears up a card info object in the main card array
   688  */
   745  */
   689 	{
   746 	{
   690 
   747 	OstTraceFunctionEntryExt( TMMCARDARRAY_DECLARECARDASGONE_ENTRY, this );
       
   748 	
   691 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mca:dcag"));
   749 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mca:dcag"));
   692 	// If we thought this one was present then mark it as not present
   750 	// If we thought this one was present then mark it as not present
   693 	TMMCard& card = Card(aCardNumber);
   751 	TMMCard& card = Card(aCardNumber);
   694 	if (card.IsPresent())
   752 	if (card.IsPresent())
   695 		{
   753 		{
   704 	card.iUsingSessionP=NULL;
   762 	card.iUsingSessionP=NULL;
   705 	card.iSetBlockLen=0;
   763 	card.iSetBlockLen=0;
   706 	card.iFlags=0; 		// Reset 'has password' and 'write protected' bit fields
   764 	card.iFlags=0; 		// Reset 'has password' and 'write protected' bit fields
   707 	card.iHighSpeedClock=0;
   765 	card.iHighSpeedClock=0;
   708 	card.iBusWidth=1;
   766 	card.iBusWidth=1;
       
   767 	OstTraceFunctionExit1( TMMCARDARRAY_DECLARECARDASGONE_EXIT, this );
   709 	}
   768 	}
   710 
   769 
   711 // return this card's index in the array or KErrNotFound if not found
   770 // return this card's index in the array or KErrNotFound if not found
   712 TInt TMMCardArray::CardIndex(const TMMCard* aCard)
   771 TInt TMMCardArray::CardIndex(const TMMCard* aCard)
   713 	{
   772 	{
       
   773 	OstTraceFunctionEntryExt( TMMCARDARRAY_CARDINDEX_ENTRY, this );
   714 	TInt i;
   774 	TInt i;
   715 	for (i = KMaxMMCardsPerStack-1; i>= 0; i--)
   775 	for (i = KMaxMMCardsPerStack-1; i>= 0; i--)
   716 		{
   776 		{
   717 		if (iCards[i] == aCard)
   777 		if (iCards[i] == aCard)
   718 			break;
   778 			break;
   719 		}
   779 		}
       
   780 	OstTraceFunctionExitExt( TMMCARDARRAY_CARDINDEX_EXIT, this, i );
   720 	return i;
   781 	return i;
   721 	}
   782 	}
   722 
   783 
   723 //	--------  class TMMCCommandDesc  --------
   784 //	--------  class TMMCCommandDesc  --------
   724 
   785 
   725 EXPORT_C TInt TMMCCommandDesc::Direction() const
   786 EXPORT_C TInt TMMCCommandDesc::Direction() const
   726 /**
   787 /**
   727  * returns -1, 0 or +1 for DT directions read, none or write respectively
   788  * returns -1, 0 or +1 for DT directions read, none or write respectively
   728  */
   789  */
   729 	{
   790 	{
       
   791 	OstTraceFunctionEntry1( TMMCCOMMANDDESC_DIRECTION_ENTRY, this );
   730 	TUint dir = iSpec.iDirection;
   792 	TUint dir = iSpec.iDirection;
   731 	TInt result = dir;
   793 	TInt result = dir;
       
   794 	TInt ret;
   732 
   795 
   733 	if( dir == 0 )
   796 	if( dir == 0 )
   734 		return( 0 );
   797 	    {
       
   798 	    ret = 0;
       
   799 		OstTraceFunctionExitExt( TMMCCOMMANDDESC_DIRECTION_EXIT1, this, ret );
       
   800 		return ret;
       
   801 	    }
   735 
   802 
   736 	if( dir & KMMCCmdDirWBitArgument )
   803 	if( dir & KMMCCmdDirWBitArgument )
   737 		result = TUint(iArgument) >> (dir & KMMCCmdDirIndBitPosition);
   804 		result = TUint(iArgument) >> (dir & KMMCCmdDirIndBitPosition);
   738 
   805 
   739 	if( dir & KMMCCmdDirNegate )
   806 	if( dir & KMMCCmdDirNegate )
   740 		result = ~result;
   807 		result = ~result;
   741 
   808 
   742 	return( ((result&1)-1)|1 );
   809 	ret = ((result&1)-1)|1;
       
   810 
       
   811 	OstTraceFunctionExitExt( TMMCCOMMANDDESC_DIRECTION_EXIT2, this, ret );
       
   812 	return ret;
   743 	}
   813 	}
   744 
   814 
   745 
   815 
   746 TBool TMMCCommandDesc::AdjustForBlockOrByteAccess(const DMMCSession& aSession)
   816 TBool TMMCCommandDesc::AdjustForBlockOrByteAccess(const DMMCSession& aSession)
   747 	{
   817 	{
       
   818 	OstTraceExt2(TRACE_FLOW, TMMCCOMMANDDESC_ADJUSTFORBLOCKORBYTEACCESS_ENTRY, "TMMCCommandDesc::AdjustForBlockOrByteAccess;Session ID=%d;this=%x", (TInt) aSession.SessionID(), (TUint) this);
   748 /**
   819 /**
   749  * The MMC session provides both block and byte based IO methods, all of which can
   820  * The MMC session provides both block and byte based IO methods, all of which can
   750  * be used on both block and byte based MMC cards.  This method adjusts the command
   821  * be used on both block and byte based MMC cards.  This method adjusts the command
   751  * arguments so that they match the underlying cards access mode.
   822  * arguments so that they match the underlying cards access mode.
   752  *
   823  *
   757 	if(iTotalLength == 0	||
   828 	if(iTotalLength == 0	||
   758 	   blockLength == 0	||
   829 	   blockLength == 0	||
   759 	   iTotalLength % KMMCardHighCapBlockSize != 0	||	// always aligned on 512 bytes
   830 	   iTotalLength % KMMCardHighCapBlockSize != 0	||	// always aligned on 512 bytes
   760 	   blockLength % KMMCardHighCapBlockSize != 0)
   831 	   blockLength % KMMCardHighCapBlockSize != 0)
   761 		{
   832 		{
   762 		return(EFalse);
   833 		OstTraceFunctionExitExt( TMMCCOMMANDDESC_ADJUSTFORBLOCKORBYTEACCESS_EXIT1, this, (TUint) EFalse );
       
   834 		return EFalse;
   763 		}
   835 		}
   764 
   836 
   765 	if(aSession.CardP()->IsHighCapacity())
   837 	if(aSession.CardP()->IsHighCapacity())
   766 		{	
   838 		{	
   767 		// high capacity (block-based) card
   839 		// high capacity (block-based) card
   770 			// The command arguments are using byte based addressing
   842 			// The command arguments are using byte based addressing
   771 			//  - adjust to block-based addressing
   843 			//  - adjust to block-based addressing
   772 			if(iArgument % KMMCardHighCapBlockSize != 0)
   844 			if(iArgument % KMMCardHighCapBlockSize != 0)
   773 				{
   845 				{
   774 				// Block based media does not support misaligned access
   846 				// Block based media does not support misaligned access
   775 				return(EFalse);
   847 				OstTraceFunctionExitExt( TMMCCOMMANDDESC_ADJUSTFORBLOCKORBYTEACCESS_EXIT2, this, (TUint) EFalse );
       
   848 				return EFalse;
   776 				}
   849 				}
   777 
   850 
   778 			// adjust for block based access
   851 			// adjust for block based access
   779 			iArgument = iArgument >> KMMCardHighCapBlockSizeLog2;
   852 			iArgument = iArgument >> KMMCardHighCapBlockSizeLog2;
   780 			iFlags |= KMMCCmdFlagBlockAddress;
   853 			iFlags |= KMMCCmdFlagBlockAddress;
   790 			const TUint32 maxBlocks = 4 * 1024 * ((1024 * 1024) >> KMMCardHighCapBlockSizeLog2);
   863 			const TUint32 maxBlocks = 4 * 1024 * ((1024 * 1024) >> KMMCardHighCapBlockSizeLog2);
   791 			
   864 			
   792 			if(iArgument > maxBlocks)
   865 			if(iArgument > maxBlocks)
   793 				{
   866 				{
   794 				// The address is out of range (>2G) - cannot convert
   867 				// The address is out of range (>2G) - cannot convert
   795 				return(EFalse);
   868 				OstTraceFunctionExitExt( TMMCCOMMANDDESC_ADJUSTFORBLOCKORBYTEACCESS_EXIT3, this, (TUint) EFalse );
       
   869 				return EFalse;
   796 				}
   870 				}
   797 
   871 
   798 			// adjust for byte-based access
   872 			// adjust for byte-based access
   799 			iArgument = iArgument << KMMCardHighCapBlockSizeLog2;
   873 			iArgument = iArgument << KMMCardHighCapBlockSizeLog2;
   800 			iFlags &= ~KMMCCmdFlagBlockAddress;
   874 			iFlags &= ~KMMCCmdFlagBlockAddress;
   801 			}
   875 			}
   802 		else if(iArgument % KMMCardHighCapBlockSize != 0)
   876 		else if(iArgument % KMMCardHighCapBlockSize != 0)
   803 			{
   877 			{
   804 			// byte addressing, unaligned address
   878 			// byte addressing, unaligned address
   805 			return(EFalse);
   879 			OstTraceFunctionExitExt( TMMCCOMMANDDESC_ADJUSTFORBLOCKORBYTEACCESS_EXIT4, this, (TUint) EFalse );
   806 			}
   880 			return EFalse;
   807 		}
   881 			}
   808 
   882 		}
   809 	return(ETrue);
   883 
       
   884 	OstTraceFunctionExitExt( TMMCCOMMANDDESC_ADJUSTFORBLOCKORBYTEACCESS_EXIT5, this, (TUint) ETrue );
       
   885 	return ETrue;
   810 	}
   886 	}
   811 
   887 
   812 void TMMCCommandDesc::Dump(TUint8* aResponseP, TMMCErr aErr)
   888 void TMMCCommandDesc::Dump(TUint8* aResponseP, TMMCErr aErr)
   813 	{
   889 	{
   814 
   890 
   963 TRCA TMMCRCAPool::GetFreeRCA()
  1039 TRCA TMMCRCAPool::GetFreeRCA()
   964 /**
  1040 /**
   965  * Returns a free RCA number from the pool or zero if none is available
  1041  * Returns a free RCA number from the pool or zero if none is available
   966  */
  1042  */
   967 	{
  1043 	{
       
  1044 	OstTraceFunctionEntry1( TMMCRCAPOOL_GETFREERCA_ENTRY, this );
   968 	TUint32 seekm = (iPool | iLocked) + 1;
  1045 	TUint32 seekm = (iPool | iLocked) + 1;
   969 	iPool |= (seekm & ~iLocked);
  1046 	iPool |= (seekm & ~iLocked);
   970 
  1047 	TUint16 ret;
       
  1048 	
   971 	if( (seekm & 0xFFFFFFFF) == 0 )
  1049 	if( (seekm & 0xFFFFFFFF) == 0 )
   972 		return( 0 );
  1050 	    {
       
  1051 	    ret = 0;
       
  1052 		OstTraceFunctionExitExt( TMMCRCAPOOL_GETFREERCA_EXIT1, this, (TUint) ret);
       
  1053 		return ret;
       
  1054 	    }
   973 
  1055 
   974 	TUint16 pos = 1;
  1056 	TUint16 pos = 1;
   975 
  1057 
   976 	if ((seekm & 0xFFFF) == 0)	{ seekm >>= 16;	pos = 17; }
  1058 	if ((seekm & 0xFFFF) == 0)	{ seekm >>= 16;	pos = 17; }
   977 	if ((seekm & 0xFF) == 0)	{ seekm >>= 8;	pos += 8; }
  1059 	if ((seekm & 0xFF) == 0)	{ seekm >>= 8;	pos += 8; }
   984 	// for this adjustment.  These functions are only ever called in this file with the iRCA
  1066 	// for this adjustment.  These functions are only ever called in this file with the iRCA
   985 	// field of a TMMCard object, and not with arbitrary values.
  1067 	// field of a TMMCard object, and not with arbitrary values.
   986 	// The iRCA field itself is only assigned values from iNewCards[] or zero.  iNewCards
  1068 	// The iRCA field itself is only assigned values from iNewCards[] or zero.  iNewCards
   987 	// in turn is fed values from this function, in DMMCStack::CIMUpdateAcqSM() / EStSendCIDIssued.
  1069 	// in turn is fed values from this function, in DMMCStack::CIMUpdateAcqSM() / EStSendCIDIssued.
   988 
  1070 
   989 	return TUint16(pos << 8 | pos);
  1071 	ret = TUint16(pos << 8 | pos);
       
  1072 	OstTraceFunctionExitExt( TMMCRCAPOOL_GETFREERCA_EXIT2, this, (TUint) ret);
       
  1073 	return ret;
   990 	}
  1074 	}
   991 
  1075 
   992 
  1076 
   993 
  1077 
   994 //	--------  class TMMCSessRing  --------
  1078 //	--------  class TMMCSessRing  --------
   996 TMMCSessRing::TMMCSessRing()
  1080 TMMCSessRing::TMMCSessRing()
   997 /**
  1081 /**
   998  * Constructor
  1082  * Constructor
   999  */
  1083  */
  1000 	: iPMark(NULL),iPoint(NULL),iPrevP(NULL),iSize(0)
  1084 	: iPMark(NULL),iPoint(NULL),iPrevP(NULL),iSize(0)
  1001 	{}
  1085 	{OstTraceFunctionEntry1( TMMCSESSRING_TMMCSESSRING_ENTRY, this );}
  1002 
  1086 
  1003 
  1087 
  1004 void TMMCSessRing::Erase()
  1088 void TMMCSessRing::Erase()
  1005 /**
  1089 /**
  1006  * Erases all the ring content
  1090  * Erases all the ring content
  1007  */
  1091  */
  1008 	{iPMark = iPoint = iPrevP = NULL; iSize = 0;}
  1092 	{
       
  1093 	OstTraceFunctionEntry1( TMMCSESSRING_ERASE_ENTRY, this );
       
  1094 	iPMark = iPoint = iPrevP = NULL; iSize = 0;
       
  1095 	OstTraceFunctionExit1( TMMCSESSRING_ERASE_EXIT, this );
       
  1096 	}
  1009 
  1097 
  1010 
  1098 
  1011 DMMCSession* TMMCSessRing::operator++(TInt)
  1099 DMMCSession* TMMCSessRing::operator++(TInt)
  1012 /**
  1100 /**
  1013  * Post increment of Point
  1101  * Post increment of Point
  1028 TBool TMMCSessRing::Point(DMMCSession* aSessP)
  1116 TBool TMMCSessRing::Point(DMMCSession* aSessP)
  1029 /**
  1117 /**
  1030  * Finds aSessP and sets Point to that position
  1118  * Finds aSessP and sets Point to that position
  1031  */
  1119  */
  1032 	{
  1120 	{
       
  1121 	OstTraceFunctionEntryExt( TMMCSESSRING_POINT_ENTRY, this );
  1033 	Point();
  1122 	Point();
  1034 
  1123 
  1035 	while( iPoint != NULL )
  1124 	while( iPoint != NULL )
  1036 		if( iPoint == aSessP )
  1125 		if( iPoint == aSessP )
  1037 			return( ETrue );
  1126 		    {
       
  1127 			OstTraceFunctionExitExt( TMMCSESSRING_POINT_EXIT1, this, (TUint) ETrue );
       
  1128 			return ETrue;
       
  1129 		    }
  1038 		else
  1130 		else
  1039 			this->operator++(0);
  1131 			this->operator++(0);
  1040 
  1132 
  1041 	return( EFalse );
  1133 	OstTraceFunctionExitExt( TMMCSESSRING_POINT_EXIT2, this, (TUint) EFalse );
       
  1134 	return EFalse;
  1042 	}
  1135 	}
  1043 
  1136 
  1044 void TMMCSessRing::Add(DMMCSession* aSessP)
  1137 void TMMCSessRing::Add(DMMCSession* aSessP)
  1045 /**
  1138 /**
  1046  * Inserts aSessP before Marker. Point is moved into the Marker position.
  1139  * Inserts aSessP before Marker. Point is moved into the Marker position.
  1047  */
  1140  */
  1048 	{
  1141 	{
       
  1142 	OstTraceFunctionEntryExt( TMMCSESSRING_ADD1_ENTRY, this );
  1049 	if( iSize == 0 )
  1143 	if( iSize == 0 )
  1050 		{
  1144 		{
  1051 		iPMark = iPrevP = iPoint = aSessP;
  1145 		iPMark = iPrevP = iPoint = aSessP;
  1052 		aSessP->iLinkP = aSessP;
  1146 		aSessP->iLinkP = aSessP;
  1053 		iSize = 1;
  1147 		iSize = 1;
       
  1148 		OstTraceFunctionExit1( TMMCSESSRING_ADD1_EXIT1, this );
  1054 		return;
  1149 		return;
  1055 		}
  1150 		}
  1056 
  1151 
  1057 	iPoint = iPMark->iLinkP;
  1152 	iPoint = iPMark->iLinkP;
  1058 	iPMark->iLinkP = aSessP;
  1153 	iPMark->iLinkP = aSessP;
  1059 	aSessP->iLinkP = iPoint;
  1154 	aSessP->iLinkP = iPoint;
  1060 	iPMark = iPrevP = aSessP;
  1155 	iPMark = iPrevP = aSessP;
  1061 	iSize++;
  1156 	iSize++;
       
  1157 	OstTraceFunctionExit1( TMMCSESSRING_ADD1_EXIT2, this );
  1062 	}
  1158 	}
  1063 
  1159 
  1064 
  1160 
  1065 void TMMCSessRing::Add(TMMCSessRing& aRing)
  1161 void TMMCSessRing::Add(TMMCSessRing& aRing)
  1066 /**
  1162 /**
  1067  * Inserts aRing before Marker. Point is moved into the Marker position.
  1163  * Inserts aRing before Marker. Point is moved into the Marker position.
  1068  * aRing Marker becomes the fisrt inserted element.
  1164  * aRing Marker becomes the fisrt inserted element.
  1069  * Erases aRing.
  1165  * Erases aRing.
  1070  */
  1166  */
  1071 	{
  1167 	{
       
  1168 	OstTraceFunctionEntry1( TMMCSESSRING_ADD2_ENTRY, this );
  1072 	Point();
  1169 	Point();
  1073 
  1170 
  1074 	if( aRing.iSize == 0 )
  1171 	if( aRing.iSize == 0 )
       
  1172 	    {
       
  1173 		OstTraceFunctionExit1( TMMCSESSRING_ADD2_EXIT1, this );
  1075 		return;
  1174 		return;
       
  1175 	    }
  1076 
  1176 
  1077 	if( iSize == 0 )
  1177 	if( iSize == 0 )
  1078 		{
  1178 		{
  1079 		iPrevP = iPMark = aRing.iPMark;
  1179 		iPrevP = iPMark = aRing.iPMark;
  1080 		iPoint = iPrevP->iLinkP;
  1180 		iPoint = iPrevP->iLinkP;
  1087 		iPrevP->iLinkP = iPoint;
  1187 		iPrevP->iLinkP = iPoint;
  1088 		iSize += aRing.iSize;
  1188 		iSize += aRing.iSize;
  1089 		}
  1189 		}
  1090 
  1190 
  1091 	aRing.Erase();
  1191 	aRing.Erase();
       
  1192 	OstTraceFunctionExit1( TMMCSESSRING_ADD2_EXIT2, this );
  1092 	}
  1193 	}
  1093 
  1194 
  1094 DMMCSession* TMMCSessRing::Remove()
  1195 DMMCSession* TMMCSessRing::Remove()
  1095 /**
  1196 /**
  1096  * Removes an element pointed to by Point.
  1197  * Removes an element pointed to by Point.
  1097  * Point (and possibly Marker) move forward as in operator++
  1198  * Point (and possibly Marker) move forward as in operator++
  1098  */
  1199  */
  1099 	{
  1200 	{
       
  1201 	OstTraceFunctionEntry1( TMMCSESSRING_REMOVE1_ENTRY, this );
  1100 	DMMCSession* remS = iPrevP;
  1202 	DMMCSession* remS = iPrevP;
  1101 
  1203 
  1102 	if( iSize < 2 )
  1204 	if( iSize < 2 )
  1103 		Erase();
  1205 		Erase();
  1104 	else
  1206 	else
  1115 			iPMark = iPrevP;
  1217 			iPMark = iPrevP;
  1116 			iPoint = NULL;
  1218 			iPoint = NULL;
  1117 			}
  1219 			}
  1118 		}
  1220 		}
  1119 
  1221 
  1120 	return( remS );
  1222 	OstTraceFunctionExitExt( TMMCSESSRING_REMOVE1_EXIT, this, ( TUint )( remS ) );
       
  1223 	return remS;
  1121 	}
  1224 	}
  1122 
  1225 
  1123 
  1226 
  1124 void TMMCSessRing::Remove(DMMCSession* aSessP)
  1227 void TMMCSessRing::Remove(DMMCSession* aSessP)
  1125 /**
  1228 /**
  1126  * Removes a specified session from the ring
  1229  * Removes a specified session from the ring
  1127  */
  1230  */
  1128 	{
  1231 	{
       
  1232 	OstTraceFunctionEntryExt( TMMCSESSRING_REMOVE2_ENTRY, this );
  1129 	if( Point(aSessP) )
  1233 	if( Point(aSessP) )
  1130 		Remove();
  1234 		Remove();
  1131 	else
  1235 	else
  1132 		DMMCSocket::Panic(DMMCSocket::EMMCSessRingNoSession);
  1236 		DMMCSocket::Panic(DMMCSocket::EMMCSessRingNoSession);
       
  1237 	OstTraceFunctionExit1( TMMCSESSRING_REMOVE2_EXIT, this );
  1133 	}
  1238 	}
  1134 
  1239 
  1135 
  1240 
  1136 
  1241 
  1137 //	--------  class TMMCStateMachine  --------
  1242 //	--------  class TMMCStateMachine  --------
  1142 
  1247 
  1143 It also resets the stack and the exit code.
  1248 It also resets the stack and the exit code.
  1144 */
  1249 */
  1145 EXPORT_C void TMMCStateMachine::Reset()
  1250 EXPORT_C void TMMCStateMachine::Reset()
  1146 	{
  1251 	{
       
  1252 	OstTraceFunctionEntry1( TMMCSTATEMACHINE_RESET_ENTRY, this );
  1147 	iAbort = EFalse;
  1253 	iAbort = EFalse;
  1148 	iSP = 0; iExitCode = 0;
  1254 	iSP = 0; iExitCode = 0;
  1149 	iStack[0].iState = 0; iStack[0].iTrapMask = 0;
  1255 	iStack[0].iState = 0; iStack[0].iTrapMask = 0;
       
  1256 	OstTraceFunctionExit1( TMMCSTATEMACHINE_RESET_EXIT, this );
  1150 	}
  1257 	}
  1151 
  1258 
  1152 
  1259 
  1153 
  1260 
  1154 
  1261 
  1157 
  1264 
  1158 @return The MultiMediaCard error code. 
  1265 @return The MultiMediaCard error code. 
  1159 */
  1266 */
  1160 EXPORT_C TMMCErr TMMCStateMachine::Dispatch()
  1267 EXPORT_C TMMCErr TMMCStateMachine::Dispatch()
  1161 	{
  1268 	{
  1162 
  1269 	OstTraceFunctionEntry1( TMMCSTATEMACHINE_DISPATCH_ENTRY, this );
       
  1270 	
  1163 	// If a state machine returns non-zero, i.e. a non-empty error set, then the second
  1271 	// If a state machine returns non-zero, i.e. a non-empty error set, then the second
  1164 	// inner while loop is broken.  The errors are thrown like an exception where the
  1272 	// inner while loop is broken.  The errors are thrown like an exception where the
  1165 	// stack is unravelled until it reaches a state machine which can handle at least
  1273 	// stack is unravelled until it reaches a state machine which can handle at least
  1166 	// one of the error codes, else this function returns with the exit code or'd with
  1274 	// one of the error codes, else this function returns with the exit code or'd with
  1167 	// KMMCErrBypass.  If the state machine returns zero, then this function returns
  1275 	// KMMCErrBypass.  If the state machine returns zero, then this function returns
  1180 		iExitCode &= ~KMMCErrBypass;
  1288 		iExitCode &= ~KMMCErrBypass;
  1181 
  1289 
  1182 		if ( iExitCode )
  1290 		if ( iExitCode )
  1183 			{
  1291 			{
  1184 			__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Err %x",iExitCode));
  1292 			__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Err %x",iExitCode));
       
  1293 			OstTrace1( TRACE_INTERNALS, TMMCSTATEMACHINE_DISPATCH, "iExitCode=0x%x", iExitCode );
  1185 			}
  1294 			}
  1186 
  1295 
  1187 		while( iSP >= 0 && !iAbort )
  1296 		while( iSP >= 0 && !iAbort )
  1188 			{
  1297 			{
  1189 			__KTRACE_OPT(KPBUS1,Kern::Printf("-msm:dsp:%02x:%08x.%02x",iSP, TUint32(iStack[iSP].iFunction), State()));
  1298 			__KTRACE_OPT(KPBUS1,Kern::Printf("-msm:dsp:%02x:%08x.%02x",iSP, TUint32(iStack[iSP].iFunction), State()));
       
  1299 			OstTraceExt3( TRACE_INTERNALS, TMMCSTATEMACHINE_DISPATCH2, "iSP=%d; iStack[iSP].iFunction=0x%08x; State=0x%02x", (TInt) iSP, (TUint) iStack[iSP].iFunction, (TUint) State() );
  1190 
  1300 
  1191 			iSuspend = ETrue;
  1301 			iSuspend = ETrue;
  1192 			const TMMCErr signal = iStack[iSP].iFunction(iContextP);
  1302 			const TMMCErr signal = iStack[iSP].iFunction(iContextP);
  1193 
  1303 
  1194 			if (signal)
  1304 			if (signal)
  1198 				}
  1308 				}
  1199 
  1309 
  1200 			if( iSuspend )
  1310 			if( iSuspend )
  1201 				{
  1311 				{
  1202 				__KTRACE_OPT(KPBUS1,Kern::Printf("<msm:dsp:exitslp"));
  1312 				__KTRACE_OPT(KPBUS1,Kern::Printf("<msm:dsp:exitslp"));
       
  1313 				OstTraceFunctionExit1( TMMCSTATEMACHINE_DISPATCH_EXIT1, this );
  1203 				return(0);
  1314 				return(0);
  1204 				}
  1315 				}
  1205 			}
  1316 			}
  1206 		}
  1317 		}
  1207 
  1318 
  1208 	__KTRACE_OPT(KPBUS1,Kern::Printf("<msm:dsp:exit%08x", iExitCode));
  1319 	__KTRACE_OPT(KPBUS1,Kern::Printf("<msm:dsp:exit%08x", iExitCode));
       
  1320 	OstTraceFunctionExit1( TMMCSTATEMACHINE_DISPATCH_EXIT2, this );
  1209 	return( KMMCErrBypass | iExitCode );
  1321 	return( KMMCErrBypass | iExitCode );
  1210 	}
  1322 	}
  1211 
  1323 
  1212 
  1324 
  1213 
  1325 
  1233 @see SMF_INVOKES
  1345 @see SMF_INVOKES
  1234 @see SMF_INVOKEWAITS 
  1346 @see SMF_INVOKEWAITS 
  1235 */
  1347 */
  1236 EXPORT_C TMMCErr TMMCStateMachine::Push(TMMCErr (*anEntry)(TAny*), TBool aSuspend)
  1348 EXPORT_C TMMCErr TMMCStateMachine::Push(TMMCErr (*anEntry)(TAny*), TBool aSuspend)
  1237 	{
  1349 	{
       
  1350 	OstTraceFunctionEntry1( TMMCSTATEMACHINE_PUSH_ENTRY, this );
  1238 	iSP++;
  1351 	iSP++;
  1239 	__ASSERT_ALWAYS(TUint(iSP)<KMaxMMCMachineStackDepth,
  1352 	__ASSERT_ALWAYS(TUint(iSP)<KMaxMMCMachineStackDepth,
  1240 		DMMCSocket::Panic(DMMCSocket::EMMCMachineStack));
  1353 		DMMCSocket::Panic(DMMCSocket::EMMCMachineStack));
  1241 	iStack[iSP].iFunction = anEntry;
  1354 	iStack[iSP].iFunction = anEntry;
  1242 	iStack[iSP].iState = 0;
  1355 	iStack[iSP].iState = 0;
  1243 	iStack[iSP].iTrapMask = 0;
  1356 	iStack[iSP].iTrapMask = 0;
  1244 	if( !aSuspend )
  1357 	if( !aSuspend )
  1245 		iSuspend = EFalse;
  1358 		iSuspend = EFalse;
  1246 	return( 0 );
  1359 	OstTraceFunctionExit1( TMMCSTATEMACHINE_PUSH_EXIT, this );
       
  1360 	return 0;
  1247 	}
  1361 	}
  1248 
  1362 
  1249 
  1363 
  1250 
  1364 
  1251 
  1365 
  1260 
  1374 
  1261 @return KMMCErrNone
  1375 @return KMMCErrNone
  1262 */
  1376 */
  1263 EXPORT_C TMMCErr TMMCStateMachine::Jump(TMMCErr (*anEntry)(TAny*), TBool aSuspend)
  1377 EXPORT_C TMMCErr TMMCStateMachine::Jump(TMMCErr (*anEntry)(TAny*), TBool aSuspend)
  1264 	{
  1378 	{
       
  1379 	OstTraceFunctionEntry1( TMMCSTATEMACHINE_JUMP_ENTRY, this );
  1265 	iStack[iSP].iFunction = anEntry;
  1380 	iStack[iSP].iFunction = anEntry;
  1266 	iStack[iSP].iState = 0;
  1381 	iStack[iSP].iState = 0;
  1267 	iStack[iSP].iTrapMask = 0;
  1382 	iStack[iSP].iTrapMask = 0;
  1268 	if( !aSuspend )
  1383 	if( !aSuspend )
  1269 		iSuspend = EFalse;
  1384 		iSuspend = EFalse;
  1270 	return( 0 );
  1385 	OstTraceFunctionExit1( TMMCSTATEMACHINE_JUMP_EXIT, this );
       
  1386 	return 0;
  1271 	}
  1387 	}
  1272 
  1388 
  1273 
  1389 
  1274 
  1390 
  1275 
  1391 
  1318 /**
  1434 /**
  1319  * Initialises the generic MMC stack.
  1435  * Initialises the generic MMC stack.
  1320  * @return KErrNone if successful, standard error code otherwise.
  1436  * @return KErrNone if successful, standard error code otherwise.
  1321  */
  1437  */
  1322 	{
  1438 	{
       
  1439 	OstTraceFunctionEntry1( DMMCSTACK_INIT_ENTRY, this );
  1323 	// allocate and initialize session object
  1440 	// allocate and initialize session object
  1324 	if ((iStackSession = AllocSession(TMMCCallBack(StackSessionCBST, this))) == 0)
  1441 	if ((iStackSession = AllocSession(TMMCCallBack(StackSessionCBST, this))) == 0)
  1325 		return(KErrNoMemory);
  1442 	    {
       
  1443 		OstTraceFunctionExitExt( DMMCSTACK_INIT_EXIT1, this, KErrNoMemory );
       
  1444 		return KErrNoMemory;
       
  1445 	    }
  1326 
  1446 
  1327 	// create helper class
  1447 	// create helper class
  1328 	if ((iBody = new DBody(*this)) == NULL)
  1448 	if ((iBody = new DBody(*this)) == NULL)
  1329 		return(KErrNoMemory);
  1449 	    {
       
  1450 		OstTraceFunctionExitExt( DMMCSTACK_INIT_EXIT2, this, KErrNoMemory );
       
  1451 		return KErrNoMemory;
       
  1452 	    }
  1330 
  1453 
  1331 	iStackSession->SetStack(this);
  1454 	iStackSession->SetStack(this);
  1332 
  1455 
  1333 	iStackDFC.SetDfcQ(&iSocket->iDfcQ);
  1456 	iStackDFC.SetDfcQ(&iSocket->iDfcQ);
  1334 
  1457 
  1337 	if ( iMaxCardsInStack > KMaxMMCardsPerStack )
  1460 	if ( iMaxCardsInStack > KMaxMMCardsPerStack )
  1338 		iMaxCardsInStack=KMaxMMCardsPerStack;
  1461 		iMaxCardsInStack=KMaxMMCardsPerStack;
  1339 
  1462 
  1340 	TInt r = iCardArray->AllocCards();
  1463 	TInt r = iCardArray->AllocCards();
  1341 
  1464 
  1342 	return(r);
  1465 	OstTraceFunctionExitExt( DMMCSTACK_INIT_EXIT3, this, r );
       
  1466 	return r;
  1343 	}
  1467 	}
  1344 
  1468 
  1345 EXPORT_C void DMMCStack::PowerUpStack()
  1469 EXPORT_C void DMMCStack::PowerUpStack()
  1346 /**
  1470 /**
  1347  * Enforce stack power-up and initialisation.
  1471  * Enforce stack power-up and initialisation.
  1348  * This is an asynchronous operation, which calls DMMCSocket::PowerUpSequenceComplete upon completion.
  1472  * This is an asynchronous operation, which calls DMMCSocket::PowerUpSequenceComplete upon completion.
  1349  */
  1473  */
  1350 	{
  1474 	{
       
  1475 	OstTraceFunctionEntry1( DMMCSTACK_POWERUPSTACK_ENTRY, this );
  1351 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:pus"));
  1476 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:pus"));
  1352 
  1477 
  1353 	if (iPSLBuf == NULL)
  1478 	if (iPSLBuf == NULL)
  1354 		{
  1479 		{
  1355 		GetBufferInfo(&iPSLBuf, &iPSLBufLen);
  1480 		GetBufferInfo(&iPSLBuf, &iPSLBufLen);
  1357 		}
  1482 		}
  1358 
  1483 
  1359 	ReportPowerDown();							// ensure power will be switch on regardless
  1484 	ReportPowerDown();							// ensure power will be switch on regardless
  1360 
  1485 
  1361 	Scheduler( iInitialise );
  1486 	Scheduler( iInitialise );
       
  1487 	OstTraceFunctionExit1( DMMCSTACK_POWERUPSTACK_EXIT, this );
  1362 	}
  1488 	}
  1363 
  1489 
  1364 void DMMCStack::QSleepStack()
  1490 void DMMCStack::QSleepStack()
  1365 /**
  1491 /**
  1366  * Schedules a session to place media in Sleep State
  1492  * Schedules a session to place media in Sleep State
  1367  */
  1493  */
  1368 	{
  1494 	{
       
  1495 	OstTraceFunctionEntry1( DMMCSTACK_QSLEEPSTACK_ENTRY, this );
  1369 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:qsleep"));
  1496 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:qsleep"));
  1370 
  1497 
  1371 	Scheduler( iSleep );
  1498 	Scheduler( iSleep );
       
  1499 	OstTraceFunctionExit1( DMMCSTACK_QSLEEPSTACK_EXIT, this );
  1372 	}
  1500 	}
  1373 
  1501 
  1374 EXPORT_C void DMMCStack::PowerDownStack()
  1502 EXPORT_C void DMMCStack::PowerDownStack()
  1375 /**
  1503 /**
  1376  * Enforce stack power down.
  1504  * Enforce stack power down.
  1380  * driver which may attempt to open immediately after this failed attempt won't have to re-power the card. 
  1508  * driver which may attempt to open immediately after this failed attempt won't have to re-power the card. 
  1381  * If no driver successfully opens on the card then the Controllers inactivity/not in use 
  1509  * If no driver successfully opens on the card then the Controllers inactivity/not in use 
  1382  * timeout system can be left to power it down.
  1510  * timeout system can be left to power it down.
  1383  */
  1511  */
  1384 	{
  1512 	{
       
  1513 	OstTraceFunctionEntry1( DMMCSTACK_POWERDOWNSTACK_ENTRY, this );
  1385 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:pds"));
  1514 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:pds"));
  1386 
  1515 
  1387 	ReportPowerDown();
  1516 	ReportPowerDown();
  1388 	iInitState = EISPending;
  1517 	iInitState = EISPending;
  1389 	DoPowerDown();
  1518 	DoPowerDown();
  1433 	// The stack may have powered down while attempting to power up (e.g. because a card has not responded), 
  1562 	// The stack may have powered down while attempting to power up (e.g. because a card has not responded), 
  1434 	// so ensure stack doesn't attempt to initialize itself again until next PowerUpStack()
  1563 	// so ensure stack doesn't attempt to initialize itself again until next PowerUpStack()
  1435 	iInitialise = EFalse;
  1564 	iInitialise = EFalse;
  1436 	iStackState &= ~(KMMCStackStateInitInProgress | KMMCStackStateInitPending | KMMCStackStateBusInconsistent | KMMCStackStateWaitingDFC);
  1565 	iStackState &= ~(KMMCStackStateInitInProgress | KMMCStackStateInitPending | KMMCStackStateBusInconsistent | KMMCStackStateWaitingDFC);
  1437 	iSessionP = NULL;
  1566 	iSessionP = NULL;
       
  1567 	OstTraceFunctionExit1( DMMCSTACK_POWERDOWNSTACK_EXIT, this );
  1438 	}
  1568 	}
  1439 
  1569 
  1440 //
  1570 //
  1441 // DMMCStack:: --- Stack Scheduler and its supplementary functions ---
  1571 // DMMCStack:: --- Stack Scheduler and its supplementary functions ---
  1442 //
  1572 //
  1443 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedGetOnDFC()
  1573 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedGetOnDFC()
  1444 /**
  1574 /**
  1445  * Initiates stack DFC. Returns either Continue or Loop.
  1575  * Initiates stack DFC. Returns either Continue or Loop.
  1446  */
  1576  */
  1447 	{
  1577 	{
       
  1578 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDGETONDFC_ENTRY, this );
  1448 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sgd"));
  1579 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sgd"));
  1449 
  1580 
  1450 	if( iDFCRunning )
  1581 	if( iDFCRunning )
  1451 		return( ESchedContinue );
  1582 	    {
       
  1583 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDGETONDFC_EXIT1, this, (TInt) ESchedContinue);
       
  1584 		return ESchedContinue;
       
  1585 	    }
  1452 
  1586 
  1453 	if( (iStackState & KMMCStackStateWaitingDFC) == 0 )
  1587 	if( (iStackState & KMMCStackStateWaitingDFC) == 0 )
  1454 		{
  1588 		{
  1455 		__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sgd:q"));
  1589 		__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sgd:q"));
  1456 		iStackState |= KMMCStackStateWaitingDFC;
  1590 		iStackState |= KMMCStackStateWaitingDFC;
  1458 			iStackDFC.Add();
  1592 			iStackDFC.Add();
  1459 		else
  1593 		else
  1460 			iStackDFC.Enque();
  1594 			iStackDFC.Enque();
  1461 		}
  1595 		}
  1462 
  1596 
  1463 	return( ESchedLoop );
  1597 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDGETONDFC_EXIT2, this, (TInt) ESchedLoop);
       
  1598 	return ESchedLoop;
  1464 	}
  1599 	}
  1465 
  1600 
  1466 void DMMCStack::SchedSetContext(DMMCSession* aSessP)
  1601 void DMMCStack::SchedSetContext(DMMCSession* aSessP)
  1467 /**
  1602 /**
  1468  * Sets up the specified session as the current session.
  1603  * Sets up the specified session as the current session.
  1469  * Invoked by JobChooser and Initialiser.
  1604  * Invoked by JobChooser and Initialiser.
  1470  * @param aSessP A pointer to the session.
  1605  * @param aSessP A pointer to the session.
  1471  */
  1606  */
  1472 	{
  1607 	{
       
  1608 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDSETCONTEXT_ENTRY, this );
  1473 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ssc"));
  1609 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ssc"));
  1474 
  1610 
  1475 	if( (iStackState & (KMMCStackStateInitPending|KMMCStackStateBusInconsistent)) != 0 &&
  1611 	if( (iStackState & (KMMCStackStateInitPending|KMMCStackStateBusInconsistent)) != 0 &&
  1476 		aSessP->iSessionID != ECIMInitStack )
  1612 		aSessP->iSessionID != ECIMInitStack )
  1477 		{
  1613 		{
  1478 		iInitialise = ETrue;
  1614 		iInitialise = ETrue;
       
  1615 		OstTraceFunctionExit1( DMMCSTACK_SCHEDSETCONTEXT_EXIT1, this );
  1479 		return;
  1616 		return;
  1480 		}
  1617 		}
  1481 
  1618 
  1482 	if( iSessionP != aSessP )
  1619 	if( iSessionP != aSessP )
  1483 		{
  1620 		{
  1495 
  1632 
  1496 		iSessionP = aSessP;
  1633 		iSessionP = aSessP;
  1497 		}
  1634 		}
  1498 
  1635 
  1499 	iSessionP->iState &= ~KMMCSessStateDoReSchedule;
  1636 	iSessionP->iState &= ~KMMCSessStateDoReSchedule;
       
  1637 	OstTraceFunctionExit1( DMMCSTACK_SCHEDSETCONTEXT_EXIT2, this );
  1500 	}
  1638 	}
  1501 
  1639 
  1502 void DMMCStack::SchedDoAbort(DMMCSession* aSessP)
  1640 void DMMCStack::SchedDoAbort(DMMCSession* aSessP)
  1503 /**
  1641 /**
  1504  * Aborts asynchronous activities of a session aSessP
  1642  * Aborts asynchronous activities of a session aSessP
  1505  * @param aSessP A pointer to the session to be aborted.
  1643  * @param aSessP A pointer to the session to be aborted.
  1506  */
  1644  */
  1507 	{
  1645 	{
       
  1646 	OstTraceFunctionEntryExt( DMMCSTACK_SCHEDDOABORT_ENTRY, this );
  1508 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sda"));
  1647 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sda"));
  1509 
  1648 
  1510 #ifdef __EPOC32__
  1649 #ifdef __EPOC32__
  1511 	if( aSessP->iBlockOn & KMMCBlockOnPollTimer )
  1650 	if( aSessP->iBlockOn & KMMCBlockOnPollTimer )
  1512 		aSessP->iPollTimer.Cancel();
  1651 		aSessP->iPollTimer.Cancel();
  1530 	
  1669 	
  1531 	
  1670 	
  1532 	(void)__e32_atomic_and_ord32(&aSessP->iBlockOn, ~(KMMCBlockOnPollTimer | KMMCBlockOnRetryTimer |
  1671 	(void)__e32_atomic_and_ord32(&aSessP->iBlockOn, ~(KMMCBlockOnPollTimer | KMMCBlockOnRetryTimer |
  1533 						  							  KMMCBlockOnWaitToLock | KMMCBlockOnASSPFunction | 
  1672 						  							  KMMCBlockOnWaitToLock | KMMCBlockOnASSPFunction | 
  1534 						  							  KMMCBlockOnInterrupt | KMMCBlockOnDataTransfer) );
  1673 						  							  KMMCBlockOnInterrupt | KMMCBlockOnDataTransfer) );
       
  1674 	OstTraceFunctionExit1( DMMCSTACK_SCHEDDOABORT_EXIT, this );
  1535 	}
  1675 	}
  1536 
  1676 
  1537 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedResolveStatBlocks(DMMCSession* aSessP)
  1677 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedResolveStatBlocks(DMMCSession* aSessP)
  1538 /**
  1678 /**
  1539  * Checks static blocking conditions and removes them as necessary
  1679  * Checks static blocking conditions and removes them as necessary
  1540  * @param aSessP A pointer to the session.
  1680  * @param aSessP A pointer to the session.
  1541  * @return EschedContinue or ESchedLoop (if scheduler is to be restarted)
  1681  * @return EschedContinue or ESchedLoop (if scheduler is to be restarted)
  1542  */
  1682  */
  1543 	{
  1683 	{
       
  1684 	OstTraceFunctionEntryExt( DMMCSTACK_SCHEDRESOLVESTATBLOCKS_ENTRY, this );
  1544 
  1685 
  1545 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:srsb"));
  1686 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:srsb"));
  1546 
  1687 
  1547 	if( (aSessP->iBlockOn & KMMCBlockOnCardInUse) && aSessP->iCardP->iUsingSessionP == NULL )
  1688 	if( (aSessP->iBlockOn & KMMCBlockOnCardInUse) && aSessP->iCardP->iUsingSessionP == NULL )
  1548 		aSessP->SynchUnBlock( KMMCBlockOnCardInUse );
  1689 		aSessP->SynchUnBlock( KMMCBlockOnCardInUse );
  1552 		// ECIMLockStack processed here
  1693 		// ECIMLockStack processed here
  1553 		iLockingSessionP = aSessP;					// in this order
  1694 		iLockingSessionP = aSessP;					// in this order
  1554 		iStackState &= ~KMMCStackStateWaitingToLock;
  1695 		iStackState &= ~KMMCStackStateWaitingToLock;
  1555 		aSessP->SynchUnBlock( KMMCBlockOnWaitToLock );
  1696 		aSessP->SynchUnBlock( KMMCBlockOnWaitToLock );
  1556 		MarkComplete( aSessP, KMMCErrNone );
  1697 		MarkComplete( aSessP, KMMCErrNone );
  1557 		return( ESchedLoop );
  1698 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDRESOLVESTATBLOCKS_EXIT1, this, (TInt) ESchedLoop );
  1558 		}
  1699 		return ESchedLoop;
  1559 
  1700 		}
  1560 	return( ESchedContinue );
  1701 
       
  1702 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDRESOLVESTATBLOCKS_EXIT2, this, (TInt) ESchedContinue );
       
  1703 	return ESchedContinue;
  1561 	}
  1704 	}
  1562 
  1705 
  1563 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedGroundDown(DMMCSession* aSessP, TMMCErr aReason)
  1706 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedGroundDown(DMMCSession* aSessP, TMMCErr aReason)
  1564 /**
  1707 /**
  1565  * Aborts all asynchronous activities of session aSessP with
  1708  * Aborts all asynchronous activities of session aSessP with
  1573  * @return ESchedLoop if the session can not be safely grounded (eg
  1716  * @return ESchedLoop if the session can not be safely grounded (eg
  1574  * iStackSession) and should therefore be aborted and/or completed by a
  1717  * iStackSession) and should therefore be aborted and/or completed by a
  1575  * separate scheduler pass.
  1718  * separate scheduler pass.
  1576  */
  1719  */
  1577 	{
  1720 	{
       
  1721 	OstTraceExt3(TRACE_FLOW, DMMCSTACK_SCHEDGROUNDDOWN_ENTRY, "DMMCStack::SchedGroundDown;aSessionP=%x;aReason=%d;this=%x", (TUint) aSessP, (TInt) aReason, (TUint) this);
  1578 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sgdn"));
  1722 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sgdn"));
  1579 
  1723 
  1580 	if( (aSessP == iStackSession) || InitStackInProgress() )
  1724 	if( (aSessP == iStackSession) || InitStackInProgress() )
  1581 		return( ESchedLoop );
  1725 	    {
       
  1726 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDGROUNDDOWN_EXIT1, this, (TInt) ESchedLoop );
       
  1727 		return ESchedLoop;
       
  1728 	    }
  1582 	
  1729 	
  1583 	if( aSessP->iState & KMMCSessStateInProgress )
  1730 	if( aSessP->iState & KMMCSessStateInProgress )
  1584 		{
  1731 		{
  1585 		SchedDoAbort( aSessP );
  1732 		SchedDoAbort( aSessP );
  1586 		//coverity[check_return]
  1733 		//coverity[check_return]
  1588 		aSessP->iMachine.SetExitCode( aReason );
  1735 		aSessP->iMachine.SetExitCode( aReason );
  1589 		aSessP->iState &= ~(KMMCSessStateSafeInGaps | KMMCSessStateDoReSchedule |
  1736 		aSessP->iState &= ~(KMMCSessStateSafeInGaps | KMMCSessStateDoReSchedule |
  1590 							KMMCSessStateDoDFC);
  1737 							KMMCSessStateDoDFC);
  1591 		}
  1738 		}
  1592 
  1739 
  1593 	return( ESchedContinue );
  1740 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDGROUNDDOWN_EXIT2, this, (TInt) ESchedContinue );
       
  1741 	return ESchedContinue;
  1594 	}
  1742 	}
  1595 
  1743 
  1596 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedEnqueStackSession(TMMCSessionTypeEnum aSessID)
  1744 DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedEnqueStackSession(TMMCSessionTypeEnum aSessID)
  1597 /**
  1745 /**
  1598  * Prepare internal session for InitStack and enque it into WorkSet.
  1746  * Prepare internal session for InitStack and enque it into WorkSet.
  1599  * @return EschedContinue or ESchedLoop
  1747  * @return EschedContinue or ESchedLoop
  1600  */
  1748  */
  1601 	{
  1749 	{
       
  1750 	OstTraceExt2(TRACE_FLOW, DMMCSTACK_SCHEDENQUESTACKSESSION_ENTRY ,"DMMCStack::SchedEnqueStackSession;aSessID=%d;this=%x", (TInt) aSessID, (TUint) this);
  1602 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sess"));
  1751 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sess"));
  1603 
  1752 
  1604 		if( iStackSession->IsEngaged() )
  1753 		if( iStackSession->IsEngaged() )
  1605 			{
  1754 			{
  1606 			MarkComplete( iStackSession, KMMCErrAbort );
  1755 			MarkComplete( iStackSession, KMMCErrAbort );
  1607 			return( ESchedLoop );
  1756 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDENQUESTACKSESSION_EXIT1, this, (TInt) ESchedLoop );
       
  1757 			return ESchedLoop;
  1608 			}
  1758 			}
  1609 
  1759 
  1610 		iStackSession->SetupCIMControl( aSessID );
  1760 		iStackSession->SetupCIMControl( aSessID );
  1611 		iWorkSet.Add( iStackSession );
  1761 		iWorkSet.Add( iStackSession );
  1612 		iStackSession->iState |= KMMCSessStateEngaged;
  1762 		iStackSession->iState |= KMMCSessStateEngaged;
  1613 		return( ESchedContinue );
  1763 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDENQUESTACKSESSION_EXIT2, this, (TInt) ESchedContinue );
       
  1764 		return ESchedContinue;
  1614 	}
  1765 	}
  1615 
  1766 
  1616 void DMMCStack::SchedGrabEntries()
  1767 void DMMCStack::SchedGrabEntries()
  1617 /**
  1768 /**
  1618  * Merges Entry queue into Ready queue. Invoked at the scheduler entry and
  1769  * Merges Entry queue into Ready queue. Invoked at the scheduler entry and
  1619  * after the completion pass
  1770  * after the completion pass
  1620  */
  1771  */
  1621 	{
  1772 	{
       
  1773 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDGRABENTRIES_ENTRY, this );
       
  1774 	
  1622 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sge"));
  1775 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sge"));
  1623 
  1776 
  1624 	iAttention = EFalse;		// Strictly in this order
  1777 	iAttention = EFalse;		// Strictly in this order
  1625 	if( !iEntryQueue.IsEmpty() )
  1778 	if( !iEntryQueue.IsEmpty() )
  1626 		{
  1779 		{
  1627 		DISABLEPREEMPTION
  1780 		DISABLEPREEMPTION
  1628 		iReadyQueue.Add( iEntryQueue );
  1781 		iReadyQueue.Add( iEntryQueue );
  1629 		RESTOREPREEMPTION
  1782 		RESTOREPREEMPTION
  1630 		}
  1783 		}
       
  1784 	OstTraceFunctionExit1( DMMCSTACK_SCHEDGRABENTRIES_EXIT, this );
  1631 	}
  1785 	}
  1632 
  1786 
  1633 void DMMCStack::SchedDisengage()
  1787 void DMMCStack::SchedDisengage()
  1634 /**
  1788 /**
  1635  * This function is called by AbortPass() and CompletionPass() to remove the session
  1789  * This function is called by AbortPass() and CompletionPass() to remove the session
  1636  * at WorkSet Point, to abort its asynchronous activities (if any) and
  1790  * at WorkSet Point, to abort its asynchronous activities (if any) and
  1637  * clear up the dependent resources
  1791  * clear up the dependent resources
  1638  */
  1792  */
  1639 	{
  1793 	{
       
  1794 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDDISENGAGE_ENTRY, this );
  1640 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sd"));
  1795 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sd"));
  1641 
  1796 
  1642 	DMMCSession* sessP = iWorkSet.Remove();
  1797 	DMMCSession* sessP = iWorkSet.Remove();
  1643 
  1798 
  1644 	SchedDoAbort( sessP );
  1799 	SchedDoAbort( sessP );
  1663 
  1818 
  1664 	if( sessP->iState & KMMCSessStateASSPEngaged )
  1819 	if( sessP->iState & KMMCSessStateASSPEngaged )
  1665 		ASSPDisengage();
  1820 		ASSPDisengage();
  1666 
  1821 
  1667 	sessP->iState = 0;
  1822 	sessP->iState = 0;
       
  1823 	OstTraceFunctionExit1( DMMCSTACK_SCHEDDISENGAGE_EXIT, this );
  1668 	}
  1824 	}
  1669 
  1825 
  1670 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedAbortPass()
  1826 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedAbortPass()
  1671 /**
  1827 /**
  1672  * DMMCStack Scheduler private inline functions. These functions were separated as inline functions
  1828  * DMMCStack Scheduler private inline functions. These functions were separated as inline functions
  1673  * only for the sake of Scheduler() clarity.
  1829  * only for the sake of Scheduler() clarity.
  1674  */
  1830  */
  1675 	{
  1831 	{
       
  1832 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDABORTPASS_ENTRY, this );
  1676 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sap"));
  1833 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sap"));
  1677 
  1834 
  1678 	iAbortReq = EFalse;
  1835 	iAbortReq = EFalse;
  1679 	SchedGrabEntries();
  1836 	SchedGrabEntries();
  1680 	DMMCSession* sessP;
  1837 	DMMCSession* sessP;
  1697 			}
  1854 			}
  1698 		else
  1855 		else
  1699 			iReadyQueue++;
  1856 			iReadyQueue++;
  1700 
  1857 
  1701 	if( iAbortReq )
  1858 	if( iAbortReq )
  1702 		return( ESchedLoop );
  1859 	    {
       
  1860 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDABORTPASS_EXIT1, this, (TInt) ESchedLoop );
       
  1861 		return ESchedLoop;
       
  1862 	    }
  1703 
  1863 
  1704 	// Clearing iAbortAll here is a bit dodgy. It wouldn't work if somebody interrupted us
  1864 	// Clearing iAbortAll here is a bit dodgy. It wouldn't work if somebody interrupted us
  1705 	// at this point, enqued a session and then immediately called Reset() - that session
  1865 	// at this point, enqued a session and then immediately called Reset() - that session
  1706 	// would not be discarded. However, the correct solution (enque Reset() requests
  1866 	// would not be discarded. However, the correct solution (enque Reset() requests
  1707 	// and process them in the Scheduler main loop) seems to be too expensive just to avoid
  1867 	// and process them in the Scheduler main loop) seems to be too expensive just to avoid
  1708 	// this particular effect.
  1868 	// this particular effect.
  1709 	iAbortAll = EFalse;
  1869 	iAbortAll = EFalse;
  1710 	return( ESchedContinue );
  1870 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDABORTPASS_EXIT2, this, (TInt) ESchedContinue  );
       
  1871 	return ESchedContinue;
  1711 	}
  1872 	}
  1712 
  1873 
  1713 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedCompletionPass()
  1874 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedCompletionPass()
  1714 /**
  1875 /**
  1715  * This function calls back all the sessions waiting to be completed
  1876  * This function calls back all the sessions waiting to be completed
  1716  * Returns either Continue or Loop.
  1877  * Returns either Continue or Loop.
  1717  */
  1878  */
  1718 	{
  1879 	{
       
  1880 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDCOMPLETIONPASS_ENTRY, this );
  1719 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:scp"));
  1881 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:scp"));
  1720 
  1882 
  1721 	iCompReq = EFalse;
  1883 	iCompReq = EFalse;
  1722 	DMMCSession* sessP;
  1884 	DMMCSession* sessP;
  1723 
  1885 
  1736 				 SchedGetOnDFC() )
  1898 				 SchedGetOnDFC() )
  1737 				{
  1899 				{
  1738 				// DFC has been queued so return back to main loop.  Next time
  1900 				// DFC has been queued so return back to main loop.  Next time
  1739 				// SchedGetOnDfc() will return EFalse, and the callback will be called.
  1901 				// SchedGetOnDfc() will return EFalse, and the callback will be called.
  1740 				iCompReq = ETrue;
  1902 				iCompReq = ETrue;
  1741 				return( ESchedLoop );
  1903 				OstTraceFunctionExitExt( DMMCSTACK_SCHEDCOMPLETIONPASS_EXIT1, this, (TInt) ESchedLoop );
       
  1904 				return ESchedLoop;
  1742 				}
  1905 				}
  1743 
  1906 
  1744 			SchedDisengage();					// calls iWorkSet.Remove
  1907 			SchedDisengage();					// calls iWorkSet.Remove
  1745 			sessP->iMMCExitCode |= iCompleteAllExitCode;
  1908 			sessP->iMMCExitCode |= iCompleteAllExitCode;
  1746 			// Update the controller store if a password operation was in progress.
  1909 			// Update the controller store if a password operation was in progress.
  1785 			}
  1948 			}
  1786 		else
  1949 		else
  1787 			iWorkSet++;
  1950 			iWorkSet++;
  1788 
  1951 
  1789 	if( iCompReq )
  1952 	if( iCompReq )
  1790 		return( ESchedLoop );
  1953 	    {
       
  1954 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDCOMPLETIONPASS_EXIT2, this, (TInt) ESchedLoop );
       
  1955 		return ESchedLoop;
       
  1956 	    }
  1791 
  1957 
  1792 	iCompleteAllExitCode = 0;
  1958 	iCompleteAllExitCode = 0;
  1793 
  1959 
  1794 	return( ESchedContinue );
  1960 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDCOMPLETIONPASS_EXIT3, this, ( TInt) ESchedContinue );
       
  1961 	return ESchedContinue;
  1795 	}
  1962 	}
  1796 
  1963 
  1797 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedInitStack()
  1964 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedInitStack()
  1798 /**
  1965 /**
  1799  * "Immediate" InitStack initiator. Returns either Continue or Loop.
  1966  * "Immediate" InitStack initiator. Returns either Continue or Loop.
  1800  */
  1967  */
  1801 	{
  1968 	{
       
  1969 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDINITSTACK_ENTRY, this );
  1802 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sis"));
  1970 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sis"));
  1803 
  1971 
  1804 	if( SchedGetOnDFC() )
  1972 	if( SchedGetOnDFC() )
  1805 		return( ESchedLoop );
  1973 	    {
       
  1974 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDINITSTACK_EXIT1, this, (TInt) ESchedLoop );
       
  1975 		return ESchedLoop;
       
  1976 	    }
  1806 
  1977 
  1807 	if( iSessionP != NULL && (iStackState & KMMCStackStateJobChooser) == 0 )
  1978 	if( iSessionP != NULL && (iStackState & KMMCStackStateJobChooser) == 0 )
  1808 		{
  1979 		{
  1809 		if( (iSessionP->iState & KMMCSessStateInProgress) )
  1980 		if( (iSessionP->iState & KMMCSessStateInProgress) )
  1810 			{
  1981 			{
  1811 			if( SchedGroundDown(iSessionP, KMMCErrPowerDown) )
  1982 			if( SchedGroundDown(iSessionP, KMMCErrPowerDown) )
  1812 				{
  1983 				{
  1813 				MarkComplete( iSessionP, KMMCErrPowerDown );
  1984 				MarkComplete( iSessionP, KMMCErrPowerDown );
  1814 				return( ESchedLoop );
  1985 				OstTraceFunctionExitExt( DMMCSTACK_SCHEDINITSTACK_EXIT2, this, (TInt) ESchedLoop );
       
  1986 				return ESchedLoop;
  1815 				}
  1987 				}
  1816 			}
  1988 			}
  1817 		else
  1989 		else
  1818 			iSessionP->iMachine.Reset();
  1990 			iSessionP->iMachine.Reset();
  1819 		}
  1991 		}
  1827 	// session isn't specifically ECIMInitStack (which it rarely will be) then we have to use
  1999 	// session isn't specifically ECIMInitStack (which it rarely will be) then we have to use
  1828 	// the stack session to perform the stack init.
  2000 	// the stack session to perform the stack init.
  1829 	if( iSessionP == NULL || iSessionP->iSessionID != ECIMInitStack )
  2001 	if( iSessionP == NULL || iSessionP->iSessionID != ECIMInitStack )
  1830 		{
  2002 		{
  1831 		if( SchedEnqueStackSession(ECIMInitStack) )
  2003 		if( SchedEnqueStackSession(ECIMInitStack) )
  1832 			return( ESchedLoop );
  2004 		    {
       
  2005 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDINITSTACK_EXIT3, this, (TInt) ESchedLoop );
       
  2006 			return ESchedLoop;
       
  2007 		    }
  1833 
  2008 
  1834 		SchedSetContext( iStackSession );	// make the internal session to be current job
  2009 		SchedSetContext( iStackSession );	// make the internal session to be current job
  1835 		}
  2010 		}
  1836 
  2011 
  1837 	// Neither client nor internal session could be blocked here, not even on "BrokenLock"
  2012 	// Neither client nor internal session could be blocked here, not even on "BrokenLock"
  1839 	DMMCSocket::Panic(DMMCSocket::EMMCInitStackBlocked) );
  2014 	DMMCSocket::Panic(DMMCSocket::EMMCInitStackBlocked) );
  1840 
  2015 
  1841 	iStackState |= KMMCStackStateInitInProgress;
  2016 	iStackState |= KMMCStackStateInitInProgress;
  1842 	// nothing can stop this session now; it's safe to clear iInitialise here.
  2017 	// nothing can stop this session now; it's safe to clear iInitialise here.
  1843 	iInitialise = EFalse;
  2018 	iInitialise = EFalse;
  1844 	return( ESchedContinue );
  2019 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDINITSTACK_EXIT4, this, (TInt) ESchedContinue );
       
  2020 	return ESchedContinue;
  1845 	}
  2021 	}
  1846 
  2022 
  1847 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedSleepStack()
  2023 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedSleepStack()
  1848 /**
  2024 /**
  1849  * "Immediate" Stack sleep mode. Returns either Continue or Loop.
  2025  * "Immediate" Stack sleep mode. Returns either Continue or Loop.
  1850  */
  2026  */
  1851 	{
  2027 	{
       
  2028 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDSLEEPSTACK_ENTRY, this );
  1852 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:SchdSlp!"));
  2029 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:SchdSlp!"));
  1853 
  2030 
  1854 	// Make sure Stack DFC is Running!
  2031 	// Make sure Stack DFC is Running!
  1855 	if( SchedGetOnDFC() )
  2032 	if( SchedGetOnDFC() )
  1856 		{
  2033 		{
  1857 		__KTRACE_OPT(KPBUS1, Kern::Printf("mst:SchdSlp - DFC not running"));
  2034 		__KTRACE_OPT(KPBUS1, Kern::Printf("mst:SchdSlp - DFC not running"));
  1858 		return( ESchedLoop );
  2035 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDSLEEPSTACK_EXIT1, this, (TInt) ESchedLoop );
       
  2036 		return ESchedLoop;
  1859 		}
  2037 		}
  1860 
  2038 
  1861 	if( iSessionP != NULL && (iStackState & KMMCStackStateJobChooser) == 0 )
  2039 	if( iSessionP != NULL && (iStackState & KMMCStackStateJobChooser) == 0 )
  1862 		{
  2040 		{
  1863 		if( (iSessionP->iState & KMMCSessStateInProgress) )
  2041 		if( (iSessionP->iState & KMMCSessStateInProgress) )
  1864 			{
  2042 			{
  1865 			// A session has been queued before sleep, 
  2043 			// A session has been queued before sleep, 
  1866 			// cancel sleep and loop for next session
  2044 			// cancel sleep and loop for next session
  1867 			iSleep = EFalse;
  2045 			iSleep = EFalse;
  1868 			return( ESchedLoop );
  2046 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDSLEEPSTACK_EXIT2, this, (TInt) ESchedLoop );
       
  2047 			return ESchedLoop;
  1869 			}
  2048 			}
  1870 		}
  2049 		}
  1871 	
  2050 	
  1872 	// Use the stack session to perform the stack sleep.
  2051 	// Use the stack session to perform the stack sleep.
  1873 	if( SchedEnqueStackSession(ECIMSleep) )
  2052 	if( SchedEnqueStackSession(ECIMSleep) )
  1874 		{
  2053 		{
  1875 		__KTRACE_OPT(KPBUS1,Kern::Printf("SchdSlp: already Enqued"));
  2054 		__KTRACE_OPT(KPBUS1,Kern::Printf("SchdSlp: already Enqued"));
  1876 		// Stack already busy cancel sleep
  2055 		// Stack already busy cancel sleep
  1877 		iSleep = EFalse;
  2056 		iSleep = EFalse;
  1878 		return( ESchedLoop );
  2057 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDSLEEPSTACK_EXIT3, this, (TInt) ESchedLoop );
       
  2058 		return ESchedLoop;
  1879 		}
  2059 		}
  1880 
  2060 
  1881 	SchedSetContext( iStackSession );	// make the internal session to be current job
  2061 	SchedSetContext( iStackSession );	// make the internal session to be current job
  1882 
  2062 
  1883 	// Sleep has now been queued
  2063 	// Sleep has now been queued
  1884 	iSleep = EFalse;
  2064 	iSleep = EFalse;
  1885 	iStackState |= KMMCStackStateSleepinProgress;
  2065 	iStackState |= KMMCStackStateSleepinProgress;
  1886 	__KTRACE_OPT(KPBUS1, Kern::Printf("<mst:SchdSlp"));
  2066 	__KTRACE_OPT(KPBUS1, Kern::Printf("<mst:SchdSlp"));
  1887 	
  2067 	
  1888 	return( ESchedLoop );
  2068 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDSLEEPSTACK_EXIT4, this, (TInt) ESchedLoop );
       
  2069 	return ESchedLoop;
  1889 	}
  2070 	}
  1890 
  2071 
  1891 
  2072 
  1892 inline TBool DMMCStack::SchedPreemptable()
  2073 inline TBool DMMCStack::SchedPreemptable()
  1893 /**
  2074 /**
  1894  * Checks if the current session can be preempted
  2075  * Checks if the current session can be preempted
  1895  */
  2076  */
  1896 	{	// strictly in the following order
  2077 	{	// strictly in the following order
       
  2078 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDPREEMPTABLE_ENTRY, this );
  1897 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:spe"));
  2079 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:spe"));
  1898 	
  2080 	
  1899 	if( (iStackState & KMMCStackStateJobChooser) ||
  2081 	if( (iStackState & KMMCStackStateJobChooser) ||
  1900 		(iSessionP->iState & KMMCSessStateDoReSchedule) )
  2082 		(iSessionP->iState & KMMCSessStateDoReSchedule) )
  1901 		return( ETrue );
  2083 	    {
       
  2084 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT1, this, (TUint) ETrue );
       
  2085 		return ETrue;
       
  2086 	    }
  1902 
  2087 
  1903 	if( (iSessionP->iBlockOn & KMMCBlockOnASSPFunction) )
  2088 	if( (iSessionP->iBlockOn & KMMCBlockOnASSPFunction) )
  1904 		return( EFalse );
  2089 	    {
       
  2090 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT2, this, (TUint) EFalse );
       
  2091 		return EFalse;
       
  2092 	    }
  1905 
  2093 
  1906 	TBool preemptDC = EFalse;	
  2094 	TBool preemptDC = EFalse;	
  1907 
  2095 
  1908 	if (iSessionP->iBlockOn & KMMCBlockOnYielding)
  2096 	if (iSessionP->iBlockOn & KMMCBlockOnYielding)
  1909 		{
  2097 		{
  1914 		{
  2102 		{
  1915 		// Added for SDIO Read/Wait and SDC support.  This condition
  2103 		// Added for SDIO Read/Wait and SDC support.  This condition
  1916 		// is set at the variant, and determines whether commands may be
  2104 		// is set at the variant, and determines whether commands may be
  1917 		// issued during the data transfer period.
  2105 		// issued during the data transfer period.
  1918 		if(!(iSessionP->iState & KMMCSessStateAllowDirectCommands))
  2106 		if(!(iSessionP->iState & KMMCSessStateAllowDirectCommands))
  1919 			return( EFalse );
  2107 		    {
       
  2108 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT3, this, (TUint) EFalse );
       
  2109 			return EFalse;
       
  2110 		    }
  1920 		
  2111 		
  1921 		// We must consider the remaining blocking conditions
  2112 		// We must consider the remaining blocking conditions
  1922 		// before being sure that we can enable pre-emtion of this session
  2113 		// before being sure that we can enable pre-emtion of this session
  1923 		preemptDC = ETrue;
  2114 		preemptDC = ETrue;
  1924 		}
  2115 		}
  1925 
  2116 
  1926 	if( (iSessionP->iBlockOn & (KMMCBlockOnCardInUse | KMMCBlockOnNoRun)) )
  2117 	if( (iSessionP->iBlockOn & (KMMCBlockOnCardInUse | KMMCBlockOnNoRun)) )
  1927 		return( ETrue );
  2118 	    {
       
  2119 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT4, this, (TUint) ETrue );
       
  2120 		return ETrue;
       
  2121 	    }
  1928 	
  2122 	
  1929 	if( (iConfig.iModes & KMMCModeEnablePreemption) == 0 )
  2123 	if( (iConfig.iModes & KMMCModeEnablePreemption) == 0 )
  1930 		return( EFalse );
  2124 	    {
       
  2125 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT5, this, (TUint) EFalse );
       
  2126 		return EFalse;
       
  2127 	    }
  1931 
  2128 
  1932 	if( (iSessionP->iBlockOn & KMMCBlockOnGapTimersMask) &&
  2129 	if( (iSessionP->iBlockOn & KMMCBlockOnGapTimersMask) &&
  1933 		(iConfig.iModes & KMMCModePreemptInGaps) &&
  2130 		(iConfig.iModes & KMMCModePreemptInGaps) &&
  1934 		(iSessionP->iState & KMMCSessStateSafeInGaps) )
  2131 		(iSessionP->iState & KMMCSessStateSafeInGaps) )
  1935 		return( ETrue );
  2132 	    {
       
  2133 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT6, this, (TUint) ETrue );
       
  2134 		return ETrue;
       
  2135 	    }
  1936 
  2136 
  1937 	if( iSessionP->iBlockOn & KMMCBlockOnInterrupt )
  2137 	if( iSessionP->iBlockOn & KMMCBlockOnInterrupt )
  1938 		return( ETrue );
  2138 	    {
       
  2139 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT7, this, (TUint) ETrue );
       
  2140 		return ETrue;
       
  2141 	    }
  1939 
  2142 
  1940 	if(preemptDC)
  2143 	if(preemptDC)
  1941 		return( ETrue );
  2144 	    {
       
  2145 		OstTraceFunctionExitExt( DDMMCSTACK_SCHEDPREEMPTABLE_EXIT8, this, (TUint) ETrue );
       
  2146 		return ETrue;
       
  2147 	    }
  1942 		
  2148 		
  1943 	return( EFalse );
  2149 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDPREEMPTABLE_EXIT9, this, (TUint) EFalse );
       
  2150 	return EFalse;
  1944 	}
  2151 	}
  1945 
  2152 
  1946 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedSession()
  2153 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedSession()
  1947 /**
  2154 /**
  1948  * Current context analyser. Returns Exit, Loop or ChooseJob.
  2155  * Current context analyser. Returns Exit, Loop or ChooseJob.
  1949  */
  2156  */
  1950 	{
  2157 	{
       
  2158 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDSESSION_ENTRY, this );
  1951 
  2159 
  1952 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ss"));
  2160 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ss"));
  1953 
  2161 
  1954 	// If no current session selected then we need to choose one
  2162 	// If no current session selected then we need to choose one
  1955 	if (iSessionP == NULL)
  2163 	if (iSessionP == NULL)
  1956 		return(ESchedChooseJob);
  2164 	    {
       
  2165 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT1, this, (TInt) ESchedChooseJob );
       
  2166 		return ESchedChooseJob;
       
  2167 	    }
  1957 
  2168 
  1958 	// Check any static blocking conditions on the current session and remove if possible
  2169 	// Check any static blocking conditions on the current session and remove if possible
  1959 	if (SchedResolveStatBlocks(iSessionP)==ESchedLoop)
  2170 	if (SchedResolveStatBlocks(iSessionP)==ESchedLoop)
  1960 		return(ESchedLoop);
  2171 	    {
       
  2172 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT2, this, (TInt) ESchedLoop );
       
  2173 		return ESchedLoop;
       
  2174 	    }
  1961 
  2175 
  1962 	// If current session is still blocked, see if we could pre-empt the session
  2176 	// If current session is still blocked, see if we could pre-empt the session
  1963 	if (iSessionP->iBlockOn)
  2177 	if (iSessionP->iBlockOn)
  1964 		{
  2178 		{
  1965 		if( SchedPreemptable() )
  2179 		if( SchedPreemptable() )
  1966 			return(ESchedChooseJob);
  2180 		    {
  1967 
  2181 		    OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT3, this, (TInt) ESchedChooseJob );
  1968 		return( ESchedExit );	// No preemption possible
  2182 			return ESchedChooseJob;
       
  2183 		    }
       
  2184 
       
  2185 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT4, this, (TInt) ESchedExit );
       
  2186 		return ESchedExit;	// No preemption possible
  1969 		}
  2187 		}
  1970 
  2188 
  1971 	// If the current session has been marked to be 'un-scheduled' then we
  2189 	// If the current session has been marked to be 'un-scheduled' then we
  1972 	// need to choose another session if ones available
  2190 	// need to choose another session if ones available
  1973 	if ( (iSessionP->iState & KMMCSessStateDoReSchedule) )
  2191 	if ( (iSessionP->iState & KMMCSessStateDoReSchedule) )
  1974 		return( ESchedChooseJob );
  2192 	    {
       
  2193 		OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT5, this, (TInt) ESchedChooseJob );
       
  2194 		return ESchedChooseJob;
       
  2195 	    }
  1975 
  2196 
  1976 	// Check if this session requires to be run in DFC context - loop if necessary
  2197 	// Check if this session requires to be run in DFC context - loop if necessary
  1977 	if ( (iSessionP->iState & KMMCSessStateDoDFC) )
  2198 	if ( (iSessionP->iState & KMMCSessStateDoDFC) )
  1978 		{
  2199 		{
  1979 		iSessionP->iState &= ~KMMCSessStateDoDFC;
  2200 		iSessionP->iState &= ~KMMCSessStateDoDFC;
  1980 		if( SchedGetOnDFC()==ESchedLoop )
  2201 		if( SchedGetOnDFC()==ESchedLoop )
  1981 			return( ESchedLoop );
  2202 		    {
       
  2203 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT6, this, (TInt) ESchedLoop );
       
  2204 			return ESchedLoop;
       
  2205 		    }
  1982 		}
  2206 		}
  1983 
  2207 
  1984 	// Now we actually execute the current session
  2208 	// Now we actually execute the current session
  1985 	if( iLockingSessionP != NULL )
  2209 	if( iLockingSessionP != NULL )
  1986 		{
  2210 		{
  2021 	iStackState &= ~KMMCStackStateReScheduled;
  2245 	iStackState &= ~KMMCStackStateReScheduled;
  2022 
  2246 
  2023 	if( exitCode )
  2247 	if( exitCode )
  2024 		MarkComplete( iSessionP, (exitCode & ~KMMCErrBypass) );
  2248 		MarkComplete( iSessionP, (exitCode & ~KMMCErrBypass) );
  2025 
  2249 
  2026 	return(ESchedLoop);
  2250 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDSESSION_EXIT7, this, (TInt) ESchedLoop );
       
  2251 	return ESchedLoop;
  2027 	}
  2252 	}
  2028 
  2253 
  2029 TBool DMMCStack::SchedYielding(DMMCSession* aSessP)
  2254 TBool DMMCStack::SchedYielding(DMMCSession* aSessP)
  2030 /**
  2255 /**
  2031  * Check whether the scheduler should yield to another command
  2256  * Check whether the scheduler should yield to another command
  2032  */
  2257  */
  2033 	{
  2258 	{
       
  2259 	OstTraceFunctionEntryExt( DMMCSTACK_SCHEDYIELDING_ENTRY, this );
  2034 	// Test whether a full loop through the sessions has occurred during a yield
  2260 	// Test whether a full loop through the sessions has occurred during a yield
  2035 	if ((aSessP->iBlockOn & KMMCBlockOnYielding) && (iStackState & KMMCStackStateYielding))
  2261 	if ((aSessP->iBlockOn & KMMCBlockOnYielding) && (iStackState & KMMCStackStateYielding))
  2036 		{
  2262 		{
  2037 		// We've looped, now stop yielding
  2263 		// We've looped, now stop yielding
  2038 		aSessP->iBlockOn &= ~KMMCBlockOnYielding;
  2264 		aSessP->iBlockOn &= ~KMMCBlockOnYielding;
  2039 		iStackState &= ~KMMCStackStateYielding;
  2265 		iStackState &= ~KMMCStackStateYielding;
  2040 		}
  2266 		}
  2041 	return(iStackState & KMMCStackStateYielding) != 0;
  2267 	TBool ret = (iStackState & KMMCStackStateYielding) != 0;
       
  2268 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDYIELDING_EXIT, this, ret );
       
  2269 	return ret;
  2042 	}
  2270 	}
  2043 
  2271 
  2044 TBool DMMCStack::SchedAllowDirectCommands(DMMCSession* aSessP)
  2272 TBool DMMCStack::SchedAllowDirectCommands(DMMCSession* aSessP)
  2045 /**
  2273 /**
  2046  * Check whether direct only commands can be run.
  2274  * Check whether direct only commands can be run.
  2047  */
  2275  */
  2048 	{
  2276 	{
       
  2277 	OstTraceFunctionEntryExt( DMMCSTACK_SCHEDALLOWDIRECTCOMMANDS_ENTRY, this );
  2049 	TBool allowDirectCommands = EFalse;
  2278 	TBool allowDirectCommands = EFalse;
  2050 
  2279 
  2051 	// Test the remaining sessions to see if they have a DMA data transfer blockage which allow direct commands only
  2280 	// Test the remaining sessions to see if they have a DMA data transfer blockage which allow direct commands only
  2052 	DMMCSession* testSessP = aSessP;
  2281 	DMMCSession* testSessP = aSessP;
  2053 	do
  2282 	do
  2056 			allowDirectCommands = ETrue;
  2285 			allowDirectCommands = ETrue;
  2057 		testSessP = testSessP->iLinkP;
  2286 		testSessP = testSessP->iLinkP;
  2058 		}			
  2287 		}			
  2059 	while((aSessP != testSessP) && (testSessP != NULL));
  2288 	while((aSessP != testSessP) && (testSessP != NULL));
  2060 
  2289 
  2061 	return(allowDirectCommands);
  2290 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDALLOWDIRECTCOMMANDS_EXIT, this, allowDirectCommands );
       
  2291 	return allowDirectCommands;
  2062 	}
  2292 	}
  2063 
  2293 
  2064 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedChooseJob()
  2294 inline DMMCStack::TMMCStackSchedStateEnum DMMCStack::SchedChooseJob()
  2065 /**
  2295 /**
  2066  * Find an unblocked job to run. Returns Exit or Loop.
  2296  * Find an unblocked job to run. Returns Exit or Loop.
  2067  */
  2297  */
  2068 	{
  2298 	{
       
  2299 	OstTraceFunctionEntry1( DMMCSTACK_SCHEDCHOOSEJOB_ENTRY, this );
  2069 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:scj"));
  2300 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:scj"));
  2070 
  2301 
  2071 	iStackState |= KMMCStackStateJobChooser;
  2302 	iStackState |= KMMCStackStateJobChooser;
  2072 	SchedGrabEntries();
  2303 	SchedGrabEntries();
  2073 	DMMCSession* sessP = NULL;
  2304 	DMMCSession* sessP = NULL;
  2108 	
  2339 	
  2109 	while( (sessP = iWorkSet) != NULL )
  2340 	while( (sessP = iWorkSet) != NULL )
  2110 		{
  2341 		{
  2111 		// first, remove all static blocking conditions
  2342 		// first, remove all static blocking conditions
  2112 		if( SchedResolveStatBlocks(sessP) )
  2343 		if( SchedResolveStatBlocks(sessP) )
  2113 			return( ESchedLoop );
  2344 		    {
       
  2345 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDCHOOSEJOB_EXIT1, this, (TInt) ESchedLoop );
       
  2346 			return ESchedLoop;
       
  2347 		    }
  2114 
  2348 
  2115 		TBool scheduleSession = ETrue;
  2349 		TBool scheduleSession = ETrue;
  2116 		// Test whether we are yielding 
  2350 		// Test whether we are yielding 
  2117 		if (SchedYielding(sessP) && (sessP->Command().iSpec.iCommandType != iYieldCommandType))
  2351 		if (SchedYielding(sessP) && (sessP->Command().iSpec.iCommandType != iYieldCommandType))
  2118 			scheduleSession = EFalse;
  2352 			scheduleSession = EFalse;
  2125 		
  2359 		
  2126 		if (scheduleSession)
  2360 		if (scheduleSession)
  2127 			{
  2361 			{
  2128 			iWorkSet.SetMarker();
  2362 			iWorkSet.SetMarker();
  2129 			SchedSetContext( sessP );
  2363 			SchedSetContext( sessP );
  2130 			return( ESchedLoop );
  2364 			OstTraceFunctionExitExt( DMMCSTACK_SCHEDCHOOSEJOB_EXIT2, this, (TInt) ESchedLoop );
       
  2365 			return ESchedLoop;
  2131 			}
  2366 			}
  2132 			
  2367 			
  2133 		iWorkSet++;
  2368 		iWorkSet++;
  2134 		}
  2369 		}
  2135 	
  2370 	
  2136 	return( ESchedExit );		
  2371 	OstTraceFunctionExitExt( DMMCSTACK_SCHEDCHOOSEJOB_EXIT3, this, (TInt) ESchedExit );
       
  2372 	return ESchedExit;		
  2137 	}
  2373 	}
  2138 
  2374 
  2139 void DMMCStack::StackDFC(TAny* aStackP)
  2375 void DMMCStack::StackDFC(TAny* aStackP)
  2140 /**
  2376 /**
  2141  * This DFC is used to startup Stack Scheduler from the background.
  2377  * This DFC is used to startup Stack Scheduler from the background.
  2142  */
  2378  */
  2143 	{
  2379 	{
       
  2380 	OstTraceFunctionEntry0( DMMCSTACK_STACKDFC_ENTRY );
  2144 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sdf"));
  2381 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sdf"));
  2145 
  2382 
  2146 	DMMCStack* const stackP = static_cast<DMMCStack*>(aStackP);
  2383 	DMMCStack* const stackP = static_cast<DMMCStack*>(aStackP);
  2147 	stackP->Scheduler( stackP->iDFCRunning );
  2384 	stackP->Scheduler( stackP->iDFCRunning );
       
  2385 	OstTraceFunctionExit0( DMMCSTACK_STACKDFC_EXIT );
  2148 	}
  2386 	}
  2149 
  2387 
  2150 void DMMCStack::Scheduler(volatile TBool& aFlag)
  2388 void DMMCStack::Scheduler(volatile TBool& aFlag)
  2151 /**
  2389 /**
  2152  * This is the main function which controls, monitors and synchronises session execution.
  2390  * This is the main function which controls, monitors and synchronises session execution.
  2153  * It's divided into the entry function Scheduler() and the scheduling mechanism itself,
  2391  * It's divided into the entry function Scheduler() and the scheduling mechanism itself,
  2154  * DoSchedule()
  2392  * DoSchedule()
  2155  */
  2393  */
  2156 	{
  2394 	{
       
  2395 	OstTraceFunctionEntry0( DMMCSTACK_SCHEDULER_ENTRY );
  2157 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sch"));
  2396 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sch"));
  2158 
  2397 
  2159 	DISABLEPREEMPTION
  2398 	DISABLEPREEMPTION
  2160 	aFlag = ETrue;
  2399 	aFlag = ETrue;
  2161 
  2400 
  2166 		}
  2405 		}
  2167 
  2406 
  2168 	iStackState |= KMMCStackStateRunning;
  2407 	iStackState |= KMMCStackStateRunning;
  2169 	RESTOREPREEMPTION
  2408 	RESTOREPREEMPTION
  2170 	DoSchedule();
  2409 	DoSchedule();
       
  2410 	OstTraceFunctionExit0( DMMCSTACK_SCHEDULER_EXIT );
  2171 	}
  2411 	}
  2172 
  2412 
  2173 void DMMCStack::DoSchedule()
  2413 void DMMCStack::DoSchedule()
  2174 	{
  2414 	{
       
  2415 	OstTraceFunctionEntry1( DMMCSTACK_DOSCHEDULE_ENTRY, this );
  2175 	__KTRACE_OPT(KPBUS1,Kern::Printf(">mst:dos"));
  2416 	__KTRACE_OPT(KPBUS1,Kern::Printf(">mst:dos"));
  2176 
  2417 
  2177 	for(;;)
  2418 	for(;;)
  2178 		{
  2419 		{
  2179 		for(;;)
  2420 		for(;;)
  2222 			iStackState &= ~KMMCStackStateRunning;
  2463 			iStackState &= ~KMMCStackStateRunning;
  2223 			iDFCRunning = EFalse;
  2464 			iDFCRunning = EFalse;
  2224 			
  2465 			
  2225 			RESTOREPREEMPTION
  2466 			RESTOREPREEMPTION
  2226 			__KTRACE_OPT(KPBUS1,Kern::Printf("<mst:dos"));
  2467 			__KTRACE_OPT(KPBUS1,Kern::Printf("<mst:dos"));
       
  2468 			OstTraceFunctionExit1( DMMCSTACK_DOSCHEDULE_EXIT1, this );
  2227 			return;
  2469 			return;
  2228 			}
  2470 			}
  2229 
  2471 
  2230 		RESTOREPREEMPTION
  2472 		RESTOREPREEMPTION
  2231 		}
  2473 		}
  2237 void DMMCStack::Add(DMMCSession* aSessP)
  2479 void DMMCStack::Add(DMMCSession* aSessP)
  2238 /**
  2480 /**
  2239  * Adds session aSessP to the EntryQueue (asynchronous function)
  2481  * Adds session aSessP to the EntryQueue (asynchronous function)
  2240  */
  2482  */
  2241 	{
  2483 	{
       
  2484 	OstTraceFunctionEntryExt( DMMCSTACK_ADD_ENTRY, this );
  2242 	ASSERT_NOT_ISR_CONTEXT
  2485 	ASSERT_NOT_ISR_CONTEXT
  2243 	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Add %d",TUint(aSessP->iSessionID)));
  2486 	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Add %d",TUint(aSessP->iSessionID)));
  2244 
  2487 
  2245 	DISABLEPREEMPTION
  2488 	DISABLEPREEMPTION
  2246 	iEntryQueue.Add( aSessP );
  2489 	iEntryQueue.Add( aSessP );
  2247 	aSessP->iState |= KMMCSessStateEngaged;
  2490 	aSessP->iState |= KMMCSessStateEngaged;
  2248 	RESTOREPREEMPTION
  2491 	RESTOREPREEMPTION
  2249 	Scheduler( iAttention );
  2492 	Scheduler( iAttention );
       
  2493 	OstTraceFunctionExit1( DMMCSTACK_ADD_EXIT, this );
  2250 	}
  2494 	}
  2251 
  2495 
  2252 void DMMCStack::Abort(DMMCSession* aSessP)
  2496 void DMMCStack::Abort(DMMCSession* aSessP)
  2253 /**
  2497 /**
  2254  * Aborts a session
  2498  * Aborts a session
  2255  */
  2499  */
  2256 	{
  2500 	{
       
  2501 	OstTraceFunctionEntryExt( DMMCSTACK_ABORT_ENTRY, this );
  2257 	ASSERT_NOT_ISR_CONTEXT
  2502 	ASSERT_NOT_ISR_CONTEXT
  2258 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:abt"));
  2503 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:abt"));
  2259 
  2504 
  2260 	if( !aSessP->IsEngaged() )
  2505 	if( !aSessP->IsEngaged() )
       
  2506 	    {
       
  2507 		OstTraceFunctionExit1( DMMCSTACK_ABORT_EXIT1, this );
  2261 		return;
  2508 		return;
       
  2509 	    }
  2262 
  2510 
  2263 	aSessP->iDoAbort = ETrue;
  2511 	aSessP->iDoAbort = ETrue;
  2264 	aSessP->iMachine.Abort();
  2512 	aSessP->iMachine.Abort();
  2265 
  2513 
  2266 	Scheduler( iAbortReq );
  2514 	Scheduler( iAbortReq );
       
  2515 	OstTraceFunctionExit1( DMMCSTACK_ABORT_EXIT2, this );
  2267 	}
  2516 	}
  2268 
  2517 
  2269 void DMMCStack::Stop(DMMCSession* aSessP)
  2518 void DMMCStack::Stop(DMMCSession* aSessP)
  2270 /**
  2519 /**
  2271  * Signals session to stop
  2520  * Signals session to stop
  2272  */
  2521  */
  2273 	{
  2522 	{
       
  2523 	OstTraceFunctionEntryExt( DMMCSTACK_STOP1_ENTRY, this );
  2274 	ASSERT_NOT_ISR_CONTEXT
  2524 	ASSERT_NOT_ISR_CONTEXT
  2275 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:stp"));
  2525 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:stp"));
  2276 
  2526 
  2277 	if( !aSessP->IsEngaged() )
  2527 	if( !aSessP->IsEngaged() )
       
  2528 	    {
       
  2529 		OstTraceFunctionExit1( DMMCSTACK_STOP1_EXIT1, this );
  2278 		return;
  2530 		return;
       
  2531 	    }
  2279 
  2532 
  2280 	aSessP->iDoStop = ETrue;
  2533 	aSessP->iDoStop = ETrue;
       
  2534 	OstTraceFunctionExit1( DMMCSTACK_STOP1_EXIT2, this );
  2281 	}
  2535 	}
  2282 
  2536 
  2283 EXPORT_C void DMMCStack::Block(DMMCSession* aSessP, TUint32 aFlag)
  2537 EXPORT_C void DMMCStack::Block(DMMCSession* aSessP, TUint32 aFlag)
  2284 	{
  2538 	{
       
  2539 	OstTraceFunctionEntryExt( DMMCSTACK_BLOCK_ENTRY, this );
  2285 	ASSERT_NOT_ISR_CONTEXT
  2540 	ASSERT_NOT_ISR_CONTEXT
  2286 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:blk"));
  2541 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:blk"));
  2287 
  2542 
  2288 	if( !aSessP->IsEngaged() )
  2543 	if( !aSessP->IsEngaged() )
       
  2544 	    {
       
  2545 		OstTraceFunctionExit1( DMMCSTACK_BLOCK_EXIT1, this );
  2289 		return;
  2546 		return;
       
  2547 	    }
  2290 
  2548 
  2291 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:blk:[aFlag=%08x, iBlockOn=%08x]", aFlag, aSessP->iBlockOn));
  2549 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:blk:[aFlag=%08x, iBlockOn=%08x]", aFlag, aSessP->iBlockOn));
       
  2550 	OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_BLOCK, "aFlag=0x%08x; iBlockOn=0x%08x", aFlag, aSessP->iBlockOn );
       
  2551 	
  2292 
  2552 
  2293 	(void)__e32_atomic_ior_ord32(&aSessP->iBlockOn, aFlag);
  2553 	(void)__e32_atomic_ior_ord32(&aSessP->iBlockOn, aFlag);
       
  2554 	OstTraceFunctionExit1( DMMCSTACK_BLOCK_EXIT2, this );
  2294 	}
  2555 	}
  2295 
  2556 
  2296 EXPORT_C void DMMCStack::UnBlock(DMMCSession* aSessP, TUint32 aFlag, TMMCErr anExitCode)
  2557 EXPORT_C void DMMCStack::UnBlock(DMMCSession* aSessP, TUint32 aFlag, TMMCErr anExitCode)
  2297 /**
  2558 /**
  2298  * aFlag is a bitset of KMMCBlockOnXXX events that have occured.  If the stack's
  2559  * aFlag is a bitset of KMMCBlockOnXXX events that have occured.  If the stack's
  2299  * session is waiting on all of these events, then it is scheduled.
  2560  * session is waiting on all of these events, then it is scheduled.
  2300  */
  2561  */
  2301 	{
  2562 	{
       
  2563 	OstTraceExt4(TRACE_FLOW, DMMCSTACK_UNBLOCK_ENTRY , "DMMCStack::UnBlock;aSessP=%x;aFlag=%x;anExitCode=%d;this=%x", (TUint) aSessP, (TUint) aFlag, (TInt) anExitCode, (TUint) this);
  2302 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ubl"));
  2564 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ubl"));
  2303 
  2565 
  2304 	if (aSessP != NULL)
  2566 	if (aSessP != NULL)
  2305 		{
  2567 		{
  2306 		__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ubl:[aFlag=%08x, iBlockOn=%08x", aFlag, aSessP->iBlockOn));
  2568 		__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ubl:[aFlag=%08x, iBlockOn=%08x", aFlag, aSessP->iBlockOn));
       
  2569 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_UNBLOCK, "aFlag=0x%08x; iBlockOn=0x%08x", aFlag, aSessP->iBlockOn );
       
  2570 		
  2307 
  2571 
  2308 		if( (aSessP->iBlockOn & aFlag) == 0 )
  2572 		if( (aSessP->iBlockOn & aFlag) == 0 )
       
  2573 		    {
       
  2574 			OstTraceFunctionExit1( DMMCSTACK_UNBLOCK_EXIT1, this );
  2309 			return;
  2575 			return;
       
  2576 		    }
  2310 
  2577 
  2311 		// Must be either in a DFC or have the KMMCSessStateDoDFC flag set
  2578 		// Must be either in a DFC or have the KMMCSessStateDoDFC flag set
  2312 		__ASSERT_DEBUG( 
  2579 		__ASSERT_DEBUG( 
  2313 			(aSessP->iState & KMMCSessStateDoDFC) != 0 || 
  2580 			(aSessP->iState & KMMCSessStateDoDFC) != 0 || 
  2314 			NKern::CurrentContext() != NKern::EInterrupt,
  2581 			NKern::CurrentContext() != NKern::EInterrupt,
  2318 		aSessP->iMachine.SetExitCode( anExitCode );
  2585 		aSessP->iMachine.SetExitCode( anExitCode );
  2319 
  2586 
  2320 		if( aSessP->iBlockOn == 0 )
  2587 		if( aSessP->iBlockOn == 0 )
  2321 			Scheduler( iAttention );
  2588 			Scheduler( iAttention );
  2322 		}
  2589 		}
       
  2590 	OstTraceFunctionExit1( DMMCSTACK_UNBLOCK_EXIT2, this );
  2323 	}
  2591 	}
  2324 
  2592 
  2325 void DMMCStack::UnlockStack(DMMCSession* aSessP)
  2593 void DMMCStack::UnlockStack(DMMCSession* aSessP)
  2326 /**
  2594 /**
  2327  * Removes stack lock. Asynchronous function.
  2595  * Removes stack lock. Asynchronous function.
  2328  */
  2596  */
  2329 	{
  2597 	{
       
  2598 	OstTraceFunctionEntryExt( DMMCSTACK_UNLOCKSTACK_ENTRY, this );
  2330 	ASSERT_NOT_ISR_CONTEXT
  2599 	ASSERT_NOT_ISR_CONTEXT
  2331 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ust"));
  2600 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:ust"));
  2332 
  2601 
  2333 	aSessP->iBrokenLock = EFalse;
  2602 	aSessP->iBrokenLock = EFalse;
  2334 
  2603 
  2335 	if( aSessP == iLockingSessionP )
  2604 	if( aSessP == iLockingSessionP )
  2336 		{
  2605 		{
  2337 		iLockingSessionP = NULL;
  2606 		iLockingSessionP = NULL;
  2338 		Scheduler( iAttention );
  2607 		Scheduler( iAttention );
  2339 		}
  2608 		}
       
  2609 	OstTraceFunctionExit1( DMMCSTACK_UNLOCKSTACK_EXIT1, this );
  2340 	}
  2610 	}
  2341 
  2611 
  2342 EXPORT_C TInt DMMCStack::Stop(TMMCard* aCardP)
  2612 EXPORT_C TInt DMMCStack::Stop(TMMCard* aCardP)
  2343 /**
  2613 /**
  2344  * Completes all sessions operating with a specified card with KMMCErrAbort.
  2614  * Completes all sessions operating with a specified card with KMMCErrAbort.
  2345  * Returns either KErrNone or KErrServerBusy.
  2615  * Returns either KErrNone or KErrServerBusy.
  2346  */
  2616  */
  2347 	{
  2617 	{
       
  2618 	OstTraceFunctionEntryExt( DMMCSTACK_STOP2_ENTRY, this );
  2348 	ASSERT_NOT_ISR_CONTEXT
  2619 	ASSERT_NOT_ISR_CONTEXT
  2349 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:stp"));
  2620 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:stp"));
  2350 
  2621 
  2351 	DISABLEPREEMPTION
  2622 	DISABLEPREEMPTION
  2352 
  2623 
  2353 	if( iStackState & KMMCStackStateRunning )
  2624 	if( iStackState & KMMCStackStateRunning )
  2354 		{
  2625 		{
  2355 		RESTOREPREEMPTION
  2626 		RESTOREPREEMPTION
  2356 		return( KErrServerBusy );	// can not operate in foreground
  2627 		return KErrServerBusy;	// can not operate in foreground
  2357 		}
  2628 		}
  2358 
  2629 
  2359 	iStackState |= KMMCStackStateRunning;
  2630 	iStackState |= KMMCStackStateRunning;
  2360 	RESTOREPREEMPTION
  2631 	RESTOREPREEMPTION
  2361 
  2632 
  2380 		else
  2651 		else
  2381 			iReadyQueue++;
  2652 			iReadyQueue++;
  2382 
  2653 
  2383 	SchedGetOnDFC();
  2654 	SchedGetOnDFC();
  2384 	DoSchedule();
  2655 	DoSchedule();
  2385 	return( KErrNone );
  2656 	OstTraceFunctionExitExt( DMMCSTACK_STOP2_EXIT, this, KErrNone );
       
  2657 	return KErrNone;
  2386 	}
  2658 	}
  2387 
  2659 
  2388 void DMMCStack::MarkComplete(DMMCSession* aSessP, TMMCErr anExitCode)
  2660 void DMMCStack::MarkComplete(DMMCSession* aSessP, TMMCErr anExitCode)
  2389 /**
  2661 /**
  2390  * Marks session to be completed on the next scheduler pass.
  2662  * Marks session to be completed on the next scheduler pass.
  2391  */
  2663  */
  2392 	{
  2664 	{
       
  2665 	OstTraceExt3(TRACE_FLOW, DMMCSTACK_MARKCOMPLETE_ENTRY ,"DMMCStack::MarkComplete;aSessP=%x;anExitCode=%d;this=%x", (TUint) aSessP, (TInt) anExitCode, (TUint) this);
  2393 	ASSERT_NOT_ISR_CONTEXT
  2666 	ASSERT_NOT_ISR_CONTEXT
  2394 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:mcp"));
  2667 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:mcp"));
  2395 
  2668 
  2396 	aSessP->SynchBlock( KMMCBlockOnNoRun );
  2669 	aSessP->SynchBlock( KMMCBlockOnNoRun );
  2397 	aSessP->iMMCExitCode = anExitCode;
  2670 	aSessP->iMMCExitCode = anExitCode;
  2398 	aSessP->iDoComplete = ETrue;
  2671 	aSessP->iDoComplete = ETrue;
  2399 	iCompReq = ETrue;
  2672 	iCompReq = ETrue;
       
  2673 	OstTraceFunctionExit1( DMMCSTACK_MARKCOMPLETE_EXIT, this );
  2400 	}
  2674 	}
  2401 
  2675 
  2402 //
  2676 //
  2403 // DMMCStack:: --- Miscellaneous ---
  2677 // DMMCStack:: --- Miscellaneous ---
  2404 //
  2678 //
  2405 EXPORT_C TUint32 DMMCStack::EffectiveModes(const TMMCStackConfig& aClientConfig)
  2679 EXPORT_C TUint32 DMMCStack::EffectiveModes(const TMMCStackConfig& aClientConfig)
  2406 /**
  2680 /**
  2407  * Calculates effective client modes as real client modes merged with iMasterConfig modes
  2681  * Calculates effective client modes as real client modes merged with iMasterConfig modes
  2408  */
  2682  */
  2409 	{
  2683 	{
       
  2684 	OstTraceFunctionEntry1( DMMCSTACK_EFFECTIVEMODES_ENTRY, this );
  2410 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:em"));
  2685 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:em"));
  2411 
  2686 
  2412 	const TUint32 masterMode = (iMasterConfig.iModes & iMasterConfig.iUpdateMask) |
  2687 	const TUint32 masterMode = (iMasterConfig.iModes & iMasterConfig.iUpdateMask) |
  2413 								(KMMCModeDefault & ~iMasterConfig.iUpdateMask);
  2688 								(KMMCModeDefault & ~iMasterConfig.iUpdateMask);
  2414 
  2689 
  2420 							((masterMode & KMMCModeMasterOverrides) | ~KMMCModeMasterOverrides);
  2695 							((masterMode & KMMCModeMasterOverrides) | ~KMMCModeMasterOverrides);
  2421 
  2696 
  2422 	const TUint32 effectiveMode = (userMode & userMask) | (masterMode & ~userMask);
  2697 	const TUint32 effectiveMode = (userMode & userMask) | (masterMode & ~userMask);
  2423 
  2698 
  2424 	if( effectiveMode & KMMCModeEnableClientConfig )
  2699 	if( effectiveMode & KMMCModeEnableClientConfig )
  2425 		return( effectiveMode );
  2700 	    {
       
  2701 		OstTraceFunctionExitExt( DMMCSTACK_EFFECTIVEMODES_EXIT1, this, ( TUint )( effectiveMode ) );
       
  2702 		return effectiveMode;
       
  2703 	    }
  2426 	else
  2704 	else
  2427 		return( (effectiveMode & KMMCModeClientOverrides) |
  2705 	    {
  2428 				(masterMode & ~(KMMCModeClientOverrides | KMMCModeClientMask)) );
  2706 	    
       
  2707 		TUint32 ret = (effectiveMode & KMMCModeClientOverrides) |
       
  2708 				(masterMode & ~(KMMCModeClientOverrides | KMMCModeClientMask));
       
  2709 		OstTraceFunctionExitExt( DMMCSTACK_EFFECTIVEMODES_EXIT2, this, ( TUint )( ret ) );
       
  2710 		return ret;
       
  2711 	    }
  2429 	}
  2712 	}
  2430 
  2713 
  2431 void DMMCStack::MergeConfig(DMMCSession* aSessP)
  2714 void DMMCStack::MergeConfig(DMMCSession* aSessP)
  2432 /**
  2715 /**
  2433  * Merges client and master configuration into iConfig
  2716  * Merges client and master configuration into iConfig
  2434  */
  2717  */
  2435 	{
  2718 	{
       
  2719 	OstTraceFunctionEntryExt( DMMCSTACK_MERGECONFIG_ENTRY, this );
  2436 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:mc"));
  2720 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:mc"));
  2437 
  2721 
  2438 	TMMCStackConfig& cC = aSessP->iConfig;
  2722 	TMMCStackConfig& cC = aSessP->iConfig;
  2439 	TMMCStackConfig& mC = iMasterConfig;
  2723 	TMMCStackConfig& mC = iMasterConfig;
  2440 	const TUint32 modes = EffectiveModes( cC );
  2724 	const TUint32 modes = EffectiveModes( cC );
  2512 							: mC.iBusConfig.iDataTimeOut;
  2796 							: mC.iBusConfig.iDataTimeOut;
  2513 
  2797 
  2514 	iConfig.iBusConfig.iBusyTimeOut = (modes & KMMCModeClientBusyTimeOut)
  2798 	iConfig.iBusConfig.iBusyTimeOut = (modes & KMMCModeClientBusyTimeOut)
  2515 							? cC.iBusConfig.iBusyTimeOut
  2799 							? cC.iBusConfig.iBusyTimeOut
  2516 							: mC.iBusConfig.iBusyTimeOut;
  2800 							: mC.iBusConfig.iBusyTimeOut;
       
  2801 	OstTraceFunctionExit1( DMMCSTACK_MERGECONFIG_EXIT, this );
  2517 	}
  2802 	}
  2518 
  2803 
  2519 TBool DMMCStack::StaticBlocks()
  2804 TBool DMMCStack::StaticBlocks()
  2520 /**
  2805 /**
  2521  * This function realises the potential blocking conditions of the current session.
  2806  * This function realises the potential blocking conditions of the current session.
  2522  * Returns ETrue if the session has to be stopped right now
  2807  * Returns ETrue if the session has to be stopped right now
  2523  */
  2808  */
  2524 	{
  2809 	{
       
  2810 	OstTraceFunctionEntry1( DMMCSTACK_STATICBLOCKS_ENTRY, this );
  2525 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:stb"));
  2811 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:stb"));
  2526 
  2812 
  2527 	if( iSessionP->iDoStop )
  2813 	if( iSessionP->iDoStop )
  2528 		{
  2814 		{
  2529 		MarkComplete( iSessionP, KMMCErrAbort );
  2815 		MarkComplete( iSessionP, KMMCErrAbort );
  2530 		return( ETrue );
  2816 		OstTraceFunctionExitExt( DMMCSTACK_STATICBLOCKS_EXIT1, this, (TUint) ETrue );
       
  2817 		return ETrue;
  2531 		}
  2818 		}
  2532 
  2819 
  2533 	if( !iDFCRunning && (iSessionP->iState & KMMCSessStateDoDFC) )
  2820 	if( !iDFCRunning && (iSessionP->iState & KMMCSessStateDoDFC) )
  2534 		return( ETrue );
  2821 	    {
  2535 
  2822 		OstTraceFunctionExitExt( DMMCSTACK_STATICBLOCKS_EXIT2, this, (TUint) ETrue );
  2536 	return( (iSessionP->iState & KMMCSessStateDoReSchedule) != 0 );
  2823 		return ETrue;
       
  2824 	    }
       
  2825 
       
  2826 	TBool ret = (iSessionP->iState & KMMCSessStateDoReSchedule) != 0; 
       
  2827 	OstTraceFunctionExitExt( DMMCSTACK_STATICBLOCKS_EXIT3, this, ret );
       
  2828 	return ret;
  2537 	}
  2829 	}
  2538 
  2830 
  2539 
  2831 
  2540 EXPORT_C TBool DMMCStack::CardDetect(TUint /*aCardNumber*/)
  2832 EXPORT_C TBool DMMCStack::CardDetect(TUint /*aCardNumber*/)
  2541 /**
  2833 /**
  2564 void DMMCStack::StackSessionCBST(TAny* aStackP)
  2856 void DMMCStack::StackSessionCBST(TAny* aStackP)
  2565 /**
  2857 /**
  2566  * Stack Session completion routine.
  2858  * Stack Session completion routine.
  2567  */
  2859  */
  2568 	{
  2860 	{
  2569 
       
  2570 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sscbs"));
  2861 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sscbs"));
  2571 	static_cast<DMMCStack *>(aStackP)->StackSessionCB();
  2862 	static_cast<DMMCStack *>(aStackP)->StackSessionCB();
  2572 	}
  2863 	}
  2573 
  2864 
  2574 
  2865 
  2575 TInt DMMCStack::StackSessionCB()
  2866 TInt DMMCStack::StackSessionCB()
  2576 	{
  2867 	{
       
  2868 	OstTraceFunctionEntry1( DMMCSTACK_STACKSESSIONCB_ENTRY, this );
  2577 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sscb "));
  2869 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:sscb "));
  2578 
  2870 
  2579 	if (iStackState & KMMCStackStateSleepinProgress)
  2871 	if (iStackState & KMMCStackStateSleepinProgress)
  2580 		{
  2872 		{
  2581 		// Sleep completed update stack state
  2873 		// Sleep completed update stack state
  2582 		iStackState &= ~KMMCStackStateSleepinProgress;
  2874 		iStackState &= ~KMMCStackStateSleepinProgress;
  2583 		return( 0 );
  2875 		OstTraceFunctionExit1( DMMCSTACK_STACKSESSIONCB_EXIT1, this );
       
  2876 		return 0;
  2584 		}
  2877 		}
  2585 	
  2878 	
  2586 	TMMCErr mmcError = iStackSession->MMCExitCode();
  2879 	TMMCErr mmcError = iStackSession->MMCExitCode();
  2587 	iStackState &= ~KMMCStackStateInitInProgress;
  2880 	iStackState &= ~KMMCStackStateInitInProgress;
  2588 
  2881 
  2644 				errCode = iAutoUnlockSession.Engage();
  2937 				errCode = iAutoUnlockSession.Engage();
  2645 				if(errCode == KErrNone)
  2938 				if(errCode == KErrNone)
  2646 					{
  2939 					{
  2647 					// don't complete power up request yet
  2940 					// don't complete power up request yet
  2648 					//  - This will be done in DMMCStack::AutoUnlockCB()
  2941 					//  - This will be done in DMMCStack::AutoUnlockCB()
       
  2942 					OstTraceFunctionExit1( DMMCSTACK_STACKSESSIONCB_EXIT2, this );
  2649 					return 0;
  2943 					return 0;
  2650 					}
  2944 					}
  2651 				}
  2945 				}
  2652 			}	// else ( !iCardArray->CardsPresent() )
  2946 			}	// else ( !iCardArray->CardsPresent() )
  2653 		}
  2947 		}
  2683 		iSocket->PowerUpSequenceComplete(errCode);
  2977 		iSocket->PowerUpSequenceComplete(errCode);
  2684 		iStackState |= KMMCStackStateRunning;
  2978 		iStackState |= KMMCStackStateRunning;
  2685 
  2979 
  2686 		}
  2980 		}
  2687 
  2981 
  2688 	return( 0 );
  2982 	OstTraceFunctionExit1( DMMCSTACK_STACKSESSIONCB_EXIT3, this );
       
  2983 	return 0;
  2689 	}
  2984 	}
  2690 
  2985 
  2691 void DMMCStack::AutoUnlockCBST(TAny *aStackP)
  2986 void DMMCStack::AutoUnlockCBST(TAny *aStackP)
  2692 	{
  2987 	{
  2693 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:aucbs"));
  2988 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:aucbs"));
  2696 	}
  2991 	}
  2697 
  2992 
  2698 
  2993 
  2699 TInt DMMCStack::AutoUnlockCB()
  2994 TInt DMMCStack::AutoUnlockCB()
  2700 	{
  2995 	{
       
  2996 	OstTraceFunctionEntry1( DMMCSTACK_AUTOUNLOCKCB_ENTRY, this );
  2701 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:aucb"));
  2997 	__KTRACE_OPT(KPBUS1,Kern::Printf("=mst:aucb"));
  2702 
  2998 
  2703 	// This is the session end callback for iAutoUnlockSession,
  2999 	// This is the session end callback for iAutoUnlockSession,
  2704 	// called at the end of the power up and initialisation process.
  3000 	// called at the end of the power up and initialisation process.
  2705 
  3001 
  2712 	if (epocErr != KErrNone)
  3008 	if (epocErr != KErrNone)
  2713 		iStackState &= ~KMMCStackStateRunning;
  3009 		iStackState &= ~KMMCStackStateRunning;
  2714 	iSocket->PowerUpSequenceComplete(epocErr);
  3010 	iSocket->PowerUpSequenceComplete(epocErr);
  2715 	iStackState |= KMMCStackStateRunning;
  3011 	iStackState |= KMMCStackStateRunning;
  2716 
  3012 
       
  3013 	OstTraceFunctionExit1( DMMCSTACK_AUTOUNLOCKCB_EXIT, this );
  2717 	return 0;
  3014 	return 0;
  2718 	}
  3015 	}
  2719 
  3016 
  2720 
  3017 
  2721 inline TMMCErr DMMCStack::AttachCardSM()
  3018 inline TMMCErr DMMCStack::AttachCardSM()
  2738 			EStAttStatus,
  3035 			EStAttStatus,
  2739 			EStEnd
  3036 			EStEnd
  2740 			};
  3037 			};
  2741 
  3038 
  2742 		DMMCSession& s=Session();
  3039 		DMMCSession& s=Session();
       
  3040 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_ATTACHCARDSM1, "Current session=0x%x", &s );
  2743 
  3041 
  2744 	SMF_BEGIN
  3042 	SMF_BEGIN
  2745 
  3043 
       
  3044 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ATTACHCARDSM2, "EStBegin" );
  2746 		if( s.iCardP == NULL )
  3045 		if( s.iCardP == NULL )
  2747 			return( KMMCErrNoCard );
  3046 		    {
       
  3047 			OstTraceFunctionExitExt( DMMCSTACK_ATTACHCARDSM_EXIT1, this, (TInt) KMMCErrNoCard );
       
  3048 			return KMMCErrNoCard;
       
  3049 		    }
  2748 
  3050 
  2749 		if( s.iCardP->iUsingSessionP != NULL && s.iCardP->iUsingSessionP != &s )
  3051 		if( s.iCardP->iUsingSessionP != NULL && s.iCardP->iUsingSessionP != &s )
  2750 			{
  3052 			{
  2751 			s.SynchBlock( KMMCBlockOnCardInUse );
  3053 			s.SynchBlock( KMMCBlockOnCardInUse );
  2752 			SMF_WAIT
  3054 			SMF_WAIT
  2753 			}
  3055 			}
  2754 
  3056 
  2755 		if( s.iCardP->IsPresent() && s.iCardP->iCID == s.iCID )
  3057 		if( s.iCardP->IsPresent() && s.iCardP->iCID == s.iCID )
  2756 			s.iCardP->iUsingSessionP = &s;
  3058 			s.iCardP->iUsingSessionP = &s;
  2757 		else
  3059 		else
  2758 			return( KMMCErrNoCard );
  3060 		    {
       
  3061 			OstTraceFunctionExitExt( DMMCSTACK_ATTACHCARDSM_EXIT2, this, (TInt) KMMCErrNoCard );
       
  3062 			return KMMCErrNoCard;
       
  3063 		    }
  2759 
  3064 
  2760 		s.iConfig.SetMode( KMMCModeCardControlled );	// for future context switching
  3065 		s.iConfig.SetMode( KMMCModeCardControlled );	// for future context switching
  2761 		iConfig.SetMode( KMMCModeCardControlled );		// for this context
  3066 		iConfig.SetMode( KMMCModeCardControlled );		// for this context
  2762 
  3067 
  2763 		// read card status if there are sticky bits in it
  3068 		// read card status if there are sticky bits in it
  2771 		m.SetTraps( KMMCErrBasic );		// to restore command stack position to its original level
  3076 		m.SetTraps( KMMCErrBasic );		// to restore command stack position to its original level
  2772 		SMF_INVOKES( ExecCommandSMST, EStAttStatus )
  3077 		SMF_INVOKES( ExecCommandSMST, EStAttStatus )
  2773 
  3078 
  2774 	SMF_STATE(EStAttStatus)
  3079 	SMF_STATE(EStAttStatus)
  2775 
  3080 
       
  3081 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ATTACHCARDSM3, "EStAttStatus" );
  2776 		s.PopCommandStack();
  3082 		s.PopCommandStack();
       
  3083 		OstTraceFunctionExitExt( DMMCSTACK_ATTACHCARDSM_EXIT3, this, (TInt) err );
  2777 		SMF_RETURN( err )
  3084 		SMF_RETURN( err )
  2778 
  3085 
  2779 	SMF_END
  3086 	SMF_END
  2780 	}
  3087 	}
  2781 
  3088 
  2793 			};
  3100 			};
  2794 
  3101 
  2795 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:InitStackSM"));
  3102 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:InitStackSM"));
  2796 
  3103 
  2797 		DMMCSession& s=Session();
  3104 		DMMCSession& s=Session();
       
  3105 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CIMINITSTACKSM1, "Current session=0x%x", &s );
  2798 
  3106 
  2799 	SMF_BEGIN
  3107 	SMF_BEGIN
  2800 
  3108 
       
  3109 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMINITSTACKSM2, "EStBegin" );
  2801 		m.SetTraps( KMMCErrAll );	// to prevent this macro from infinite restarts via iInitialise
  3110 		m.SetTraps( KMMCErrAll );	// to prevent this macro from infinite restarts via iInitialise
  2802 
  3111 
  2803 		SMF_INVOKES( CIMUpdateAcqSMST, EStInitDone )
  3112 		SMF_INVOKES( CIMUpdateAcqSMST, EStInitDone )
  2804 
  3113 
  2805 	SMF_STATE(EStInitDone)
  3114 	SMF_STATE(EStInitDone)
  2806 
  3115 
       
  3116 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMINITSTACKSM3, "EStInitDone" );
  2807 		s.iState &= ~KMMCSessStateInProgress;	// now we won't be restarted
  3117 		s.iState &= ~KMMCSessStateInProgress;	// now we won't be restarted
  2808 		SchedGetOnDFC();						// StackSessionCB must be on DFC
  3118 		SchedGetOnDFC();						// StackSessionCB must be on DFC
       
  3119 		OstTraceFunctionExitExt( DMMCSTACK_CIMINITSTACKSM_EXIT, this, (TInt) err );
  2809 		SMF_RETURN( err )						// _?_ power cycles can be performed here if error
  3120 		SMF_RETURN( err )						// _?_ power cycles can be performed here if error
  2810 
  3121 
  2811 	SMF_END
  3122 	SMF_END
  2812 	}
  3123 	}
  2813 
  3124 
  2838 
  3149 
  2839 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:UpdAcqSM"));
  3150 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:UpdAcqSM"));
  2840 
  3151 
  2841 		DMMCSession& s=Session();
  3152 		DMMCSession& s=Session();
  2842 		DMMCPsu* psu=(DMMCPsu*)iSocket->iVcc;
  3153 		DMMCPsu* psu=(DMMCPsu*)iSocket->iVcc;
       
  3154 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM1, "Current session=0x%x", &s );
  2843 
  3155 
  2844 	SMF_BEGIN
  3156 	SMF_BEGIN
  2845 
  3157 
       
  3158 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM2, "EStBegin" );
  2846 		// This macro works naked and must not be preempted
  3159 		// This macro works naked and must not be preempted
  2847 		iConfig.RemoveMode( KMMCModeEnablePreemption | KMMCModeCardControlled );
  3160 		iConfig.RemoveMode( KMMCModeEnablePreemption | KMMCModeCardControlled );
  2848 		// Ensure DFC is running before and after powering up
  3161 		// Ensure DFC is running before and after powering up
  2849 		if( SchedGetOnDFC() )	// Such a direct synchronisation with Scheduler() can only
  3162 		if( SchedGetOnDFC() )	// Such a direct synchronisation with Scheduler() can only
  2850 			SMF_WAIT			// be used in this macro
  3163 			SMF_WAIT			// be used in this macro
  2863 		psu->SetVoltage(iCurrentOpRange);
  3176 		psu->SetVoltage(iCurrentOpRange);
  2864 		SMF_INVOKES( DoPowerUpSMST, EStPoweredUp )
  3177 		SMF_INVOKES( DoPowerUpSMST, EStPoweredUp )
  2865 
  3178 
  2866 	SMF_STATE(EStPoweredUp)
  3179 	SMF_STATE(EStPoweredUp)
  2867 
  3180 
       
  3181 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM3, "EStPoweredUp" );
  2868 		// Switch on the bus clock in identification mode
  3182 		// Switch on the bus clock in identification mode
  2869 		SetBusConfigDefaults(iMasterConfig.iBusConfig, KMMCBusClockFOD);
  3183 		SetBusConfigDefaults(iMasterConfig.iBusConfig, KMMCBusClockFOD);
  2870 		DoSetClock(KMMCBusClockFOD);
  3184 		DoSetClock(KMMCBusClockFOD);
  2871 
  3185 
  2872 		// Make sure controller is in 1-bit bus width mode
  3186 		// Make sure controller is in 1-bit bus width mode
  2877 		iConfig.RemoveMode( KMMCModeEnablePreemption | KMMCModeCardControlled );
  3191 		iConfig.RemoveMode( KMMCModeEnablePreemption | KMMCModeCardControlled );
  2878 		SMF_INVOKES( InitClockOnSMST, EStClockOn )	// Feed init clock to the bus
  3192 		SMF_INVOKES( InitClockOnSMST, EStClockOn )	// Feed init clock to the bus
  2879 
  3193 
  2880 	SMF_STATE(EStClockOn)
  3194 	SMF_STATE(EStClockOn)
  2881 
  3195 
       
  3196 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM4, "EStClockOn" );
  2882 		// Check if there are any cards present in the stack
  3197 		// Check if there are any cards present in the stack
  2883 		if (!HasCardsPresent())
  3198 		if (!HasCardsPresent())
  2884 			SMF_GOTOS( EStCheckStack )
  3199 			SMF_GOTOS( EStCheckStack )
  2885 
  3200 
  2886 		if( !InitStackInProgress() )
  3201 		if( !InitStackInProgress() )
  2893 			iInitContext++;				// Pass number must never be zero
  3208 			iInitContext++;				// Pass number must never be zero
  2894 		s.iInitContext = iInitContext;	// this session is always in a proper context
  3209 		s.iInitContext = iInitContext;	// this session is always in a proper context
  2895 
  3210 
  2896 	SMF_STATE(EStStartInterrogation)
  3211 	SMF_STATE(EStStartInterrogation)
  2897 
  3212 
       
  3213 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM5, "EStStartInterrogation" );
  2898 		// NB: RCAs are not unlocked here. They will be unlocked one by one during the update of card info array.
  3214 		// NB: RCAs are not unlocked here. They will be unlocked one by one during the update of card info array.
  2899 		SMF_INVOKES( AcquireStackSMST, EStCheckStack )
  3215 		SMF_INVOKES( AcquireStackSMST, EStCheckStack )
  2900 
  3216 
  2901 	SMF_STATE(EStCheckStack)
  3217 	SMF_STATE(EStCheckStack)
  2902 
  3218 
       
  3219 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM6, "EStCheckStack" );
  2903 		// Check that all known cards are still present by issuing select/deselect
  3220 		// Check that all known cards are still present by issuing select/deselect
  2904 		SMF_INVOKES( CheckStackSMST, EStCardCap )
  3221 		SMF_INVOKES( CheckStackSMST, EStCardCap )
  2905 
  3222 
  2906 	SMF_STATE(EStCardCap)
  3223 	SMF_STATE(EStCardCap)
  2907 
  3224 
       
  3225 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM7, "EStCardCap" );
  2908 		// Call a licencee-specific state machine to allow card capabilities to be modified.
  3226 		// Call a licencee-specific state machine to allow card capabilities to be modified.
  2909 		SMF_INVOKES( ModifyCardCapabilitySMST, EStIssueDSR )
  3227 		SMF_INVOKES( ModifyCardCapabilitySMST, EStIssueDSR )
  2910 
  3228 
  2911 	SMF_STATE(EStIssueDSR)
  3229 	SMF_STATE(EStIssueDSR)
  2912 
  3230 
  2916 		// If the bus is not multiplexed (ie - MMC stack), then the max clock is set to
  3234 		// If the bus is not multiplexed (ie - MMC stack), then the max clock is set to
  2917 		// the lowest common denominator of all cards in the stack.  Otherwise (in the case
  3235 		// the lowest common denominator of all cards in the stack.  Otherwise (in the case
  2918 		// of a multiplexed bus such as SD), the highest clock is returned and the clock
  3236 		// of a multiplexed bus such as SD), the highest clock is returned and the clock
  2919 		// rate is changed when a new card is selected.
  3237 		// rate is changed when a new card is selected.
  2920 		//
  3238 		//
       
  3239 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM8, "EStIssueDSR" );
  2921 		TUint maxClk;
  3240 		TUint maxClk;
  2922 		iCardArray->UpdateAcquisitions(&maxClk);
  3241 		iCardArray->UpdateAcquisitions(&maxClk);
  2923 		SetBusConfigDefaults( iMasterConfig.iBusConfig, maxClk );
  3242 		SetBusConfigDefaults( iMasterConfig.iBusConfig, maxClk );
  2924 		DoSetClock(maxClk);
  3243 		DoSetClock(maxClk);
  2925 
  3244 
  2930 		// switch to normal iConfig clock mode
  3249 		// switch to normal iConfig clock mode
  2931 		InitClockOff();
  3250 		InitClockOff();
  2932 		
  3251 		
  2933 	SMF_STATE(EStFinishUp)
  3252 	SMF_STATE(EStFinishUp)
  2934 
  3253 
       
  3254 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMUPDATEACQSM9, "EStFinishUp" );
  2935 		s.iState &= ~(KMMCSessStateInProgress | KMMCSessStateCritical);
  3255 		s.iState &= ~(KMMCSessStateInProgress | KMMCSessStateCritical);
  2936 
  3256 
  2937 		// Update/Init stack has been completed. 
  3257 		// Update/Init stack has been completed. 
  2938 
  3258 
  2939 	SMF_END
  3259 	SMF_END
  2965 			EStEnd
  3285 			EStEnd
  2966 			};
  3286 			};
  2967 
  3287 
  2968 	DMMCSession& s = Session();
  3288 	DMMCSession& s = Session();
  2969 	TBool initSingleCard = (s.CardP() == NULL) ? (TBool)EFalse : (TBool)ETrue;
  3289 	TBool initSingleCard = (s.CardP() == NULL) ? (TBool)EFalse : (TBool)ETrue;
       
  3290 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM1, "Current session=0x%x", &s );
  2970 
  3291 
  2971 	SMF_BEGIN
  3292 	SMF_BEGIN
  2972 
  3293 
       
  3294 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM2, "EStBegin" );
  2973 		if(initSingleCard)
  3295 		if(initSingleCard)
  2974 			{
  3296 			{
  2975 			iSelectedCardIndex = iCxCardCount;
  3297 			iSelectedCardIndex = iCxCardCount;
  2976 			TMMCard* cardP = iCardArray->CardP(iSelectedCardIndex);
  3298 			TMMCard* cardP = iCardArray->CardP(iSelectedCardIndex);
  2977 
  3299 
  2992 		
  3314 		
  2993 		// ...fall through...
  3315 		// ...fall through...
  2994 
  3316 
  2995 	SMF_STATE(EStTestNextCard)
  3317 	SMF_STATE(EStTestNextCard)
  2996 
  3318 
       
  3319 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM3, "EStTestNextCard" );
       
  3320 
  2997 		// any more cards ?
  3321 		// any more cards ?
  2998 		if (++iSelectedCardIndex >= iCxCardCount)
  3322 		if (++iSelectedCardIndex >= iCxCardCount)
  2999 			SMF_GOTOS(EStNoMoreCards);
  3323 			SMF_GOTOS(EStNoMoreCards);
  3000 
  3324 
  3001 		// if no card in this slot, try next one
  3325 		// if no card in this slot, try next one
  3009 		if(cardP->IsLocked())
  3333 		if(cardP->IsLocked())
  3010 			SMF_GOTOS(EStTestNextCard);
  3334 			SMF_GOTOS(EStTestNextCard);
  3011 
  3335 
  3012 	SMF_STATE(EStGetExtendedCSD)
  3336 	SMF_STATE(EStGetExtendedCSD)
  3013 
  3337 
       
  3338 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM4, "EStGetExtendedCSD" );
       
  3339 	
  3014 		// Get the Extended CSD if this is an MMC version 4 card
  3340 		// Get the Extended CSD if this is an MMC version 4 card
  3015 
  3341 
  3016 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), SpecVers() %u", s.CardP()->CSD().SpecVers()));
  3342 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), SpecVers() %u", s.CardP()->CSD().SpecVers()));
       
  3343 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM5, "SpecVers()=%u", s.CardP()->CSD().SpecVers() );
       
  3344 		
  3017 
  3345 
  3018 		// clear the Extended CSD contents in case this is a pre-version 4 card or the read fails.
  3346 		// clear the Extended CSD contents in case this is a pre-version 4 card or the read fails.
  3019 		memset(s.CardP()->iExtendedCSD.Ptr(), 0, KMMCExtendedCSDLength);
  3347 		memset(s.CardP()->iExtendedCSD.Ptr(), 0, KMMCExtendedCSDLength);
  3020 
  3348 
  3021 		if (s.CardP()->CSD().SpecVers() < 4) 
  3349 		if (s.CardP()->CSD().SpecVers() < 4) 
  3028 
  3356 
  3029 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Sending ECmdSendExtendedCSD"));
  3357 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Sending ECmdSendExtendedCSD"));
  3030 		SMF_INVOKES(CIMReadWriteBlocksSMST, EStGotExtendedCSD)
  3358 		SMF_INVOKES(CIMReadWriteBlocksSMST, EStGotExtendedCSD)
  3031 
  3359 
  3032 	SMF_STATE(EStGotExtendedCSD)
  3360 	SMF_STATE(EStGotExtendedCSD)
  3033 				
  3361 		
       
  3362 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM6, "EStGotExtendedCSD" );
  3034 		if (err != KMMCErrNone)
  3363 		if (err != KMMCErrNone)
  3035 			{
  3364 			{
  3036 			SMF_GOTOS(EStExit);
  3365 			SMF_GOTOS(EStExit);
  3037 			}
  3366 			}
  3038 
  3367 
  3041 		// Call a licencee-specific state machine to allow the Extended CSD register to be modified.
  3370 		// Call a licencee-specific state machine to allow the Extended CSD register to be modified.
  3042 		SMF_INVOKES( ModifyCardCapabilitySMST, EStGotModifiedExtendedCSD )
  3371 		SMF_INVOKES( ModifyCardCapabilitySMST, EStGotModifiedExtendedCSD )
  3043 
  3372 
  3044 	SMF_STATE(EStGotModifiedExtendedCSD)
  3373 	SMF_STATE(EStGotModifiedExtendedCSD)
  3045 
  3374 
       
  3375 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM7, "EStGotExtendedCSD" );
       
  3376 	
  3046 		__KTRACE_OPT(KPBUS1, Kern::Printf("Extended CSD"));
  3377 		__KTRACE_OPT(KPBUS1, Kern::Printf("Extended CSD"));
  3047 		__KTRACE_OPT(KPBUS1, Kern::Printf("CSDStructureVer:            %u", s.CardP()->ExtendedCSD().CSDStructureVer()));
  3378 		__KTRACE_OPT(KPBUS1, Kern::Printf("CSDStructureVer:            %u", s.CardP()->ExtendedCSD().CSDStructureVer()));
  3048 		__KTRACE_OPT(KPBUS1, Kern::Printf("ExtendedCSDRev:             %u", s.CardP()->ExtendedCSD().ExtendedCSDRev()));
  3379 		__KTRACE_OPT(KPBUS1, Kern::Printf("ExtendedCSDRev:             %u", s.CardP()->ExtendedCSD().ExtendedCSDRev()));
  3049 		__KTRACE_OPT(KPBUS1, Kern::Printf("-------------------------------"));
  3380 		__KTRACE_OPT(KPBUS1, Kern::Printf("-------------------------------"));
  3050 		__KTRACE_OPT(KPBUS1, Kern::Printf("SupportedCmdSet:            %u", s.CardP()->ExtendedCSD().SupportedCmdSet()));
  3381 		__KTRACE_OPT(KPBUS1, Kern::Printf("SupportedCmdSet:            %u", s.CardP()->ExtendedCSD().SupportedCmdSet()));
  3068 		__KTRACE_OPT(KPBUS1, Kern::Printf("SleepCurrentVccQ:           %u", s.CardP()->ExtendedCSD().SleepCurrentVccQ()));
  3399 		__KTRACE_OPT(KPBUS1, Kern::Printf("SleepCurrentVccQ:           %u", s.CardP()->ExtendedCSD().SleepCurrentVccQ()));
  3069 		__KTRACE_OPT(KPBUS1, Kern::Printf("SleepAwakeTimeout:          %u", s.CardP()->ExtendedCSD().SleepAwakeTimeout()));
  3400 		__KTRACE_OPT(KPBUS1, Kern::Printf("SleepAwakeTimeout:          %u", s.CardP()->ExtendedCSD().SleepAwakeTimeout()));
  3070 		__KTRACE_OPT(KPBUS1, Kern::Printf("BootConfig:                 %u", s.CardP()->ExtendedCSD().BootConfig()));
  3401 		__KTRACE_OPT(KPBUS1, Kern::Printf("BootConfig:                 %u", s.CardP()->ExtendedCSD().BootConfig()));
  3071 		__KTRACE_OPT(KPBUS1, Kern::Printf("BootBusWidth:               %u", s.CardP()->ExtendedCSD().BootBusWidth()));
  3402 		__KTRACE_OPT(KPBUS1, Kern::Printf("BootBusWidth:               %u", s.CardP()->ExtendedCSD().BootBusWidth()));
  3072 		__KTRACE_OPT(KPBUS1, Kern::Printf("EraseGroupDef:              %u", s.CardP()->ExtendedCSD().EraseGroupDef()));
  3403 		__KTRACE_OPT(KPBUS1, Kern::Printf("EraseGroupDef:              %u", s.CardP()->ExtendedCSD().EraseGroupDef()));
  3073 				
  3404 		
       
  3405 		OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_INITSTACKAFTERUNLOCKSM8, "CSDStructureVer=%u; ExtendedCSDRev=%u; SupportedCmdSet=%u", s.CardP()->ExtendedCSD().CSDStructureVer(), s.CardP()->ExtendedCSD().ExtendedCSDRev(), s.CardP()->ExtendedCSD().SupportedCmdSet() );
       
  3406 		OstTraceDefExt4( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_INITSTACKAFTERUNLOCKSM9, "PowerClass26Mhz360V=0x%02x; PowerClass52Mhz360V=0x%02x; PowerClass26Mhz195V=0x%02x; PowerClass52Mhz195V=0x%02x", s.CardP()->ExtendedCSD().PowerClass26Mhz360V(), s.CardP()->ExtendedCSD().PowerClass52Mhz360V(), s.CardP()->ExtendedCSD().PowerClass26Mhz195V(), s.CardP()->ExtendedCSD().PowerClass52Mhz195V() );
       
  3407 		OstTraceDefExt5( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_INITSTACKAFTERUNLOCKSM10, "CardType=%u; CmdSet=%u; CmdSetRev=%u; PowerClass=%u; HighSpeedTiming=%u", s.CardP()->ExtendedCSD().CardType(), s.CardP()->ExtendedCSD().CmdSet(), s.CardP()->ExtendedCSD().CmdSetRev(), s.CardP()->ExtendedCSD().PowerClass(), s.CardP()->ExtendedCSD().HighSpeedTiming() );
       
  3408 		OstTraceDefExt5( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_INITSTACKAFTERUNLOCKSM11, "HighCapacityEraseGroupSize=%u; AccessSize=%u; BootInfo=%u; BootSizeMultiple=%u; EraseTimeoutMultiple=%u", s.CardP()->ExtendedCSD().HighCapacityEraseGroupSize(), s.CardP()->ExtendedCSD().AccessSize(), s.CardP()->ExtendedCSD().BootInfo(), s.CardP()->ExtendedCSD().BootSizeMultiple(), s.CardP()->ExtendedCSD().EraseTimeoutMultiple() );
       
  3409 		OstTraceDefExt5( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_INITSTACKAFTERUNLOCKSM12, "ReliableWriteSector=%u; HighCapWriteProtGroupSize=%u; SleepCurrentVcc=%u; SleepCurrentVccQ=%u; SleepAwakeTimeout=%u", s.CardP()->ExtendedCSD().ReliableWriteSector(), s.CardP()->ExtendedCSD().HighCapacityWriteProtectGroupSize(), s.CardP()->ExtendedCSD().SleepCurrentVcc(), s.CardP()->ExtendedCSD().SleepCurrentVccQ(), s.CardP()->ExtendedCSD().SleepAwakeTimeout() );
       
  3410 		OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_INITSTACKAFTERUNLOCKSM13, "BootConfig=%u; BootBusWidth=%u; EraseGroupDef=%u", s.CardP()->ExtendedCSD().BootConfig(), s.CardP()->ExtendedCSD().BootBusWidth(), s.CardP()->ExtendedCSD().EraseGroupDef() );
       
  3411 		
  3074 		if (s.CardP()->ExtendedCSD().ExtendedCSDRev() >= 3)
  3412 		if (s.CardP()->ExtendedCSD().ExtendedCSDRev() >= 3)
  3075 			{
  3413 			{
  3076 			if (!(s.CardP()->ExtendedCSD().EraseGroupDef()) && s.CardP()->ExtendedCSD().HighCapacityEraseGroupSize())
  3414 			if (!(s.CardP()->ExtendedCSD().EraseGroupDef()) && s.CardP()->ExtendedCSD().HighCapacityEraseGroupSize())
  3077 				{
  3415 				{
  3078 				// Need to ensure that media is using correct erase group sizes.
  3416 				// Need to ensure that media is using correct erase group sizes.
  3081 					TExtendedCSD::EEraseGroupDefIndex,
  3419 					TExtendedCSD::EEraseGroupDefIndex,
  3082 					TExtendedCSD::EEraseGrpDefEnableHighCapSizes,
  3420 					TExtendedCSD::EEraseGrpDefEnableHighCapSizes,
  3083 					0);
  3421 					0);
  3084 	
  3422 	
  3085 				__KTRACE_OPT(KPBUS1, Kern::Printf(">Writing to EXT_CSD (EEraseGroupDefIndex), arg %08X", (TUint32) arg));
  3423 				__KTRACE_OPT(KPBUS1, Kern::Printf(">Writing to EXT_CSD (EEraseGroupDefIndex), arg %08X", (TUint32) arg));
       
  3424 				OstTrace1( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM14, "Writing to EXT_CSD (EEraseGroupDefIndex); arg=0x%08x", (TUint32) arg );
       
  3425 				
  3086 				s.FillCommandDesc(ECmdSwitch, arg);
  3426 				s.FillCommandDesc(ECmdSwitch, arg);
  3087 				
  3427 				
  3088 				SMF_INVOKES(ExecSwitchCommandST, EStEraseGroupDefSet)
  3428 				SMF_INVOKES(ExecSwitchCommandST, EStEraseGroupDefSet)
  3089 				}
  3429 				}
  3090 			}
  3430 			}
  3091 		
  3431 		
  3092 		SMF_GOTOS(EStDetermineBusWidthAndClock)
  3432 		SMF_GOTOS(EStDetermineBusWidthAndClock)
  3093 		
  3433 		
  3094 	SMF_STATE(EStEraseGroupDefSet)
  3434 	SMF_STATE(EStEraseGroupDefSet)
  3095 	
  3435 	
       
  3436 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM15, "EStEraseGroupDefSet" );
       
  3437 	
  3096 		if (err == KMMCErrNone)
  3438 		if (err == KMMCErrNone)
  3097 			{
  3439 			{
  3098 			// EEraseGroupDef has been updated succussfully, 
  3440 			// EEraseGroupDef has been updated succussfully, 
  3099 			// update the Extended CSD to reflect this			
  3441 			// update the Extended CSD to reflect this			
  3100 			memset( s.CardP()->iExtendedCSD.Ptr()+TExtendedCSD::EEraseGroupDefIndex, TExtendedCSD::EEraseGrpDefEnableHighCapSizes, 1);
  3442 			memset( s.CardP()->iExtendedCSD.Ptr()+TExtendedCSD::EEraseGroupDefIndex, TExtendedCSD::EEraseGrpDefEnableHighCapSizes, 1);
  3101 			}
  3443 			}
  3102 	
  3444 	
  3103 	SMF_STATE(EStDetermineBusWidthAndClock)
  3445 	SMF_STATE(EStDetermineBusWidthAndClock)
  3104 	
  3446 	
       
  3447 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM16, "EStDetermineBusWidthAndClock" );
  3105 		SMF_INVOKES( DetermineBusWidthAndClockSMST, EStGotBusWidthAndClock )
  3448 		SMF_INVOKES( DetermineBusWidthAndClockSMST, EStGotBusWidthAndClock )
  3106 
  3449 
  3107     SMF_STATE(EStGotBusWidthAndClock)
  3450     SMF_STATE(EStGotBusWidthAndClock)
  3108 
  3451 
       
  3452 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM17, "EStGotBusWidthAndClock" );
  3109 		SMF_NEXTS(initSingleCard ? EStExit : EStTestNextCard)
  3453 		SMF_NEXTS(initSingleCard ? EStExit : EStTestNextCard)
  3110 
  3454 
  3111 		if(iMultiplexedBus || iCardArray->CardsPresent() == 1)
  3455 		if(iMultiplexedBus || iCardArray->CardsPresent() == 1)
  3112 			{
  3456 			{
  3113 			SMF_CALL( ConfigureHighSpeedSMST )
  3457 			SMF_CALL( ConfigureHighSpeedSMST )
  3115 		
  3459 		
  3116 		SMF_GOTONEXTS
  3460 		SMF_GOTONEXTS
  3117 
  3461 
  3118 	SMF_STATE(EStNoMoreCards)
  3462 	SMF_STATE(EStNoMoreCards)
  3119 
  3463 
       
  3464 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM18, "EStNoMoreCards" );
  3120 
  3465 
  3121 	SMF_STATE(EStExit)
  3466 	SMF_STATE(EStExit)
       
  3467 	
       
  3468 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_INITSTACKAFTERUNLOCKSM19, "EStExit" );
  3122 		m.ResetTraps();
  3469 		m.ResetTraps();
  3123 
  3470 
  3124 	SMF_END
  3471 	SMF_END
  3125 	}
  3472 	}
  3126 
  3473 
  3152 			EStEnd
  3499 			EStEnd
  3153 			};
  3500 			};
  3154 
  3501 
  3155 	DMMCSession& s = Session();
  3502 	DMMCSession& s = Session();
  3156 	TMMCard* cardP = iCardArray->CardP(iSelectedCardIndex);
  3503 	TMMCard* cardP = iCardArray->CardP(iSelectedCardIndex);
       
  3504 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM1, "Current session=0x%x", &s );
  3157 
  3505 
  3158 	SMF_BEGIN
  3506 	SMF_BEGIN
       
  3507 	
       
  3508 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM2, "EStBegin" );
  3159 		// Trap Switch errors & no-response errors
  3509 		// Trap Switch errors & no-response errors
  3160 		m.SetTraps(KMMCErrResponseTimeOut | KMMCErrStatus);
  3510 		m.SetTraps(KMMCErrResponseTimeOut | KMMCErrStatus);
  3161 
  3511 
  3162 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), iCxCardCount %u", iCxCardCount));
  3512 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), iCxCardCount %u", iCxCardCount));
  3163 
  3513 
  3164 
  3514 
  3165 	SMF_STATE(EStWritePowerClass)
  3515 	SMF_STATE(EStWritePowerClass)
  3166 
  3516 
       
  3517 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM3, "EStWritePowerClass" );
       
  3518 	
  3167 		// Check the card type is valid
  3519 		// Check the card type is valid
  3168 		// The only currently valid values for this field are 0x01 or 0x03
  3520 		// The only currently valid values for this field are 0x01 or 0x03
  3169 		TUint cardType = cardP->iExtendedCSD.CardType();
  3521 		TUint cardType = cardP->iExtendedCSD.CardType();
  3170 		if (cardType != (TExtendedCSD::EHighSpeedCard26Mhz) && 
  3522 		if (cardType != (TExtendedCSD::EHighSpeedCard26Mhz) && 
  3171 			cardType != (TExtendedCSD::EHighSpeedCard26Mhz | TExtendedCSD::EHighSpeedCard52Mhz))
  3523 			cardType != (TExtendedCSD::EHighSpeedCard26Mhz | TExtendedCSD::EHighSpeedCard52Mhz))
  3172 			{
  3524 			{
  3173 			__KTRACE_OPT(KPBUS1, Kern::Printf("Unsupported card type %u", cardType));
  3525 			__KTRACE_OPT(KPBUS1, Kern::Printf("Unsupported card type %u", cardType));
       
  3526 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM4, "Unsupported card type=%u", cardType );
       
  3527 			
  3174 			SMF_GOTOS(EStExit);
  3528 			SMF_GOTOS(EStExit);
  3175 			}
  3529 			}
  3176 
  3530 
  3177 		// determine the optimum bus width & clock speed which match the power constraints
  3531 		// determine the optimum bus width & clock speed which match the power constraints
  3178 		TUint powerClass;
  3532 		TUint powerClass;
  3191 				TExtendedCSD::EPowerClassIndex,
  3545 				TExtendedCSD::EPowerClassIndex,
  3192 				powerClass,
  3546 				powerClass,
  3193 				0);
  3547 				0);
  3194 
  3548 
  3195 			__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Writing to EXT_CSD (EPowerClass), arg %08X", (TUint32) arg));
  3549 			__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Writing to EXT_CSD (EPowerClass), arg %08X", (TUint32) arg));
       
  3550 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM5, "Writing to EXT_CSD (EPowerClass); arg=0x%08x", (TUint32) arg );
  3196 			s.FillCommandDesc(ECmdSwitch, arg);
  3551 			s.FillCommandDesc(ECmdSwitch, arg);
  3197 			SMF_INVOKES(ExecSwitchCommandST, EStStartBusTest)
  3552 			SMF_INVOKES(ExecSwitchCommandST, EStStartBusTest)
  3198 			}
  3553 			}
  3199 
  3554 
  3200 	SMF_STATE(EStStartBusTest)
  3555 	SMF_STATE(EStStartBusTest)
  3201 		
  3556 		
       
  3557         OstTrace0( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM6, "EStStartBusTest" );
       
  3558         	
  3202 		if (err != KMMCErrNone)
  3559 		if (err != KMMCErrNone)
  3203 			{
  3560 			{
  3204 			SMF_GOTOS(EStExit);
  3561 			SMF_GOTOS(EStExit);
  3205 			}
  3562 			}
  3206 
  3563 
  3207 		// We have determined the capabilities of the host and card.
  3564 		// We have determined the capabilities of the host and card.
  3208 		//  - Before switching to the required bus width, perform the BUSTEST sequence
  3565 		//  - Before switching to the required bus width, perform the BUSTEST sequence
  3209 		SMF_INVOKES(ExecBusTestSMST, EStExit);
  3566 		SMF_INVOKES(ExecBusTestSMST, EStExit);
  3210 
  3567 
  3211 	SMF_STATE(EStExit)
  3568 	SMF_STATE(EStExit)
       
  3569 	
       
  3570 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCKSM7, "EStExit" );
  3212 		m.ResetTraps();
  3571 		m.ResetTraps();
  3213 
  3572 
  3214 	SMF_END
  3573 	SMF_END
  3215 	}
  3574 	}
  3216 
  3575 
  3242 			EStEnd
  3601 			EStEnd
  3243 			};
  3602 			};
  3244 
  3603 
  3245 	DMMCSession& s = Session();
  3604 	DMMCSession& s = Session();
  3246 	TMMCard* cardP = iCardArray->CardP(iSelectedCardIndex);
  3605 	TMMCard* cardP = iCardArray->CardP(iSelectedCardIndex);
       
  3606 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM1, "Current session=0x%x", &s );
  3247 
  3607 
  3248 	SMF_BEGIN
  3608 	SMF_BEGIN
  3249 
  3609 
       
  3610         OstTrace0( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM2, "EStBegin" );
       
  3611         
  3250 		// Trap Switch errors & no-response errors
  3612 		// Trap Switch errors & no-response errors
  3251 		m.SetTraps(KMMCErrResponseTimeOut | KMMCErrStatus);
  3613 		m.SetTraps(KMMCErrResponseTimeOut | KMMCErrStatus);
  3252 
  3614 
  3253 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), iCxCardCount %u", iCxCardCount));
  3615 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), iCxCardCount %u", iCxCardCount));
       
  3616 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM3, "iCxCardCount=%d", iCxCardCount );
  3254 
  3617 
  3255 		cardP->SetHighSpeedClock(0);
  3618 		cardP->SetHighSpeedClock(0);
  3256 
  3619 
  3257 		// Check the card type is valid
  3620 		// Check the card type is valid
  3258 		// The only currently valid values for this field are 0x01 or 0x03
  3621 		// The only currently valid values for this field are 0x01 or 0x03
  3259 		TUint cardType = cardP->iExtendedCSD.CardType();
  3622 		TUint cardType = cardP->iExtendedCSD.CardType();
  3260 		if (cardType != (TExtendedCSD::EHighSpeedCard26Mhz) && 
  3623 		if (cardType != (TExtendedCSD::EHighSpeedCard26Mhz) && 
  3261 			cardType != (TExtendedCSD::EHighSpeedCard26Mhz | TExtendedCSD::EHighSpeedCard52Mhz))
  3624 			cardType != (TExtendedCSD::EHighSpeedCard26Mhz | TExtendedCSD::EHighSpeedCard52Mhz))
  3262 			{
  3625 			{
  3263 			__KTRACE_OPT(KPBUS1, Kern::Printf("Unsupported card type %u", cardType));
  3626 			__KTRACE_OPT(KPBUS1, Kern::Printf("Unsupported card type %u", cardType));
       
  3627 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM4, "Unsupported card type=%u", cardType );
  3264 			SMF_GOTOS(EStExit);
  3628 			SMF_GOTOS(EStExit);
  3265 			}
  3629 			}
  3266 
  3630 
  3267 		// If the bus width is 4 or 8, send SWITCH cmd and write the BUS_WIDTH byte of the EXT_CSD register
  3631 		// If the bus width is 4 or 8, send SWITCH cmd and write the BUS_WIDTH byte of the EXT_CSD register
  3268 
  3632 
  3273 				TExtendedCSD::EBusWidthModeIndex,
  3637 				TExtendedCSD::EBusWidthModeIndex,
  3274 				(iBusWidthAndClock & E4BitMask) ? TExtendedCSD::EExtCsdBusWidth4 : TExtendedCSD::EExtCsdBusWidth8,
  3638 				(iBusWidthAndClock & E4BitMask) ? TExtendedCSD::EExtCsdBusWidth4 : TExtendedCSD::EExtCsdBusWidth8,
  3275 				0);
  3639 				0);
  3276 
  3640 
  3277 			__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Writing to EXT_CSD (EBusWidthMode), arg %08X", (TUint32) arg));
  3641 			__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Writing to EXT_CSD (EBusWidthMode), arg %08X", (TUint32) arg));
       
  3642 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM5, "Writing to EXT_CSD (EBusWidthMode); arg=0x%x", (TUint32) arg );
  3278 			s.FillCommandDesc(ECmdSwitch, arg);
  3643 			s.FillCommandDesc(ECmdSwitch, arg);
  3279 			SMF_INVOKES(ExecSwitchCommandST, EStConfigureBusWidth)
  3644 			SMF_INVOKES(ExecSwitchCommandST, EStConfigureBusWidth)
  3280 			}
  3645 			}
  3281 
  3646 
  3282 	SMF_STATE(EStConfigureBusWidth)
  3647 	SMF_STATE(EStConfigureBusWidth)
  3283 
  3648 
       
  3649         OstTrace0( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM6, "EStConfigureBusWidth" );
       
  3650         
  3284 		if (err != KMMCErrNone)
  3651 		if (err != KMMCErrNone)
  3285 			{
  3652 			{
  3286 			SMF_GOTOS(EStExit);
  3653 			SMF_GOTOS(EStExit);
  3287 			}
  3654 			}
  3288 
  3655 
  3297 			DoSetBusWidth(EBusWidth8);
  3664 			DoSetBusWidth(EBusWidth8);
  3298 			}
  3665 			}
  3299 		// fall through to next state
  3666 		// fall through to next state
  3300 
  3667 
  3301 	SMF_STATE(EStWriteHsTiming)
  3668 	SMF_STATE(EStWriteHsTiming)
       
  3669 	
       
  3670 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM7, "EStWriteHsTiming" );
       
  3671 	
  3302 		if (iBusWidthAndClock == E1Bit20Mhz)
  3672 		if (iBusWidthAndClock == E1Bit20Mhz)
  3303 			SMF_GOTOS(EStExit);
  3673 			SMF_GOTOS(EStExit);
  3304 
  3674 
  3305 		TMMCArgument arg = TExtendedCSD::GetWriteArg(
  3675 		TMMCArgument arg = TExtendedCSD::GetWriteArg(
  3306 			TExtendedCSD::EWriteByte,
  3676 			TExtendedCSD::EWriteByte,
  3307 			TExtendedCSD::EHighSpeedInterfaceTimingIndex,
  3677 			TExtendedCSD::EHighSpeedInterfaceTimingIndex,
  3308 			1,	// turn on high speed (26 or 52 Mhz, depending on the card type)
  3678 			1,	// turn on high speed (26 or 52 Mhz, depending on the card type)
  3309 			0);
  3679 			0);
  3310 
  3680 
  3311 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Writing to EXT_CSD (EHighSpeedInterfaceTiming), arg %08X", (TUint32) arg));
  3681 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ConfigureHighSpeed(), Writing to EXT_CSD (EHighSpeedInterfaceTiming), arg %08X", (TUint32) arg));
       
  3682 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM8, "Writing to EXT_CSD (EHighSpeedInterfaceTiming); arg=0x%x", (TUint32) arg );
  3312 		s.FillCommandDesc(ECmdSwitch, arg);
  3683 		s.FillCommandDesc(ECmdSwitch, arg);
  3313 		SMF_INVOKES(ExecSwitchCommandST, EStConfigureClock)
  3684 		SMF_INVOKES(ExecSwitchCommandST, EStConfigureClock)
  3314 
  3685 
  3315 
  3686 
  3316 	SMF_STATE(EStConfigureClock)
  3687 	SMF_STATE(EStConfigureClock)
  3317 
  3688 
       
  3689 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM9, "EStConfigureClock" );
       
  3690 	
  3318 		if (err != KMMCErrNone)
  3691 		if (err != KMMCErrNone)
  3319 			{
  3692 			{
  3320 			DoSetBusWidth(EBusWidth1);
  3693 			DoSetBusWidth(EBusWidth1);
  3321 			SMF_GOTOS(EStExit);
  3694 			SMF_GOTOS(EStExit);
  3322 			}
  3695 			}
  3325 			MHZ_TO_KHZ(((iBusWidthAndClock & E52MhzMask) ? 
  3698 			MHZ_TO_KHZ(((iBusWidthAndClock & E52MhzMask) ? 
  3326 			            TMMCMachineInfoV4::EClockSpeed52Mhz:
  3699 			            TMMCMachineInfoV4::EClockSpeed52Mhz:
  3327 			            TMMCMachineInfoV4::EClockSpeed26Mhz)));
  3700 			            TMMCMachineInfoV4::EClockSpeed26Mhz)));
  3328 
  3701 
  3329 	SMF_STATE(EStExit)
  3702 	SMF_STATE(EStExit)
       
  3703 	
       
  3704 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CONFIGUREHIGHSPEEDSM10, "EStExit" );
       
  3705 	
  3330 		m.ResetTraps();
  3706 		m.ResetTraps();
  3331 
  3707 
  3332 	SMF_END
  3708 	SMF_END
  3333 	}
  3709 	}
  3334 
  3710 
  3343 			EStGetStatus,
  3719 			EStGetStatus,
  3344 			EStEnd
  3720 			EStEnd
  3345 			};
  3721 			};
  3346 
  3722 
  3347 		DMMCSession& s=Session();
  3723 		DMMCSession& s=Session();
       
  3724 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECSWITCHCOMMAND1, "Current session=0x%x", &s );
  3348 
  3725 
  3349 	SMF_BEGIN
  3726 	SMF_BEGIN
  3350 		SMF_INVOKES(ExecCommandSMST, EStSendStatus)
  3727     	OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSWITCHCOMMAND2, "EStBegin" );
       
  3728     	SMF_INVOKES(ExecCommandSMST, EStSendStatus)
  3351 
  3729 
  3352 	SMF_STATE(EStSendStatus)
  3730 	SMF_STATE(EStSendStatus)
       
  3731 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSWITCHCOMMAND3, "EStSendStatus" );
  3353 		s.FillCommandDesc(ECmdSendStatus, 0);
  3732 		s.FillCommandDesc(ECmdSendStatus, 0);
  3354 		SMF_INVOKES(ExecCommandSMST, EStGetStatus)
  3733 		SMF_INVOKES(ExecCommandSMST, EStGetStatus)
  3355 
  3734 
  3356 	SMF_STATE(EStGetStatus)
  3735 	SMF_STATE(EStGetStatus)
       
  3736 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSWITCHCOMMAND4, "EStGetStatus" );
  3357 		const TMMCStatus st(s.ResponseP());
  3737 		const TMMCStatus st(s.ResponseP());
  3358 
  3738 
  3359 		const TMMCardStateEnum st1 = st.State();
  3739 		const TMMCardStateEnum st1 = st.State();
  3360 		if (st1 == ECardStatePrg)
  3740 		if (st1 == ECardStatePrg)
  3361 			{
  3741 			{
  3381 			EStDone,
  3761 			EStDone,
  3382 			EStEnd
  3762 			EStEnd
  3383 			};
  3763 			};
  3384 
  3764 
  3385 		DMMCSession& s=Session();
  3765 		DMMCSession& s=Session();
       
  3766 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM1, "Current session=0x%x", &s );
  3386 
  3767 
  3387 	SMF_BEGIN
  3768 	SMF_BEGIN
  3388 	
  3769 	
       
  3770         OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM2, "EStBegin" );
       
  3771         
  3389 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ExecSleepCommandSM()"));
  3772 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ExecSleepCommandSM()"));
  3390 		
  3773 		
  3391 		iAutoUnlockIndex = -1;
  3774 		iAutoUnlockIndex = -1;
  3392 		// drop through....
  3775 		// drop through....
  3393 		
  3776 		
  3394 	SMF_STATE(EStIndexNxtCard)
  3777 	SMF_STATE(EStIndexNxtCard)
  3395 	
  3778 	
       
  3779 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM3, "EStIndexNxtCard" );
  3396 		__KTRACE_OPT(KPBUS1, Kern::Printf(">EStIndexNxtCard"));
  3780 		__KTRACE_OPT(KPBUS1, Kern::Printf(">EStIndexNxtCard"));
  3397 		// the cycle is finished when iAutoUnlockIndex == KMaxMultiMediaCardsPerStack
  3781 		// the cycle is finished when iAutoUnlockIndex == KMaxMultiMediaCardsPerStack
  3398 		if(iAutoUnlockIndex >= TInt(KMaxMMCardsPerStack))
  3782 		if(iAutoUnlockIndex >= TInt(KMaxMMCardsPerStack))
  3399 			{
  3783 			{
  3400 			SMF_GOTOS(EStUpdateStackState);
  3784 			SMF_GOTOS(EStUpdateStackState);
  3413 
  3797 
  3414 			// don't increment iAutoUnlockIndex in continuation loop
  3798 			// don't increment iAutoUnlockIndex in continuation loop
  3415 			if (useIndex)
  3799 			if (useIndex)
  3416 				{
  3800 				{
  3417 				__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: is v4.3 device",iAutoUnlockIndex));
  3801 				__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: is v4.3 device",iAutoUnlockIndex));
       
  3802 				OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM4, "Card[%d]: is v4.3+ device", iAutoUnlockIndex );
  3418 				break;
  3803 				break;
  3419 				}
  3804 				}
  3420 			}
  3805 			}
  3421 		
  3806 		
  3422 		if (!useIndex)
  3807 		if (!useIndex)
  3433 		// CMD5 is an AC command, ExecCommandSMST will automatically issue a deselect
  3818 		// CMD5 is an AC command, ExecCommandSMST will automatically issue a deselect
  3434 		SMF_INVOKES(ExecCommandSMST, EStSleepAwakeIssued)
  3819 		SMF_INVOKES(ExecCommandSMST, EStSleepAwakeIssued)
  3435 		
  3820 		
  3436 	SMF_STATE(EStSleepAwakeIssued)
  3821 	SMF_STATE(EStSleepAwakeIssued)
  3437 		 
  3822 		 
       
  3823 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM5, "EStSleepAwakeIssued" );
  3438 		__KTRACE_OPT(KPBUS1, Kern::Printf(">EStSleepAwakeIssued!"));
  3824 		__KTRACE_OPT(KPBUS1, Kern::Printf(">EStSleepAwakeIssued!"));
  3439 		
  3825 		
  3440 		const TMMCStatus status(s.ResponseP());
  3826 		const TMMCStatus status(s.ResponseP());
  3441 		
  3827 		
  3442 		s.PopCommandStack();
  3828 		s.PopCommandStack();
  3444 		if(status.State() == ECardStateStby || status.State() == ECardStateSlp)
  3830 		if(status.State() == ECardStateStby || status.State() == ECardStateSlp)
  3445 			{			
  3831 			{			
  3446 			// R1b is issued before Sleep state is achieved and 
  3832 			// R1b is issued before Sleep state is achieved and 
  3447 			// will therefore return the previous state which was Standby
  3833 			// will therefore return the previous state which was Standby
  3448 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: SLEEP",iAutoUnlockIndex));
  3834 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: SLEEP",iAutoUnlockIndex));
       
  3835 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM6, "Card[%d]: SLEEP", iAutoUnlockIndex );
  3449 			
  3836 			
  3450 			// Ensure card status is ECardStateSlp
  3837 			// Ensure card status is ECardStateSlp
  3451 			s.CardP()->iStatus.UpdateState(ECardStateSlp);
  3838 			s.CardP()->iStatus.UpdateState(ECardStateSlp);
  3452 			
  3839 			
  3453 			// Update Stack state to indicate media is sleep mode
  3840 			// Update Stack state to indicate media is sleep mode
  3454 			iStackState |= KMMCStackStateSleep;
  3841 			iStackState |= KMMCStackStateSleep;
  3455 			}
  3842 			}
  3456 		else
  3843 		else
  3457 			{ 
  3844 			{ 
  3458 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: UNKNOWN",iAutoUnlockIndex));
  3845 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: UNKNOWN",iAutoUnlockIndex));
       
  3846 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM7, "Card[%d]: UNKNOWN", iAutoUnlockIndex );
       
  3847 			
  3459 			return (KMMCErrStatus);
  3848 			return (KMMCErrStatus);
  3460 			}
  3849 			}
  3461 		
  3850 		
  3462 		SMF_GOTOS(EStIndexNxtCard)
  3851 		SMF_GOTOS(EStIndexNxtCard)
  3463 
  3852 
  3464 	SMF_STATE(EStUpdateStackState)
  3853 	SMF_STATE(EStUpdateStackState)
  3465 
  3854 
       
  3855 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM8, "EStUpdateStackState" );
  3466 		if (iStackState & KMMCStackStateSleep)
  3856 		if (iStackState & KMMCStackStateSleep)
  3467 			{ 
  3857 			{ 
  3468 			// Media has been transitioned to sleep state
  3858 			// Media has been transitioned to sleep state
  3469 			iStackState &= ~KMMCStackStateSleep;
  3859 			iStackState &= ~KMMCStackStateSleep;
  3470 			
  3860 			
  3475 			// No media transitioned to sleep state or media was already in sleep state,
  3865 			// No media transitioned to sleep state or media was already in sleep state,
  3476 			// nothing to do...
  3866 			// nothing to do...
  3477 			
  3867 			
  3478 	SMF_STATE(EStDone)
  3868 	SMF_STATE(EStDone)
  3479 		
  3869 		
       
  3870 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECSLEEPCOMMANDSM9, "EStDone" );
  3480 		__KTRACE_OPT(KPBUS1, Kern::Printf("<ExecSleepCommandSM()"));
  3871 		__KTRACE_OPT(KPBUS1, Kern::Printf("<ExecSleepCommandSM()"));
  3481 		
  3872 		
  3482 	SMF_END
  3873 	SMF_END
  3483 	}
  3874 	}
  3484 
  3875 
  3494 			EStDone,
  3885 			EStDone,
  3495 			EStEnd
  3886 			EStEnd
  3496 			};
  3887 			};
  3497 
  3888 
  3498 		DMMCSession& s=Session();
  3889 		DMMCSession& s=Session();
       
  3890 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM1, "Current session=0x%x", &s );
  3499 
  3891 
  3500 	SMF_BEGIN
  3892 	SMF_BEGIN
  3501 	
  3893 	
       
  3894 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM2, "EStBegin" );
  3502 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ExecAwakeCommandSM()"));
  3895 		__KTRACE_OPT(KPBUS1, Kern::Printf(">ExecAwakeCommandSM()"));
  3503 		
  3896 		
  3504 		// Call PSL to ensure VccQ is powered up before continuing
  3897 		// Call PSL to ensure VccQ is powered up before continuing
  3505 		SMF_INVOKES( DoWakeUpSMST, EStPoweredUp )
  3898 		SMF_INVOKES( DoWakeUpSMST, EStPoweredUp )
  3506 		
  3899 		
  3507 	SMF_STATE(EStPoweredUp)	
  3900 	SMF_STATE(EStPoweredUp)	
  3508 
  3901 
       
  3902 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM3, "EStPoweredUp" );
  3509 		__KTRACE_OPT(KPBUS1, Kern::Printf("VccQ Powered Up"));
  3903 		__KTRACE_OPT(KPBUS1, Kern::Printf("VccQ Powered Up"));
  3510 		
  3904 		
  3511 		//Issue CMD5 to awaken media
  3905 		//Issue CMD5 to awaken media
  3512 		s.PushCommandStack();		
  3906 		s.PushCommandStack();		
  3513 		s.FillCommandDesc(ECmdSleepAwake);
  3907 		s.FillCommandDesc(ECmdSleepAwake);
  3515 		
  3909 		
  3516 		SMF_INVOKES(IssueCommandCheckResponseSMST, EStAwakeIssued)
  3910 		SMF_INVOKES(IssueCommandCheckResponseSMST, EStAwakeIssued)
  3517 		
  3911 		
  3518 	SMF_STATE(EStAwakeIssued)
  3912 	SMF_STATE(EStAwakeIssued)
  3519 		 
  3913 		 
       
  3914 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM4, "EStAwakeIssued" );
  3520 		__KTRACE_OPT(KPBUS1, Kern::Printf(">>EStAwakeIssued!"));
  3915 		__KTRACE_OPT(KPBUS1, Kern::Printf(">>EStAwakeIssued!"));
  3521 		
  3916 		
  3522 		TMMCStatus status(s.ResponseP());
  3917 		TMMCStatus status(s.ResponseP());
  3523 
  3918 
  3524 		if(status.State() == ECardStateStby || status.State() == ECardStateSlp)
  3919 		if(status.State() == ECardStateStby || status.State() == ECardStateSlp)
  3525 			{			
  3920 			{			
  3526 			// R1b is issued before Standby state is achieved and 
  3921 			// R1b is issued before Standby state is achieved and 
  3527 			// will therefore return the previous state which was Sleep
  3922 			// will therefore return the previous state which was Sleep
  3528 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: STANDBY",iAutoUnlockIndex));
  3923 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: STANDBY",iAutoUnlockIndex));
  3529 			
  3924 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM5, "Card[%d]: STANDBY", iAutoUnlockIndex );
  3530 			s.CardP()->iStatus.UpdateState(ECardStateStby);
  3925 			s.CardP()->iStatus.UpdateState(ECardStateStby);
  3531 			}
  3926 			}
  3532 		else
  3927 		else
  3533 			{ 
  3928 			{ 
  3534 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: UNKNOWN",iAutoUnlockIndex));
  3929 			__KTRACE_OPT(KPBUS1, Kern::Printf(">Card[%d]: UNKNOWN",iAutoUnlockIndex));
  3535 			return (KMMCErrStatus);
  3930 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM6, "Card[%d]: UNKNOWN", iAutoUnlockIndex );
       
  3931 			OstTraceFunctionExitExt( DMMCSTACK_EXECAWAKECOMMANDSM_EXIT, this, (TInt) KMMCErrStatus );
       
  3932 			return KMMCErrStatus;
  3536 			}
  3933 			}
  3537 
  3934 
  3538 		s.PopCommandStack();	
  3935 		s.PopCommandStack();	
  3539 
  3936 
  3540 	SMF_STATE(EStDone)
  3937 	SMF_STATE(EStDone)
  3541 	
  3938 	
       
  3939 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECAWAKECOMMANDSM7, "EStDone" );
  3542 		__KTRACE_OPT(KPBUS1, Kern::Printf("<ExecAwakeCommandSM()"));
  3940 		__KTRACE_OPT(KPBUS1, Kern::Printf("<ExecAwakeCommandSM()"));
  3543 	
  3941 	
  3544 	SMF_END
  3942 	SMF_END
  3545 	}
  3943 	}
  3546 
  3944 
  3551 	const TMMCard& aCard, 
  3949 	const TMMCard& aCard, 
  3552 	TBool aLowVoltage,
  3950 	TBool aLowVoltage,
  3553 	TUint& aPowerClass,
  3951 	TUint& aPowerClass,
  3554 	TBusWidthAndClock& aBusWidthAndClock)
  3952 	TBusWidthAndClock& aBusWidthAndClock)
  3555 	{
  3953 	{
       
  3954 	OstTraceExt2(TRACE_FLOW, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCK_ENTRY, "DMMCStack::DetermineBusWidthAndClock;aLowVoltage=%d;this=%x", (TInt) aLowVoltage, (TUint) this);
  3556 
  3955 
  3557 	// Set default return values - in case power constraints aren't matched
  3956 	// Set default return values - in case power constraints aren't matched
  3558 	aPowerClass = 0;
  3957 	aPowerClass = 0;
  3559 	aBusWidthAndClock = E1Bit20Mhz;
  3958 	aBusWidthAndClock = E1Bit20Mhz;
  3560 
  3959 
  3562 	// NB If the PSL doesn not support TMMCMachineInfoV4, return
  3961 	// NB If the PSL doesn not support TMMCMachineInfoV4, return
  3563 	TMMCMachineInfoV4 machineInfo;
  3962 	TMMCMachineInfoV4 machineInfo;
  3564 	TMMCMachineInfoV4Pckg machineInfoPckg(machineInfo);
  3963 	TMMCMachineInfoV4Pckg machineInfoPckg(machineInfo);
  3565 	MachineInfo(machineInfoPckg);
  3964 	MachineInfo(machineInfoPckg);
  3566 	if (machineInfo.iVersion < TMMCMachineInfoV4::EVersion4)
  3965 	if (machineInfo.iVersion < TMMCMachineInfoV4::EVersion4)
       
  3966 	    {
       
  3967 		OstTraceFunctionExit1( DMMCSTACK_DETERMINEBUSWIDTHANDCLOCK_EXIT1, this );
  3567 		return;
  3968 		return;
       
  3969 	    }
  3568 
  3970 
  3569 	TBusWidth maxBusWidth = machineInfo.iMaxBusWidth;
  3971 	TBusWidth maxBusWidth = machineInfo.iMaxBusWidth;
  3570 	TInt maxClockSpeedInMhz = machineInfo.iMaxClockSpeedInMhz;
  3972 	TInt maxClockSpeedInMhz = machineInfo.iMaxClockSpeedInMhz;
  3571 
  3973 
  3572 	TUint32 controllerWidthAndClock = E1Bit20Mhz;
  3974 	TUint32 controllerWidthAndClock = E1Bit20Mhz;
  3612 		aBusWidthAndClock = TBusWidthAndClock(targetWidthAndClock);
  4014 		aBusWidthAndClock = TBusWidthAndClock(targetWidthAndClock);
  3613 		break;
  4015 		break;
  3614 		}
  4016 		}
  3615 
  4017 
  3616 	__KTRACE_OPT(KPBUS1, Kern::Printf("aPowerClass %u, targetWidthAndClock = %08X", aPowerClass, aBusWidthAndClock));
  4018 	__KTRACE_OPT(KPBUS1, Kern::Printf("aPowerClass %u, targetWidthAndClock = %08X", aPowerClass, aBusWidthAndClock));
       
  4019 	OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_DETERMINEBUSWIDTHANDCLOCK, "aPowerClass=%u; targetWidthAndClock=0x%08x", aPowerClass, (TUint) aBusWidthAndClock );
       
  4020 	OstTraceFunctionExit1( DMMCSTACK_DETERMINEBUSWIDTHANDCLOCK_EXIT2, this );
  3617 	}
  4021 	}
  3618 
  4022 
  3619 TUint DMMCStack::GetPowerClass(const TMMCard& aCard, TBusWidthAndClock aWidthAndClock, TBool aLowVoltage)
  4023 TUint DMMCStack::GetPowerClass(const TMMCard& aCard, TBusWidthAndClock aWidthAndClock, TBool aLowVoltage)
  3620 	{
  4024 	{
       
  4025 	OstTraceExt3(TRACE_FLOW, DMMCSTACK_GETPOWERCLASS_ENTRY, "DMMCStack::GetPowerClass;aWidthAndClock=%d;aLowVoltage=%d;this=%x", (TInt) aWidthAndClock, (TInt) aLowVoltage, (TUint) this);
  3621 	// The power class for 4 bit bus configurations is in the low nibble,
  4026 	// The power class for 4 bit bus configurations is in the low nibble,
  3622 	// The power class for 8 bit bus configurations is in the high nibble,
  4027 	// The power class for 8 bit bus configurations is in the high nibble,
  3623 	#define LO_NIBBLE(val) (val & 0x0F)
  4028 	#define LO_NIBBLE(val) (val & 0x0F)
  3624 	#define HI_NIBBLE(val) ((val >> 4) & 0x0F)
  4029 	#define HI_NIBBLE(val) ((val >> 4) & 0x0F)
  3625 
  4030 
  3668 				powerClass = 0;
  4073 				powerClass = 0;
  3669 				break;
  4074 				break;
  3670 			}
  4075 			}
  3671 		}
  4076 		}
  3672 
  4077 
       
  4078 		OstTraceFunctionExitExt( DMMCSTACK_GETPOWERCLASS_EXIT, this, powerClass );
  3673 		return powerClass;
  4079 		return powerClass;
  3674 	}
  4080 	}
  3675 
  4081 
  3676 //
  4082 //
  3677 // Execute the BUSTEST procedure for a given bus width
  4083 // Execute the BUSTEST procedure for a given bus width
  3687 		EStExit,
  4093 		EStExit,
  3688 		EStEnd
  4094 		EStEnd
  3689 		};
  4095 		};
  3690 
  4096 
  3691 	DMMCSession& s = Session();
  4097 	DMMCSession& s = Session();
       
  4098 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM1, "Current session=0x%x", &s );
  3692 
  4099 
  3693 	SMF_BEGIN
  4100 	SMF_BEGIN
  3694 		//
  4101 		//
  3695 		// Start the BUSTEST sequence at the maximum supported by the PSL
  4102 		// Start the BUSTEST sequence at the maximum supported by the PSL
  3696 		//  - iSpare[0] keeps track of the current bus width
  4103 		//  - iSpare[0] keeps track of the current bus width
  3697 		//
  4104 		//
       
  4105 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM2, "EStBegin" );
  3698 		if (iBusWidthAndClock & E8BitMask)
  4106 		if (iBusWidthAndClock & E8BitMask)
  3699 			{
  4107 			{
  3700 			iSpare[0] = EBusWidth8;
  4108 			iSpare[0] = EBusWidth8;
  3701 			__KTRACE_OPT(KPBUS1, Kern::Printf("...Hardware supports 8-bit bus"));
  4109 			__KTRACE_OPT(KPBUS1, Kern::Printf("...Hardware supports 8-bit bus"));
       
  4110 			OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM3, "Hardware supports 8-bit bus" );
  3702 			}
  4111 			}
  3703 		else if(iBusWidthAndClock & E4BitMask)
  4112 		else if(iBusWidthAndClock & E4BitMask)
  3704 			{
  4113 			{
  3705 			iSpare[0] = EBusWidth4;
  4114 			iSpare[0] = EBusWidth4;
  3706 			__KTRACE_OPT(KPBUS1, Kern::Printf("...Hardware supports 4-bit bus"));
  4115 			__KTRACE_OPT(KPBUS1, Kern::Printf("...Hardware supports 4-bit bus"));
       
  4116 			OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM4, "Hardware supports 4-bit bus" );
  3707 			}
  4117 			}
  3708 		else
  4118 		else
  3709 			{
  4119 			{
  3710 			__KTRACE_OPT(KPBUS1, Kern::Printf("...Hardware supports 1-bit bus"));
  4120 			__KTRACE_OPT(KPBUS1, Kern::Printf("...Hardware supports 1-bit bus"));
       
  4121 			OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM5, "Hardware supports 1-bit bus" );
  3711 			iSpare[0] = EBusWidth1;
  4122 			iSpare[0] = EBusWidth1;
  3712 			}
  4123 			}
  3713 
  4124 
  3714 		// remove KMMCModeCardControlled so that IssueCommandCheckResponseSMST doesn't try to 
  4125 		// remove KMMCModeCardControlled so that IssueCommandCheckResponseSMST doesn't try to 
  3715 		// override the bus width & clock rate using the card settings
  4126 		// override the bus width & clock rate using the card settings
  3717 
  4128 
  3718 	SMF_STATE(EstSendBusTest_W)
  4129 	SMF_STATE(EstSendBusTest_W)
  3719 		//
  4130 		//
  3720 		// Issue the BUSTEST_W command
  4131 		// Issue the BUSTEST_W command
  3721 		//
  4132 		//
       
  4133 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM6, "EStSendBusTest_W" );
  3722 		TInt length = 2;
  4134 		TInt length = 2;
  3723 		switch(iSpare[0])
  4135 		switch(iSpare[0])
  3724 			{
  4136 			{
  3725 			case EBusWidth8:
  4137 			case EBusWidth8:
  3726 				// Set the host to 8-bit mode
  4138 				// Set the host to 8-bit mode
  3727 				__KTRACE_OPT(KPBUS1, Kern::Printf("BUSTEST : EBusWidth8"));
  4139 				__KTRACE_OPT(KPBUS1, Kern::Printf("BUSTEST : EBusWidth8"));
       
  4140 				OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM7, "BUSTEST : EBusWidth8" );
  3728 				DoSetBusWidth(EBusWidth8);
  4141 				DoSetBusWidth(EBusWidth8);
  3729 				iPSLBuf[0] = 0x55;
  4142 				iPSLBuf[0] = 0x55;
  3730 				iPSLBuf[1] = 0xaa;
  4143 				iPSLBuf[1] = 0xaa;
  3731 				break;
  4144 				break;
  3732 
  4145 
  3733 			case EBusWidth4:
  4146 			case EBusWidth4:
  3734 				// Set the host to 4-bit mode
  4147 				// Set the host to 4-bit mode
  3735 				__KTRACE_OPT(KPBUS1, Kern::Printf("BUSTEST : EBusWidth4"));
  4148 				__KTRACE_OPT(KPBUS1, Kern::Printf("BUSTEST : EBusWidth4"));
       
  4149 				OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM8, "BUSTEST : EBusWidth4" );
  3736 				DoSetBusWidth(EBusWidth4);
  4150 				DoSetBusWidth(EBusWidth4);
  3737 				iPSLBuf[0] = 0x5a;
  4151 				iPSLBuf[0] = 0x5a;
  3738 				iPSLBuf[1] = 0x00;
  4152 				iPSLBuf[1] = 0x00;
  3739 				break;
  4153 				break;
  3740 
  4154 
  3741 			case EBusWidth1:
  4155 			case EBusWidth1:
  3742 			default:
  4156 			default:
  3743 				// Set the host to 1-bit mode
  4157 				// Set the host to 1-bit mode
  3744 				__KTRACE_OPT(KPBUS1, Kern::Printf("BUSTEST : EBusWidth1"));
  4158 				__KTRACE_OPT(KPBUS1, Kern::Printf("BUSTEST : EBusWidth1"));
       
  4159 				OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM9, "BUSTEST : EBusWidth1" );
  3745 				DoSetBusWidth(EBusWidth1);
  4160 				DoSetBusWidth(EBusWidth1);
  3746 				iPSLBuf[0] = 0x40;
  4161 				iPSLBuf[0] = 0x40;
  3747 				iPSLBuf[1] = 0x00;
  4162 				iPSLBuf[1] = 0x00;
  3748 				break;
  4163 				break;
  3749 			}	
  4164 			}	
  3750 
  4165 
  3751 		// Issue BUSTEST_W
  4166 		// Issue BUSTEST_W
  3752 
  4167 
  3753 		__KTRACE_OPT(KPBUS1, Kern::Printf("...Issue BUSTEST_W [%02x:%02x]", iPSLBuf[1], iPSLBuf[0]));
  4168 		__KTRACE_OPT(KPBUS1, Kern::Printf("...Issue BUSTEST_W [%02x:%02x]", iPSLBuf[1], iPSLBuf[0]));
       
  4169 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM10, "Issue BUSTEST_W [%02x:%02x]", (TUint) iPSLBuf[1], (TUint) iPSLBuf[0] );
  3754 
  4170 
  3755 		m.SetTraps(KMMCErrDataCRC); // CRC check is optional for BUSTEST
  4171 		m.SetTraps(KMMCErrDataCRC); // CRC check is optional for BUSTEST
  3756 
  4172 
  3757 		s.FillCommandDesc(ECmdBustest_W);
  4173 		s.FillCommandDesc(ECmdBustest_W);
  3758 		s.FillCommandArgs(0, length, &iPSLBuf[0], length);
  4174 		s.FillCommandArgs(0, length, &iPSLBuf[0], length);
  3760 
  4176 
  3761 	SMF_STATE(EstSendBusTest_R)
  4177 	SMF_STATE(EstSendBusTest_R)
  3762 		//
  4178 		//
  3763 		// Issue the BUSTEST_R command
  4179 		// Issue the BUSTEST_R command
  3764 		//
  4180 		//
       
  4181 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM11, "EStSendBusTest_R" );
  3765 		__KTRACE_OPT(KPBUS1, Kern::Printf("...got BUSTEST_W response : %02x", err));
  4182 		__KTRACE_OPT(KPBUS1, Kern::Printf("...got BUSTEST_W response : %02x", err));
       
  4183 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM12, "Got BUSTEST_W response=0x%02x", err );
  3766 
  4184 
  3767 		if(err == KMMCErrNone || err == KMMCErrDataCRC)
  4185 		if(err == KMMCErrNone || err == KMMCErrDataCRC)
  3768 			{
  4186 			{
  3769 			__KTRACE_OPT(KPBUS1, Kern::Printf("...sending BUSTEST_R"));
  4187 			__KTRACE_OPT(KPBUS1, Kern::Printf("...sending BUSTEST_R"));
       
  4188 			OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM13, "Sending BUSTEST_R" );
  3770 
  4189 
  3771 			iPSLBuf[0] = 0;
  4190 			iPSLBuf[0] = 0;
  3772 			iPSLBuf[1] = 0;
  4191 			iPSLBuf[1] = 0;
  3773 
  4192 
  3774 			s.FillCommandDesc(ECmdBustest_R);
  4193 			s.FillCommandDesc(ECmdBustest_R);
  3775 			s.FillCommandArgs(0, 2, &iPSLBuf[0], 2);
  4194 			s.FillCommandArgs(0, 2, &iPSLBuf[0], 2);
  3776 			SMF_INVOKES(IssueCommandCheckResponseSMST, EstGotBusTest_R)
  4195 			SMF_INVOKES(IssueCommandCheckResponseSMST, EstGotBusTest_R)
  3777 			}
  4196 			}
  3778 		else
  4197 		else
  3779 			{
  4198 			{
       
  4199 			OstTraceFunctionExitExt( DMMCSTACK_EXECBUSTESTSM_EXIT, this, (TInt) KMMCErrNotSupported );
  3780 			SMF_RETURN(KMMCErrNotSupported);
  4200 			SMF_RETURN(KMMCErrNotSupported);
  3781 			}
  4201 			}
  3782 
  4202 
  3783 	SMF_STATE(EstGotBusTest_R)
  4203 	SMF_STATE(EstGotBusTest_R)
  3784 		//
  4204 		//
  3785 		// Validate the BUSTEST_R data with that issued by BUSTEST_W
  4205 		// Validate the BUSTEST_R data with that issued by BUSTEST_W
  3786 		//
  4206 		//
       
  4207 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM14, "EStGotBusTest_R" );
  3787 		__KTRACE_OPT(KPBUS1, Kern::Printf("...got BUSTEST_R response [%02x:%02x] : err(%02x)", iPSLBuf[1], iPSLBuf[0], err));
  4208 		__KTRACE_OPT(KPBUS1, Kern::Printf("...got BUSTEST_R response [%02x:%02x] : err(%02x)", iPSLBuf[1], iPSLBuf[0], err));
       
  4209 		OstTraceExt3( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM15, "Got BUSTEST_R response [%02x:%02x]; err(%x)", (TUint) iPSLBuf[1], (TUint) iPSLBuf[0], (TUint) err );
  3788 
  4210 
  3789 		TBool retry = EFalse;
  4211 		TBool retry = EFalse;
  3790 		TBool is52MHzSupported = (iBusWidthAndClock & E52MhzMask) ? (TBool)ETrue : (TBool)EFalse;
  4212 		TBool is52MHzSupported = (iBusWidthAndClock & E52MhzMask) ? (TBool)ETrue : (TBool)EFalse;
  3791 
  4213 
  3792 		switch(iSpare[0])
  4214 		switch(iSpare[0])
  3843 			}	
  4265 			}	
  3844 
  4266 
  3845 		if(retry)
  4267 		if(retry)
  3846 			{
  4268 			{
  3847 			__KTRACE_OPT(KPBUS1, Kern::Printf("...BUSTEST Failed : Retry"));
  4269 			__KTRACE_OPT(KPBUS1, Kern::Printf("...BUSTEST Failed : Retry"));
       
  4270 			OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM16, "BUSTEST Failed : Retry" );
  3848 			SMF_GOTOS(EstSendBusTest_W);
  4271 			SMF_GOTOS(EstSendBusTest_W);
  3849 			}
  4272 			}
  3850 		
  4273 		
  3851 		switch(iBusWidthAndClock)
  4274 		switch(iBusWidthAndClock)
  3852 			{
  4275 			{
  3864 				iCardArray->CardP(iSelectedCardIndex)->SetBusWidth(8);
  4287 				iCardArray->CardP(iSelectedCardIndex)->SetBusWidth(8);
  3865 				break;
  4288 				break;
  3866 			}
  4289 			}
  3867 
  4290 
  3868 		__KTRACE_OPT(KPBUS1, Kern::Printf("...BUSTEST OK"));
  4291 		__KTRACE_OPT(KPBUS1, Kern::Printf("...BUSTEST OK"));
       
  4292 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM17, "BUSTEST OK" );
  3869 
  4293 
  3870 		DoSetBusWidth(EBusWidth1);
  4294 		DoSetBusWidth(EBusWidth1);
  3871 
  4295 
  3872 	SMF_STATE(EStExit)
  4296 	SMF_STATE(EStExit)
       
  4297 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECBUSTESTSM18, "EStExit" );
  3873 		iConfig.SetMode( KMMCModeCardControlled );
  4298 		iConfig.SetMode( KMMCModeCardControlled );
  3874 
  4299 
  3875 	SMF_END
  4300 	SMF_END
  3876 	}
  4301 	}
  3877 
  4302 
  3883  * The default implementation here does nothing
  4308  * The default implementation here does nothing
  3884  * Replaces Dummy2()
  4309  * Replaces Dummy2()
  3885 */
  4310 */
  3886 EXPORT_C void DMMCStack::GetInterface(TInterfaceId aInterfaceId, MInterface*& aInterfacePtr)
  4311 EXPORT_C void DMMCStack::GetInterface(TInterfaceId aInterfaceId, MInterface*& aInterfacePtr)
  3887 	{
  4312 	{
       
  4313 	OstTraceFunctionEntry1( DMMCSTACK_GETINTERFACE_ENTRY, this );
  3888 	if (aInterfaceId == KInterfaceCancelSession)
  4314 	if (aInterfaceId == KInterfaceCancelSession)
  3889 		{
  4315 		{
  3890 		DMMCSession* session = (DMMCSession*&) aInterfacePtr;
  4316 		DMMCSession* session = (DMMCSession*&) aInterfacePtr;
  3891 		Abort(session);
  4317 		Abort(session);
  3892 		UnlockStack(session);
  4318 		UnlockStack(session);
  3893 		}
  4319 		}
  3894 
  4320 
       
  4321 	OstTraceFunctionExit1( DMMCSTACK_GETINTERFACE_EXIT, this );
  3895 	}
  4322 	}
  3896 
  4323 
  3897 
  4324 
  3898 TMMCErr DMMCStack::GoIdleSM()
  4325 TMMCErr DMMCStack::GoIdleSM()
  3899 /**
  4326 /**
  3909 			EStIdleEndCheck,
  4336 			EStIdleEndCheck,
  3910 			EStEnd
  4337 			EStEnd
  3911 			};
  4338 			};
  3912 
  4339 
  3913 		DMMCSession& s=Session();
  4340 		DMMCSession& s=Session();
       
  4341 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_GOIDLESM1, "Current session=0x%x", &s );
  3914 
  4342 
  3915 	SMF_BEGIN
  4343 	SMF_BEGIN
  3916 
  4344 
       
  4345 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_GOIDLESM2, "EStBegin" );
  3917 		s.FillCommandDesc( ECmdGoIdleState, 0 );
  4346 		s.FillCommandDesc( ECmdGoIdleState, 0 );
  3918 		iCxPollRetryCount = KMMCIdleCommandsAtRestart;
  4347 		iCxPollRetryCount = KMMCIdleCommandsAtRestart;
  3919 
  4348 
  3920 	SMF_STATE(EStIdleLoop)
  4349 	SMF_STATE(EStIdleLoop)
       
  4350 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_GOIDLESM3, "EStIdleLoop" );
  3921 		SMF_INVOKES( ExecCommandSMST, EStIdleEndCheck )
  4351 		SMF_INVOKES( ExecCommandSMST, EStIdleEndCheck )
  3922 
  4352 
  3923 	SMF_STATE(EStIdleEndCheck)
  4353 	SMF_STATE(EStIdleEndCheck)
  3924 
  4354 
       
  4355 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_GOIDLESM4, "EStIdleEndCheck" );
  3925 		if( --iCxPollRetryCount > 0 )
  4356 		if( --iCxPollRetryCount > 0 )
  3926 			SMF_INVOKES( RetryGapTimerSMST, EStIdleLoop )
  4357 			SMF_INVOKES( RetryGapTimerSMST, EStIdleLoop )
  3927 
  4358 
  3928 		iStackState &= ~(KMMCStackStateDoDeselect|KMMCStackStateBusInconsistent);
  4359 		iStackState &= ~(KMMCStackStateDoDeselect|KMMCStackStateBusInconsistent);
  3929 		iSelectedCard = 0;
  4360 		iSelectedCard = 0;
  3963 			EStEnd
  4394 			EStEnd
  3964 			};
  4395 			};
  3965 
  4396 
  3966 		DMMCSession& s=Session();
  4397 		DMMCSession& s=Session();
  3967 		DMMCPsu* psu=(DMMCPsu*)iSocket->iVcc;
  4398 		DMMCPsu* psu=(DMMCPsu*)iSocket->iVcc;
       
  4399 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM1, "Current session=0x%x", &s );
  3968 
  4400 
  3969 	SMF_BEGIN
  4401 	SMF_BEGIN
  3970 
  4402 
       
  4403 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM2, "EStBegin" );
  3971 		iRCAPool.ReleaseUnlocked();
  4404 		iRCAPool.ReleaseUnlocked();
  3972 		iCxPollRetryCount = 0; // Reset max number of poll attempts on card busy
  4405 		iCxPollRetryCount = 0; // Reset max number of poll attempts on card busy
  3973 
  4406 
  3974 		SMF_INVOKES( GoIdleSMST, EStIdle )
  4407 		SMF_INVOKES( GoIdleSMST, EStIdle )
  3975 
  4408 
  3976 	SMF_STATE(EStIdle)
  4409 	SMF_STATE(EStIdle)
  3977 
  4410 
       
  4411 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM3, "EStIdle" );
  3978 		// If this platform doesn't support an adjustable voltage PSU then there is
  4412 		// If this platform doesn't support an adjustable voltage PSU then there is
  3979 		// no point in interogating the card(s) present for their supported range
  4413 		// no point in interogating the card(s) present for their supported range
  3980 		if ( !(psu->VoltageSupported()&KMMCAdjustableOpVoltage) )
  4414 		if ( !(psu->VoltageSupported()&KMMCAdjustableOpVoltage) )
  3981 			{
  4415 			{
  3982 			// if the PSU isn't adjustable then it can't support low voltage mode
  4416 			// if the PSU isn't adjustable then it can't support low voltage mode
  3991 
  4425 
  3992 		SMF_INVOKES( ExecCommandSMST, EStFullRangeDone )
  4426 		SMF_INVOKES( ExecCommandSMST, EStFullRangeDone )
  3993 
  4427 
  3994 	SMF_STATE(EStFullRangeDone)
  4428 	SMF_STATE(EStFullRangeDone)
  3995 
  4429 
       
  4430 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM4, "EStFullRangeDone" );
  3996 		if( err )												// If timeout
  4431 		if( err )												// If timeout
  3997 			{
  4432 			{
  3998 			iConfig.RemoveMode( KMMCModeEnableTimeOutRetry );	// There is no point to do it second time
  4433 			iConfig.RemoveMode( KMMCModeEnableTimeOutRetry );	// There is no point to do it second time
  3999 			}
  4434 			}
  4000 		else
  4435 		else
  4006 
  4441 
  4007 			if (newrange==0)
  4442 			if (newrange==0)
  4008 				{
  4443 				{
  4009 				// One or more card is incompatible with our h/w
  4444 				// One or more card is incompatible with our h/w
  4010 				if (iMaxCardsInStack<=1)
  4445 				if (iMaxCardsInStack<=1)
  4011 					return( KMMCErrNotSupported ); // There can only be one card - we don't support it.
  4446 				    {
       
  4447 					OstTraceFunctionExitExt( DMMCSTACK_ACQUIRESTACKSM_EXIT1, this, (TInt) KMMCErrNotSupported );
       
  4448 					return KMMCErrNotSupported; // There can only be one card - we don't support it.
       
  4449 				    }
  4012 				else
  4450 				else
  4013 					// Force the default range
  4451 					// Force the default range
  4014 					iCurrentOpRange=(psu->VoltageSupported() & ~KMMCAdjustableOpVoltage);  
  4452 					iCurrentOpRange=(psu->VoltageSupported() & ~KMMCAdjustableOpVoltage);  
  4015 				}
  4453 				}
  4016 			else
  4454 			else
  4024 			SMF_INVOKES( SwitchToLowVoltageSMST, EStSetRangeLoop )
  4462 			SMF_INVOKES( SwitchToLowVoltageSMST, EStSetRangeLoop )
  4025 			}
  4463 			}
  4026 
  4464 
  4027 	SMF_STATE(EStSetRangeLoop)
  4465 	SMF_STATE(EStSetRangeLoop)
  4028 
  4466 
       
  4467 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM5, "EStSetRangeLoop" );
  4029 		// Repeat CMD1 this time setting Current Op Range
  4468 		// Repeat CMD1 this time setting Current Op Range
  4030 		s.Command().iArgument = iCurrentOpRange | KMMCOCRAccessModeHCS | KMMCOCRBusy;
  4469 		s.Command().iArgument = iCurrentOpRange | KMMCOCRAccessModeHCS | KMMCOCRBusy;
  4031 
  4470 
  4032 		m.SetTraps( KMMCErrResponseTimeOut );
  4471 		m.SetTraps( KMMCErrResponseTimeOut );
  4033 
  4472 
  4034 		SMF_INVOKES( ExecCommandSMST, EStSetRangeBusyCheck )
  4473 		SMF_INVOKES( ExecCommandSMST, EStSetRangeBusyCheck )
  4035 
  4474 
  4036 	SMF_STATE(EStSetRangeBusyCheck)
  4475 	SMF_STATE(EStSetRangeBusyCheck)
  4037 
  4476 
       
  4477 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM6, "EStSetRangeLoop" );
  4038 		if( !err )
  4478 		if( !err )
  4039 			{
  4479 			{
  4040 			// Bit31 of the OCR response is low if the cards are still powering up.
  4480 			// Bit31 of the OCR response is low if the cards are still powering up.
  4041 			const TUint32 ocrResponse = TMMC::BigEndian32(s.ResponseP());
  4481 			const TUint32 ocrResponse = TMMC::BigEndian32(s.ResponseP());
  4042 
  4482 
  4043 			const TBool isBusy = ((ocrResponse & KMMCOCRBusy) == 0);
  4483 			const TBool isBusy = ((ocrResponse & KMMCOCRBusy) == 0);
  4044 			__KTRACE_OPT(KPBUS1,Kern::Printf("-mmc:upd:bsy%d", isBusy));
  4484 			__KTRACE_OPT(KPBUS1,Kern::Printf("-mmc:upd:bsy%d", isBusy));
       
  4485 			OstTrace1( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM7, "MMC busy status=%d", isBusy );
  4045 
  4486 
  4046 			if (isBusy)	
  4487 			if (isBusy)	
  4047 				{
  4488 				{
  4048 				// Some cards are still busy powering up. Check if we should timeout
  4489 				// Some cards are still busy powering up. Check if we should timeout
  4049 				if ( ++iCxPollRetryCount > iConfig.OpCondBusyTimeout() )
  4490 				if ( ++iCxPollRetryCount > iConfig.OpCondBusyTimeout() )
  4050 					return( KMMCErrBusTimeOut );
  4491 				    {
       
  4492 					OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM8, "Peripheral bus timeout" );
       
  4493 					OstTraceFunctionExitExt( DMMCSTACK_ACQUIRESTACKSM_EXIT2, this, (TInt) KMMCErrBusTimeOut );
       
  4494 					return KMMCErrBusTimeOut;
       
  4495 				    }
  4051 				m.ResetTraps();
  4496 				m.ResetTraps();
  4052 				SMF_INVOKES( RetryGapTimerSMST, EStSetRangeLoop )
  4497 				SMF_INVOKES( RetryGapTimerSMST, EStSetRangeLoop )
  4053 				}
  4498 				}
  4054 
  4499 
  4055 			iSpare[0] = 0;
  4500 			iSpare[0] = 0;
  4056 
  4501 
  4057 			if((ocrResponse & KMMCOCRAccessModeMask) == KMMCOCRAccessModeHCS)
  4502 			if((ocrResponse & KMMCOCRAccessModeMask) == KMMCOCRAccessModeHCS)
  4058 				{
  4503 				{
  4059 				__KTRACE_OPT(KPBUS1, Kern::Printf("Found large MMC card."));
  4504 				__KTRACE_OPT(KPBUS1, Kern::Printf("Found large MMC card."));
       
  4505 				OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM9, "Found large MMC card" );
  4060 				iSpare[0] = KMMCardIsHighCapacity;
  4506 				iSpare[0] = KMMCardIsHighCapacity;
  4061 				}
  4507 				}
  4062 			}
  4508 			}
  4063 
  4509 
  4064 		iConfig.SetMode( EffectiveModes(s.iConfig) & KMMCModeEnableTimeOutRetry );	// Restore original setting
  4510 		iConfig.SetMode( EffectiveModes(s.iConfig) & KMMCModeEnableTimeOutRetry );	// Restore original setting
  4065 
  4511 
  4066 		// All cards are now ready and notified of the voltage range - ask ASSP to set it up
  4512 		// All cards are now ready and notified of the voltage range - ask ASSP to set it up
  4067 		psu->SetVoltage(iCurrentOpRange);
  4513 		psu->SetVoltage(iCurrentOpRange);
  4068 		if (psu->SetState(EPsuOnFull) != KErrNone)
  4514 		if (psu->SetState(EPsuOnFull) != KErrNone)
  4069 			return(KMMCErrHardware);
  4515 		    {
       
  4516 			OstTraceFunctionExitExt( DMMCSTACK_ACQUIRESTACKSM_EXIT3, this, (TInt) KMMCErrHardware );
       
  4517 			return KMMCErrHardware;
       
  4518 		    }
  4070 
  4519 
  4071 		iCardArray->InitNewCardScan(); // Collect new cards, one by one
  4520 		iCardArray->InitNewCardScan(); // Collect new cards, one by one
  4072 
  4521 
  4073 	SMF_STATE(EStCIDLoop)
  4522 	SMF_STATE(EStCIDLoop)
  4074 
  4523 
       
  4524 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM10, "EStCIDLoop" );
  4075 		if ( iCardArray->NewCardCount() >= iMaxCardsInStack )
  4525 		if ( iCardArray->NewCardCount() >= iMaxCardsInStack )
  4076 			SMF_GOTOS( EStCIDsDone )
  4526 			SMF_GOTOS( EStCIDsDone )
  4077 
  4527 
  4078 		s.FillCommandDesc( ECmdAllSendCID, 0 );
  4528 		s.FillCommandDesc( ECmdAllSendCID, 0 );
  4079 		m.SetTraps( KMMCErrResponseTimeOut );
  4529 		m.SetTraps( KMMCErrResponseTimeOut );
  4080 
  4530 
  4081 		SMF_INVOKES( ExecCommandSMST, EStSendCIDIssued )
  4531 		SMF_INVOKES( ExecCommandSMST, EStSendCIDIssued )
  4082 
  4532 
  4083 	SMF_STATE(EStSendCIDIssued)
  4533 	SMF_STATE(EStSendCIDIssued)
  4084 
  4534 
       
  4535 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM11, "EStSendCIDIssued" );
  4085 		if( !err )
  4536 		if( !err )
  4086 			{
  4537 			{
  4087 			// A card responded with a CID. Create a new card entry in the card array 
  4538 			// A card responded with a CID. Create a new card entry in the card array 
  4088 			// and initialise this entry with the CID. The card array allocates it an
  4539 			// and initialise this entry with the CID. The card array allocates it an
  4089 			// RCA, either the old RCA if we have seen this card before, or a new one.
  4540 			// RCA, either the old RCA if we have seen this card before, or a new one.
  4096 			SMF_INVOKES( ExecCommandSMST, EStCIDLoop )
  4547 			SMF_INVOKES( ExecCommandSMST, EStCIDLoop )
  4097 			}
  4548 			}
  4098 
  4549 
  4099 	SMF_STATE(EStCIDsDone)
  4550 	SMF_STATE(EStCIDsDone)
  4100 
  4551 
       
  4552 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM12, "EStCIDsDone" );
  4101 		// All cards are initialised; get all their CSDs
  4553 		// All cards are initialised; get all their CSDs
  4102 		m.ResetTraps();				// We are no longer processing any errors
  4554 		m.ResetTraps();				// We are no longer processing any errors
  4103 
  4555 
  4104 		if( iCardArray->NewCardCount()==0 )
  4556 		if( iCardArray->NewCardCount()==0 )
  4105 			SMF_EXIT						// No new cards acquired
  4557 			SMF_EXIT						// No new cards acquired
  4107 		iCxCardCount=0;							// New cards index
  4559 		iCxCardCount=0;							// New cards index
  4108 		s.FillCommandDesc( ECmdSendCSD );
  4560 		s.FillCommandDesc( ECmdSendCSD );
  4109 
  4561 
  4110 	SMF_STATE(EStCSDLoop)
  4562 	SMF_STATE(EStCSDLoop)
  4111 
  4563 
       
  4564 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM13, "EStCSDLoop" );
  4112 		s.Command().iArgument = TMMCArgument(iCardArray->NewCardP(iCxCardCount)->iRCA);
  4565 		s.Command().iArgument = TMMCArgument(iCardArray->NewCardP(iCxCardCount)->iRCA);
  4113 		SMF_INVOKES( ExecCommandSMST, EStSendCSDDone )
  4566 		SMF_INVOKES( ExecCommandSMST, EStSendCSDDone )
  4114 
  4567 
  4115 	SMF_STATE(EStSendCSDDone)
  4568 	SMF_STATE(EStSendCSDDone)
  4116 
  4569 
       
  4570 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM14, "EStSendCSDDone" );
  4117 		// Store the CSD in the new card entry
  4571 		// Store the CSD in the new card entry
  4118 		TMMCard* cardP = iCardArray->NewCardP(iCxCardCount);
  4572 		TMMCard* cardP = iCardArray->NewCardP(iCxCardCount);
  4119 		cardP->iCSD = s.ResponseP();
  4573 		cardP->iCSD = s.ResponseP();
  4120 
  4574 
  4121 		// Perform MMC Specific parsing of the CSD structure
  4575 		// Perform MMC Specific parsing of the CSD structure
  4136 
  4590 
  4137 		SMF_NEXTS(EStMergeCards)
  4591 		SMF_NEXTS(EStMergeCards)
  4138 
  4592 
  4139 	SMF_STATE(EStMergeCards)
  4593 	SMF_STATE(EStMergeCards)
  4140 
  4594 
       
  4595 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM15, "EStMergeCards" );
  4141 		// Merging the old card info with newly acquired cards (we will ask each card for status
  4596 		// Merging the old card info with newly acquired cards (we will ask each card for status
  4142 		// to determine whether it's really present later).
  4597 		// to determine whether it's really present later).
  4143 		if( SchedGetOnDFC() )
  4598 		if( SchedGetOnDFC() )
  4144 			SMF_WAIT
  4599 			SMF_WAIT
  4145 		if ( iCardArray->MergeCards(ETrue)==KErrNone )
  4600 		if ( iCardArray->MergeCards(ETrue)==KErrNone )
  4147 
  4602 
  4148 		SMF_INVOKES( CheckStackSMST, EStReMergeCards ) // No space so check if any cards have gone
  4603 		SMF_INVOKES( CheckStackSMST, EStReMergeCards ) // No space so check if any cards have gone
  4149 
  4604 
  4150 	SMF_STATE(EStReMergeCards)
  4605 	SMF_STATE(EStReMergeCards)
  4151 
  4606 
       
  4607 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ACQUIRESTACKSM16, "EStReMergeCards" );
  4152 		if( SchedGetOnDFC() )
  4608 		if( SchedGetOnDFC() )
  4153 			SMF_WAIT
  4609 			SMF_WAIT
  4154 		if ( iCardArray->MergeCards(EFalse)!=KErrNone ) // There are more cards in the stack than we can handle
  4610 		if ( iCardArray->MergeCards(EFalse)!=KErrNone ) // There are more cards in the stack than we can handle
  4155 			return(KMMCErrTooManyCards);
  4611 		    {
       
  4612 			OstTraceFunctionExitExt( DMMCSTACK_ACQUIRESTACKSM_EXIT4, this, (TInt) KMMCErrTooManyCards );
       
  4613 			return KMMCErrTooManyCards;
       
  4614 		    }
  4156 
  4615 
  4157 	SMF_END
  4616 	SMF_END
  4158 	}
  4617 	}
  4159 
  4618 
  4160 
  4619 
  4174 		};
  4633 		};
  4175 
  4634 
  4176 	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:SwLowVolt"));
  4635 	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:SwLowVolt"));
  4177 
  4636 
  4178 	DMMCPsu* psu=(DMMCPsu*)iSocket->iVcc;
  4637 	DMMCPsu* psu=(DMMCPsu*)iSocket->iVcc;
       
  4638 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_SWITCHTOLOWVOLTAGESM1, "Current PSU=0x%x", psu );
  4179 
  4639 
  4180 	SMF_BEGIN
  4640 	SMF_BEGIN
       
  4641 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_SWITCHTOLOWVOLTAGESM2, "EStBegin" );
  4181 		// turn power off
  4642 		// turn power off
  4182 		DoPowerDown();
  4643 		DoPowerDown();
  4183 		psu->SetState(EPsuOff);
  4644 		psu->SetState(EPsuOff);
  4184 
  4645 
  4185 		// turn power back on in low voltage mode
  4646 		// turn power back on in low voltage mode
  4186 		psu->SetVoltage(iCurrentOpRange);
  4647 		psu->SetVoltage(iCurrentOpRange);
  4187 		if (psu->SetState(EPsuOnFull) != KErrNone)
  4648 		if (psu->SetState(EPsuOnFull) != KErrNone)
  4188 			return(KMMCErrHardware);
  4649 		    {
       
  4650 			OstTraceFunctionExitExt( DMMCSTACK_SWITCHTOLOWVOLTAGESM_EXIT, this, (TInt) KMMCErrHardware );
       
  4651 			return KMMCErrHardware;
       
  4652 		    }
  4189 
  4653 
  4190 		SMF_INVOKES( DoPowerUpSMST, EStPoweredUp )
  4654 		SMF_INVOKES( DoPowerUpSMST, EStPoweredUp )
  4191 
  4655 
  4192 	SMF_STATE(EStPoweredUp)
  4656 	SMF_STATE(EStPoweredUp)
       
  4657 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_SWITCHTOLOWVOLTAGESM3, "EStPoweredUp" );
  4193 		// turn the clock back on
  4658 		// turn the clock back on
  4194 		SMF_INVOKES( InitClockOnSMST, EStClockOn )	// Feed init clock to the bus
  4659 		SMF_INVOKES( InitClockOnSMST, EStClockOn )	// Feed init clock to the bus
  4195 
  4660 
  4196 	SMF_STATE(EStClockOn)
  4661 	SMF_STATE(EStClockOn)
       
  4662 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_SWITCHTOLOWVOLTAGESM4, "EStClockOn" );
  4197 		// wait for 1ms and then 74 clock cycles
  4663 		// wait for 1ms and then 74 clock cycles
  4198 		// 74 clock cylces @ 400 Khz = 74 / 400,000 = 0.000185 secs = 0.185 ms
  4664 		// 74 clock cylces @ 400 Khz = 74 / 400,000 = 0.000185 secs = 0.185 ms
  4199 		// so total wait = 1.185 ms
  4665 		// so total wait = 1.185 ms
  4200 		SMF_INVOKES(LowVoltagePowerupTimerSMST, EStEnd);
  4666 		SMF_INVOKES(LowVoltagePowerupTimerSMST, EStEnd);
  4201 
  4667 
  4215 			EStFinish,
  4681 			EStFinish,
  4216 			EStEnd
  4682 			EStEnd
  4217 			};
  4683 			};
  4218 
  4684 
  4219 		DMMCSession& s=Session();
  4685 		DMMCSession& s=Session();
       
  4686 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CIMCHECKSTACKSM1, "Current session=0x%x", &s );
  4220 
  4687 
  4221 	SMF_BEGIN
  4688 	SMF_BEGIN
  4222 
  4689 
       
  4690 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMCHECKSTACKSM2, "EStBegin" );
  4223 		// This macro works naked and must not be preempted
  4691 		// This macro works naked and must not be preempted
  4224 		iConfig.RemoveMode( KMMCModeEnablePreemption | KMMCModeCardControlled );
  4692 		iConfig.RemoveMode( KMMCModeEnablePreemption | KMMCModeCardControlled );
  4225 		s.iState |= KMMCSessStateInProgress;
  4693 		s.iState |= KMMCSessStateInProgress;
  4226 
  4694 
  4227 		SMF_INVOKES( CheckStackSMST, EStFinish )
  4695 		SMF_INVOKES( CheckStackSMST, EStFinish )
  4228 
  4696 
  4229 	SMF_STATE(EStFinish)
  4697 	SMF_STATE(EStFinish)
  4230 
  4698 
       
  4699 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMCHECKSTACKSM3, "EStFinish" );
  4231 		s.iState &= ~KMMCSessStateInProgress;
  4700 		s.iState &= ~KMMCSessStateInProgress;
  4232 
  4701 
  4233 	SMF_END
  4702 	SMF_END
  4234 	}
  4703 	}
  4235 
  4704 
  4248 			EStCardDeselected,
  4717 			EStCardDeselected,
  4249 			EStEnd
  4718 			EStEnd
  4250 			};
  4719 			};
  4251 
  4720 
  4252 		DMMCSession& s=Session();
  4721 		DMMCSession& s=Session();
       
  4722 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CHECKSTACKSM1, "Current session=0x%x", &s );
  4253 
  4723 
  4254 	SMF_BEGIN
  4724 	SMF_BEGIN
  4255 
  4725 
       
  4726 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKSTACKSM2, "EStBegin" );
  4256 		iCxCardCount=-1;
  4727 		iCxCardCount=-1;
  4257 		m.SetTraps( KMMCErrResponseTimeOut );
  4728 		m.SetTraps( KMMCErrResponseTimeOut );
  4258 
  4729 
  4259 	SMF_STATE(EStLoop)
  4730 	SMF_STATE(EStLoop)
  4260 
  4731 
       
  4732 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKSTACKSM3, "EStLoop" );
  4261 		if ( ++iCxCardCount == (TInt)iMaxCardsInStack )
  4733 		if ( ++iCxCardCount == (TInt)iMaxCardsInStack )
  4262 			SMF_EXIT
  4734 			SMF_EXIT
  4263 
  4735 
  4264 		if ( !iCardArray->CardP(iCxCardCount)->IsPresent() )
  4736 		if ( !iCardArray->CardP(iCxCardCount)->IsPresent() )
  4265 			SMF_GOTOS( EStLoop )					// card's not present
  4737 			SMF_GOTOS( EStLoop )					// card's not present
  4268 		s.FillCommandDesc(ECmdSelectCard, arg);
  4740 		s.FillCommandDesc(ECmdSelectCard, arg);
  4269 		SMF_INVOKES(ExecCommandSMST, EStCardSelectedGotStatus)
  4741 		SMF_INVOKES(ExecCommandSMST, EStCardSelectedGotStatus)
  4270 
  4742 
  4271 	SMF_STATE(EStCardSelectedGotStatus)
  4743 	SMF_STATE(EStCardSelectedGotStatus)
  4272 
  4744 
       
  4745 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKSTACKSM4, "EStCardSelectedGotStatus" );
  4273 		__KTRACE_OPT(KPBUS1, Kern::Printf("-mst:cssm:err%08x", err));
  4746 		__KTRACE_OPT(KPBUS1, Kern::Printf("-mst:cssm:err%08x", err));
       
  4747 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CHECKSTACKSM5, "err=0x%08x", err );
  4274 
  4748 
  4275 		if(err)
  4749 		if(err)
  4276 			{
  4750 			{
  4277 			// Timeout - the card is no longer present so remove from the card array
  4751 			// Timeout - the card is no longer present so remove from the card array
  4278 			iCardArray->DeclareCardAsGone(iCxCardCount);
  4752 			iCardArray->DeclareCardAsGone(iCxCardCount);
  4291 
  4765 
  4292 		s.FillCommandDesc(ECmdSelectCard, 0);
  4766 		s.FillCommandDesc(ECmdSelectCard, 0);
  4293 		SMF_INVOKES(ExecCommandSMST, EStCardDeselected)
  4767 		SMF_INVOKES(ExecCommandSMST, EStCardDeselected)
  4294 			
  4768 			
  4295 	SMF_STATE(EStCardDeselected)
  4769 	SMF_STATE(EStCardDeselected)
       
  4770 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKSTACKSM6, "EStCardDeselected" );
  4296 		SMF_GOTOS( EStLoop )
  4771 		SMF_GOTOS( EStLoop )
  4297 
  4772 
  4298 	SMF_END
  4773 	SMF_END
  4299 	}
  4774 	}
  4300 
  4775 
  4323 			EStCardDeselected,
  4798 			EStCardDeselected,
  4324 			EStEnd
  4799 			EStEnd
  4325 			};
  4800 			};
  4326 
  4801 
  4327 		DMMCSession& s=Session();
  4802 		DMMCSession& s=Session();
       
  4803 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM1, "Current session=0x%x", &s );
  4328 
  4804 
  4329 	SMF_BEGIN
  4805 	SMF_BEGIN
  4330 
  4806 
       
  4807 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM2, "EStBegin" );
  4331 		iCxCardCount=-1;
  4808 		iCxCardCount=-1;
  4332 		m.SetTraps( KMMCErrResponseTimeOut );
  4809 		m.SetTraps( KMMCErrResponseTimeOut );
  4333 		iMinorBufLen = KMinMinorBufSize;
  4810 		iMinorBufLen = KMinMinorBufSize;
  4334 
  4811 
  4335 	SMF_STATE(EStLoop)
  4812 	SMF_STATE(EStLoop)
  4344 		s.FillCommandDesc(ECmdSelectCard, arg);
  4821 		s.FillCommandDesc(ECmdSelectCard, arg);
  4345 		SMF_INVOKES(ExecCommandSMST, EStCardSelectedGotStatus)
  4822 		SMF_INVOKES(ExecCommandSMST, EStCardSelectedGotStatus)
  4346 
  4823 
  4347 	SMF_STATE(EStCardSelectedGotStatus)
  4824 	SMF_STATE(EStCardSelectedGotStatus)
  4348 
  4825 
       
  4826 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM3, "EStCardSelectedGotStatus" );
  4349 		__KTRACE_OPT(KPBUS1, Kern::Printf("-mst:cssm:err%08x", err));
  4827 		__KTRACE_OPT(KPBUS1, Kern::Printf("-mst:cssm:err%08x", err));
       
  4828 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM4, "err=0x%08x", err );
  4350 		if ( !err )
  4829 		if ( !err )
  4351 			{
  4830 			{
  4352 			TMMCard& card=*(iCardArray->CardP(iCxCardCount));
  4831 			TMMCard& card=*(iCardArray->CardP(iCxCardCount));
  4353 			card.iStatus=s.ResponseP(); // Got the response
  4832 			card.iStatus=s.ResponseP(); // Got the response
  4354 
  4833 
  4398 
  4877 
  4399 		SMF_GOTOS( EStLoop )
  4878 		SMF_GOTOS( EStLoop )
  4400 
  4879 
  4401 	SMF_STATE(EStCheckLockStatus)
  4880 	SMF_STATE(EStCheckLockStatus)
  4402 
  4881 
       
  4882 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM5, "EStCheckLockStatus" );
  4403 		__KTRACE_OPT(KPBUS1, Kern::Printf("-mst:cssm:err%08x", err));
  4883 		__KTRACE_OPT(KPBUS1, Kern::Printf("-mst:cssm:err%08x", err));
       
  4884 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM6, "err=0x%08x", err );
  4404 
  4885 
  4405 		if ((err & KMMCErrUpdPswd) || 
  4886 		if ((err & KMMCErrUpdPswd) || 
  4406 		   ((err & KMMCErrStatus) && (s.LastStatus().Error() == KMMCStatErrLockUnlock)))
  4887 		   ((err & KMMCErrStatus) && (s.LastStatus().Error() == KMMCStatErrLockUnlock)))
  4407 			{
  4888 			{
  4408 			// ECMDLockUnlock (with LockUnlockLockUnlock param) succeeded.
  4889 			// ECMDLockUnlock (with LockUnlockLockUnlock param) succeeded.
  4418 
  4899 
  4419 		s.FillCommandDesc(ECmdSelectCard, 0);
  4900 		s.FillCommandDesc(ECmdSelectCard, 0);
  4420 		SMF_INVOKES(ExecCommandSMST, EStCardDeselected)
  4901 		SMF_INVOKES(ExecCommandSMST, EStCardDeselected)
  4421 			
  4902 			
  4422 	SMF_STATE(EStCardDeselected)
  4903 	SMF_STATE(EStCardDeselected)
       
  4904 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CHECKLOCKSTATUSSM7, "EStCardDeselected" );
  4423 		SMF_GOTOS( EStLoop )
  4905 		SMF_GOTOS( EStLoop )
  4424 
  4906 
  4425 	SMF_END
  4907 	SMF_END
  4426 	}
  4908 	}
  4427 
  4909 
  4463 			EStBegin=0,
  4945 			EStBegin=0,
  4464 			EStEnd
  4946 			EStEnd
  4465 			};
  4947 			};
  4466 #ifdef __EPOC32__
  4948 #ifdef __EPOC32__
  4467 		DMMCSession& s=Session();
  4949 		DMMCSession& s=Session();
       
  4950 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_POLLGAPTIMERSM1, "Current session=0x%x", &s );
  4468 #endif
  4951 #endif
  4469 
  4952 
  4470 	SMF_BEGIN
  4953 	SMF_BEGIN
  4471 
  4954 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_POLLGAPTIMERSM2, "EStBegin" );
  4472 #ifdef __EPOC32__
  4955 #ifdef __EPOC32__
  4473 		s.SynchBlock( KMMCBlockOnPollTimer );
  4956 		s.SynchBlock( KMMCBlockOnPollTimer );
  4474 		s.iPollTimer.OneShot(KMMCPollGapInMilliseconds,EFalse);
  4957 		s.iPollTimer.OneShot(KMMCPollGapInMilliseconds,EFalse);
  4475 
  4958 
  4476 		SMF_EXITWAIT
  4959 		SMF_EXITWAIT
  4495 			EStBegin=0,
  4978 			EStBegin=0,
  4496 			EStEnd
  4979 			EStEnd
  4497 			};
  4980 			};
  4498 #ifdef __EPOC32__
  4981 #ifdef __EPOC32__
  4499 		DMMCSession& s=Session();
  4982 		DMMCSession& s=Session();
       
  4983 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_RETRYGAPTIMERSM1, "Current session=0x%x", &s );
  4500 #endif
  4984 #endif
  4501 
  4985 
  4502 	SMF_BEGIN
  4986 	SMF_BEGIN
  4503 
  4987 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_RETRYGAPTIMERSM2, "EStBegin" );
  4504 #ifdef __EPOC32__
  4988 #ifdef __EPOC32__
  4505 		s.SynchBlock( KMMCBlockOnRetryTimer );
  4989 		s.SynchBlock( KMMCBlockOnRetryTimer );
  4506 		s.iRetryTimer.OneShot(KMMCRetryGapInMilliseconds,EFalse);
  4990 		s.iRetryTimer.OneShot(KMMCRetryGapInMilliseconds,EFalse);
  4507 
  4991 
  4508 		SMF_EXITWAIT
  4992 		SMF_EXITWAIT
  4528 		EStEnd
  5012 		EStEnd
  4529 		};
  5013 		};
  4530 
  5014 
  4531 #ifdef __EPOC32__
  5015 #ifdef __EPOC32__
  4532 	DMMCSession &s = Session();
  5016 	DMMCSession &s = Session();
       
  5017 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_PROGRAMTIMERSM1, "Current session=0x%x", &s );
  4533 #endif
  5018 #endif
  4534 
  5019 
  4535 	SMF_BEGIN
  5020 	SMF_BEGIN
       
  5021 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_PROGRAMTIMERSM2, "EStBegin" );
  4536 #ifdef __EPOC32__
  5022 #ifdef __EPOC32__
  4537 		s.SynchBlock(KMMCBlockOnPgmTimer);
  5023 		s.SynchBlock(KMMCBlockOnPgmTimer);
  4538 		s.iProgramTimer.Cancel();
  5024 		s.iProgramTimer.Cancel();
  4539 		s.iProgramTimer.OneShot(ProgramPeriodInMilliSeconds(),EFalse);
  5025 		s.iProgramTimer.OneShot(ProgramPeriodInMilliSeconds(),EFalse);
  4540 
  5026 
  4560 		EStEnd
  5046 		EStEnd
  4561 		};
  5047 		};
  4562 
  5048 
  4563 #ifdef __EPOC32__
  5049 #ifdef __EPOC32__
  4564 	DMMCSession &s = Session();
  5050 	DMMCSession &s = Session();
       
  5051 	OstTrace1( TRACE_INTERNALS, DMMCSTACK_LOWVOLTAGEPOWERUPTIMERSM1, "Current session=0x%x", &s );
  4565 #endif
  5052 #endif
  4566 
  5053 
  4567 	SMF_BEGIN
  5054 	SMF_BEGIN
       
  5055 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_LOWVOLTAGEPOWERUPTIMERSM2, "EStBegin" );
  4568 #ifdef __EPOC32__
  5056 #ifdef __EPOC32__
  4569 		s.SynchBlock(KMMCBlockOnRetryTimer);
  5057 		s.SynchBlock(KMMCBlockOnRetryTimer);
  4570 		s.iRetryTimer.OneShot(KMMCLowVoltagePowerUpTimeoutInMilliseconds,EFalse);
  5058 		s.iRetryTimer.OneShot(KMMCLowVoltagePowerUpTimeoutInMilliseconds,EFalse);
  4571 
  5059 
  4572 		SMF_EXITWAIT
  5060 		SMF_EXITWAIT
  4614 			EStErrRecover,
  5102 			EStErrRecover,
  4615 			EStEnd
  5103 			EStEnd
  4616 			};
  5104 			};
  4617 
  5105 
  4618 		DMMCSession& s=Session();
  5106 		DMMCSession& s=Session();
       
  5107 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM1, "Current session=0x%x", &s );
  4619 		
  5108 		
  4620 	SMF_BEGIN
  5109 	SMF_BEGIN
  4621 
  5110 
       
  5111 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM2, "EStBegin" );
  4622 		if ( ( s.CardRCA() != 0 ) && ( (s.CardP()->iStatus.State()) == ECardStateSlp) )
  5112 		if ( ( s.CardRCA() != 0 ) && ( (s.CardP()->iStatus.State()) == ECardStateSlp) )
  4623 			{
  5113 			{
  4624 			// Currently selected media is asleep, so it must be awoken
  5114 			// Currently selected media is asleep, so it must be awoken
  4625 			SMF_INVOKES(ExecAwakeCommandSMST,EStExecCmd)
  5115 			SMF_INVOKES(ExecAwakeCommandSMST,EStExecCmd)
  4626 			}
  5116 			}
  4627 	
  5117 	
  4628 	SMF_STATE(EStExecCmd)
  5118 	SMF_STATE(EStExecCmd)
  4629 	
  5119 	
       
  5120 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM3, "EStExecCmd" );
  4630 		TMMCCommandDesc& cmd = s.Command();
  5121 		TMMCCommandDesc& cmd = s.Command();
  4631 		// clearup some internally used flags
  5122 		// clearup some internally used flags
  4632 		cmd.iFlags &= ~(KMMCCmdFlagExecTopBusy|KMMCCmdFlagExecSelBusy);
  5123 		cmd.iFlags &= ~(KMMCCmdFlagExecTopBusy|KMMCCmdFlagExecSelBusy);
  4633 		cmd.iPollAttempts = cmd.iTimeOutRetries = cmd.iCRCRetries = 0;
  5124 		cmd.iPollAttempts = cmd.iTimeOutRetries = cmd.iCRCRetries = 0;
  4634 
  5125 
  4635 	SMF_STATE(EStRetry)
  5126 	SMF_STATE(EStRetry)
  4636 
  5127 
       
  5128 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM4, "EStRetry" );
  4637 		TMMCCommandDesc& cmd = s.Command();
  5129 		TMMCCommandDesc& cmd = s.Command();
  4638 		m.SetTraps( KMMCErrBasic & ~Command().iExecNotHandle);	// Processing all trappable errors
  5130 		m.SetTraps( KMMCErrBasic & ~Command().iExecNotHandle);	// Processing all trappable errors
  4639 
  5131 
  4640 		if (iMultiplexedBus)
  5132 		if (iMultiplexedBus)
  4641 			{
  5133 			{
  4666 		s.PushCommandStack();
  5158 		s.PushCommandStack();
  4667 		s.FillCommandDesc( ECmdSelectCard, 0 );		// Deselect - RCA=0
  5159 		s.FillCommandDesc( ECmdSelectCard, 0 );		// Deselect - RCA=0
  4668 		iCxDeselectCount=iDeselectsToIssue;
  5160 		iCxDeselectCount=iDeselectsToIssue;
  4669 
  5161 
  4670 	SMF_STATE(EStDeselectLoop)
  5162 	SMF_STATE(EStDeselectLoop)
  4671 
  5163 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM5, "EStDeselectLoop" );
  4672 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStDeselectEndCheck)	
  5164 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStDeselectEndCheck)	
  4673 
  5165 
  4674 	SMF_STATE(EStDeselectEndCheck)
  5166 	SMF_STATE(EStDeselectEndCheck)
  4675 
  5167 
       
  5168 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM6, "EStDeselectEndCheck" );
  4676 		// If we got an error and this is the last de-select then give up
  5169 		// If we got an error and this is the last de-select then give up
  4677 		if (err && iCxDeselectCount == 1)
  5170 		if (err && iCxDeselectCount == 1)
  4678 			{
  5171 			{
  4679 			s.PopCommandStack();
  5172 			s.PopCommandStack();
       
  5173 			OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT1, this, (TInt) err );
  4680 			SMF_RETURN(err)
  5174 			SMF_RETURN(err)
  4681 			}
  5175 			}
  4682 
  5176 
  4683 		if (--iCxDeselectCount > 0)
  5177 		if (--iCxDeselectCount > 0)
  4684 			SMF_INVOKES(RetryGapTimerSMST,EStDeselectLoop)
  5178 			SMF_INVOKES(RetryGapTimerSMST,EStDeselectLoop)
  4686 		s.PopCommandStack();
  5180 		s.PopCommandStack();
  4687 		iStackState &= ~KMMCStackStateDoDeselect;
  5181 		iStackState &= ~KMMCStackStateDoDeselect;
  4688 
  5182 
  4689 	SMF_STATE(EStAnalyseCommand)
  5183 	SMF_STATE(EStAnalyseCommand)
  4690 
  5184 
       
  5185 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM7, "EStAnalyseCommand" );
  4691 		TMMCCommandDesc& cmd = s.Command();
  5186 		TMMCCommandDesc& cmd = s.Command();
  4692 		// Check if its un-important whether the card is in transfer state (i.e
  5187 		// Check if its un-important whether the card is in transfer state (i.e
  4693 		// selected) or not for the command we are about to execute. Such
  5188 		// selected) or not for the command we are about to execute. Such
  4694 		// commands are CMD0, CMD7 and CMD13.
  5189 		// commands are CMD0, CMD7 and CMD13.
  4695 		
  5190 		
  4696 		// This state machine should never send CMD55
  5191 		// This state machine should never send CMD55
  4697 		if (cmd.iCommand == ECmdAppCmd)
  5192 		if (cmd.iCommand == ECmdAppCmd)
       
  5193 		    {
       
  5194 		    OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT2, this, (TInt) KMMCErrNotSupported );
  4698 			SMF_RETURN (KMMCErrNotSupported)
  5195 			SMF_RETURN (KMMCErrNotSupported)
       
  5196 		    }
  4699 
  5197 
  4700 		SMF_NEXTS( EStTestAppCommand )
  5198 		SMF_NEXTS( EStTestAppCommand )
  4701 		if (cmd.iCommand == ECmdGoIdleState || cmd.iCommand == ECmdSelectCard || cmd.iCommand == ECmdSendStatus)
  5199 		if (cmd.iCommand == ECmdGoIdleState || cmd.iCommand == ECmdSelectCard || cmd.iCommand == ECmdSendStatus)
  4702 			{
  5200 			{
  4703 			SMF_GOTONEXTS
  5201 			SMF_GOTONEXTS
  4715 				{
  5213 				{
  4716 				if ( (iConfig.iModes & KMMCModeCardControlled) == 0 )
  5214 				if ( (iConfig.iModes & KMMCModeCardControlled) == 0 )
  4717 					SMF_GOTONEXTS
  5215 					SMF_GOTONEXTS
  4718 				// Get the RCA of the card
  5216 				// Get the RCA of the card
  4719 				if ( (targetRCA = s.CardRCA()) == 0 )
  5217 				if ( (targetRCA = s.CardRCA()) == 0 )
       
  5218 				    {
       
  5219 				    OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT3, this, (TInt) KMMCErrNoCard );
  4720 					SMF_RETURN( KMMCErrNoCard )
  5220 					SMF_RETURN( KMMCErrNoCard )
       
  5221 				    }
  4721 				break;
  5222 				break;
  4722 				}
  5223 				}
  4723 			default:
  5224 			default:
  4724 				SMF_GOTONEXTS
  5225 				SMF_GOTONEXTS
  4725 			}
  5226 			}
  4735 		s.FillCommandDesc(ECmdSelectCard,targetRCA);
  5236 		s.FillCommandDesc(ECmdSelectCard,targetRCA);
  4736 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStSelectDone)	
  5237 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStSelectDone)	
  4737 
  5238 
  4738 	SMF_STATE(EStSelectDone)
  5239 	SMF_STATE(EStSelectDone)
  4739 
  5240 
       
  5241 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM8, "EStSelectDone" );
  4740 		TMMCCommandDesc& cmd = s.Command();
  5242 		TMMCCommandDesc& cmd = s.Command();
  4741 		
  5243 		
  4742 		if ( err )
  5244 		if ( err )
  4743 			{
  5245 			{
  4744 			cmd.iFlags &= ~(KMMCCmdFlagASSPFlags|KMMCCmdFlagExecSelBusy);
  5246 			cmd.iFlags &= ~(KMMCCmdFlagASSPFlags|KMMCCmdFlagExecSelBusy);
  4746 			if (err == KMMCErrBusyTimeOut)
  5248 			if (err == KMMCErrBusyTimeOut)
  4747 				cmd.iFlags |= KMMCCmdFlagExecSelBusy;
  5249 				cmd.iFlags |= KMMCCmdFlagExecSelBusy;
  4748 
  5250 
  4749 			s.PopCommandStack();
  5251 			s.PopCommandStack();
  4750 			SMF_NEXTS(EStErrRecover)
  5252 			SMF_NEXTS(EStErrRecover)
  4751 			return(err);		// re-enter the next state with that error
  5253 			OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT4, this, (TInt) err );
       
  5254 			return err;		// re-enter the next state with that error
  4752 			}
  5255 			}
  4753 
  5256 
  4754 		// Are we trying to recover from a top-level command returning busy (by de-selecting and re-selecting)
  5257 		// Are we trying to recover from a top-level command returning busy (by de-selecting and re-selecting)
  4755 		if ( cmd.iFlags & KMMCCmdFlagExecTopBusy )
  5258 		if ( cmd.iFlags & KMMCCmdFlagExecTopBusy )
  4756 			{
  5259 			{
  4787 			SMF_GOTOS( EStTestAppCommand )
  5290 			SMF_GOTOS( EStTestAppCommand )
  4788 			}
  5291 			}
  4789 
  5292 
  4790 	SMF_STATE(EStBlockCountCmdIssued)
  5293 	SMF_STATE(EStBlockCountCmdIssued)
  4791 		
  5294 		
       
  5295 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM9, "EStBlockCountCmdIssued" );
  4792 		const TMMCStatus status(s.ResponseP());
  5296 		const TMMCStatus status(s.ResponseP());
  4793 		s.PopCommandStack();
  5297 		s.PopCommandStack();
  4794 		if (status.Error())
  5298 		if (status.Error())
       
  5299 		    {
       
  5300 		    OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT5, this, (TInt) KMMCErrStatus );
  4795 			SMF_RETURN(KMMCErrStatus)
  5301 			SMF_RETURN(KMMCErrStatus)
       
  5302 		    }
  4796 
  5303 
  4797 		if(err & KMMCErrNotSupported)
  5304 		if(err & KMMCErrNotSupported)
  4798 			{
  5305 			{
  4799 			// Not supported by the PSL, so use standard Stop Transmission mode
  5306 			// Not supported by the PSL, so use standard Stop Transmission mode
  4800 			s.Command().iSpec.iUseStopTransmission = ETrue;
  5307 			s.Command().iSpec.iUseStopTransmission = ETrue;
  4801 			}
  5308 			}
  4802 		// Fall through...		
  5309 		// Fall through...		
  4803 
  5310 
  4804 	SMF_STATE(EStTestAppCommand)
  5311 	SMF_STATE(EStTestAppCommand)
       
  5312 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM10, "EStTestAppCommand" );
  4805 		TMMCCommandDesc& cmd = s.Command();
  5313 		TMMCCommandDesc& cmd = s.Command();
  4806 		if (cmd.iSpec.iCommandClass != KMMCCmdClassApplication)
  5314 		if (cmd.iSpec.iCommandClass != KMMCCmdClassApplication)
  4807 			SMF_GOTOS( EStIssueCommand )
  5315 			SMF_GOTOS( EStIssueCommand )
  4808 
  5316 
  4809 		s.PushCommandStack();
  5317 		s.PushCommandStack();
  4810 		s.FillCommandDesc(ECmdAppCmd, s.CardRCA()); // Send APP_CMD (CMD55)	
  5318 		s.FillCommandDesc(ECmdAppCmd, s.CardRCA()); // Send APP_CMD (CMD55)	
  4811 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStIssueAppCommandDone)
  5319 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStIssueAppCommandDone)
  4812 		
  5320 		
  4813 	SMF_STATE(EStIssueAppCommandDone)
  5321 	SMF_STATE(EStIssueAppCommandDone)
       
  5322 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM11, "EStIssueAppCommandDone" );
  4814 		s.PopCommandStack();
  5323 		s.PopCommandStack();
  4815 		if ( err )
  5324 		if ( err )
  4816 			{
  5325 			{
  4817 			SMF_NEXTS(EStErrRecover)
  5326 			SMF_NEXTS(EStErrRecover)
  4818 			return(err);		// re-enter the next state with that error
  5327             OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT6, this, (TInt) err );
       
  5328 			return err;		// re-enter the next state with that error
  4819 			}
  5329 			}
  4820 
  5330 
  4821 
  5331 
  4822 	SMF_STATE(EStIssueCommand)
  5332 	SMF_STATE(EStIssueCommand)
  4823 
  5333 
       
  5334 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM12, "EStIssueCommand" );
  4824 		TMMCCommandDesc& cmd = s.Command();
  5335 		TMMCCommandDesc& cmd = s.Command();
  4825 		// If its an addressed command (rather than a selected command), then
  5336 		// If its an addressed command (rather than a selected command), then
  4826 		// setup the argument with the RCA. (Commands requiring card to be
  5337 		// setup the argument with the RCA. (Commands requiring card to be
  4827 		// selected - ACS don't matter since selected cards don't need an RCA now).
  5338 		// selected - ACS don't matter since selected cards don't need an RCA now).
  4828 		if ((iConfig.iModes & KMMCModeCardControlled) && cmd.iSpec.iCommandType==ECmdTypeAC )
  5339 		if ((iConfig.iModes & KMMCModeCardControlled) && cmd.iSpec.iCommandType==ECmdTypeAC )
  4829 			{
  5340 			{
  4830 			const TRCA targetRCA = s.CardRCA();
  5341 			const TRCA targetRCA = s.CardRCA();
  4831 			if ( targetRCA == 0 )
  5342 			if ( targetRCA == 0 )
       
  5343 			    {
       
  5344 			    OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT7, this, (TInt) KMMCErrNoCard );
  4832 				SMF_RETURN( KMMCErrNoCard )
  5345 				SMF_RETURN( KMMCErrNoCard )
       
  5346 			    }
  4833 			cmd.iArgument.SetRCA(targetRCA);
  5347 			cmd.iArgument.SetRCA(targetRCA);
  4834 			}
  5348 			}
  4835 
  5349 
  4836 		// Issue the top-level command
  5350 		// Issue the top-level command
  4837 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStCommandIssued)
  5351 		SMF_INVOKES(IssueCommandCheckResponseSMST,EStCommandIssued)
  4838 
  5352 
  4839 	SMF_STATE(EStCommandIssued)
  5353 	SMF_STATE(EStCommandIssued)
  4840 
  5354 
       
  5355 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM13, "EStCommandIssued" );
  4841 		// If command was succesful then we've finished.
  5356 		// If command was succesful then we've finished.
  4842 		if (!err)
  5357 		if (!err)
  4843 			SMF_EXIT
  5358 			SMF_EXIT
  4844 
  5359 
  4845 	SMF_STATE(EStErrRecover)
  5360 	SMF_STATE(EStErrRecover)
  4846 
  5361 
       
  5362 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_EXECCOMMANDSM14, "EStErrRecover" );
  4847 		TMMCCommandDesc& cmd = s.Command();
  5363 		TMMCCommandDesc& cmd = s.Command();
  4848 		const TUint32 modes=iConfig.iModes;
  5364 		const TUint32 modes=iConfig.iModes;
  4849 		SMF_NEXTS(EStRetry)
  5365 		SMF_NEXTS(EStRetry)
  4850 
  5366 
  4851 		m.ResetTraps();							// no more re-entries via return()
  5367 		m.ResetTraps();							// no more re-entries via return()
  4861 			s.iBytesTransferred += cmd.iBytesDone;
  5377 			s.iBytesTransferred += cmd.iBytesDone;
  4862 
  5378 
  4863 			if (cmd.iTotalLength < cmd.BlockLength())
  5379 			if (cmd.iTotalLength < cmd.BlockLength())
  4864 				{
  5380 				{
  4865 				DeselectsToIssue(1);
  5381 				DeselectsToIssue(1);
  4866 				return(err);
  5382 				OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT8, this, (TInt) err );
       
  5383 				return err;
  4867 				}
  5384 				}
  4868 			}
  5385 			}
  4869 
  5386 
  4870 		if ((modes & KMMCModeEnableRetries) == 0)
  5387 		if ((modes & KMMCModeEnableRetries) == 0)
  4871 			return( err );
  5388 		    {
       
  5389 			OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT9, this, (TInt) err );
       
  5390 			return err;
       
  5391 		    }
  4872 
  5392 
  4873 		const TUint32 toMask = (KMMCErrResponseTimeOut|KMMCErrDataTimeOut);
  5393 		const TUint32 toMask = (KMMCErrResponseTimeOut|KMMCErrDataTimeOut);
  4874 		const TUint32 crcMask = (KMMCErrResponseCRC|KMMCErrDataCRC|KMMCErrCommandCRC);
  5394 		const TUint32 crcMask = (KMMCErrResponseCRC|KMMCErrDataCRC|KMMCErrCommandCRC);
  4875 
  5395 
  4876 		if( (err & ~(toMask|crcMask)) == KMMCErrNone ) // time-outs/CRC errors
  5396 		if( (err & ~(toMask|crcMask)) == KMMCErrNone ) // time-outs/CRC errors
  4878 			if( cmd.iSpec.iCommandType == ECmdTypeADTCS )	// for data transfer commands
  5398 			if( cmd.iSpec.iCommandType == ECmdTypeADTCS )	// for data transfer commands
  4879 				{
  5399 				{
  4880 				DeselectsToIssue( 1 );						// enforce deselect before any retries
  5400 				DeselectsToIssue( 1 );						// enforce deselect before any retries
  4881 
  5401 
  4882 				if( (modes & KMMCModeCardControlled) == 0 )
  5402 				if( (modes & KMMCModeCardControlled) == 0 )
  4883 					return( err );		// we wouldn't know what to select - no retries
  5403 				    {
       
  5404 					OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT10, this, (TInt) err );
       
  5405 					return err;		// we wouldn't know what to select - no retries
       
  5406 				    }
  4884 				}
  5407 				}
  4885 
  5408 
  4886 			TUint32 gapEnabled = 0;
  5409 			TUint32 gapEnabled = 0;
  4887 
  5410 
  4888 			if( err & toMask )
  5411 			if( err & toMask )
  4890 				cmd.iTimeOutRetries++;
  5413 				cmd.iTimeOutRetries++;
  4891 				gapEnabled |= KMMCModeTimeOutRetryGap;
  5414 				gapEnabled |= KMMCModeTimeOutRetryGap;
  4892 
  5415 
  4893 				if( (modes & KMMCModeEnableTimeOutRetry) == 0 ||
  5416 				if( (modes & KMMCModeEnableTimeOutRetry) == 0 ||
  4894 					cmd.iTimeOutRetries > iConfig.iTimeOutRetries )
  5417 					cmd.iTimeOutRetries > iConfig.iTimeOutRetries )
  4895 					return( err );
  5418 				    {
       
  5419 					OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT11, this, (TInt) err );
       
  5420 					return err;
       
  5421 				    }
  4896 				}
  5422 				}
  4897 
  5423 
  4898 			if( err & crcMask )
  5424 			if( err & crcMask )
  4899 				{
  5425 				{
  4900 				cmd.iCRCRetries++;
  5426 				cmd.iCRCRetries++;
  4901 				gapEnabled |= KMMCModeCRCRetryGap;
  5427 				gapEnabled |= KMMCModeCRCRetryGap;
  4902 
  5428 
  4903 				if( (modes & KMMCModeEnableCRCRetry) == 0	||
  5429 				if( (modes & KMMCModeEnableCRCRetry) == 0	||
  4904 					cmd.iCRCRetries > iConfig.iCRCRetries		||
  5430 					cmd.iCRCRetries > iConfig.iCRCRetries		||
  4905 					((err & KMMCErrDataCRC) != 0 && (modes & KMMCModeDataCRCRetry) == 0) )
  5431 					((err & KMMCErrDataCRC) != 0 && (modes & KMMCModeDataCRCRetry) == 0) )
  4906 					return( err );
  5432 				    {
       
  5433 					OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT12, this, (TInt) err );
       
  5434 					return err;
       
  5435 				    }
  4907 				}
  5436 				}
  4908 
  5437 
  4909 			if( (modes & gapEnabled) == gapEnabled )
  5438 			if( (modes & gapEnabled) == gapEnabled )
  4910 				{
  5439 				{
  4911 				if( modes & KMMCModeCardControlled )
  5440 				if( modes & KMMCModeCardControlled )
  4933 
  5462 
  4934 //			ReportInconsistentBusState();	// ASSP layer should have it done
  5463 //			ReportInconsistentBusState();	// ASSP layer should have it done
  4935 			s.iGlobalRetries++;
  5464 			s.iGlobalRetries++;
  4936 
  5465 
  4937 			if( s.iGlobalRetries > KMMCMaxGlobalRetries )
  5466 			if( s.iGlobalRetries > KMMCMaxGlobalRetries )
  4938 				return( err );
  5467 			    {
       
  5468 				OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT13, this, (TInt) err );
       
  5469 				return err;
       
  5470 			    }
  4939 
  5471 
  4940 			s.SwapMe();		// To prevent the initialiser from aborting this session
  5472 			s.SwapMe();		// To prevent the initialiser from aborting this session
  4941 			SMF_WAIT		// Initialiser will take over here
  5473 			SMF_WAIT		// Initialiser will take over here
  4942 			}
  5474 			}
  4943 
  5475 
  4950 			cmd.iPollAttempts++;
  5482 			cmd.iPollAttempts++;
  4951 
  5483 
  4952 			if( (modes & KMMCModeEnableBusyPoll) == 0 ||
  5484 			if( (modes & KMMCModeEnableBusyPoll) == 0 ||
  4953 				((modes & KMMCModeCardControlled) == 0 && cmd.iCommand != ECmdSelectCard) ||
  5485 				((modes & KMMCModeCardControlled) == 0 && cmd.iCommand != ECmdSelectCard) ||
  4954 				cmd.iPollAttempts > iConfig.iPollAttempts )
  5486 				cmd.iPollAttempts > iConfig.iPollAttempts )
  4955 				return( err );
  5487 			    {
       
  5488 				OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT14, this, (TInt) err );
       
  5489 				return err;
       
  5490 			    }
  4956 
  5491 
  4957 			if( modes & KMMCModeBusyPollGap )
  5492 			if( modes & KMMCModeBusyPollGap )
  4958 				{
  5493 				{
  4959 				s.iState |= KMMCSessStateSafeInGaps;	// preemption allowed
  5494 				s.iState |= KMMCSessStateSafeInGaps;	// preemption allowed
  4960 				SMF_CALL( PollGapTimerSMST )
  5495 				SMF_CALL( PollGapTimerSMST )
  4969 
  5504 
  4970 			// No preemption, just repeat the Deselect/Select sequence
  5505 			// No preemption, just repeat the Deselect/Select sequence
  4971 			SMF_GOTONEXTS
  5506 			SMF_GOTONEXTS
  4972 			}
  5507 			}
  4973 
  5508 
  4974 		return( err );
  5509 		OstTraceFunctionExitExt( DMMCSTACK_EXECCOMMANDSM_EXIT15, this, (TInt) err );
       
  5510 		return err;
  4975 
  5511 
  4976 	SMF_END
  5512 	SMF_END
  4977 	}
  5513 	}
  4978 
  5514 
  4979 TMMCErr DMMCStack::IssueCommandCheckResponseSM()
  5515 TMMCErr DMMCStack::IssueCommandCheckResponseSM()
  4993 		EStEnd
  5529 		EStEnd
  4994 		};
  5530 		};
  4995 
  5531 
  4996 		DMMCSession& s=Session();
  5532 		DMMCSession& s=Session();
  4997 		TMMCCommandDesc& cmd = Command();
  5533 		TMMCCommandDesc& cmd = Command();
       
  5534 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM1, "Current session=0x%x", &s );
  4998 
  5535 
  4999 	SMF_BEGIN
  5536 	SMF_BEGIN
  5000 
  5537 
       
  5538 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM2, "EStBegin" );
  5001 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Issue %d %x",TUint(cmd.iCommand),TUint(cmd.iArgument)));
  5539 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Issue %d %x",TUint(cmd.iCommand),TUint(cmd.iArgument)));
  5002 
  5540 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM3, "CMD%02d(0x%08x)", TUint(cmd.iCommand), TUint(cmd.iArgument) );
       
  5541 		
  5003 		// Stop the Controller from powering down the card due to bus inactivity
  5542 		// Stop the Controller from powering down the card due to bus inactivity
  5004 		iSocket->ResetInactivity(0);
  5543 		iSocket->ResetInactivity(0);
  5005 
  5544 
  5006 	SMF_STATE(EStIssueCommand)
  5545 	SMF_STATE(EStIssueCommand)
  5007 
  5546 
       
  5547 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM4, "EStIssueCommand" );
  5008 		// If command is directed at a specific card then save this command in card object
  5548 		// If command is directed at a specific card then save this command in card object
  5009 		if (iConfig.iModes & KMMCModeCardControlled)
  5549 		if (iConfig.iModes & KMMCModeCardControlled)
  5010 			{
  5550 			{
  5011 			s.iCardP->iLastCommand = cmd.iCommand;
  5551 			s.iCardP->iLastCommand = cmd.iCommand;
  5012 
  5552 
  5026 		m.SetTraps(KMMCErrAll);
  5566 		m.SetTraps(KMMCErrAll);
  5027 		SMF_INVOKES(IssueMMCCommandSMST,EStCommandIssued)
  5567 		SMF_INVOKES(IssueMMCCommandSMST,EStCommandIssued)
  5028 
  5568 
  5029 	SMF_STATE(EStCommandIssued)
  5569 	SMF_STATE(EStCommandIssued)
  5030 
  5570 
       
  5571 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM5, "EStCommandIssued" );
  5031 #ifdef ENABLE_DETAILED_SD_COMMAND_TRACE
  5572 #ifdef ENABLE_DETAILED_SD_COMMAND_TRACE
  5032 		cmd.Dump(s.ResponseP(), err);
  5573 		cmd.Dump(s.ResponseP(), err);
  5033 #endif
  5574 #endif
  5034 
  5575 
       
  5576 		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM6, "MMC Protocol: CMD%02d(0x%08x)", (TInt) cmd.iCommand, (TUint) cmd.iArgument );
       
  5577 		OstTraceDefExt4( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM7, "MMC Protocol: RSP%d - LEN 0x%08x - ERR 0x%08x - STAT 0x%08x", (TUint) cmd.iSpec.iResponseType, (TUint) cmd.iSpec.iResponseLength, (TUint) err, (TUint) TMMC::BigEndian32(s.ResponseP()) );
       
  5578 		
  5035 		TMMCErr exitCode=err;
  5579 		TMMCErr exitCode=err;
  5036 		// If we have just de-selected all cards in the stack, RCA(0) then ignore response timeout.
  5580 		// If we have just de-selected all cards in the stack, RCA(0) then ignore response timeout.
  5037 		if ( cmd.iCommand==ECmdSelectCard && TRCA(cmd.iArgument)==0 )
  5581 		if ( cmd.iCommand==ECmdSelectCard && TRCA(cmd.iArgument)==0 )
  5038 			exitCode &= ~KMMCErrResponseTimeOut;
  5582 			exitCode &= ~KMMCErrResponseTimeOut;
  5039 		else
  5583 		else
  5045 				  (cmd.iSpec.iResponseType==ERespTypeR1 || cmd.iSpec.iResponseType==ERespTypeR1B)) )
  5589 				  (cmd.iSpec.iResponseType==ERespTypeR1 || cmd.iSpec.iResponseType==ERespTypeR1B)) )
  5046 				{
  5590 				{
  5047 				TMMCStatus status=s.ResponseP();
  5591 				TMMCStatus status=s.ResponseP();
  5048 				s.iLastStatus=status;
  5592 				s.iLastStatus=status;
  5049 				__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:ec:st=%08x", TUint32(status)));
  5593 				__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:ec:st=%08x", TUint32(status)));
       
  5594 				OstTrace1( TRACE_INTERNALS, DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM8, "status=0x%08x", TUint32(status) );
  5050 
  5595 
  5051 				if (iConfig.iModes & KMMCModeCardControlled)
  5596 				if (iConfig.iModes & KMMCModeCardControlled)
  5052 					s.iCardP->iStatus=status;
  5597 					s.iCardP->iStatus=status;
  5053 
  5598 
  5054 				// Update exit code if card status is reporting an error (in case not done already)
  5599 				// Update exit code if card status is reporting an error (in case not done already)
  5060 		// If we've just selected a card and the command was succesful then
  5605 		// If we've just selected a card and the command was succesful then
  5061 		// remember which one so we don't need to do it twice.
  5606 		// remember which one so we don't need to do it twice.
  5062 		if (cmd.iCommand==ECmdSelectCard && exitCode==KMMCErrNone)
  5607 		if (cmd.iCommand==ECmdSelectCard && exitCode==KMMCErrNone)
  5063 			iSelectedCard=TRCA(cmd.iArgument);
  5608 			iSelectedCard=TRCA(cmd.iArgument);
  5064 
  5609 
       
  5610 		OstTraceFunctionExitExt( DMMCSTACK_ISSUECOMMANDCHECKRESPONSESM_EXIT, this, ( TInt ) exitCode );
  5065 		SMF_RETURN(exitCode)
  5611 		SMF_RETURN(exitCode)
  5066 
  5612 
  5067 	SMF_END
  5613 	SMF_END
  5068 	}
  5614 	}
  5069 
  5615 
  5087 			EStFinish,
  5633 			EStFinish,
  5088 			EStEnd
  5634 			EStEnd
  5089 			};
  5635 			};
  5090 
  5636 
  5091 		DMMCSession& s=Session();
  5637 		DMMCSession& s=Session();
       
  5638 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_NAKEDSESSIONSM1, "Current session=0x%x", &s );
  5092 
  5639 
  5093 	SMF_BEGIN
  5640 	SMF_BEGIN
       
  5641 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_NAKEDSESSIONSM2, "EStBegin" );
  5094 		s.iState |= KMMCSessStateInProgress;
  5642 		s.iState |= KMMCSessStateInProgress;
  5095 
  5643 
  5096 		if( (iConfig.iModes & KMMCModeCardControlled) != 0 )
  5644 		if( (iConfig.iModes & KMMCModeCardControlled) != 0 )
  5097 			SMF_INVOKES( AttachCardSMST, EStAttached )
  5645 			SMF_INVOKES( AttachCardSMST, EStAttached )
  5098 
  5646 
  5099 	SMF_BPOINT(EStAttached)
  5647 	SMF_BPOINT(EStAttached)
  5100 
  5648 
       
  5649 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_NAKEDSESSIONSM3, "EStAttached" );
  5101 		SMF_INVOKES( ExecCommandSMST, EStFinish )
  5650 		SMF_INVOKES( ExecCommandSMST, EStFinish )
  5102 
  5651 
  5103 	SMF_STATE(EStFinish)
  5652 	SMF_STATE(EStFinish)
  5104 
  5653 
       
  5654 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_NAKEDSESSIONSM4, "EStFinish" );
  5105 		s.iState &= ~KMMCSessStateInProgress;
  5655 		s.iState &= ~KMMCSessStateInProgress;
  5106 	SMF_END
  5656 	SMF_END
  5107 	}
  5657 	}
  5108 
  5658 
  5109 inline TMMCErr DMMCStack::CIMSetupCardSM()
  5659 inline TMMCErr DMMCStack::CIMSetupCardSM()
  5121 			EStGotCSD,
  5671 			EStGotCSD,
  5122 			EStEnd
  5672 			EStEnd
  5123 			};
  5673 			};
  5124 
  5674 
  5125 		DMMCSession& s=Session();
  5675 		DMMCSession& s=Session();
       
  5676 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_CIMSETUPCARDSM1, "Current session=0x%x; Last status=0x%x", (TUint) &s, (TUint) s.iLastStatus );
  5126 
  5677 
  5127 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:SetupCardSM %x",TUint(s.iLastStatus)));
  5678 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:SetupCardSM %x",TUint(s.iLastStatus)));
  5128 
  5679 
  5129 	SMF_BEGIN
  5680 	SMF_BEGIN
       
  5681 	
       
  5682 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMSETUPCARDSM2, "EStBegin" );
  5130 		s.iState |= KMMCSessStateInProgress;
  5683 		s.iState |= KMMCSessStateInProgress;
  5131 
  5684 
  5132 		SMF_INVOKES( AttachCardSMST, EStAttached )	// attachment is mandatory here
  5685 		SMF_INVOKES( AttachCardSMST, EStAttached )	// attachment is mandatory here
  5133 
  5686 
  5134 	SMF_BPOINT(EStAttached)
  5687 	SMF_BPOINT(EStAttached)
  5135 
  5688 
       
  5689 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMSETUPCARDSM3, "EStAttached" );
  5136 		s.FillCommandDesc( ECmdSelectCard, 0 );
  5690 		s.FillCommandDesc( ECmdSelectCard, 0 );
  5137 		SMF_INVOKES( ExecCommandSMST, EStSelected )
  5691 		SMF_INVOKES( ExecCommandSMST, EStSelected )
  5138 
  5692 
  5139 	SMF_STATE(EStSelected)
  5693 	SMF_STATE(EStSelected)
  5140 
  5694 
       
  5695 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMSETUPCARDSM4, "EStSelected" );
  5141 		if( !s.iCardP->IsReady() )
  5696 		if( !s.iCardP->IsReady() )
  5142 			return( KMMCErrNoCard );
  5697 		    {
       
  5698 			OstTraceFunctionExitExt( DMMCSTACK_CIMSETUPCARDSM_EXIT, this, (TInt) KMMCErrNoCard );
       
  5699 			return KMMCErrNoCard;
       
  5700 		    }
  5143 
  5701 
  5144 		s.FillCommandDesc( ECmdSendCSD, Command().iArgument ); // NB: the card will be deselected to execute this command
  5702 		s.FillCommandDesc( ECmdSendCSD, Command().iArgument ); // NB: the card will be deselected to execute this command
  5145 		SMF_INVOKES( ExecCommandSMST, EStGotCSD )
  5703 		SMF_INVOKES( ExecCommandSMST, EStGotCSD )
  5146 
  5704 
  5147 	SMF_STATE(EStGotCSD)
  5705 	SMF_STATE(EStGotCSD)
  5148 
  5706 
       
  5707 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMSETUPCARDSM5, "EStGotCSD" );
  5149 		s.iCardP->iCSD = s.ResponseP();
  5708 		s.iCardP->iCSD = s.ResponseP();
  5150 
  5709 
  5151 		s.iState &= ~KMMCSessStateInProgress;
  5710 		s.iState &= ~KMMCSessStateInProgress;
  5152 	SMF_END
  5711 	SMF_END
  5153 	}
  5712 	}
  5186 			EStRWFinish,
  5745 			EStRWFinish,
  5187 			EStEnd
  5746 			EStEnd
  5188 			};
  5747 			};
  5189 
  5748 
  5190 		DMMCSession& s=Session();
  5749 		DMMCSession& s=Session();
       
  5750 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM1, "Current session=0x%x; Last status=0x%x", (TUint) &s, (TUint) s.iLastStatus );
  5191 
  5751 
  5192 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:RWBlocksSM %x",TUint(s.iLastStatus)));
  5752 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:RWBlocksSM %x",TUint(s.iLastStatus)));
  5193 
  5753 
  5194 	SMF_BEGIN
  5754 	SMF_BEGIN
  5195 
  5755 
       
  5756 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM2, "EStBegin" );
  5196 		if(s.iSessionID == ECIMWriteBlock || s.iSessionID == ECIMWriteMBlock)
  5757 		if(s.iSessionID == ECIMWriteBlock || s.iSessionID == ECIMWriteMBlock)
  5197 			{
  5758 			{
  5198 			// Check that the card supports class 4 (Write) commands
  5759 			// Check that the card supports class 4 (Write) commands
  5199 			const TUint ccc = s.iCardP->CSD().CCC();
  5760 			const TUint ccc = s.iCardP->CSD().CCC();
  5200 			if(!(ccc & KMMCCmdClassBlockWrite))
  5761 			if(!(ccc & KMMCCmdClassBlockWrite))
  5201 				return( KMMCErrNotSupported );
  5762 			    {
       
  5763 				OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT1, this, (TInt) KMMCErrNotSupported );
       
  5764 				return KMMCErrNotSupported;
       
  5765 			    }
  5202 			}
  5766 			}
  5203 
  5767 
  5204 		s.iState |= KMMCSessStateInProgress;
  5768 		s.iState |= KMMCSessStateInProgress;
  5205 		m.SetTraps(KMMCErrInitContext);
  5769 		m.SetTraps(KMMCErrInitContext);
  5206 
  5770 
  5207 	SMF_STATE(EStRestart)		// NB: ErrBypass is not processed here
  5771 	SMF_STATE(EStRestart)		// NB: ErrBypass is not processed here
  5208 
  5772 
       
  5773 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM3, "EStRestart" );
  5209 		SMF_CALLMEWR(EStRestart) // Create a recursive call entry to recover from the errors trapped
  5774 		SMF_CALLMEWR(EStRestart) // Create a recursive call entry to recover from the errors trapped
  5210 		m.SetTraps(KMMCErrStatus);
  5775 		m.SetTraps(KMMCErrStatus);
  5211 		if (s.Command().iSpec.iCommandClass!=KMMCCmdClassApplication || s.Command().iCommand==ECmdAppCmd)
  5776 		if (s.Command().iSpec.iCommandClass!=KMMCCmdClassApplication || s.Command().iCommand==ECmdAppCmd)
  5212 			{
  5777 			{
  5213 			s.ResetCommandStack();
  5778 			s.ResetCommandStack();
  5214 			SMF_INVOKES( AttachCardSMST, EStAttached )	// attachment is mandatory here
  5779 			SMF_INVOKES( AttachCardSMST, EStAttached )	// attachment is mandatory here
  5215 			}
  5780 			}
  5216 
  5781 
  5217 	SMF_BPOINT(EStAttached)
  5782 	SMF_BPOINT(EStAttached)
  5218 
  5783 
       
  5784 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM4, "EStAttached" );
  5219 		TMMCCommandDesc& cmd = s.Command();
  5785 		TMMCCommandDesc& cmd = s.Command();
  5220 
  5786 
  5221 		const TUint32 blockLength = cmd.BlockLength();
  5787 		const TUint32 blockLength = cmd.BlockLength();
  5222 		if(blockLength == 0)
  5788 		if(blockLength == 0)
       
  5789 		    {
       
  5790 			OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT2, this, (TInt) KMMCErrArgument );
  5223 			return KMMCErrArgument;
  5791 			return KMMCErrArgument;
       
  5792 		    }
  5224 
  5793 
  5225 		if(s.iSessionID == ECIMReadBlock	||
  5794 		if(s.iSessionID == ECIMReadBlock	||
  5226 		   s.iSessionID == ECIMWriteBlock	||
  5795 		   s.iSessionID == ECIMWriteBlock	||
  5227 		   s.iSessionID == ECIMReadMBlock	||
  5796 		   s.iSessionID == ECIMReadMBlock	||
  5228 		   s.iSessionID == ECIMWriteMBlock)
  5797 		   s.iSessionID == ECIMWriteMBlock)
  5229 			{	
  5798 			{	
  5230 			// read/write operation
  5799 			// read/write operation
  5231 			if(!cmd.AdjustForBlockOrByteAccess(s))
  5800 			if(!cmd.AdjustForBlockOrByteAccess(s))
  5232 				{
  5801 				{
  5233 				// unable to convert command arguments to suit the underlying block/byte access mode
  5802 				// unable to convert command arguments to suit the underlying block/byte access mode
       
  5803 				OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT3, this, (TInt) KMMCErrArgument );
  5234 				return KMMCErrArgument;
  5804 				return KMMCErrArgument;
  5235 				}
  5805 				}
  5236 			}
  5806 			}
  5237 
  5807 
  5238 		// Set the block length if it has changed. Always set for ECIMLockUnlock.
  5808 		// Set the block length if it has changed. Always set for ECIMLockUnlock.
  5246 		s.FillCommandDesc( ECmdSetBlockLen, blockLength );
  5816 		s.FillCommandDesc( ECmdSetBlockLen, blockLength );
  5247 		SMF_INVOKES( ExecCommandSMST, EStLength1 )
  5817 		SMF_INVOKES( ExecCommandSMST, EStLength1 )
  5248 
  5818 
  5249 	SMF_STATE(EStLength1)
  5819 	SMF_STATE(EStLength1)
  5250 
  5820 
       
  5821 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM5, "EStAttached" );
  5251 		const TMMCStatus status(s.ResponseP());
  5822 		const TMMCStatus status(s.ResponseP());
  5252 		s.PopCommandStack();
  5823 		s.PopCommandStack();
  5253 		if (status.Error())
  5824 		if (status.Error())
       
  5825 		    {
       
  5826 		    OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT4, this, (TInt) KMMCErrStatus );
  5254 			SMF_RETURN(KMMCErrStatus)
  5827 			SMF_RETURN(KMMCErrStatus)
       
  5828 		    }
  5255 		s.iCardP->iSetBlockLen = s.Command().BlockLength();
  5829 		s.iCardP->iSetBlockLen = s.Command().BlockLength();
  5256 
  5830 
  5257 	SMF_STATE(EStLengthSet)
  5831 	SMF_STATE(EStLengthSet)
  5258 
  5832 
       
  5833 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM6, "EStLengthSet" );
  5259 		TMMCCommandDesc& cmd = s.Command();
  5834 		TMMCCommandDesc& cmd = s.Command();
  5260 		TUint opType = 0;
  5835 		TUint opType = 0;
  5261 		const TUint kTypeWrite =	KBit0;
  5836 		const TUint kTypeWrite =	KBit0;
  5262 		const TUint kTypeMultiple =	KBit1;
  5837 		const TUint kTypeMultiple =	KBit1;
  5263 		const TUint kTypeSpecial =	KBit2;
  5838 		const TUint kTypeSpecial =	KBit2;
  5314 				// data transmission, then it may return KMMCErrNotSupported to force
  5889 				// data transmission, then it may return KMMCErrNotSupported to force
  5315 				// the 'Stop Transmission' mode to be used instead.
  5890 				// the 'Stop Transmission' mode to be used instead.
  5316 				//
  5891 				//
  5317 				if(s.iCardP->CSD().SpecVers() >= 3)
  5892 				if(s.iCardP->CSD().SpecVers() >= 3)
  5318 					{
  5893 					{
       
  5894 					OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM7, "CMD12 (STOP_TRANSMISSION) not used" );
       
  5895 					
  5319 					cmd.iSpec.iUseStopTransmission = EFalse;
  5896 					cmd.iSpec.iUseStopTransmission = EFalse;
  5320 					SMF_NEXTS(EStIssueBlockCount)
  5897 					SMF_NEXTS(EStIssueBlockCount)
  5321 					}
  5898 					}
  5322 				else
  5899 				else
  5323 					{
  5900 					{
  5327 			}
  5904 			}
  5328 
  5905 
  5329 		SMF_GOTONEXTS
  5906 		SMF_GOTONEXTS
  5330 
  5907 
  5331 	SMF_STATE(EStIssueBlockCount)
  5908 	SMF_STATE(EStIssueBlockCount)
       
  5909 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM8, "EStIssueBlockCount" );
  5332 		//
  5910 		//
  5333 		// Issues SET_BLOCK_COUNT (CMD23) for MB R/W data transfers.
  5911 		// Issues SET_BLOCK_COUNT (CMD23) for MB R/W data transfers.
  5334 		// This is only issued if MMC version >= 3.1 and the PSL
  5912 		// This is only issued if MMC version >= 3.1 and the PSL
  5335 		// supports this mode of operation.
  5913 		// supports this mode of operation.
  5336 		//
  5914 		//
  5350 		s.FillCommandDesc( ECmdSetBlockCount, args );
  5928 		s.FillCommandDesc( ECmdSetBlockCount, args );
  5351 		SMF_INVOKES( ExecCommandSMST, EStBlockCountCmdIssued )
  5929 		SMF_INVOKES( ExecCommandSMST, EStBlockCountCmdIssued )
  5352 
  5930 
  5353 	SMF_STATE(EStBlockCountCmdIssued)
  5931 	SMF_STATE(EStBlockCountCmdIssued)
  5354 		
  5932 		
       
  5933 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM9, "EStBlockCountCmdIssued" );
  5355 		const TMMCStatus status(s.ResponseP());
  5934 		const TMMCStatus status(s.ResponseP());
  5356 		s.PopCommandStack();
  5935 		s.PopCommandStack();
  5357 		if (status.Error())
  5936 		if (status.Error())
       
  5937 		    {
       
  5938 		    OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT5, this, (TInt) KMMCErrStatus );
  5358 			SMF_RETURN(KMMCErrStatus)
  5939 			SMF_RETURN(KMMCErrStatus)
       
  5940 		    }
  5359 
  5941 
  5360 		if(err & KMMCErrNotSupported)
  5942 		if(err & KMMCErrNotSupported)
  5361 			{
  5943 			{
  5362 			// Not supported by the PSL, so use standard Stop Transmission mode
  5944 			// Not supported by the PSL, so use standard Stop Transmission mode
  5363 			s.Command().iSpec.iUseStopTransmission = ETrue;
  5945 			s.Command().iSpec.iUseStopTransmission = ETrue;
  5365 
  5947 
  5366 		SMF_GOTOS(EStBpoint1)
  5948 		SMF_GOTOS(EStBpoint1)
  5367 
  5949 
  5368 	SMF_STATE(EStAppCmdIssued)
  5950 	SMF_STATE(EStAppCmdIssued)
  5369 
  5951 
       
  5952 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM10, "EStAppCmdIssued" );
  5370 		const TMMCStatus status(s.ResponseP());
  5953 		const TMMCStatus status(s.ResponseP());
  5371 		s.PopCommandStack();
  5954 		s.PopCommandStack();
  5372 		if (status.Error())
  5955 		if (status.Error())
       
  5956 		    {
       
  5957 		    OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT6, this, (TInt) KMMCErrStatus );
  5373 			SMF_RETURN(KMMCErrStatus)
  5958 			SMF_RETURN(KMMCErrStatus)
       
  5959 		    }
  5374 
  5960 
  5375 	SMF_BPOINT(EStBpoint1)
  5961 	SMF_BPOINT(EStBpoint1)
  5376 
  5962 
       
  5963 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM11, "EStBpoint1" );
  5377 		// NB We need to trap KMMCErrStatus errors, because if one occurs, 
  5964 		// NB We need to trap KMMCErrStatus errors, because if one occurs, 
  5378 		// we still need to wait to exit PRG/RCV/DATA state 
  5965 		// we still need to wait to exit PRG/RCV/DATA state 
  5379 		m.SetTraps(KMMCErrStatus);
  5966 		m.SetTraps(KMMCErrStatus);
  5380 
  5967 
  5381 		SMF_INVOKES( ExecCommandSMST, EStIssued )
  5968 		SMF_INVOKES( ExecCommandSMST, EStIssued )
  5382 
  5969 
  5383 	SMF_STATE(EStIssued)
  5970 	SMF_STATE(EStIssued)
  5384 
  5971 
       
  5972 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM12, "EStIssued" );
  5385 		// check state of card after data transfer with CMD13.
  5973 		// check state of card after data transfer with CMD13.
  5386 
  5974 
  5387 		if (s.Command().Direction() != 0)
  5975 		if (s.Command().Direction() != 0)
  5388 			{
  5976 			{
  5389 			SMF_GOTOS(EStWaitFinish)
  5977 			SMF_GOTOS(EStWaitFinish)
  5390 			}
  5978 			}
  5391 
  5979 
  5392 		SMF_GOTOS(EStRWFinish);
  5980 		SMF_GOTOS(EStRWFinish);
  5393 
  5981 
  5394 	SMF_STATE(EStWaitFinish)
  5982 	SMF_STATE(EStWaitFinish)
       
  5983 
       
  5984 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM13, "EStWaitFinish" );
  5395 		// Save the status and examine it after issuing CMD13...
  5985 		// Save the status and examine it after issuing CMD13...
  5396 		// NB We don't know where in the command stack the last response is stored (e.g. there may 
  5986 		// NB We don't know where in the command stack the last response is stored (e.g. there may 
  5397 		// have bee a Deselect/Select issued), but we do know last response is stored in iLastStatus
  5987 		// have bee a Deselect/Select issued), but we do know last response is stored in iLastStatus
  5398 		TMMC::BigEndian4Bytes(s.ResponseP(), s.iLastStatus);
  5988 		TMMC::BigEndian4Bytes(s.ResponseP(), s.iLastStatus);
  5399 
  5989 
  5400 		s.PushCommandStack();
  5990 		s.PushCommandStack();
  5401 		s.FillCommandDesc(ECmdSendStatus, 0);
  5991 		s.FillCommandDesc(ECmdSendStatus, 0);
  5402 		SMF_INVOKES(ExecCommandSMST, EStWaitFinish1)
  5992 		SMF_INVOKES(ExecCommandSMST, EStWaitFinish1)
  5403 
  5993 
  5404 	SMF_STATE(EStWaitFinish1)
  5994 	SMF_STATE(EStWaitFinish1)
       
  5995 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM14, "EStWaitFinish1" );
  5405 		const TMMCStatus status(s.ResponseP());
  5996 		const TMMCStatus status(s.ResponseP());
  5406 		s.PopCommandStack();
  5997 		s.PopCommandStack();
  5407 
  5998 
  5408 #ifdef __WINS__
  5999 #ifdef __WINS__
  5409 		SMF_GOTOS(EStRWFinish);
  6000 		SMF_GOTOS(EStRWFinish);
  5412 		if (st1 == ECardStatePrg || st1 == ECardStateRcv || st1 == ECardStateData)
  6003 		if (st1 == ECardStatePrg || st1 == ECardStateRcv || st1 == ECardStateData)
  5413 			{
  6004 			{
  5414 			SMF_INVOKES(ProgramTimerSMST, EStWaitFinish);
  6005 			SMF_INVOKES(ProgramTimerSMST, EStWaitFinish);
  5415 			}
  6006 			}
  5416 		if (status.Error())
  6007 		if (status.Error())
       
  6008 		    {
       
  6009 		    OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT7, this, (TInt) KMMCErrStatus );
  5417 			SMF_RETURN(KMMCErrStatus)
  6010 			SMF_RETURN(KMMCErrStatus)
       
  6011 		    }
  5418 #endif
  6012 #endif
  5419 		
  6013 		
  5420 		// Fall through if CURRENT_STATE is not PGM or DATA
  6014 		// Fall through if CURRENT_STATE is not PGM or DATA
  5421 	SMF_STATE(EStRWFinish)
  6015 	SMF_STATE(EStRWFinish)
  5422 
  6016 
       
  6017 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEBLOCKSSM15, "EStRWFinish" );
  5423 		if (TMMCStatus(s.ResponseP()).Error() != 0)
  6018 		if (TMMCStatus(s.ResponseP()).Error() != 0)
       
  6019 		    {
       
  6020 		    OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT8, this, (TInt) KMMCErrStatus );
  5424 			SMF_RETURN(KMMCErrStatus);
  6021 			SMF_RETURN(KMMCErrStatus);
       
  6022 		    }
  5425 
  6023 
  5426 		s.iState &= ~KMMCSessStateInProgress;
  6024 		s.iState &= ~KMMCSessStateInProgress;
  5427 
  6025 
  5428 		// skip over recursive entry or throw error and catch in CIMLockUnlockSM()
  6026 		// skip over recursive entry or throw error and catch in CIMLockUnlockSM()
  5429 		return (s.Command().iCommand == ECmdLockUnlock) ? KMMCErrUpdPswd : KMMCErrBypass;
  6027 		TMMCErr ret = (s.Command().iCommand == ECmdLockUnlock) ? KMMCErrUpdPswd : KMMCErrBypass; 
       
  6028 		OstTraceFunctionExitExt( DMMCSTACK_CIMREADWRITEBLOCKSSM_EXIT9, this, (TInt) ret );
       
  6029 		return ret;
  5430 
  6030 
  5431 	SMF_END
  6031 	SMF_END
  5432 	}
  6032 	}
  5433 
  6033 
  5434 inline TMMCErr DMMCStack::CIMEraseSM()
  6034 inline TMMCErr DMMCStack::CIMEraseSM()
  5451 			EStEraseFinish,
  6051 			EStEraseFinish,
  5452 			EStEnd
  6052 			EStEnd
  5453 			};
  6053 			};
  5454 
  6054 
  5455 		DMMCSession& s=Session();
  6055 		DMMCSession& s=Session();
       
  6056 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_CIMERASESM1, "Current session=0x%x; Last status=0x%x", (TUint) &s, (TUint) s.iLastStatus );
       
  6057 		
  5456 
  6058 
  5457 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:EraseSM %x",TUint(s.iLastStatus)));
  6059 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:EraseSM %x",TUint(s.iLastStatus)));
  5458 
  6060 
  5459 	SMF_BEGIN
  6061 	SMF_BEGIN
  5460 
  6062 
       
  6063 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM2, "EStBegin" );
  5461 		// Check that the card supports class 4 (Write) commands
  6064 		// Check that the card supports class 4 (Write) commands
  5462 		const TUint ccc = s.iCardP->CSD().CCC();
  6065 		const TUint ccc = s.iCardP->CSD().CCC();
  5463 		if(!(ccc & KMMCCmdClassErase))
  6066 		if(!(ccc & KMMCCmdClassErase))
  5464 			return( KMMCErrNotSupported );
  6067 		    {
       
  6068 			OstTraceFunctionExitExt( DMMCSTACK_CIMERASESM_EXIT1, this, (TInt) KMMCErrNotSupported );
       
  6069 			return KMMCErrNotSupported;
       
  6070 		    }
  5465 
  6071 
  5466 		s.iState |= KMMCSessStateInProgress;
  6072 		s.iState |= KMMCSessStateInProgress;
  5467 		m.SetTraps( KMMCErrInitContext );
  6073 		m.SetTraps( KMMCErrInitContext );
  5468 
  6074 
  5469 	SMF_STATE(EStRestart)
  6075 	SMF_STATE(EStRestart)
  5470 
  6076 
       
  6077 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM3, "EStRestart" );
  5471 		SMF_CALLMEWR(EStRestart) // Create a recursive call entry to recover from Init
  6078 		SMF_CALLMEWR(EStRestart) // Create a recursive call entry to recover from Init
  5472 
  6079 
  5473 		s.ResetCommandStack();
  6080 		s.ResetCommandStack();
  5474 		SMF_INVOKES( AttachCardSMST, EStAttached )		// attachment is mandatory
  6081 		SMF_INVOKES( AttachCardSMST, EStAttached )		// attachment is mandatory
  5475 
  6082 
  5476 	SMF_BPOINT(EStAttached)
  6083 	SMF_BPOINT(EStAttached)
  5477 
  6084 
       
  6085 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM4, "EStAttached" );
  5478 		TMMCCommandDesc& cmd = s.Command();
  6086 		TMMCCommandDesc& cmd = s.Command();
  5479 
  6087 
  5480 		if(cmd.iTotalLength == 0)
  6088 		if(cmd.iTotalLength == 0)
  5481 			return( KMMCErrArgument );
  6089 		    {
       
  6090 			OstTraceFunctionExitExt( DMMCSTACK_CIMERASESM_EXIT2, this, (TInt) KMMCErrArgument );
       
  6091 			return KMMCErrArgument;
       
  6092 		    }
  5482 
  6093 
  5483 		switch( s.iSessionID )
  6094 		switch( s.iSessionID )
  5484 			{
  6095 			{
  5485 			case ECIMEraseSector:
  6096 			case ECIMEraseSector:
       
  6097 				OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM5, "ECIMEraseSector" );
  5486 				TMMCEraseInfo eraseInfo;
  6098 				TMMCEraseInfo eraseInfo;
  5487 				s.iCardP->GetEraseInfo(eraseInfo);
  6099 				s.iCardP->GetEraseInfo(eraseInfo);
  5488 				cmd.iBlockLength = eraseInfo.iMinEraseSectorSize;
  6100 				cmd.iBlockLength = eraseInfo.iMinEraseSectorSize;
  5489 				cmd.iCommand = ECmdTagSectorStart;
  6101 				cmd.iCommand = ECmdTagSectorStart;
  5490 				break;
  6102 				break;
  5491 			case ECIMEraseGroup:
  6103 			case ECIMEraseGroup:
       
  6104 				OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM6, "ECIMEraseGroup" );
  5492 				cmd.iBlockLength = s.iCardP->iCSD.EraseGroupSize();
  6105 				cmd.iBlockLength = s.iCardP->iCSD.EraseGroupSize();
  5493 				if(cmd.iBlockLength == 0 || cmd.iTotalLength % cmd.iBlockLength != 0)
  6106 				if(cmd.iBlockLength == 0 || cmd.iTotalLength % cmd.iBlockLength != 0)
       
  6107 				    {
       
  6108 					OstTraceFunctionExitExt( DMMCSTACK_CIMERASESM_EXIT3, this, (TInt) KMMCErrArgument );
  5494 					return KMMCErrArgument;
  6109 					return KMMCErrArgument;
       
  6110 				    }
  5495 				cmd.iCommand = ECmdTagEraseGroupStart;
  6111 				cmd.iCommand = ECmdTagEraseGroupStart;
  5496 				break;
  6112 				break;
  5497 			default:
  6113 			default:
  5498 				DMMCSocket::Panic(DMMCSocket::EMMCEraseSessionID);
  6114 				DMMCSocket::Panic(DMMCSocket::EMMCEraseSessionID);
  5499 			}
  6115 			}
  5500 
  6116 
  5501 		if(!cmd.AdjustForBlockOrByteAccess(s))
  6117 		if(!cmd.AdjustForBlockOrByteAccess(s))
       
  6118 		    {
       
  6119 			OstTraceFunctionExitExt( DMMCSTACK_CIMERASESM_EXIT4, this, (TInt) KMMCErrArgument );
  5502 			return KMMCErrArgument;
  6120 			return KMMCErrArgument;
       
  6121 		    }
  5503 
  6122 
  5504 		iConfig.RemoveMode( KMMCModeEnablePreemption );	// erase sequence must not be pre-empted
  6123 		iConfig.RemoveMode( KMMCModeEnablePreemption );	// erase sequence must not be pre-empted
  5505 
  6124 
  5506 		const TUint flags = cmd.iFlags;
  6125 		const TUint flags = cmd.iFlags;
  5507 		s.FillCommandDesc();
  6126 		s.FillCommandDesc();
  5508 		cmd.iFlags = flags;
  6127 		cmd.iFlags = flags;
  5509 		SMF_INVOKES( ExecCommandSMST, EStStartTagged )
  6128 		SMF_INVOKES( ExecCommandSMST, EStStartTagged )
  5510 
  6129 
  5511 	SMF_STATE(EStStartTagged)
  6130 	SMF_STATE(EStStartTagged)
  5512 
  6131 
       
  6132 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM7, "EStStartTagged" );
  5513 		const TMMCCommandDesc& cmd = s.Command();
  6133 		const TMMCCommandDesc& cmd = s.Command();
  5514 
  6134 
  5515 		TMMCCommandEnum command;
  6135 		TMMCCommandEnum command;
  5516 		TUint endAddr = cmd.iArgument;
  6136 		TUint endAddr = cmd.iArgument;
  5517 		if(s.iSessionID == ECIMEraseSector)
  6137 		if(s.iSessionID == ECIMEraseSector)
  5537 		s.FillCommandDesc( command, endAddr );
  6157 		s.FillCommandDesc( command, endAddr );
  5538 		SMF_INVOKES( ExecCommandSMST, EStEndTagged )
  6158 		SMF_INVOKES( ExecCommandSMST, EStEndTagged )
  5539 
  6159 
  5540 	SMF_STATE(EStEndTagged)
  6160 	SMF_STATE(EStEndTagged)
  5541 
  6161 
       
  6162 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM8, "EStEndTagged" );
  5542 		// Increase the inactivity timeout as an erase operation can potentially take a long time
  6163 		// Increase the inactivity timeout as an erase operation can potentially take a long time
  5543 		// At the moment this is a somewhat arbitrary 30 seconds. This could be calculated more accurately
  6164 		// At the moment this is a somewhat arbitrary 30 seconds. This could be calculated more accurately
  5544 		// using TAAC,NSAC, R2W_FACTOR etc. but that seems to yield very large values (?)
  6165 		// using TAAC,NSAC, R2W_FACTOR etc. but that seems to yield very large values (?)
  5545 		const TInt KMaxEraseTimeoutInSeconds = 30;
  6166 		const TInt KMaxEraseTimeoutInSeconds = 30;
  5546 		iBody->SetInactivityTimeout(KMaxEraseTimeoutInSeconds);
  6167 		iBody->SetInactivityTimeout(KMaxEraseTimeoutInSeconds);
  5547 		m.SetTraps(KMMCErrAll);
  6168 		m.SetTraps(KMMCErrAll);
  5548 		s.FillCommandDesc( ECmdErase, 0 );
  6169 		s.FillCommandDesc( ECmdErase, 0 );
  5549 		SMF_INVOKES( ExecCommandSMST, EStErased )
  6170 		SMF_INVOKES( ExecCommandSMST, EStErased )
  5550 
  6171 
  5551 	SMF_STATE(EStErased)
  6172 	SMF_STATE(EStErased)
       
  6173 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM9, "EStErased" );
  5552 		m.SetTraps( KMMCErrInitContext );
  6174 		m.SetTraps( KMMCErrInitContext );
  5553 		iBody->RestoreInactivityTimeout();
  6175 		iBody->RestoreInactivityTimeout();
  5554 		if (err != KMMCErrNone)
  6176 		if (err != KMMCErrNone)
       
  6177 		    {
       
  6178 		    OstTraceFunctionExitExt( DMMCSTACK_CIMERASESM_EXIT5, this, (TInt) err );
  5555 			SMF_RETURN(err);
  6179 			SMF_RETURN(err);
       
  6180 		    }
  5556 
  6181 
  5557 
  6182 
  5558 	SMF_STATE(EStWaitFinish)
  6183 	SMF_STATE(EStWaitFinish)
  5559 
  6184 
       
  6185 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM10, "EStWaitFinish" );
  5560 		s.PushCommandStack();
  6186 		s.PushCommandStack();
  5561 		s.FillCommandDesc(ECmdSendStatus, 0);
  6187 		s.FillCommandDesc(ECmdSendStatus, 0);
  5562 		SMF_INVOKES(ExecCommandSMST, EStWaitFinish1)
  6188 		SMF_INVOKES(ExecCommandSMST, EStWaitFinish1)
  5563 
  6189 
  5564 	SMF_STATE(EStWaitFinish1)
  6190 	SMF_STATE(EStWaitFinish1)
  5565 
  6191 
       
  6192 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM11, "EStWaitFinish1" );
  5566 		const TMMCStatus st(s.ResponseP());
  6193 		const TMMCStatus st(s.ResponseP());
  5567 		s.PopCommandStack();
  6194 		s.PopCommandStack();
  5568 
  6195 
  5569 #ifdef __WINS__
  6196 #ifdef __WINS__
  5570 		SMF_GOTOS(EStEraseFinish);
  6197 		SMF_GOTOS(EStEraseFinish);
  5577 #endif
  6204 #endif
  5578 		
  6205 		
  5579 		// Fall through if CURRENT_STATE is not PGM or DATA
  6206 		// Fall through if CURRENT_STATE is not PGM or DATA
  5580 	SMF_STATE(EStEraseFinish)
  6207 	SMF_STATE(EStEraseFinish)
  5581 
  6208 
       
  6209 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMERASESM12, "EStEraseFinish" );
  5582 		s.iState &= ~KMMCSessStateInProgress;
  6210 		s.iState &= ~KMMCSessStateInProgress;
  5583 		return( KMMCErrBypass );		// to skip over the recursive entry
  6211 		OstTraceFunctionExitExt( DMMCSTACK_CIMERASESM_EXIT6, this, (TInt) KMMCErrBypass );
       
  6212 		return KMMCErrBypass;		// to skip over the recursive entry
  5584 
  6213 
  5585 	SMF_END
  6214 	SMF_END
  5586 	}
  6215 	}
  5587 
  6216 
  5588 inline TMMCErr DMMCStack::CIMReadWriteIOSM()
  6217 inline TMMCErr DMMCStack::CIMReadWriteIOSM()
  5601 			EStEnd
  6230 			EStEnd
  5602 			};
  6231 			};
  5603 
  6232 
  5604 		DMMCSession& s=Session();
  6233 		DMMCSession& s=Session();
  5605 		TMMCCommandDesc& cmd = s.Command();
  6234 		TMMCCommandDesc& cmd = s.Command();
       
  6235 		OstTraceExt2( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEIOSM1, "Current session=0x%x; Last status=0x%x", (TUint) &s, (TUint) s.iLastStatus );
       
  6236 		
  5606 
  6237 
  5607 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:IOSM %x",TUint(s.iLastStatus)));
  6238 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:IOSM %x",TUint(s.iLastStatus)));
  5608 
  6239 
  5609 	SMF_BEGIN
  6240 	SMF_BEGIN
       
  6241 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEIOSM2, "EStBegin" );
  5610 		s.iState |= KMMCSessStateInProgress;
  6242 		s.iState |= KMMCSessStateInProgress;
  5611 		TUint argument = (TUint(cmd.iArgument)&0x7F) << 8; // shift reg addr into a proper position
  6243 		TUint argument = (TUint(cmd.iArgument)&0x7F) << 8; // shift reg addr into a proper position
  5612 
  6244 
  5613 		switch( s.iSessionID )
  6245 		switch( s.iSessionID )
  5614 			{
  6246 			{
  5626 
  6258 
  5627 		SMF_INVOKES( AttachCardSMST, EStIOLoop )	// attachment's mandatory
  6259 		SMF_INVOKES( AttachCardSMST, EStIOLoop )	// attachment's mandatory
  5628 
  6260 
  5629 	SMF_STATE(EStReadIO)
  6261 	SMF_STATE(EStReadIO)
  5630 
  6262 
       
  6263 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEIOSM3, "EStReadIO" );
  5631 		*(cmd.iDataMemoryP)++ = s.ResponseP()[3];
  6264 		*(cmd.iDataMemoryP)++ = s.ResponseP()[3];
  5632 		cmd.iTotalLength--;
  6265 		cmd.iTotalLength--;
  5633 
  6266 
  5634 	SMF_BPOINT(EStIOLoop)
  6267 	SMF_BPOINT(EStIOLoop)
  5635 
  6268 
       
  6269 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMREADWRITEIOSM4, "EStIOLoop" );
  5636 		s.iBytesTransferred++;
  6270 		s.iBytesTransferred++;
  5637 
  6271 
  5638 		if( cmd.iTotalLength == 0 )
  6272 		if( cmd.iTotalLength == 0 )
  5639 			{
  6273 			{
  5640 			s.iState &= ~KMMCSessStateInProgress;
  6274 			s.iState &= ~KMMCSessStateInProgress;
  5674 			EStEnd
  6308 			EStEnd
  5675 			};
  6309 			};
  5676 
  6310 
  5677 		DMMCSession& s=Session();
  6311 		DMMCSession& s=Session();
  5678 		TMMCCommandDesc& cmd = Command();
  6312 		TMMCCommandDesc& cmd = Command();
       
  6313 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM1, "Current session=0x%x", &s );
  5679 
  6314 
  5680 		__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm"));
  6315 		__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm"));
  5681 
  6316 
  5682 	SMF_BEGIN
  6317 	SMF_BEGIN
       
  6318         
       
  6319 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM2, "EStBegin" );
  5683 		m.SetTraps(KMMCErrStatus | KMMCErrUpdPswd);
  6320 		m.SetTraps(KMMCErrStatus | KMMCErrUpdPswd);
  5684 		cmd.iUnlockRetries = 0;					// attempt counter
  6321 		cmd.iUnlockRetries = 0;					// attempt counter
  5685 		iCMD42CmdByte = cmd.iDataMemoryP[0];
  6322 		iCMD42CmdByte = cmd.iDataMemoryP[0];
  5686 
  6323 
  5687 	SMF_STATE(EStRetry)
  6324 	SMF_STATE(EStRetry)
       
  6325 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM3, "EStRetry" );
  5688 		__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:%x/%x", cmd.iUnlockRetries, (iSessionP == &iAutoUnlockSession) ? KMMCMaxAutoUnlockRetries : iConfig.iUnlockRetries));
  6326 		__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:%x/%x", cmd.iUnlockRetries, (iSessionP == &iAutoUnlockSession) ? KMMCMaxAutoUnlockRetries : iConfig.iUnlockRetries));
  5689 
  6327 
  5690 	if (iCMD42CmdByte == KMMCLockUnlockErase)
  6328 	if (iCMD42CmdByte == KMMCLockUnlockErase)
  5691 		{
  6329 		{
  5692 		// Section 4.6.2 of version 4.2 of the the MMC specification states that 
  6330 		// Section 4.6.2 of version 4.2 of the the MMC specification states that 
  5698 
  6336 
  5699 
  6337 
  5700 		SMF_INVOKES(CIMReadWriteBlocksSMST, EStTestR1);
  6338 		SMF_INVOKES(CIMReadWriteBlocksSMST, EStTestR1);
  5701 	
  6339 	
  5702 	SMF_STATE(EStTestR1)
  6340 	SMF_STATE(EStTestR1)
       
  6341 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM4, "EStTestR1" );
  5703 		if (iCMD42CmdByte == KMMCLockUnlockErase)
  6342 		if (iCMD42CmdByte == KMMCLockUnlockErase)
  5704 			{
  6343 			{
  5705 			m.SetTraps(KMMCErrStatus | KMMCErrUpdPswd);
  6344 			m.SetTraps(KMMCErrStatus | KMMCErrUpdPswd);
  5706 			iBody->RestoreInactivityTimeout();
  6345 			iBody->RestoreInactivityTimeout();
  5707 			}
  6346 			}
  5711 			const TMMCStatus st = s.LastStatus();	// set in ExecCommandSM() / EStCommandIssued
  6350 			const TMMCStatus st = s.LastStatus();	// set in ExecCommandSM() / EStCommandIssued
  5712 			TMMCCommandDesc& cmd0 = Command();
  6351 			TMMCCommandDesc& cmd0 = Command();
  5713 			
  6352 			
  5714 			__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:EStTestR1 [err: %08x, st:%08x] : RETRY [%d]", 
  6353 			__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:EStTestR1 [err: %08x, st:%08x] : RETRY [%d]", 
  5715 											  err, (TInt)s.LastStatus(), cmd0.iUnlockRetries));
  6354 											  err, (TInt)s.LastStatus(), cmd0.iUnlockRetries));
       
  6355 			OstTraceExt3( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM5, "err=%08x; Last status=%d; Unlock retries=%d", (TUint) err, (TInt) s.LastStatus(), (TUint) cmd0.iUnlockRetries );
  5716 
  6356 
  5717 			const TInt KMaxRetries = (iSessionP == &iAutoUnlockSession) ? KMMCMaxAutoUnlockRetries : iConfig.iUnlockRetries;
  6357 			const TInt KMaxRetries = (iSessionP == &iAutoUnlockSession) ? KMMCMaxAutoUnlockRetries : iConfig.iUnlockRetries;
  5718 			
  6358 			
  5719 			// retry if LOCK_UNLOCK_FAIL only error bit
  6359 			// retry if LOCK_UNLOCK_FAIL only error bit
  5720 			if (!(	iCMD42CmdByte == 0	// LOCK_UNLOCK = 0; SET_PWD = 0
  6360 			if (!(	iCMD42CmdByte == 0	// LOCK_UNLOCK = 0; SET_PWD = 0
  5721 				&&	err == KMMCErrStatus && st.Error() == KMMCStatErrLockUnlock
  6361 				&&	err == KMMCErrStatus && st.Error() == KMMCStatErrLockUnlock
  5722 				&&	(iConfig.iModes & KMMCModeEnableUnlockRetry) != 0
  6362 				&&	(iConfig.iModes & KMMCModeEnableUnlockRetry) != 0
  5723 				&&	++cmd0.iUnlockRetries < KMaxRetries ))
  6363 				&&	++cmd0.iUnlockRetries < KMaxRetries ))
  5724 				{
  6364 				{
  5725 				__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:abt"));
  6365 				__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:abt"));
  5726 
  6366                 OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM6, "LockUnlock abort" );
       
  6367                 OstTraceFunctionExitExt( DMMCSTACK_CIMLOCKUNLOCKSM_EXIT, this, (TInt) err );
  5727 				SMF_RETURN(err);
  6368 				SMF_RETURN(err);
  5728 				}
  6369 				}
  5729 
  6370 
  5730 			__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:retry"));
  6371 			__KTRACE_OPT(KPBUS1, Kern::Printf("mmc:clusm:retry"));
       
  6372 			OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMLOCKUNLOCKSM7, "LockUnlock retry" );
  5731 
  6373 
  5732 #ifdef __EPOC32__
  6374 #ifdef __EPOC32__
  5733 			s.SynchBlock(KMMCBlockOnRetryTimer);
  6375 			s.SynchBlock(KMMCBlockOnRetryTimer);
  5734 			s.iRetryTimer.OneShot(KMMCUnlockRetryGapInMilliseconds,EFalse);
  6376 			s.iRetryTimer.OneShot(KMMCUnlockRetryGapInMilliseconds,EFalse);
  5735 			SMF_WAITS(EStRetry)
  6377 			SMF_WAITS(EStRetry)
  5751 			
  6393 			
  5752 			SMF_EXIT;
  6394 			SMF_EXIT;
  5753 			}
  6395 			}
  5754 		else if (err != KMMCErrNone)
  6396 		else if (err != KMMCErrNone)
  5755 			{
  6397 			{
       
  6398 			OstTraceFunctionExitExt( DMMCSTACK_CIMLOCKUNLOCKSM_EXIT2, this, (TInt) err );
  5756 			SMF_RETURN(err);
  6399 			SMF_RETURN(err);
  5757 			}
  6400 			}
  5758 
  6401 
  5759 
  6402 
  5760 	SMF_END
  6403 	SMF_END
  5778 			};
  6421 			};
  5779 
  6422 
  5780 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:CIMAutoUnlockSM"));
  6423 		__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:CIMAutoUnlockSM"));
  5781 
  6424 
  5782 		DMMCSession& s=Session();
  6425 		DMMCSession& s=Session();
       
  6426 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CIMAUTOUNLOCKSM1, "Current session=0x%x", &s );
  5783 
  6427 
  5784 	SMF_BEGIN
  6428 	SMF_BEGIN
  5785 
  6429 
       
  6430 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMAUTOUNLOCKSM2, "EStBegin" );
  5786 		iAutoUnlockIndex = -1;
  6431 		iAutoUnlockIndex = -1;
  5787 
  6432 
  5788 		m.SetTraps(KMMCErrAll);	// Trap (and ignore) all errors during auto-unlock
  6433 		m.SetTraps(KMMCErrAll);	// Trap (and ignore) all errors during auto-unlock
  5789 
  6434 
  5790 	SMF_STATE(EStNextIndex)
  6435 	SMF_STATE(EStNextIndex)
  5791 
  6436 
       
  6437 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMAUTOUNLOCKSM3, "EStNextIndex" );
  5792 		if(err)
  6438 		if(err)
  5793 			{
  6439 			{
  5794 			iSocket->PasswordControlEnd(&Session(), err);
  6440 			iSocket->PasswordControlEnd(&Session(), err);
  5795 			}
  6441 			}
  5796 
  6442 
  5830 		//
  6476 		//
  5831 		// Upon completion, test the next card before performing further initialisation.
  6477 		// Upon completion, test the next card before performing further initialisation.
  5832 		//
  6478 		//
  5833 
  6479 
  5834 		TMMCard &cd = *(iCardArray->CardP(iAutoUnlockIndex++));
  6480 		TMMCard &cd = *(iCardArray->CardP(iAutoUnlockIndex++));
       
  6481 		OstTrace1( TRACE_INTERNALS, DMMCSTACK_CIMAUTOUNLOCKSM4, "Attempting to unlock card %d", cd.Number() );
       
  6482 		
  5835 		s.SetCard(&cd);
  6483 		s.SetCard(&cd);
  5836 
  6484 
  5837 		const TInt kPWD_LEN = mp->iPWD.Length();
  6485 		const TInt kPWD_LEN = mp->iPWD.Length();
  5838 		iPSLBuf[0] = 0;				// LOCK_UNLOCK = 0; unlock
  6486 		iPSLBuf[0] = 0;				// LOCK_UNLOCK = 0; unlock
  5839 		iPSLBuf[1] = static_cast<TUint8>(kPWD_LEN);
  6487 		iPSLBuf[1] = static_cast<TUint8>(kPWD_LEN);
  5847 
  6495 
  5848 		SMF_INVOKES( CIMLockUnlockSMST, EStNextIndex )
  6496 		SMF_INVOKES( CIMLockUnlockSMST, EStNextIndex )
  5849 
  6497 
  5850 	SMF_STATE(EStInitStackAfterUnlock)
  6498 	SMF_STATE(EStInitStackAfterUnlock)
  5851 
  6499 
       
  6500 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMAUTOUNLOCKSM5, "EStInitStackAfterUnlock" );
  5852 		//
  6501 		//
  5853 		// We've attempted to unlock all cards (successfully or not)
  6502 		// We've attempted to unlock all cards (successfully or not)
  5854 		//  - Now perform second-stage initialisation that can only be performed
  6503 		//  - Now perform second-stage initialisation that can only be performed
  5855 		//    on unlocked cards (such as setting bus width, high speed etc..)
  6504 		//    on unlocked cards (such as setting bus width, high speed etc..)
  5856 		//
  6505 		//
  5858 		m.ResetTraps();
  6507 		m.ResetTraps();
  5859 
  6508 
  5860 		SMF_INVOKES( InitStackAfterUnlockSMST, EStDone )
  6509 		SMF_INVOKES( InitStackAfterUnlockSMST, EStDone )
  5861 
  6510 
  5862 	SMF_STATE(EStDone)
  6511 	SMF_STATE(EStDone)
       
  6512 		OstTrace0( TRACE_INTERNALS, DMMCSTACK_CIMAUTOUNLOCKSM6, "EStDone" );
  5863 
  6513 
  5864 	SMF_END
  6514 	SMF_END
  5865 	}
  6515 	}
  5866 
  6516 
  5867 inline TMMCErr DMMCStack::NoSessionSM()
  6517 inline TMMCErr DMMCStack::NoSessionSM()
  6014 * controllers can override this to generate more specific objects.
  6664 * controllers can override this to generate more specific objects.
  6015 * @param aCallBack Callback function to notify the client that a session has completed
  6665 * @param aCallBack Callback function to notify the client that a session has completed
  6016 * @return A pointer to the new session
  6666 * @return A pointer to the new session
  6017 */
  6667 */
  6018 	{
  6668 	{
       
  6669 	OstTraceFunctionEntry1( DMMCSTACK_ALLOCSESSION_ENTRY, this );
  6019 	return new DMMCSession(aCallBack);
  6670 	return new DMMCSession(aCallBack);
  6020 	}
  6671 	}
  6021 
  6672 
  6022 EXPORT_C void DMMCStack::Dummy1() {}
  6673 EXPORT_C void DMMCStack::Dummy1() {}
  6023 
  6674 
  6025  * Calls the PSL-implemented function SetBusWidth() if the bus width has changed
  6676  * Calls the PSL-implemented function SetBusWidth() if the bus width has changed
  6026  *
  6677  *
  6027  */
  6678  */
  6028 void DMMCStack::DoSetBusWidth(TUint32 aBusWidth)
  6679 void DMMCStack::DoSetBusWidth(TUint32 aBusWidth)
  6029 	{
  6680 	{
       
  6681 	OstTraceFunctionEntryExt( DMMCSTACK_DOSETBUSWIDTH_ENTRY, this );
  6030 	if (iBody->iCurrentSelectedBusWidth != aBusWidth)
  6682 	if (iBody->iCurrentSelectedBusWidth != aBusWidth)
  6031 		{
  6683 		{
  6032 		iBody->iCurrentSelectedBusWidth = aBusWidth;
  6684 		iBody->iCurrentSelectedBusWidth = aBusWidth;
  6033 		SetBusWidth(aBusWidth);
  6685 		SetBusWidth(aBusWidth);
  6034 		}
  6686 		}
       
  6687 	OstTraceFunctionExit1( DMMCSTACK_DOSETBUSWIDTH_EXIT, this );
  6035 	}
  6688 	}
  6036 
  6689 
  6037 /**
  6690 /**
  6038  * Sets iConfig.iBusConfig.iBusClock - which the PSL SHOULD use to set the clock before every command.
  6691  * Sets iConfig.iBusConfig.iBusClock - which the PSL SHOULD use to set the clock before every command.
  6039  *
  6692  *
  6042  *
  6695  *
  6043  * @param aClock The requested clock frequency in Kilohertz
  6696  * @param aClock The requested clock frequency in Kilohertz
  6044  */
  6697  */
  6045 void DMMCStack::DoSetClock(TUint32 aClock)
  6698 void DMMCStack::DoSetClock(TUint32 aClock)
  6046 	{
  6699 	{
       
  6700 	OstTraceFunctionEntryExt( DMMCSTACK_DOSETCLOCK_ENTRY, this );
  6047 	iConfig.iBusConfig.iBusClock = aClock;
  6701 	iConfig.iBusConfig.iBusClock = aClock;
  6048 
  6702 
  6049 	if (iPoweredUp&&(iBody->iCurrentSelectedClock != aClock))
  6703 	if (iPoweredUp&&(iBody->iCurrentSelectedClock != aClock))
  6050 		{
  6704 		{
  6051 		iBody->iCurrentSelectedClock = aClock;
  6705 		iBody->iCurrentSelectedClock = aClock;
  6052 		SetBusConfigDefaults(iConfig.iBusConfig, aClock);
  6706 		SetBusConfigDefaults(iConfig.iBusConfig, aClock);
  6053 		}
  6707 		}
       
  6708 	OstTraceFunctionExit1( DMMCSTACK_DOSETCLOCK_EXIT, this );
  6054 	}
  6709 	}
  6055 
  6710 
  6056 
  6711 
  6057 TUint DMMCStack::MaxTranSpeedInKilohertz(const TMMCard& aCard) const
  6712 TUint DMMCStack::MaxTranSpeedInKilohertz(const TMMCard& aCard) const
  6058 	{
  6713 	{
       
  6714 	OstTraceFunctionEntry1( DMMCSTACK_MAXTRANSPEEDINKILOHERTZ_ENTRY, this );
  6059 	TUint32 highSpeedClock = aCard.HighSpeedClock();
  6715 	TUint32 highSpeedClock = aCard.HighSpeedClock();
  6060 	return highSpeedClock ? highSpeedClock : aCard.MaxTranSpeedInKilohertz();
  6716 	TUint ret = highSpeedClock ? highSpeedClock : aCard.MaxTranSpeedInKilohertz(); 
       
  6717 	OstTraceFunctionExitExt( DMMCSTACK_MAXTRANSPEEDINKILOHERTZ_EXIT, this, ret );
       
  6718 	return ret;
  6061 	}
  6719 	}
  6062 
  6720 
  6063 
  6721 
  6064 
  6722 
  6065 EXPORT_C void DMMCStack::SetBusWidth(TUint32 /*aBusWidth*/)
  6723 EXPORT_C void DMMCStack::SetBusWidth(TUint32 /*aBusWidth*/)
  6075  * Returns the bus width as a TBusWidth given a card's bus width 
  6733  * Returns the bus width as a TBusWidth given a card's bus width 
  6076  * expressed as an integer (1,4 or 8)
  6734  * expressed as an integer (1,4 or 8)
  6077  * @return the bus width encoded as a TBusWidth
  6735  * @return the bus width encoded as a TBusWidth
  6078  */
  6736  */
  6079 	{
  6737 	{
       
  6738 	OstTraceFunctionEntryExt( DMMCSTACK_BUSWIDTHENCODING_ENTRY, this );
  6080 	TBusWidth busWidth = EBusWidth1;
  6739 	TBusWidth busWidth = EBusWidth1;
  6081 
  6740 
  6082 	switch(aBusWidth)
  6741 	switch(aBusWidth)
  6083 		{
  6742 		{
  6084 		case 8: 
  6743 		case 8: 
  6093 			break;
  6752 			break;
  6094 		default:
  6753 		default:
  6095 			DMMCSocket::Panic(DMMCSocket::EMMCBadBusWidth);
  6754 			DMMCSocket::Panic(DMMCSocket::EMMCBadBusWidth);
  6096 
  6755 
  6097 		}
  6756 		}
       
  6757 	OstTraceFunctionExitExt( DMMCSTACK_BUSWIDTHENCODING_EXIT, this, ( TUint )&( busWidth ) );
  6098 	return busWidth;
  6758 	return busWidth;
  6099 	}
  6759 	}
  6100 
  6760 
  6101 /**
  6761 /**
  6102  * class DMMCSocket 
  6762  * class DMMCSocket 
  6108  * @param aPasswordStore pointer to the password store
  6768  * @param aPasswordStore pointer to the password store
  6109  */
  6769  */
  6110 	:DPBusSocket(aSocketNumber),
  6770 	:DPBusSocket(aSocketNumber),
  6111 	iPasswordStore(aPasswordStore)
  6771 	iPasswordStore(aPasswordStore)
  6112 	{
  6772 	{
       
  6773 	OstTraceFunctionEntryExt( DMMCSOCKET_DMMCSOCKET_ENTRY, this );
  6113 	}
  6774 	}
  6114 
  6775 
  6115 TInt DMMCSocket::TotalSupportedCards()
  6776 TInt DMMCSocket::TotalSupportedCards()
  6116 /**
  6777 /**
  6117  * Returns the total number of MMC slots supported by the socket.
  6778  * Returns the total number of MMC slots supported by the socket.
  6118  * @return The number of MMC slots supported by the socket
  6779  * @return The number of MMC slots supported by the socket
  6119  */
  6780  */
  6120 	{
  6781 	{
       
  6782 	OstTraceFunctionEntry1( DMMCSOCKET_TOTALSUPPORTEDCARDS_ENTRY, this );
       
  6783 	OstTraceFunctionExitExt( DMMCSOCKET_TOTALSUPPORTEDCARDS_EXIT, this, iMachineInfo.iTotalSockets );
  6121 	return iMachineInfo.iTotalSockets;
  6784 	return iMachineInfo.iTotalSockets;
  6122 	}
  6785 	}
  6123 
  6786 
  6124 
  6787 
  6125 // -------- Password store management --------
  6788 // -------- Password store management --------
  6148  * @return KErrAccessDenied An attempt to lock or clear was made with a NULL password.
  6811  * @return KErrAccessDenied An attempt to lock or clear was made with a NULL password.
  6149  * @return KErrLocked An an attempt to unlock was made with a NULL password.
  6812  * @return KErrLocked An an attempt to unlock was made with a NULL password.
  6150  * @return KErrNone on success
  6813  * @return KErrNone on success
  6151  */
  6814  */
  6152 	{
  6815 	{
       
  6816 	OstTraceExt3(TRACE_FLOW, DMMCSOCKET_PREPARESTORE_ENTRY, "DMMCSocket::PrepareStore;aBus=%d;aFunc=%d;this=%x", aBus, aFunc, (TUint) this);
  6153 	TInt r = 0;
  6817 	TInt r = 0;
  6154 
  6818 
  6155 	TMMCard *card=iStack->CardP(aBus);
  6819 	TMMCard *card=iStack->CardP(aBus);
  6156 	__ASSERT_ALWAYS(card, Panic(EMMCSessionNoPswdCard));
  6820 	__ASSERT_ALWAYS(card, Panic(EMMCSessionNoPswdCard));
  6157 	const TCID &cid = card->CID();
  6821 	const TCID &cid = card->CID();
  6194 	default:
  6858 	default:
  6195 		Panic(EMMCSessionPswdCmd);
  6859 		Panic(EMMCSessionPswdCmd);
  6196 		break;
  6860 		break;
  6197 		}
  6861 		}
  6198 
  6862 
       
  6863 	OstTraceFunctionExitExt( DMMCSOCKET_PREPARESTORE_EXIT, this, r );
  6199 	return r;
  6864 	return r;
  6200 	}
  6865 	}
  6201 
  6866 
  6202 
  6867 
  6203 TInt DMMCSocket::PasswordControlStart(const TCID &aCID, const TMediaPassword *aPWD)
  6868 TInt DMMCSocket::PasswordControlStart(const TCID &aCID, const TMediaPassword *aPWD)
  6216  * trying to unlock a card with the wrong password.
  6881  * trying to unlock a card with the wrong password.
  6217  * 
  6882  * 
  6218  * See PasswordControlEnd() for recovery policy.
  6883  * See PasswordControlEnd() for recovery policy.
  6219  */
  6884  */
  6220 	{
  6885 	{
       
  6886 	OstTraceFunctionEntry1( DMMCSOCKET_PASSWORDCONTROLSTART_ENTRY, this );
  6221 	TInt r = KErrNone;							// error code
  6887 	TInt r = KErrNone;							// error code
  6222 
  6888 
  6223 	TBool changed = EFalse;						// compress store if changed
  6889 	TBool changed = EFalse;						// compress store if changed
  6224 
  6890 
  6225 	TBuf8<KMMCCIDLength> cid;					// convert to TBuf8<> for comparison
  6891 	TBuf8<KMMCCIDLength> cid;					// convert to TBuf8<> for comparison
  6264 
  6930 
  6265 		if (!s)
  6931 		if (!s)
  6266 			{
  6932 			{
  6267 			TMediaPassword mp;					// empty, to indicate !s
  6933 			TMediaPassword mp;					// empty, to indicate !s
  6268 			if ((r = iPasswordStore->InsertMapping(aCID, mp, TMapping::EStPending)) != KErrNone)
  6934 			if ((r = iPasswordStore->InsertMapping(aCID, mp, TMapping::EStPending)) != KErrNone)
       
  6935 			    {
       
  6936 				OstTraceFunctionExitExt( DMMCSOCKET_PASSWORDCONTROLSTART_EXIT1, this, r );
  6269 				return r;
  6937 				return r;
       
  6938 			    }
  6270 
  6939 
  6271 			changed = ETrue;
  6940 			changed = ETrue;
  6272 			}
  6941 			}
  6273 		}
  6942 		}
  6274 
  6943 
  6275 	if (changed)
  6944 	if (changed)
  6276 		iPasswordStore->iStore->Compress();
  6945 		iPasswordStore->iStore->Compress();
  6277 
  6946 
       
  6947 	OstTraceFunctionExitExt( DMMCSOCKET_PASSWORDCONTROLSTART_EXIT2, this, r );
  6278 	return r;
  6948 	return r;
  6279 	}
  6949 	}
  6280 
  6950 
  6281 
  6951 
  6282 
  6952 
  6302  * 	I	invalidate	R	restore
  6972  * 	I	invalidate	R	restore
  6303  * '
  6973  * '
  6304  * See PasswordControlStart() for details of how store set up.
  6974  * See PasswordControlStart() for details of how store set up.
  6305  */
  6975  */
  6306 	{
  6976 	{
       
  6977 	OstTraceFunctionEntryExt( DMMCSOCKET_PASSWORDCONTROLEND_ENTRY, this );
  6307 	// autounlock is a special case because the PasswordControlStart() will
  6978 	// autounlock is a special case because the PasswordControlStart() will
  6308 	// not have been called (the CID is not known in ks context.)  The mapping
  6979 	// not have been called (the CID is not known in ks context.)  The mapping
  6309 	// for this specific card is removed on failure, because it is the current
  6980 	// for this specific card is removed on failure, because it is the current
  6310 	// mapping that is definitely wrong.
  6981 	// mapping that is definitely wrong.
  6311 
  6982 
  6352 		TMapping mp, *pmp;						// get mapping to mutate
  7023 		TMapping mp, *pmp;						// get mapping to mutate
  6353 		mp.iCID = cid;
  7024 		mp.iCID = cid;
  6354 		TInt psn = iPasswordStore->iStore->Find(mp, iPasswordStore->iIdentityRelation);
  7025 		TInt psn = iPasswordStore->iStore->Find(mp, iPasswordStore->iIdentityRelation);
  6355 		if (psn == KErrNotFound)
  7026 		if (psn == KErrNotFound)
  6356 			{
  7027 			{
       
  7028 			OstTraceFunctionExit1( DMMCSOCKET_PASSWORDCONTROLEND_EXIT1, this );
  6357 			return;
  7029 			return;
  6358 			}
  7030 			}
  6359 		else
  7031 		else
  6360 			{
  7032 			{
  6361 			pmp = &(*iPasswordStore->iStore)[psn];
  7033 			pmp = &(*iPasswordStore->iStore)[psn];
  6384 				if (s)	// s & ~t & ~f
  7056 				if (s)	// s & ~t & ~f
  6385 					pmp->iState = TMapping::EStInvalid;	// wipe
  7057 					pmp->iState = TMapping::EStInvalid;	// wipe
  6386 				}
  7058 				}
  6387 			}	// else (f)
  7059 			}	// else (f)
  6388 		}	// else if (aSessP == &iStack->iAutoUnlockSession)
  7060 		}	// else if (aSessP == &iStack->iAutoUnlockSession)
       
  7061 	OstTraceFunctionExit1( DMMCSOCKET_PASSWORDCONTROLEND_EXIT2, this );
  6389 	}
  7062 	}
  6390 
  7063 
  6391 
  7064 
  6392 TMMCPasswordStore::TMMCPasswordStore()
  7065 TMMCPasswordStore::TMMCPasswordStore()
  6393 /**
  7066 /**
  6394  * Contructor
  7067  * Contructor
  6395  */
  7068  */
  6396 	: iIdentityRelation(TMMCPasswordStore::CompareCID)
  7069 	: iIdentityRelation(TMMCPasswordStore::CompareCID)
  6397 	{
  7070 	{
       
  7071 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_TMMCPASSWORDSTORE_ENTRY, this );
  6398 	}
  7072 	}
  6399 
  7073 
  6400 TInt TMMCPasswordStore::Init()
  7074 TInt TMMCPasswordStore::Init()
  6401 /**
  7075 /**
  6402  * Initialises the password store and allocates resources.
  7076  * Initialises the password store and allocates resources.
  6403  * @return KErrNone if successful, standard error code otherwise.
  7077  * @return KErrNone if successful, standard error code otherwise.
  6404  */
  7078  */
  6405 	{
  7079 	{
       
  7080 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_INIT_ENTRY, this );
  6406 	// We don't have a destructor yet as this object lasts forever
  7081 	// We don't have a destructor yet as this object lasts forever
  6407 	iStore = new RArray<TMapping>(4, _FOFF(TMapping, iCID));
  7082 	iStore = new RArray<TMapping>(4, _FOFF(TMapping, iCID));
  6408 	if(!iStore)
  7083 	if(!iStore)
       
  7084 	    {
       
  7085 		OstTraceFunctionExitExt( TMMCPASSWORDSTORE_INIT_EXIT1, this, KErrNoMemory );
  6409 		return KErrNoMemory;
  7086 		return KErrNoMemory;
       
  7087 	    }
       
  7088 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_INIT_EXIT2, this, KErrNone );
  6410 	return KErrNone;
  7089 	return KErrNone;
  6411 	}
  7090 	}
  6412 
  7091 
  6413 EXPORT_C TBool TMMCPasswordStore::IsMappingIncorrect(const TCID& aCID, const TMediaPassword& aPWD)
  7092 EXPORT_C TBool TMMCPasswordStore::IsMappingIncorrect(const TCID& aCID, const TMediaPassword& aPWD)
  6414 /**
  7093 /**
  6415  * Returns true if the password is definitely incorrect, i.e. if a valid entry with a
  7094  * Returns true if the password is definitely incorrect, i.e. if a valid entry with a
  6416  * different password exists.  Returns false if correct (because the mapping matches,)
  7095  * different password exists.  Returns false if correct (because the mapping matches,)
  6417  * or if cannot tell (because no valid mapping.)
  7096  * or if cannot tell (because no valid mapping.)
  6418  */
  7097  */
  6419 	{
  7098 	{
       
  7099 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_ISMAPPINGINCORRECT_ENTRY, this );
  6420 	TMapping* pmp = FindMappingInStore(aCID);
  7100 	TMapping* pmp = FindMappingInStore(aCID);
  6421 	return (pmp != 0 && pmp->iState == TMapping::EStValid && pmp->iPWD.Compare(aPWD) != 0);
  7101 	TBool ret = pmp != 0 && pmp->iState == TMapping::EStValid && pmp->iPWD.Compare(aPWD) != 0;
       
  7102 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_ISMAPPINGINCORRECT_EXIT, this, ret );
       
  7103 	return ret;
  6422 	}
  7104 	}
  6423 
  7105 
  6424 TMapping *TMMCPasswordStore::FindMappingInStore(const TCID &aCID)
  7106 TMapping *TMMCPasswordStore::FindMappingInStore(const TCID &aCID)
  6425 /**
  7107 /**
  6426  * return pointer to aCID mapping in store or NULL if not found
  7108  * return pointer to aCID mapping in store or NULL if not found
  6427  */
  7109  */
  6428 	{
  7110 	{
       
  7111 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_FINDMAPPINGINSTORE_ENTRY, this );
  6429 	TMapping *pmp = NULL;
  7112 	TMapping *pmp = NULL;
  6430 	TMapping mp;								// 8 + 16 + 8 + 16 + 4 bytes
  7113 	TMapping mp;								// 8 + 16 + 8 + 16 + 4 bytes
  6431 	mp.iCID.SetLength(KMMCCIDLength);
  7114 	mp.iCID.SetLength(KMMCCIDLength);
  6432 	aCID.Copy(&mp.iCID[0]);
  7115 	aCID.Copy(&mp.iCID[0]);
  6433 
  7116 
  6434 	TInt psn=iStore->Find(mp, iIdentityRelation);
  7117 	TInt psn=iStore->Find(mp, iIdentityRelation);
  6435 	if(psn!=KErrNotFound)
  7118 	if(psn!=KErrNotFound)
  6436 		{
  7119 		{
  6437 		pmp = &(*iStore)[psn];
  7120 		pmp = &(*iStore)[psn];
  6438 		}
  7121 		}
       
  7122 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_FINDMAPPINGINSTORE_EXIT, this, ( TUint )( pmp ) );
  6439 	return pmp;
  7123 	return pmp;
  6440 	}
  7124 	}
  6441 
  7125 
  6442 TInt TMMCPasswordStore::InsertMapping(const TCID &aCID, const TMediaPassword &aPWD, TMapping::TState aState)
  7126 TInt TMMCPasswordStore::InsertMapping(const TCID &aCID, const TMediaPassword &aPWD, TMapping::TState aState)
  6443 /**
  7127 /**
  6447  * 
  7131  * 
  6448  * If the CID is already bound to something in the store, then this operation
  7132  * If the CID is already bound to something in the store, then this operation
  6449  * is a binary search, otherwise it may involve kernel heap allocation.
  7133  * is a binary search, otherwise it may involve kernel heap allocation.
  6450  */
  7134  */
  6451 	{
  7135 	{
       
  7136 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_INSERTMAPPING_ENTRY, this );
  6452 	TInt r = KErrNone;
  7137 	TInt r = KErrNone;
  6453 	TMapping mpN;
  7138 	TMapping mpN;
  6454 	mpN.iCID.SetLength(KMMCCIDLength);
  7139 	mpN.iCID.SetLength(KMMCCIDLength);
  6455 	aCID.Copy(&mpN.iCID[0]);					// copies from aCID into buffer.
  7140 	aCID.Copy(&mpN.iCID[0]);					// copies from aCID into buffer.
  6456 
  7141 
  6467 		mpE.iPWD.Copy(aPWD);
  7152 		mpE.iPWD.Copy(aPWD);
  6468 		mpE.iState = aState;
  7153 		mpE.iState = aState;
  6469 		r = KErrNone;
  7154 		r = KErrNone;
  6470 		}
  7155 		}
  6471 
  7156 
       
  7157 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_INSERTMAPPING_EXIT, this, r );
  6472 	return r;
  7158 	return r;
  6473 	}
  7159 	}
  6474 
  7160 
  6475 TInt TMMCPasswordStore::PasswordStoreLengthInBytes()
  7161 TInt TMMCPasswordStore::PasswordStoreLengthInBytes()
  6476 /**
  7162 /**
  6477  * virtual from DPeriphBusController, kern exec
  7163  * virtual from DPeriphBusController, kern exec
  6478  * return number of bytes needed for persistent file representation
  7164  * return number of bytes needed for persistent file representation
  6479  * of the password store
  7165  * of the password store
  6480  */
  7166  */
  6481 	{
  7167 	{
       
  7168 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_PASSWORDSTORELENGTHINBYTES_ENTRY, this );
  6482 	TInt sz = 0;
  7169 	TInt sz = 0;
  6483 
  7170 
  6484 	for (TInt i = 0; i < iStore->Count(); ++i)
  7171 	for (TInt i = 0; i < iStore->Count(); ++i)
  6485 		{
  7172 		{
  6486 		const TMapping &mp = (*iStore)[i];
  7173 		const TMapping &mp = (*iStore)[i];
  6487 		if (mp.iState == TMapping::EStValid)
  7174 		if (mp.iState == TMapping::EStValid)
  6488 			sz += KMMCCIDLength + sizeof(TInt32) + mp.iPWD.Length();
  7175 			sz += KMMCCIDLength + sizeof(TInt32) + mp.iPWD.Length();
  6489 		}
  7176 		}
  6490 
  7177 
       
  7178 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_PASSWORDSTORELENGTHINBYTES_EXIT, this, sz );
  6491 	return sz;
  7179 	return sz;
  6492 	}
  7180 	}
  6493 
  7181 
  6494 TBool TMMCPasswordStore::ReadPasswordData(TDes8 &aBuf)
  7182 TBool TMMCPasswordStore::ReadPasswordData(TDes8 &aBuf)
  6495 /**
  7183 /**
  6498  * data.  aBuf is resized to contain exactly the password data from
  7186  * data.  aBuf is resized to contain exactly the password data from
  6499  * the store.  If its maximum length is not enough then KErrOverflow
  7187  * the store.  If its maximum length is not enough then KErrOverflow
  6500  * is returned and aBuf is not mutated.
  7188  * is returned and aBuf is not mutated.
  6501  */
  7189  */
  6502 	{
  7190 	{
       
  7191 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_READPASSWORDDATA_ENTRY, this );
  6503 	TInt r=KErrNone;										// error code
  7192 	TInt r=KErrNone;										// error code
  6504 
  7193 
  6505 	if (PasswordStoreLengthInBytes() > aBuf.MaxLength())
  7194 	if (PasswordStoreLengthInBytes() > aBuf.MaxLength())
  6506 		r = KErrOverflow;
  7195 		r = KErrOverflow;
  6507 	else
  7196 	else
  6524 			}
  7213 			}
  6525 
  7214 
  6526 		r = KErrNone;
  7215 		r = KErrNone;
  6527 		}
  7216 		}
  6528 
  7217 
       
  7218 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_READPASSWORDDATA_EXIT, this, r );
  6529 	return r;
  7219 	return r;
  6530 	}
  7220 	}
  6531 
  7221 
  6532 
  7222 
  6533 TInt TMMCPasswordStore::WritePasswordData(TDesC8 &aBuf)
  7223 TInt TMMCPasswordStore::WritePasswordData(TDesC8 &aBuf)
  6534 /**
  7224 /**
  6535  * virtual from DPeriphBusController, kern server
  7225  * virtual from DPeriphBusController, kern server
  6536  * replace current store with data from persistent representation in aBuf.
  7226  * replace current store with data from persistent representation in aBuf.
  6537  */
  7227  */
  6538 	{
  7228 	{
       
  7229 	OstTraceFunctionEntry1( TMMCPASSWORDSTORE_WRITEPASSWORDDATA_ENTRY, this );
  6539 	// should only be called at boot up, but remove chance of duplicate entries
  7230 	// should only be called at boot up, but remove chance of duplicate entries
  6540 	iStore->Reset();
  7231 	iStore->Reset();
  6541 
  7232 
  6542 	TInt iBIdx;									// buffer index
  7233 	TInt iBIdx;									// buffer index
  6543 
  7234 
  6563 		// skip over PWD_LEN and PWD to next entry
  7254 		// skip over PWD_LEN and PWD to next entry
  6564 		iBIdx += sizeof(TInt32) + pwd_len;
  7255 		iBIdx += sizeof(TInt32) + pwd_len;
  6565 		}
  7256 		}
  6566 
  7257 
  6567 	if (corrupt)
  7258 	if (corrupt)
       
  7259 	    {
       
  7260 		OstTraceFunctionExitExt( TMMCPASSWORDSTORE_WRITEPASSWORDDATA_EXIT1, this, KErrCorrupt );
  6568 		return KErrCorrupt;
  7261 		return KErrCorrupt;
       
  7262 	    }
  6569 
  7263 
  6570 	// Build the store from the entries in the buffer.
  7264 	// Build the store from the entries in the buffer.
  6571 	TInt r = KErrNone;							// error code
  7265 	TInt r = KErrNone;							// error code
  6572 	for (iBIdx = 0; r == KErrNone && iBIdx < aBuf.Length(); )
  7266 	for (iBIdx = 0; r == KErrNone && iBIdx < aBuf.Length(); )
  6573 		{
  7267 		{
  6587 	// atomic from the startup thread's point of view.
  7281 	// atomic from the startup thread's point of view.
  6588 
  7282 
  6589 	if (r != KErrNone)
  7283 	if (r != KErrNone)
  6590 		iStore->Reset();
  7284 		iStore->Reset();
  6591 
  7285 
       
  7286 	OstTraceFunctionExitExt( TMMCPASSWORDSTORE_WRITEPASSWORDDATA_EXIT2, this, r );
  6592 	return r;
  7287 	return r;
  6593 	}
  7288 	}
  6594 
  7289 
  6595 TInt TMMCPasswordStore::CompareCID(const TMapping& aLeft, const TMapping& aRight)
  7290 TInt TMMCPasswordStore::CompareCID(const TMapping& aLeft, const TMapping& aRight)
  6596 /**
  7291 /**
  6597  * CID Comparason Functions for RArray::Find
  7292  * CID Comparason Functions for RArray::Find
  6598  */
  7293  */
  6599 	{
  7294 	{
       
  7295 	OstTraceFunctionEntry0( TMMCPASSWORDSTORE_COMPARECID_ENTRY );
  6600 	return(aLeft.iCID == aRight.iCID);
  7296 	return(aLeft.iCID == aRight.iCID);
  6601 	}
  7297 	}
  6602 
  7298 
  6603 void DMMCSocket::InitiatePowerUpSequence()
  7299 void DMMCSocket::InitiatePowerUpSequence()
  6604 /**
  7300 /**
  6605  * Initiates a power up sequence on the stack
  7301  * Initiates a power up sequence on the stack
  6606  */
  7302  */
  6607 	{
  7303 	{
       
  7304 	OstTraceFunctionEntry1( DMMCSOCKET_INITIATEPOWERUPSEQUENCE_ENTRY, this );
  6608 	iStack->PowerUpStack();
  7305 	iStack->PowerUpStack();
       
  7306 	OstTraceFunctionExit1( DMMCSOCKET_INITIATEPOWERUPSEQUENCE_EXIT, this );
  6609 	}
  7307 	}
  6610 
  7308 
  6611 TBool DMMCSocket::CardIsPresent()
  7309 TBool DMMCSocket::CardIsPresent()
  6612 /**
  7310 /**
  6613  * Indicates the presence of a card.
  7311  * Indicates the presence of a card.
  6614  * @return ETrue if a card is present, EFalse otherwise
  7312  * @return ETrue if a card is present, EFalse otherwise
  6615  */
  7313  */
  6616 	{
  7314 	{
  6617 	return(iStack->HasCardsPresent());
  7315 	OstTraceFunctionEntry1( DMMCSOCKET_CARDISPRESENT_ENTRY, this );
       
  7316 	TInt r = iStack->HasCardsPresent();
       
  7317 	OstTraceFunctionExitExt( DMMCSOCKET_CARDISPRESENT_EXIT, this, r );
       
  7318 	return r;
  6618 	}
  7319 	}
  6619 
  7320 
  6620 void DMMCSocket::AdjustPartialRead(const TMMCard* aCard, TUint32 aStart, TUint32 aEnd, TUint32* aPhysStart, TUint32* aPhysEnd) const
  7321 void DMMCSocket::AdjustPartialRead(const TMMCard* aCard, TUint32 aStart, TUint32 aEnd, TUint32* aPhysStart, TUint32* aPhysEnd) const
  6621 /**
  7322 /**
  6622  * Calculates the minimum range that must be read off a card, an optimisation that takes advantage
  7323  * Calculates the minimum range that must be read off a card, an optimisation that takes advantage
  6628  * @param aEnd The required end position
  7329  * @param aEnd The required end position
  6629  * @param aPhysStart The adjusted start position
  7330  * @param aPhysStart The adjusted start position
  6630  * @param aPhysEnd The adjusted end position
  7331  * @param aPhysEnd The adjusted end position
  6631  */
  7332  */
  6632 	{
  7333 	{
       
  7334 	OstTraceFunctionEntryExt( DMMCSOCKET_ADJUSTPARTIALREAD_ENTRY, this );
  6633 	iStack->AdjustPartialRead(aCard, aStart, aEnd, aPhysStart, aPhysEnd);
  7335 	iStack->AdjustPartialRead(aCard, aStart, aEnd, aPhysStart, aPhysEnd);
       
  7336 	OstTraceFunctionExit1( DMMCSOCKET_ADJUSTPARTIALREAD_EXIT, this );
  6634 	}
  7337 	}
  6635 
  7338 
  6636 void DMMCSocket::GetBufferInfo(TUint8** aMDBuf, TInt* aMDBufLen)
  7339 void DMMCSocket::GetBufferInfo(TUint8** aMDBuf, TInt* aMDBufLen)
  6637 /**
  7340 /**
  6638  * Returns the details of the buffer allocated by the socket for data transfer operations.  The buffer
  7341  * Returns the details of the buffer allocated by the socket for data transfer operations.  The buffer
  6640  * allocated for DMA transfers.
  7343  * allocated for DMA transfers.
  6641  * @param aMDBuf A pointer to the allocated buffer
  7344  * @param aMDBuf A pointer to the allocated buffer
  6642  * @param aMDBufLen The length of the allocated buffer
  7345  * @param aMDBufLen The length of the allocated buffer
  6643  */
  7346  */
  6644 	{
  7347 	{
       
  7348 	OstTraceFunctionEntryExt( DMMCSOCKET_GETBUFFERINFO_ENTRY, this );
  6645 	iStack->GetBufferInfo(aMDBuf, aMDBufLen);
  7349 	iStack->GetBufferInfo(aMDBuf, aMDBufLen);
       
  7350 	OstTraceFunctionExit1( DMMCSOCKET_GETBUFFERINFO_EXIT, this );
  6646 	}
  7351 	}
  6647 
  7352 
  6648 void DMMCSocket::Reset1()
  7353 void DMMCSocket::Reset1()
  6649 /**
  7354 /**
  6650  * Resets the socket by powering down the stack.
  7355  * Resets the socket by powering down the stack.
  6651  * If there are operations in progress (inCritical), this call will be deferred
  7356  * If there are operations in progress (inCritical), this call will be deferred
  6652  * until the operation is complete.  In the case of an emergency power down,
  7357  * until the operation is complete.  In the case of an emergency power down,
  6653  * this will occur immediately.
  7358  * this will occur immediately.
  6654  */
  7359  */
  6655 	{
  7360 	{
       
  7361 	OstTraceFunctionEntry1( DMMCSOCKET_RESET1_ENTRY, this );
  6656 	if (iState == EPBusCardAbsent)
  7362 	if (iState == EPBusCardAbsent)
  6657 	    {
  7363 	    {
  6658 	    // Reset is result of card eject!
  7364 	    // Reset is result of card eject!
  6659 	    iStack->iStackState |= KMMCStackStateCardRemoved;
  7365 	    iStack->iStackState |= KMMCStackStateCardRemoved;
  6660 	    }
  7366 	    }
  6661 	
  7367 	
  6662 	
  7368 	
  6663 	iStack->PowerDownStack();
  7369 	iStack->PowerDownStack();
       
  7370 	OstTraceFunctionExit1( DMMCSOCKET_RESET1_EXIT, this );
  6664 	}
  7371 	}
  6665 
  7372 
  6666 void DMMCSocket::Reset2()
  7373 void DMMCSocket::Reset2()
  6667 /**
  7374 /**
  6668  * Resets the socket in response to a PSU fault or media change.
  7375  * Resets the socket in response to a PSU fault or media change.
  6677 /**
  7384 /**
  6678  * Allocates resources and initialises the MMC socket and associated stack object.
  7385  * Allocates resources and initialises the MMC socket and associated stack object.
  6679  * @return KErrNotReady if no stack has been allocated, standard error code otherwise
  7386  * @return KErrNotReady if no stack has been allocated, standard error code otherwise
  6680  */
  7387  */
  6681 	{
  7388 	{
       
  7389 	OstTraceFunctionEntry1( DMMCSOCKET_INIT_ENTRY, this );
  6682 	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Init"));
  7390 	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Init"));
  6683 	
  7391 	
  6684 	GetMachineInfo();
  7392 	GetMachineInfo();
  6685 
  7393 
  6686 	// We need to make sure the stack is initialised,
  7394 	// We need to make sure the stack is initialised,
  6687 	// as DPBusSocket::Init() will initiate a power up sequence
  7395 	// as DPBusSocket::Init() will initiate a power up sequence
  6688 	if(iStack == NULL)
  7396 	if(iStack == NULL)
       
  7397 	    {
       
  7398 		OstTraceFunctionExitExt( DMMCSOCKET_INIT_EXIT1, this, KErrNotReady );
  6689 		return KErrNotReady;
  7399 		return KErrNotReady;
       
  7400 	    }
  6690 
  7401 
  6691 	TInt r = iStack->Init();
  7402 	TInt r = iStack->Init();
  6692 	if (r!=KErrNone)
  7403 	if (r!=KErrNone)
       
  7404 	    {
       
  7405 		OstTraceFunctionExitExt( DMMCSOCKET_INIT_EXIT2, this, r );
  6693 		return r;
  7406 		return r;
       
  7407 	    }
  6694 
  7408 
  6695 	r = DPBusSocket::Init();
  7409 	r = DPBusSocket::Init();
  6696 	if (r!=KErrNone)
  7410 	if (r!=KErrNone)
       
  7411 	    {
       
  7412 		OstTraceFunctionExitExt( DMMCSOCKET_INIT_EXIT3, this, r );
  6697 		return r;
  7413 		return r;
       
  7414 	    }
  6698 	
  7415 	
       
  7416 	OstTraceFunctionExitExt( DMMCSOCKET_INIT_EXIT4, this, KErrNone );
  6699 	return KErrNone;
  7417 	return KErrNone;
  6700 	}
  7418 	}
  6701 
  7419 
  6702 void DMMCSocket::GetMachineInfo()
  7420 void DMMCSocket::GetMachineInfo()
  6703 /**
  7421 /**
  6704  * Gets the platform specific configuration information.
  7422  * Gets the platform specific configuration information.
  6705  * @see TMMCMachineInfo
  7423  * @see TMMCMachineInfo
  6706  */
  7424  */
  6707 	{
  7425 	{
       
  7426 	OstTraceFunctionEntry1( DMMCSOCKET_GETMACHINEINFO_ENTRY, this );
  6708 	// Get machine info from the stack
  7427 	// Get machine info from the stack
  6709 	iStack->MachineInfo(iMachineInfo);
  7428 	iStack->MachineInfo(iMachineInfo);
  6710 
  7429 
  6711 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iTotalSockets %u", iMachineInfo.iTotalSockets));
  7430 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iTotalSockets %u", iMachineInfo.iTotalSockets));
  6712 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iTotalMediaChanges %u", iMachineInfo.iTotalMediaChanges));
  7431 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iTotalMediaChanges %u", iMachineInfo.iTotalMediaChanges));
  6713 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iTotalPrimarySupplies %u", iMachineInfo.iTotalPrimarySupplies));
  7432 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iTotalPrimarySupplies %u", iMachineInfo.iTotalPrimarySupplies));
  6714 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iSPIMode %u", iMachineInfo.iSPIMode));
  7433 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iSPIMode %u", iMachineInfo.iSPIMode));
  6715 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iBaseBusNumber %u", iMachineInfo.iBaseBusNumber));
  7434 	__KTRACE_OPT(KPBUS1, Kern::Printf(">GetMI : iBaseBusNumber %u", iMachineInfo.iBaseBusNumber));
  6716 
  7435 	OstTraceDefExt5( OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCSOCKET_GETMACHINEINFO, "iTotalSockets=%d; iTotalMediaChanges=%d; iTotalPrimarySupplies=%d; iSPIMode=%d; iBaseBusNumber=%d", iMachineInfo.iTotalSockets, iMachineInfo.iTotalMediaChanges, iMachineInfo.iTotalPrimarySupplies, iMachineInfo.iSPIMode, iMachineInfo.iBaseBusNumber );
       
  7436 	
       
  7437 	
       
  7438 	OstTraceFunctionExit1( DMMCSOCKET_GETMACHINEINFO_EXIT, this );
  6717 	}
  7439 	}
  6718 
  7440 
  6719 
  7441 
  6720 // MMC specific functions
  7442 // MMC specific functions
  6721 
  7443 
  6723 /**
  7445 /**
  6724  * Panic the MMC Controller
  7446  * Panic the MMC Controller
  6725  * @param aPanic The panic code
  7447  * @param aPanic The panic code
  6726  */
  7448  */
  6727 	{
  7449 	{
  6728 
  7450 	OstTraceFunctionEntry0( DMMCSOCKET_PANIC_ENTRY );
  6729 	_LIT(KPncNm,"PBUS-MMC");
  7451 	_LIT(KPncNm,"PBUS-MMC");
  6730 	Kern::PanicCurrentThread(KPncNm,aPanic);
  7452 	Kern::PanicCurrentThread(KPncNm,aPanic);
  6731 	}
  7453 	}
  6732 
  7454 
  6733 EXPORT_C DMMCPsu::DMMCPsu(TInt aPsuNum, TInt aMediaChangedNum)
  7455 EXPORT_C DMMCPsu::DMMCPsu(TInt aPsuNum, TInt aMediaChangedNum)
  6736  * @param aPsuNum The power supply number
  7458  * @param aPsuNum The power supply number
  6737  * @param aMediaChangedNum The associated media change number
  7459  * @param aMediaChangedNum The associated media change number
  6738  */
  7460  */
  6739 	: DPBusPsuBase(aPsuNum, aMediaChangedNum)
  7461 	: DPBusPsuBase(aPsuNum, aMediaChangedNum)
  6740 	{
  7462 	{
       
  7463 	OstTraceFunctionEntryExt( DMMCPSU_DMMCPSU_ENTRY, this );
  6741 	
  7464 	
  6742 	iVoltageSetting=0x00ffc000; // Default voltage range - 2.6V to 3.6V (OCR reg. format).
  7465 	iVoltageSetting=0x00ffc000; // Default voltage range - 2.6V to 3.6V (OCR reg. format).
       
  7466 	OstTraceFunctionExit1( DMMCPSU_DMMCPSU_EXIT, this );
  6743 	}
  7467 	}
  6744 
  7468 
  6745 EXPORT_C TInt DMMCPsu::DoCreate()
  7469 EXPORT_C TInt DMMCPsu::DoCreate()
  6746 /**
  7470 /**
  6747  * Create a DMMCPsu object.
  7471  * Create a DMMCPsu object.
  6761  * and therefore if VccQ supply can be turned off.
  7485  * and therefore if VccQ supply can be turned off.
  6762  * 
  7486  * 
  6763  * @Param aPtr reference to DMMCPsu Object to be acted upon.
  7487  * @Param aPtr reference to DMMCPsu Object to be acted upon.
  6764  */
  7488  */
  6765 	{	
  7489 	{	
       
  7490 	OstTraceFunctionEntry0( DMMCPSU_SLEEPCHECK_ENTRY );
  6766 	DMMCPsu& self = *static_cast<DMMCPsu*>(aPtr);
  7491 	DMMCPsu& self = *static_cast<DMMCPsu*>(aPtr);
  6767 	
  7492 	
  6768 	if (
  7493 	if (
  6769 		(self.iNotLockedTimeout&&!self.IsLocked()&&++self.iNotLockedCount>self.iNotLockedTimeout) ||
  7494 		(self.iNotLockedTimeout&&!self.IsLocked()&&++self.iNotLockedCount>self.iNotLockedTimeout) ||
  6770 		(self.iInactivityTimeout&&++self.iInactivityCount>self.iInactivityTimeout)
  7495 		(self.iInactivityTimeout&&++self.iInactivityCount>self.iInactivityTimeout)
  6771 	   )
  7496 	   )
  6772 		{
  7497 		{
  6773 		DMMCSocket* socket = static_cast<DMMCSocket*>(self.iSocket);
  7498 		DMMCSocket* socket = static_cast<DMMCSocket*>(self.iSocket);
  6774 		socket->iStack->QSleepStack();
  7499 		socket->iStack->QSleepStack();
  6775 		}
  7500 		}
       
  7501 	OstTraceFunctionExit0( DMMCPSU_SLEEPCHECK_EXIT );
  6776 	}
  7502 	}
  6777 
  7503 
  6778 EXPORT_C DMMCMediaChange::DMMCMediaChange(TInt aMediaChangeNum)
  7504 EXPORT_C DMMCMediaChange::DMMCMediaChange(TInt aMediaChangeNum)
  6779 /**
  7505 /**
  6780  * Constructor for a DMMCMediaChange object
  7506  * Constructor for a DMMCMediaChange object
  6781  * @param aMediaChangeNum The media change number
  7507  * @param aMediaChangeNum The media change number
  6782  */
  7508  */
  6783 	: DMediaChangeBase(aMediaChangeNum)
  7509 	: DMediaChangeBase(aMediaChangeNum)
  6784 	{}
  7510 	{
       
  7511 	OstTraceFunctionEntryExt( DMMCMEDIACHANGE_DMMCMEDIACHANGE_ENTRY, this );
       
  7512 	}
  6785 
  7513 
  6786 EXPORT_C TInt DMMCMediaChange::Create()
  7514 EXPORT_C TInt DMMCMediaChange::Create()
  6787 /**
  7515 /**
  6788  * Create a DMMCMediaChange object.
  7516  * Create a DMMCMediaChange object.
  6789  * This should be overridden at the variant layer to allow interrupts and
  7517  * This should be overridden at the variant layer to allow interrupts and
  6790  * other variant-specific parameters to be initialised.  The base class implementation
  7518  * other variant-specific parameters to be initialised.  The base class implementation
  6791  * should be called prior to any variant-specific initialisation.
  7519  * should be called prior to any variant-specific initialisation.
  6792  * @return Standard Symbian OS error code.
  7520  * @return Standard Symbian OS error code.
  6793  */
  7521  */
  6794 	{
  7522 	{
  6795 	return DMediaChangeBase::Create();
  7523 	OstTraceFunctionEntry1( DMMCMEDIACHANGE_CREATE_ENTRY, this );
  6796 	}
  7524 	TInt r = DMediaChangeBase::Create();
  6797 
  7525 	OstTraceFunctionExitExt( DMMCMEDIACHANGE_CREATE_EXIT, this, r );
       
  7526 	return r;
       
  7527 	}
       
  7528