diff -r 000000000000 -r a41df078684a kernel/eka/include/drivers/mmc.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/include/drivers/mmc.inl Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,1528 @@ +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +// WARNING: This file contains some APIs which are internal and are subject +// to change without noticed. Such APIs should therefore not be used +// outside the Kernel and Hardware Services package. +// + +/** + + A static function that takes the 4 bytes that are stored in a memory location + in ascending address order, and returns them as a 32-bit unsigned integer + in big-endian format. + + @param aPtr A pointer to the memory location containing the 4 bytes to be stored. + + @return A 32 bit unsigned integer containing the 4 bytes in big-endian format. +*/ +inline TUint32 TMMC::BigEndian32(const TUint8* aPtr) + {return( (aPtr[0]<<24) | (aPtr[1]<<16) | (aPtr[2]<<8) | (aPtr[3]) );} + + + + +/** +A static function that takes the specified 32-bit unsigned integer, assumed to +be in big-endian format, and stores this into the specified memory location. + +@param aPtr A pointer to a 4 byte memory location which is to contain + the unsigned integer. +@param aVal A 32 bit unsigned integer in big-endian format. +*/ +inline void TMMC::BigEndian4Bytes(TUint8* aPtr, TUint32 aVal) + { + aPtr[0] = (TUint8)(aVal >> 24); + aPtr[1] = (TUint8)(aVal >> 16); + aPtr[2] = (TUint8)(aVal >> 8); + aPtr[3] = (TUint8)aVal; + } + + + + +// -------- class TCID -------- + +inline TCID::TCID(const TUint8* aPtr) + {memcpy(&iData[0], aPtr, KMMCCIDLength);} + +inline TCID& TCID::operator=(const TCID& aCID) + {memcpy(&iData[0], &aCID.iData[0], KMMCCIDLength); return(*this);} + +inline TCID& TCID::operator=(const TUint8* aPtr) + {memcpy(&iData[0], aPtr, KMMCCIDLength); return(*this);} + +inline TBool TCID::operator==(const TCID& aCID) const + {return(memcompare(&iData[0],KMMCCIDLength,&aCID.iData[0],KMMCCIDLength)==0);} + +inline TBool TCID::operator==(const TUint8* aPtr) const + {return(memcompare(&iData[0],KMMCCIDLength,aPtr,KMMCCIDLength)==0);} + +inline void TCID::Copy(TUint8* aPtr) const + {memcpy(aPtr, &iData[0], KMMCCIDLength);} + +inline TUint8 TCID::At(TUint anIndex) const + {return(iData[KMMCCIDLength-1-anIndex]);} + +// -------- class TCSD -------- + +inline TCSD::TCSD(const TUint8* aPtr) + {memcpy(&iData[0], aPtr, KMMCCSDLength);} + +inline TCSD& TCSD::operator=(const TCSD& aCSD) + {memcpy(&iData[0], &aCSD.iData[0], KMMCCSDLength); return(*this);} + +inline TCSD& TCSD::operator=(const TUint8* aPtr) + {memcpy(&iData[0], aPtr, KMMCCSDLength); return(*this);} + +inline void TCSD::Copy(TUint8* aPtr) const + {memcpy(aPtr, &iData[0], KMMCCSDLength);} + +inline TUint8 TCSD::At(TUint anIndex) const // anIndex byte in little-endian format + {return(iData[KMMCCSDLength-1-anIndex]);} + +// Raw field accessors. Encoded values such as memory capacity are calulated in +// non-inline functions defined in ps_mmc.cpp. + +inline TUint TCSD::CSDStructure() const {return( CSDField(127,126) );} +inline TUint TCSD::SpecVers() const {return( CSDField(125,122) );} +inline TUint TCSD::Reserved120() const {return( CSDField(121,120) );} +inline TUint TCSD::TAAC() const {return( CSDField(119,112) );} +inline TUint TCSD::NSAC() const {return( CSDField(111,104) );} +inline TUint TCSD::TranSpeed() const {return( CSDField(103,96) );} +inline TUint TCSD::CCC() const {return( CSDField(95,84) );} +inline TUint TCSD::ReadBlLen() const {return( CSDField(83,80) );} +inline TBool TCSD::ReadBlPartial() const {return( CSDField(79,79) );} +inline TBool TCSD::WriteBlkMisalign() const {return( CSDField(78,78) );} +inline TBool TCSD::ReadBlkMisalign() const {return( CSDField(77,77) );} +inline TBool TCSD::DSRImp() const {return( CSDField(76,76) );} +inline TUint TCSD::Reserved74() const {return( CSDField(75,74) );} +inline TUint TCSD::CSize() const {return( CSDField(73,62) );} +inline TUint TCSD::VDDRCurrMin() const {return( CSDField(61,59) );} +inline TUint TCSD::VDDRCurrMax() const {return( CSDField(58,56) );} +inline TUint TCSD::VDDWCurrMin() const {return( CSDField(55,53) );} +inline TUint TCSD::VDDWCurrMax() const {return( CSDField(52,50) );} +inline TUint TCSD::CSizeMult() const {return( CSDField(49,47) );} + +inline TUint TCSD::EraseGrpSize() const {return( CSDField(46,42) );} +inline TUint TCSD::EraseGrpMult() const {return( CSDField(41,37) );} +inline TUint TCSD::WPGrpSize() const {return( CSDField(36,32) );} + +inline TBool TCSD::WPGrpEnable() const {return( CSDField(31,31) );} +inline TUint TCSD::DefaultECC() const {return( CSDField(30,29) );} +inline TUint TCSD::R2WFactor() const {return( CSDField(28,26) );} +inline TUint TCSD::WriteBlLen() const {return( CSDField(25,22) );} +inline TBool TCSD::WriteBlPartial() const {return( CSDField(21,21) );} +inline TUint TCSD::Reserved16() const {return( CSDField(20,16) );} +inline TBool TCSD::FileFormatGrp() const {return( CSDField(15,15) );} +inline TBool TCSD::Copy() const {return( CSDField(14,14) );} +inline TBool TCSD::PermWriteProtect() const {return( CSDField(13,13) );} +inline TBool TCSD::TmpWriteProtect() const {return( CSDField(12,12) );} +inline TUint TCSD::FileFormat() const {return( CSDField(11,10) );} +inline TUint TCSD::ECC() const {return( CSDField(9,8) );} +inline TUint TCSD::CRC() const {return( CSDField(7,1) );} + +// -------- class TExtendedCSD -------- + +inline TExtendedCSD::TExtendedCSD() // Default constructor + {} + +inline TExtendedCSD::TExtendedCSD(const TUint8* aPtr) + {memcpy(&iData[0], aPtr, KMMCExtendedCSDLength);} + +inline TExtendedCSD& TExtendedCSD::operator=(const TExtendedCSD& aCSD) + {memcpy(&iData[0], &aCSD.iData[0], KMMCExtendedCSDLength); return(*this);} + +inline TExtendedCSD& TExtendedCSD::operator=(const TUint8* aPtr) + {memcpy(&iData[0], aPtr, KMMCExtendedCSDLength); return(*this);} + +inline TMMCArgument TExtendedCSD::GetWriteArg(TExtCSDAccessBits aAccess, TExtCSDModesFieldIndex aIndex, TUint aValue, TUint aCmdSet) + {return TMMCArgument((aAccess << 24) | (aIndex << 16) | (aValue << 8) | (aCmdSet));} + +inline TUint8* TExtendedCSD::Ptr() {return &iData[0];} + +// Raw field accessors. +// "Properties Segment" of Extended CSD - i.e. read-only fields +inline TUint TExtendedCSD::SupportedCmdSet() const {return iData[504];} +inline TUint TExtendedCSD::SectorCount() const {return(iData[212] | ((TUint)iData[213] << 8) | ((TUint)iData[214] << 16) | ((TUint)iData[215] << 24));} +inline TUint TExtendedCSD::MinPerfWrite8Bit52Mhz() const {return iData[210];} +inline TUint TExtendedCSD::MinPerfRead8Bit52Mhz() const {return iData[209];} +inline TUint TExtendedCSD::MinPerfWrite8Bit26Mhz_4Bit52Mhz() const {return iData[208];} +inline TUint TExtendedCSD::MinPerfRead8Bit26Mhz_4Bit52Mhz() const {return iData[207];} +inline TUint TExtendedCSD::MinPerfWrite4Bit26Mhz() const {return iData[206];} +inline TUint TExtendedCSD::MinPerfRead4Bit26Mhz() const {return iData[205];} +inline TUint TExtendedCSD::PowerClass26Mhz360V() const {return iData[203];} +inline TUint TExtendedCSD::PowerClass52Mhz360V() const {return iData[202];} +inline TUint TExtendedCSD::PowerClass26Mhz195V() const {return iData[201];} +inline TUint TExtendedCSD::PowerClass52Mhz195V() const {return iData[200];} +inline TUint TExtendedCSD::CardType() const {return iData[196];} +inline TUint TExtendedCSD::CSDStructureVer() const {return iData[194];} +inline TUint TExtendedCSD::ExtendedCSDRev() const {return iData[EExtendedCSDRevIndex];} +inline TUint TExtendedCSD::AccessSize() const {return iData[EAccessSizeIndex];} +inline TUint TExtendedCSD::HighCapacityEraseGroupSize() const {return iData[EHighCapacityEraseGroupSizeIndex];} +inline TUint TExtendedCSD::BootInfo() const {return iData[228];} +inline TUint TExtendedCSD::BootSizeMultiple() const {return iData[226];} +inline TUint TExtendedCSD::EraseTimeoutMultiple() const {return iData[223];} +inline TUint TExtendedCSD::ReliableWriteSector() const {return iData[222];} +inline TUint TExtendedCSD::HighCapacityWriteProtectGroupSize() const {return iData[221];} +inline TUint TExtendedCSD::SleepCurrentVcc() const {return iData[220];} +inline TUint TExtendedCSD::SleepCurrentVccQ() const {return iData[219];} +inline TUint TExtendedCSD::SleepAwakeTimeout() const {return iData[217];} + +// "Modes Segment" of Extended CSD - i.e. modifiable fields +inline TUint TExtendedCSD::CmdSet() const {return iData[ECmdSetIndex];} +inline TUint TExtendedCSD::CmdSetRev() const {return iData[ECmdSetRevIndex];} +inline TUint TExtendedCSD::PowerClass() const {return iData[EPowerClassIndex];} +inline TUint TExtendedCSD::HighSpeedTiming() const {return iData[EHighSpeedInterfaceTimingIndex];} +inline TUint TExtendedCSD::BusWidthMode() const {return iData[EBusWidthModeIndex];} +inline TUint TExtendedCSD::BootConfig() const {return iData[EBootConfigIndex];} +inline TUint TExtendedCSD::BootBusWidth() const {return iData[EBootBusWidthIndex];} +inline TUint TExtendedCSD::EraseGroupDef() const {return iData[EEraseGroupDefIndex];} + +// -------- class TMMCStatus -------- + /** + * Constructor for TMMCStatus. + * @param aPtr A pointer to the memory location containing the 4 bytes to be stored. + The 4 bytes corresponds to MMC card response. Refer to the MMC card specification for the possible values of response. + */ +inline TMMCStatus::TMMCStatus(const TUint8* aPtr) : iData(TMMC::BigEndian32(aPtr)) {} + +/** + * constructs the TMMCStatus object with value corresponding to MMC status register. + * @param aData Value corresponding to MMC status register. + */ +inline TMMCStatus::TMMCStatus(const TUint32& aData) : iData(aData) {} + +/** + * Gets the bitfield(32 bits) representing the MMC status register. + * @return Value corresponding to MMC status register. + */ +inline TMMCStatus::operator TUint32() const {return(iData);} + +/** + * Gets the error status. + * For the possible values, refer to the MMC card R1 Response. + * @see DMMCStack + * @return MMC card error status. + */ +inline TUint32 TMMCStatus::Error() const { return(iData & KMMCStatErrorMask); } + +/** + * Gets the MMC card's current state machine. + * For the possible values of the state machine, refer to the MMC card specification. + * @return The current state of the state machine. + */ +inline TMMCardStateEnum TMMCStatus::State() const + { return((TMMCardStateEnum)(iData & KMMCStatCurrentStateMask)); } + +/** + * Replace the MMC card's current state with supplied value + * @param aState The new MMC card State + */ +inline void TMMCStatus::UpdateState(TMMCardStateEnum aState) + { + iData &= ~KMMCStatCurrentStateMask; + iData |= aState; + } + + +// -------- class TMMCArgument -------- + +inline TMMCArgument::TMMCArgument() +/** + * Default constructor + * Initialises the argument to zero. + */ + {} + +inline TMMCArgument::TMMCArgument(const TUint32& aData) + : iData(aData) +/** + * Constructs a TMMCArgument with a 32-bit parameter. + * @param aData The 32-bit parameter. + */ + {} + +inline TMMCArgument::TMMCArgument(TRCA anRCA) : iData(TUint(anRCA)<<16) +/** + * Constructs a TMMCArgument with a Relative Card Address (RCA). + * @param anRCA The RCA. + */ + {} +inline TMMCArgument::TMMCArgument(TDSR aDSR) : iData(TUint(aDSR)<<16) +/** + * Constructs a TMMCArgument with a Driver Stage Register (DSR). + * @param aDSR The DSR. + */ + {} + +inline TMMCArgument::operator TUint32() const +/** + * Converts the TMMCArgument to it's raw 32-bit representation. + * @return Raw 32-bit argument data + */ + {return(iData);} + +inline void TMMCArgument::SetRCA(TRCA anRCA) +/** + * Sets the Relative Card Address + * @param anRCA The RCA. + */ + {iData=(iData&0xFFFF)|(TUint(anRCA)<<16);} + +// -------- class TRCA -------- + +inline TRCA::TRCA(TUint16 aData) : iData(aData) +/** + * Constructs a TRCA with a 16-bit RCA. + * @param aData The 16-bit RCA. + */ + {} + +inline TRCA::TRCA(TInt aData) : iData(static_cast(aData)) +/** + * Constructs a TRCA with a parameter of type TInt. + * @param aData The TInt parameter. + */ + {} + +inline TRCA::TRCA(TMMCArgument aData) +/** + * Constructs a TRCA with a TMMCArgument containing a RCA. + * @param aData The argument containing the RCA. + */ + {iData=(TUint16)((TUint32(aData)>>16)&0xFFFF);} + +inline TRCA::operator TUint16() const +/** + * Converts the TRCA to it's raw 16-bit representation. + * @return Raw 16-bit RCA + */ + {return(iData);} + +// -------- class TDSR -------- + +inline TDSR::TDSR() +/** + * Default constructor. + * Initialises the DRS to zero + */ + {} + +inline TDSR::TDSR(TUint16 aData) : iData(aData) +/** + * Constructs a TDSR with a 16-bit DSR. + * @param aData The 16-bit DSR. + */ + {} + +inline TDSR::operator TUint16() const +/** + * Converts the TDSR to it's raw 16-bit representation. + * @return Raw 16-bit DSR + */ + {return(iData);} + + +// -------- class TMMCard -------- +inline TBool TMMCard::IsHighCapacity() const { return (iFlags & KMMCardIsHighCapacity) != 0; } + +inline TBool TMMCard::IsPresent() const +// +// If the card is present, its index shows the card number + 1 +// + {return( iIndex != 0 );} + +inline TInt TMMCard::Number() const {return( iIndex - 1 );} +inline TMMCMediaTypeEnum TMMCard::MediaType() const {return(iCSD.MediaType());} +inline const TCID& TMMCard::CID() const {return(iCID);} +inline const TCSD& TMMCard::CSD() const {return(iCSD);} +inline const TExtendedCSD& TMMCard::ExtendedCSD() const {return(iExtendedCSD);} +inline TRCA TMMCard::RCA() const {return(iRCA);} +inline TBool TMMCard::HasPassword() const {return(iFlags&KMMCardHasPassword);} +inline TBool TMMCard::IsWriteProtected() const {return(iFlags&KMMCardIsWriteProtected);} + +inline TUint TMMCard::DeviceSize() const + { + TInt64 capacity = DeviceSize64(); + return(capacity > KMaxTInt ? KMaxTInt : I64LOW(capacity)); + } + +/** +Gets the bus width setting for this card. +Note returned value may differ from current host controller bus width setting. +returns 1, 4 or 8 +*/ +inline TInt TMMCard::BusWidth() const + {return iBusWidth;} + +/** +Sets the bus width setting for this card. +Note this buswidth will not be applied to the host controller and is only used for recording. + +@param aBusWidth the bus width to set - valid values are 1, 4 or 8 +*/ +inline void TMMCard::SetBusWidth(TInt aBusWidth) + {iBusWidth=aBusWidth;} + +inline void TMMCard::SetHighSpeedClock(TUint32 aHighSpeedClock) + {iHighSpeedClock = aHighSpeedClock;} +inline TUint32 TMMCard::HighSpeedClock() const + {return iHighSpeedClock;} + +// -------- class TMMCardArray -------- + +inline TMMCardArray::TMMCardArray(DMMCStack* anOwningStack) + {iOwningStack=anOwningStack;} +inline TUint TMMCardArray::NewCardCount() + {return(iNewCardsCount);} +inline TInt TMMCardArray::CardsPresent() + {return(iCardsPresent);} +inline TMMCard* TMMCardArray::NewCardP(TUint aNewCardNumber) + {return(iNewCards[aNewCardNumber]);} +inline TMMCard* TMMCardArray::CardP(TUint aCardNumber) + {return(iCards[aCardNumber]);} +inline TMMCard& TMMCardArray::NewCard(TUint aCardNumber) + {return *iNewCards[aCardNumber];} +inline TMMCard& TMMCardArray::Card(TUint aCardNumber) + {return *iCards[aCardNumber];} + +// -------- class TMMCCommandDesc -------- + +inline TBool TMMCCommandDesc::IsBlockCmd() const + { return ((iFlags & KMMCCmdFlagBlockAddress) != 0); } + +inline TUint32 TMMCCommandDesc::NumBlocks() const + { return iTotalLength / BlockLength(); } + +inline TInt64 TMMCCommandDesc::Arg64() const + { return IsBlockCmd()? ((TInt64)(TUint32)iArgument) << KMMCardHighCapBlockSizeLog2 : (TInt64)(TUint32)iArgument; } + +inline TBool TMMCCommandDesc::IsDoubleBuffered() const + { return ((iFlags & KMMCCmdFlagDoubleBuffer) != 0); } + +inline TBool TMMCCommandDesc::IsPhysicalAddress() const + { return ((iFlags & KMMCCmdFlagPhysAddr) != 0); } + +/** +Returns the buffer length in bytes. If the current request is double-buffered, +this returns the amount of data available in the currently active buffer. +If the command is not double-buffered, the total amount of data to be transferred is returned. + +@return Buffer length in bytes +*/ +inline TUint32 TMMCCommandDesc::BufferLength() const + { return (IsDoubleBuffered() ? (iBlockLength >> 16) << KMMCardHighCapBlockSizeLog2 : iTotalLength); } + +inline TUint32 TMMCCommandDesc::BlockLength() const + { return (IsDoubleBuffered() ? (iBlockLength & 0x0000FFFF) : iBlockLength); } + +// -------- class TMMCStackConfig -------- + +inline TMMCStackConfig::TMMCStackConfig() : iUpdateMask(0), iClientMask(0) +/** + * Constructor for a TMMCStackConfig object. + */ + {} + +inline void TMMCStackConfig::SetMode(TUint32 aMask) +/** + * Enable a single mode or a set of modes. + * Enabled modes should be considered by the Controller as effective. However, client mode + * settings may be overridden by master settings. + * @param aMask The mode(s) to be set. + */ + {iModes |= aMask; iUpdateMask |= aMask;} + +inline void TMMCStackConfig::RemoveMode(TUint32 aMask) +/** + * Disable a single mode or a set of modes. + * Disabled modes should be considered by the Controller as not in effect. However, client mode + * settings may be overridden by master settings. + * @param aMask The mode(s) to be removed. + */ + {iModes &= ~aMask; iUpdateMask |= aMask;} + +inline void TMMCStackConfig::UseDefault(TUint32 aMask) +/** + * Restore a single mode or a set of modes to the default setting setting for the platform. + * @param aMask The mode(s) to be restored. + */ + {iUpdateMask &= ~aMask; iClientMask &= ~aMask;} + +inline void TMMCStackConfig::SetPollAttempts(TUint aData) +/** + * Set the number of attempts the Controller is allowed to make to recover on busy timeout during writes to the card. + * The default setting for this is KMMCMaxPollAttempts (i.e. 5). + * @param aData The number of attempts to make to recover on busy timeout during write + */ + {iPollAttempts=aData; iClientMask |= KMMCModeClientPollAttempts; } + +inline void TMMCStackConfig::SetOpCondBusyTimeout(TUint16 aData) +/** + * Set the number of attempts the Controller is allowed to make to recover on busy timeout + * while waiting for a card which is slow to power up during stack initialisation. The default setting + * for this is KMMCMaxOpCondBusyTimeout (i.e. 100). + * @param aData The number of attempts to make to recover on busy timeout during power up +*/ + {iOpCondBusyTimeout=aData; iClientMask |= KMMCModeClientiOpCondBusyTimeout; } + +inline TInt TMMCStackConfig::OpCondBusyTimeout() +/** + * Return the number of attempts the Controller is allowed to make to recover on busy timeout + * while waiting for a card which is slow to power up during stack initialisation. + * @return The number of attempts to make to recover on busy timeout +*/ + {return((TInt)iOpCondBusyTimeout);} + +inline void TMMCStackConfig::SetTimeOutRetries(TUint aData) +/** + * Set the number of auto reties the Controller is allowed to make on command response time-out or data + * block receive timeout situations. The default setting for this is KMMCMaxTimeOutRetries (i.e. 1). + * @param aData The number of auto reties to make on command response time-out or data block receive timeout condition. + */ + {iTimeOutRetries=aData; iClientMask |= KMMCModeClientTimeOutRetries; } + +inline void TMMCStackConfig::SetCRCRetries(TUint aData) +/** + * Set the number of auto reties the Controller is allowed to make on CRC error situations. + * The default setting for this is KMMCMaxCRCRetries (i.e. 1). + * @param aData The number of auto reties to make on a CRC error condition. + */ + {iCRCRetries=aData; iClientMask |= KMMCModeClientCRCRetries; } + +inline void TMMCStackConfig::SetBusClockInKhz(TUint aData) +/** + * Set the bus clock speed in kilohertz. + * The default master setting for this depends on the platform (set in DMMCStack::SetBusConfigDefaults). + * @param aData The bus clock speed in kilohertz + */ + {iBusConfig.iBusClock=aData; iClientMask |= KMMCModeClientBusClock; } + +inline void TMMCStackConfig::SetTicksClockIn(TUint aData) +/** + * Set the number of clock ticks in the ClockIn phase to be used. + * The default master setting for this depends on the platform (set in DMMCStack::SetBusConfigDefaults). + * @param aData The number of clock ticks in the ClockIn phase + */ + {iBusConfig.iClockIn=aData; iClientMask |= KMMCModeClientClockIn; } + +inline void TMMCStackConfig::SetTicksClockOut(TUint aData) +/** + * Set the number of clock ticks in the ClockOut phase to be used. + * The default master setting for this depends on the platform (set in DMMCStack::SetBusConfigDefaults). + * @param aData The number of clock ticks in the ClockOut phase + */ + {iBusConfig.iClockOut=aData; iClientMask |= KMMCModeClientClockOut; } + +inline void TMMCStackConfig::SetResponseTimeOutInTicks(TUint aData) +/** + * Set the response timeout value to be used (in bus clock ticks). + * If a command response is not received within this period then the Controller will either retry or return an error. + * The default master setting for this depends on the platform (set in DMMCStack::SetBusConfigDefaults). + * @param aData The response timeout in bus clock ticks + */ + {iBusConfig.iResponseTimeOut=aData; iClientMask |= KMMCModeClientResponseTimeOut; } + +inline void TMMCStackConfig::SetDataTimeOutInMcs(TUint aData) +/** + * Set the data timeout value to be used (in microseconds). + * If an expected data block is not received from the card within this period then the Controller will + * either retry or return an error. + * The default master setting for this depends on the platform (set in DMMCStack::SetBusConfigDefaults). + * @param aData The data timeout in microseconds + */ + {iBusConfig.iDataTimeOut=aData; iClientMask |= KMMCModeClientDataTimeOut; } + +inline void TMMCStackConfig::SetBusyTimeOutInMcs(TUint aData) +/** + * Set the busy timeout value to be used (in microseconds). + * If a data block is not requested by the card within this period then the Controller will either retry + * or return an error. + * The default master setting for this depends on the platform (set in DMMCStack::SetBusConfigDefaults). + * @param aData The busy timeout in microseconds + */ + {iBusConfig.iBusyTimeOut=aData; iClientMask |= KMMCModeClientBusyTimeOut; } + + +// -------- class TMMCRCAPool -------- + +inline TMMCRCAPool::TMMCRCAPool() : iLocked(0) {} +inline void TMMCRCAPool::LockRCA(TRCA anRCA) {iLocked |= (1 << (((TUint(anRCA) / 257) - 1) & 31));} +inline void TMMCRCAPool::UnlockRCA(TRCA anRCA) {iLocked &= ~(1 << (((TUint(anRCA) / 257) - 1) & 31));} +inline void TMMCRCAPool::ReleaseUnlocked() {iPool = 0;} + + +// -------- class TMMCSessRing -------- + +inline TBool TMMCSessRing::IsEmpty() const {return(iSize==0);} +inline void TMMCSessRing::SetMarker() {iPMark=iPrevP;} +inline void TMMCSessRing::AdvanceMarker() {if(iPMark != NULL) iPMark=iPMark->iLinkP;} +inline void TMMCSessRing::Point() {iPoint=((iPrevP=iPMark)==NULL)? NULL : iPMark->iLinkP;} +inline TUint TMMCSessRing::Size() const {return(iSize);} +inline TMMCSessRing::operator DMMCSession*() const {return(iPoint);} + + +// -------- class TMMCStateMachine -------- + + +/** +Gets the current MultiMediCard error code. + +@return The current MultiMediCard error code. +*/ +inline TMMCErr TMMCStateMachine::ExitCode() { return(iExitCode); } + + + + +/** +Gets the current MultiMediCard error code, and sets a new error code. + +@param aCode The new error code value to be set. + +@return The current MultiMediCard error code. +*/ +inline TMMCErr TMMCStateMachine::SetExitCode(TMMCErr aCode) { return __e32_atomic_swp_ord32(&iExitCode, aCode); } + + + + +/** +Gets the current state of the state machine. + +Note that this is the state of the current state entry within +the state machine stack. + +@return The current state of the state machine. +*/ +inline TUint TMMCStateMachine::State() { return(iStack[iSP].iState); } + + + + +/** +Sets the state of the state machine. + +Note that this sets the state of the current state entry within +the state machine stack. + +@param aState The state to be set. + +@return KMMCErrNone +*/ +inline TMMCErr TMMCStateMachine::SetState(TUint aState) { iStack[iSP].iState=aState; return(0); } + + + + +/** +Prevents the state machine from blocking. +*/ +inline void TMMCStateMachine::SuppressSuspension() { iSuspend = EFalse; } + + + + +/** +Sets the trap mask for the current state machine entry. + +This defines the set of errors that the state machine function +wants to trap. + +@param aMask The set of error values. This is a set of TMMCErr bits. + +@see TMMCErr +*/ +inline void TMMCStateMachine::SetTraps(TMMCErr aMask) { iStack[iSP].iTrapMask=aMask; } + + + + +/** +Clears the trap mask. + +@see TMMCStateMachine::SetTraps() +*/ +inline void TMMCStateMachine::ResetTraps() { iStack[iSP].iTrapMask=0; } + + + + +/** +Aborts the session. +*/ +inline void TMMCStateMachine::Abort() { iAbort=ETrue; } + + + + +/** +Initialises the state machine. + +The function sets up the state machine function for the first state entry on +the state machine stack. + +It also sets up the context. In practice, the context is a pointer to +the DMMCStack stack object, i.e. the object representing the MultiMediaCard +stack. The pointer is passed to the state machine functions when they +are dispatched. + +@param anEntry The state machine function for the first state machine entry. +@param aContextP A pointer to the context. +*/ +inline void TMMCStateMachine::Setup(TMMCErr (*anEntry)(TAny*), TAny* aContextP) + {iContextP = aContextP; iStack[0].iFunction = anEntry; Reset();} + + + + +/** +Pops the current state entry off the state machine stack. + +@param aSuspend Indicates whether the state machine is to block; + specify ETrue to block, EFalse not to block. + +@return KMMCErrNone. +*/ +inline TMMCErr TMMCStateMachine::Pop(TBool aSuspend) + {iSP--; if(!aSuspend) iSuspend = EFalse; return( 0 );} + + + + +/** +Pushes the next state entry onto the stack, specifying the current state +function as the child function that is to be run, and requests the state +machine to block. + +@return A MultiMediaCard error code returned from a call to TMMCStateMachine::Push(). +*/ +inline TMMCErr TMMCStateMachine::PushMe() {return(Push(iStack[iSP].iFunction,ETrue));} + + +// -------- class DMMCSession -------- + +inline void DMMCSession::SetStack(DMMCStack* aStackP) +/** + * Assign a stack to the session. + * + * If an attempt is made to engage the session before a stack has been assigned to it + * then the request will fail straight away. It is possible to change the stack controller + * assigned to the session as long as this is not attempted while the session is engaged. + * + * @param aStackP A pointer to the stack to be assigned to the session + */ + {iStackP = aStackP;} + +inline void DMMCSession::SetupCIMUpdateAcq() +/** + * Set up the session to perform the CIM_UPDATE_ACQ macro as outlined by the MMCA. + * + * Having set-up the session for this operation, the client must then engage the session + * before the operation can commence. The CIM_UPDATE_ACQ macro starts an identification + * cycle of a card stack. New cards are initialised but old cards keep their configuration. + * The process ends with all compatible cards being moved to their stand-by state. + */ + {iSessionID = ECIMUpdateAcq;} + +inline void DMMCSession::SetupCIMInitStack() +/** + * Set up the session to perform the CIM_INIT_STACK macro as outlined by the MMCA. + * + * Having set-up the session for this operation, the client must then engage the session + * before the operation can commence. The CIM_UPDATE_ACQ macro sends all cards to the idle + * state and then executes the update acquisition sequence. + */ + {iSessionID = ECIMInitStack;} + +inline void DMMCSession::SetupCIMCheckStack() +/** + * Set up the session to perform the CIM_CHECK_STACK macro as outlined by the MMCA. + * + * Having set-up the session for this operation, the client must then engage the session + * before the operation can commence. The CIM_CHECK_STACK macro attempts to read the CSD + * of each active card in the stack, updating the data held by the stack controller for each card. + */ + {iSessionID = ECIMCheckStack;} + +inline void DMMCSession::SetupCIMSetupCard() +/** + * Set up the session to perform the CIM_SETUP_CARD macro as outlined by the MMCA. + * + * Having set-up the session for this operation, the client must then engage the session + * before the operation can commence. The CIM_SETUP_CARD macro selects a particular card + * for data transfer and reads back its CSD. + */ + {iSessionID = ECIMSetupCard;} + +inline void DMMCSession::SetupCIMLockStack() +/** + * Set up the session to lock the stack for this session only (so that only this session + * can be engaged upon it). This prevents any other sessions from being engaged upon it. + * + * Having set-up the session for this operation, the client must then engage this session before + * the stack becomes locked. In fact, no card bus activity results when this session is engaged. + * However, because it may take some time for the Controller to be able to lock the stack for this + * session, the mechanism for locking the stack still involves submitting a session. + * When issuing a series of application specific commands, the client will want to lock the stack, + * preventing any other client from generating bus activity during this period. This is accomplished + * by issuing this function and then engaging that session. If successful, the stack will be locked + * until the DMMCSession::UnlockStack() function is issued. + */ + {iSessionID = ECIMLockStack;} + +inline void DMMCSession::UnlockStack() +/** + * Unlock this session as the locking session for the stack, the stack having previously been locked + * to this session using the DMMCSession. + */ + {if(iStackP != NULL) iStackP->UnlockStack(this);} + +inline void DMMCSession::SetupCIMInitStackAfterUnlock() +/** + * Set up the session to perform the second stage of initialisation after unlocking of the card + * + * This is provided to allow types of cards (particularly SD cards) to access the SD_STATUS and + * associated registers during initialisation, which are only available once the card is unlocked. + */ + { + iCardP = NULL; + iSessionID = ECIMInitStackAfterUnlock; + } + +inline void DMMCSession::SetupCIMAutoUnlock() +/** + * Set up the session to perform auto-unlocking of the card + */ + {iSessionID = ECIMAutoUnlock;} + +inline void DMMCSession::Stop() +/** + * Signal the session to complete immediately with KErrAbort + * (i.e. the session end call-back function will be called). + */ + {if(iStackP != NULL) iStackP->Stop(this);} + +inline void DMMCSession::Abort() +/** + * Signal the session to abort immediately with no completion + * (i.e. the session end call-back function will not be called). + */ + {if(iStackP != NULL) iStackP->Abort(this);} + +inline TMMCSessionTypeEnum DMMCSession::SessionID() const +/** + * Returns the current session type for this session. + * + * @return A TMMCSessionTypeEnum describing the sesion type + */ + {return(iSessionID);} + +inline DMMCStack* DMMCSession::StackP() const +/** + * Returns the DMMCStack object serving this session. + * + * @return A pointer to the DMMCStack object serving this session. + */ + {return(iStackP);} + +inline TMMCard* DMMCSession::CardP() const +/** + * Returns a pointer to the TMMCard object which this session is set to use. + * + * @return A pointer to the TMMCard object which this session is set to use. + */ + {return(iCardP);} + +inline TBool DMMCSession::IsEngaged() const +/** + * Return ETrue if this session is currently queued on the DMMCStack object serving this session. + * + * @return ETrue if this session is currently queued, otherwise EFalse + */ + {return((iState & KMMCSessStateEngaged) != 0);} + +inline TMMCErr DMMCSession::MMCExitCode() const +/** + * Returns the last MMC specific error code returned to this session. + * + * @return a TMMCErr describing the MMC specific error code + */ + {return(iMMCExitCode);} + +inline TMMCStatus DMMCSession::LastStatus() const +/** + * Returns the last status information from the card (i.e. the last R1 response received from the card). + * + * @return a TMMCStatus describing the status information + */ + {return(iLastStatus);} + +inline TUint32 DMMCSession::BytesTransferred() const +/** + * Returns the total number of bytes transferred in this session. + * + * @return the total number of bytes transferred in this session. + */ + {return(iBytesTransferred);} + +inline TUint8* DMMCSession::ResponseP() +/** + * Returns a pointer to a buffer containing the last command response received in this session. + * + * @return a buffer with format TUint8[KMMCMaxResponseLength] (where KMMCMaxResponseLength = 16). + */ + {return(&iCommand[iCmdSP].iResponse[0]);} + +inline TUint32 DMMCSession::EffectiveModes() const +/** + * Returns the modes which the DMMCStack object serving this session will consider as effective. + * + * @return the modes which the DMMCStack object serving this session will consider as effective + */ + {if(iStackP != NULL) return(iStackP->EffectiveModes(iConfig)); return(0);} + +inline void DMMCSession::Block(TUint32 aFlag) + {iStackP->Block(this, aFlag);} + +inline void DMMCSession::UnBlock(TUint32 aFlag, TMMCErr anExitCode) + {iStackP->UnBlock(this, aFlag, anExitCode);} + +inline void DMMCSession::SwapMe() + {iState |= KMMCSessStateDoReSchedule;} + +inline void DMMCSession::ResetCommandStack() +/** + * Resets the command stack, setting the stack pointer to zero. + */ + {iCmdSP = 0;} + +/** +Increments the command stack pointer. + +@panic PBUS-MMC 6 if the stack pointer lies outside the bounds of the stack. +*/ +inline void DMMCSession::PushCommandStack() + { + __ASSERT_ALWAYS(TUint(++iCmdSP)=0, + DMMCSocket::Panic(DMMCSocket::EMMCCommandStack)); + } + +inline TMMCCommandDesc& DMMCSession::Command() +/** + * Returns the current command, as referred to by the stack pointer. + * @return A TMMCCommandDesc reference, containing the current command. + */ + {return(iCommand[iCmdSP]);} + + +// +// Data transfer macros setup (block mode) +// + +inline void DMMCSession::SetupCIMReadBlock(TMMCArgument aBlockAddr, TUint8* aMemoryP, TUint32 aBlocks) +/** + * Sets the session up to perform the CIM_READ_BLOCK macro as outlined by the MMCA. + * Having set-up the session for this operation, the client must then engage the session before the operation can commence. + * The CIM_READ_BLOCK macro reads a single block from the card. It starts by setting the block length (CMD16) to 512 Bytes. + * It then reads 'aBlocks' blocks of data from the card at offset 'aBlockAddr' on the card into system memory starting at + * address 'aMemoryP'. + * + * @param aBlockAddr Contains offset (in blocks) to the block to be read from the card + * @param aMemoryP host destination address + * @param aBlocks The number of blocks to read from the card + */ + { + ResetCommandStack(); + FillCommandArgs(aBlockAddr, aBlocks << KMMCardHighCapBlockSizeLog2, aMemoryP, KMMCardHighCapBlockSize); + Command().iFlags |= KMMCCmdFlagBlockAddress; + iSessionID = (aBlocks > 1)? ECIMReadMBlock : ECIMReadBlock; + } + +inline void DMMCSession::SetupCIMWriteBlock(TMMCArgument aBlockAddr, TUint8* aMemoryP, TUint32 aBlocks) +/** + * Set up the session to perform the CIM_WRITE_BLOCK macro as outlined by the MMCA. + * Having set-up the session for this operation, the client must then engage the session before the operation can commence. + * The CIM_WRITE_BLOCK macro writes a single block to the card. It starts by setting the block length (CMD16) to 512 Bytes. + * It then writes 'aBlocks' block of data to the card at offset 'aBlockAddr' on the card reading from system memory starting + * at address 'aMemoryP'. + * + * @param aBlockAddr Contains offset to the block (in blocks) to be written on the card + * @param aMemoryP Host source address + * @param aBlocks The number of blocks to write to the card + */ + { + ResetCommandStack(); + FillCommandArgs(aBlockAddr, aBlocks << KMMCardHighCapBlockSizeLog2, aMemoryP, KMMCardHighCapBlockSize); + Command().iFlags |= KMMCCmdFlagBlockAddress; + iSessionID = (aBlocks > 1)? ECIMWriteMBlock : ECIMWriteBlock; + } + +inline void DMMCSession::SetupCIMEraseMSector(TMMCArgument aBlockAddr, TUint32 aBlocks) +/** + * Set up the session to perform the CIM_ERASE_SECTOR macro broadly as outlined by the MMCA. + * However, the macro only performs a sector erase of a contiguous area and doesn't support the un-tagging of particular sectors + * within the initial tagged area. Having set-up the session for this operation, the client must then engage the session before + * the operation can commence. + * + * The CIM_ERASE_SECTOR macro erases a range of sectors on the card starting at offset (in blocks) 'aBlockAddr' on the card and ending at offset + * 'aBlockAddr'+'aBlocks' (in blocks). The entire area specified must lie within a single erase group. (The erase group size can be read from the CSD). + * The tag sector start command (CMD32) is first issued setting the address of the first sector to be erased. + * This is followed by the tag sector end command (CMD33) setting the address of the last sector to be erased. Now that the erase + * sectors are tagged, the erase command (CMD38) is sent followed by a send status command (CMD13) to read any additional status + * information from the card. + * + * @param aBlockAddr Contains offset (in blocks) to the first block to be erased + * @param aBlocks Total number of blocks to erase + */ + { + ResetCommandStack(); + FillCommandArgs(aBlockAddr, aBlocks << KMMCardHighCapBlockSizeLog2, NULL, 0); + Command().iFlags |= KMMCCmdFlagBlockAddress; + iSessionID = ECIMEraseSector; + } + +inline void DMMCSession::SetupCIMEraseMGroup(TMMCArgument aBlockAddr, TUint32 aBlocks) +/** + * Set up the session to perform the CIM_ERASE_GROUP macro broadly as outlined by the MMCA. + * However, the macro only performs an erase group erase of a contiguous area and doesn't support the un-tagging of particular + * erase groups within the initial tagged area. Having set-up the session for this operation, the client must then engage the + * session before the operation can commence. + * + * The CIM_ERASE_GROUP macro erases a range of erase groups on the card starting at offset (in blocks) 'aDevAddr' on the card and ending at + * offset 'aBlockAddr'+'aBlocks' (in blocks). The tag ease group start command (CMD35) is first issued setting + * the address of the first erase group to be erased. This is followed by the tag erase group end command (CMD36) setting the + * address of the last erase group to be erased. Now that the erase groups are tagged, the erase command (CMD38) is sent followed + * by a send status command (CMD13) to read any additional status information from the card. + * + * @param aBlockAddr Contains offset (in blocks) to the first block to be erased + * @param aBlocks Total number of blocks to erase + */ + { + ResetCommandStack(); + FillCommandArgs(aBlockAddr, aBlocks << KMMCardHighCapBlockSizeLog2, NULL, 0); + Command().iFlags |= KMMCCmdFlagBlockAddress; + iSessionID = ECIMEraseGroup; + } + +inline void DMMCSession::EnableDoubleBuffering(TUint32 aNumBlocks) +/** + * When called before a data transfer operation is engaged, specifies that the data + * transfer operation is to be double-buffered. + * + * @param aNumBlocks The number of blocks to transfer per double-buffer transfer. + * + * @internalTechnology + */ + { + __KTRACE_OPT(KPBUS1, Kern::Printf("++ DMMCSession::EnableDoubleBuffering(%d Blocks)", aNumBlocks)) + + //__ASSERT_ALWAYS(iSessionID == ECIMWriteMBlock || iSessionID == ECIMReadMBlock, DMMCSocket::Panic(DMMCSocket::EMMCInvalidDBCommand)); + + Command().iBlockLength &= 0x0000FFFF; + Command().iBlockLength |= aNumBlocks << 16; + Command().iFlags |= KMMCCmdFlagDoubleBuffer; + } + +inline void DMMCSession::SetDataTransferCallback(TMMCCallBack& aCallback) +/** + * Registers the data transfer callback function to be called when more data is required by the PSL, + * typically while the hardware is busy performing a DMA transfer. + * + * @param aCallback The callback function. + * + * @internalTechnology + */ + { + __KTRACE_OPT(KPBUS1, Kern::Printf("++ DMMCSession::SetDataTransferCallback")); + + iDataTransferCallback = aCallback; + } + +inline void DMMCSession::MoreDataAvailable(TUint32 aNumBlocks, TUint8* aMemoryP, TInt aError) +/** + * Called by the MMC Media Driver after copying data from the client thread to indicate to the + * PSL that data is available in the next data buffer. Should be called at the end of the + * data transfer callback function, at which point the stack will be unblocked enabling the + * next data transfer to take place. + * + * @param aNumBlocks The number of blocks available in the buffer. + * @param aMemoryP A pointer to the host memory containing the next blocks of data. + * @param aError The result of the data callback. + * + * @internalTechnology + */ + { + __KTRACE_OPT(KPBUS1, Kern::Printf("++ DMMCSession::MoreDataAvailable(%d blocks, %08x, %d)", aNumBlocks, aMemoryP, aError)); + + Command().iDataMemoryP = aMemoryP; + EnableDoubleBuffering(aNumBlocks); + + iStackP->UnBlock(this, KMMCBlockOnMoreData, aError == KErrNone ? KMMCErrNone : KMMCErrGeneral); + } + +inline TBool DMMCSession::RequestMoreData() +/** + * Called by the PSL to request the next blocks of data to be transferred from the media driver + * to the PSL. This would typically be called while the hardware is busy transferring the current + * block of data, allowing the media driver to copy data from the client in parallel. + * + * This method will set the state machine to block on KMMCBlockOnMoreData, so the PSL must block + * the state machine using an SMF_WAITS (or equivalent). When the Media Driver has populated the + * next buffer, the current command descriptor will be updated and the state machine unblocked. + * + * @return ETrue if all conditions are met to perform double-buffering (ie - command is enabled + * for double-buffering and the last transfer has not already been satisfied). If + * successful, upon exit the state machine will be blocked with the KMMCBlockOnMOreData + * condition and the Media Driver's data transfer callback invoked. + * + * + */ + { + __KTRACE_OPT(KPBUS1, Kern::Printf("++ DMMCSession::RequestMoreData()")); + + if(Command().IsDoubleBuffered() && (Command().iBytesDone + Command().BufferLength() < Command().iTotalLength)) + { + iStackP->Block(this, KMMCBlockOnMoreData); + iDataTransferCallback.CallBack(); + return(ETrue); + } + + return(EFalse); + } + + +// -------- class DMMCSocket -------- + +inline TBool DMMCSocket::SupportsDoubleBuffering() +/** + * @return ETrue If the PSL supports double buffering, as specified by the + * PSL by setting the ESupportsDoubleBuffering flag in ::MachineInfo. + * + * @internalTechnology + */ + { + return ((iMachineInfo.iFlags & TMMCMachineInfo::ESupportsDoubleBuffering) ? (TBool)ETrue : (TBool)EFalse); + } + +inline TUint32 DMMCSocket::MaxDataTransferLength() +/** + * @return The maximum length that the PSL supports in a single data transfer. + * Returns Zero if the PSL has no limitation on the maximum length of data transfer. + * + * @internalTechnology + */ + { + return(0x20000 << ((iMachineInfo.iFlags & TMMCMachineInfo::EMaxTransferLength_16M) >> 8)); + } + +inline TUint32 DMMCSocket::DmaAlignment() +/** + * @return Byte alignment required by the DMA Controller. + * e.g. 16 Bit addressing scheme equates to 2 byte alignment. + * + * @internalTechnology + */ + { + const TUint32 DmaAddrMsk = TMMCMachineInfo::EDma8BitAddressing | + TMMCMachineInfo::EDma16BitAddressing | + TMMCMachineInfo::EDma32BitAddressing | + TMMCMachineInfo::EDma64BitAddressing; + return ((iMachineInfo.iFlags & DmaAddrMsk) >> 3); + } + +// -------- class DMMCStack -------- + +inline void DMMCStack::ReportPowerUp() +/** + * Called by the variant layer to indicate that a + * power up operation has successfully completed. + */ + {iPoweredUp = ETrue;} + +inline void DMMCStack::ReportPowerDown() +/** + * Indicates that that power down operation has successfully completed. + * Following power down, the stack enters a state pending the next power up operation. + */ + {iPoweredUp = EFalse; iStackState |= KMMCStackStateInitPending;} + +inline void DMMCStack::Reset() +/** + * Resets the stack by aborting all current requests. + */ + {iAbortAll = ETrue; Scheduler(iAbortReq);} + +inline void DMMCStack::CompleteAll(TMMCErr aCode) +/** + * Stops and dequeues all sessions queued on this stack (including those queued by other clients). + * Each of the sessions affected will complete immediately with error code 'aCode' (i.e. the session + * end call-back function will be called). + * @param aCode The MMC error code to be returned. + */ + {iCompleteAllExitCode = aCode; Scheduler(iCompReq);} + +inline TUint DMMCStack::MaxCardsInStack() const +/** + * Returns the maximum number of MultiMediaCards which could ever be present in this stack. + * i.e. the total number of physical card slots associated with this stack on this platform. + * (This is initialised from the DMMCSocket::TotalSupportedCards) + * @return The number of supported cards. + */ + {return( iMaxCardsInStack );} + +inline TMMCard* DMMCStack::CardP(TUint aCardNumber) +/** + * Returns a pointer to the specified card. + * @param aCardNumber The card number. + * @return A pointer to the specified card. + */ + {return( (aCardNumberCardP(aCardNumber)) : NULL );} + +inline DMMCSocket* DMMCStack::MMCSocket() const +/** + * Returns a pointer to associated socket object. + * @return A pointer to the associated socket. + */ + {return( iSocket );} + +inline TMMCPasswordStore* DMMCStack::PasswordStore() const +/** + * Returns a pointer to the associated password store. + * @return A pointer to the associated password store. + */ + {return( iSocket->iPasswordStore );} + +inline TBool DMMCStack::InitStackInProgress() const +/** + * Reports the initialisation state of the stack (i.e is the CIM_INIT_STACK macro in progress). + * @return ETrue if the stack is being initialised, EFalse otherwise. + */ + {return( (iStackState & KMMCStackStateInitInProgress) != 0 );} + +inline TBool DMMCStack::HasSessionsQueued() const +/** + * Reports if any of the session queues have submitted session engaged. + * @return ETrue if there are any sessions engaged on this stack, EFalse otherwise. + */ + {return((iWorkSet.Size()!=0) || (iReadyQueue.Size()!=0) || (iEntryQueue.Size()!=0));} + +inline TBool DMMCStack::HasCardsPresent() +/** + * Reports if any cards are present on the stack + * @return ETrue if there are any sessions engaged on this stack, EFalse otherwise. + */ + { + for (TUint i=0 ; iDemandPagingInfo(aInfo); + else + return KErrNotSupported; + } + + +inline void DMMCStack::CancelSession(DMMCSession* aSession) + { + GetInterface(KInterfaceCancelSession, (MInterface*&) aSession); + } + +inline TRCA DMMCStack::SelectedCard() const +/** + * Returns the Relative Card Address (RCA) of the currently selected card + * @return A TRCA object containing the Relative Card Address. + */ + { + return iSelectedCard; + } + +inline TMMCStateMachine& DMMCStack::Machine() +/** + * Returns the current sessions MMC State Machine object. + * @return A TMMCStateMachine reference to the current sessions State Machine object. + */ + {return( iSessionP->iMachine );} + +inline TMMCBusConfig& DMMCStack::BusConfig() +/** + * Returns the current bus configuration. + * @return A TMMCBusConfig reference describing current sessions bus configuration. + */ + {return( iConfig.iBusConfig );} + +inline TMMCBusConfig& DMMCStack::MasterBusConfig() +/** + * Returns the master bus configuration. + * @return A TMMCBusConfig reference describing the master bus configuration. + */ + {return( iMasterConfig.iBusConfig );} + +inline TMMCCommandDesc& DMMCStack::Command() +/** + * Returns the current sessions command description. + * @return A TMMCCommandDesc reference describing current sessions command. + */ + {return( iSessionP->Command() );} + +inline DMMCSession& DMMCStack::Session() +/** + * Returns the current session object. + * @return A reference to the current DMMCSession object. + */ + {return(*iSessionP);} + +inline void DMMCStack::BlockCurrentSession(TUint32 aFlag) +/** + * Indicates that the current session is to be blocked (ie - waiting on an asynchronous response such as interrupt). + * The state machine will only unblock when an unblock request with the matching argument is called. + * In the PSL level of the Controller you should always use KMMCBlockOnASSPFunction as the argument. + * @param aFlag Bitmask describing the reason for blocking. + */ + {Block(iSessionP,aFlag);} + +inline void DMMCStack::UnBlockCurrentSession(TUint32 aFlag, TMMCErr anExitCode) +/** + * Indicates that the current session is to be unblocked (ie - an a asynchronous operation has completed). + * The state machine will only unblock when an unblock request with the matching argument is called. + * @param aFlag Bitmask describing the reason for unblocking. + * @param anExitCode KMMCErrNone if successful, otherwise a standard TMMCErr code. + */ + {UnBlock(iSessionP,aFlag,anExitCode);} + +inline void DMMCStack::ReportInconsistentBusState() +/** + * Indicates that something has gone wrong, so the stack needs re-initialising. + */ + {iStackState |= KMMCStackStateBusInconsistent;} + +inline void DMMCStack::ReportASSPEngaged() +/** + * Called by the PSL to indicate that a session has been engaged. + */ + {iSessionP->iState |= KMMCSessStateASSPEngaged;} + +inline void DMMCStack::ReportASSPDisengaged() +/** + * Called by the PSL to indicate that a session has completed or has been aborted. + */ + {iSessionP->iState &= ~KMMCSessStateASSPEngaged;} + +inline TRCA DMMCStack::CurrentSessCardRCA() +/** + * Returns the Relative Card Address (RCA) in use by the current session. + * @return A TRCA object containing the Relative Card Address. + */ + {return(iSessionP->CardRCA());} + + +inline TMMCErr DMMCStack::BaseModifyCardCapabilitySMST( TAny* aStackP ) + { return( static_cast(aStackP)->DMMCStack::ModifyCardCapabilitySM() ); } + +inline TMMCErr DMMCStack::InitCurrentCardAfterUnlockSMST( TAny* aStackP ) + { return( static_cast(aStackP)->DMMCStack::InitStackAfterUnlockSM() ); } + +/** +Increments the current session's command stack pointer. + +@see DMMCSession::PushCommandStack() +*/ +inline void DMMCStack::CurrentSessPushCmdStack() + {iSessionP->PushCommandStack();} + + + +/** +Decrements the current session's command stack pointer. + +@see DMMCSession::PopCommandStack() +*/ +inline void DMMCStack::CurrentSessPopCmdStack() + {iSessionP->PopCommandStack();} + +/** +Allows the stack to yield to another command temporarily, for one loop of the scheduler only. + +@param aCommandType The command type to yield to. +*/ +inline void DMMCStack::YieldStack(TMMCCommandTypeEnum aCommandType) + { + BlockCurrentSession(KMMCBlockOnYielding); + iYieldCommandType = aCommandType; + iStackState |= KMMCStackStateYielding; + } + + +inline void DMMCStack::CurrentSessFillCmdDesc(TMMCCommandEnum aCommand) +/** + * Initialises the current sessions command according to whether it is a normal + * or an application command. + * @param aCommand Contains the command. + */ + {iSessionP->FillCommandDesc(aCommand);} + +inline void DMMCStack::CurrentSessFillCmdDesc(TMMCCommandEnum aCommand,TMMCArgument anArgument) +/** + * Initialises the current sessions command with an argument according to whether + * it is a normal or an application command. + * @param aCommand Contains the command. + * @param anArgument Specifies the argument. + */ + {iSessionP->FillCommandDesc(aCommand,anArgument);} + +inline void DMMCStack::CurrentSessFillCmdArgs(TMMCArgument anArgument,TUint32 aLength,TUint8* aMemoryP,TUint32 aBlkLen) +/** + * Initialises the current sessions command arguments with the specified parameters + * It is necessary to have set the command arguments with this command prior + * to engaging a read/write macro or command. + * @param anArgument Command specific argument. + * @param aLength aLength Total number of bytes to read/write. + * @param aMemoryP Host source/destination address + * @param aBlkLen Block length + */ + {iSessionP->FillCommandArgs(anArgument,aLength,aMemoryP,aBlkLen);} + +inline void DMMCStack::DeselectsToIssue(TUint aNumber) +/** + * Specifies how many deselects to issue during deselection. + * @param aNumber The number of deselects to issue. + */ + {iDeselectsToIssue = aNumber; iStackState |= KMMCStackStateDoDeselect;} + +// -------- class DMMCController -------- + +inline DMMCStack* DMMCSocket::Stack(TInt aBus) +/** + * Returns a pointer to the DMMCStack object corresponding to the specified MMC card. + * @param aBus The MMC card number. + * @return A pointer to the DMMCStack object corresponding to the specified card. + */ + {return( ((TInt)aBus < iMachineInfo.iTotalSockets) ? iStack : NULL );} + +inline void DMMCSocket::ResetInactivity(TInt /*aBus*/) +/** + * Resets the sockets PSU inactivity timer. + * Commonly used to prevent reset due to inactivity + * while waiting for a response from the card. + * @param aBus Unused + */ + { + iVcc->ResetInactivityTimer(); + if (iVccCore) + iVccCore->ResetInactivityTimer(); + } + +inline const TMMCMachineInfo& DMMCSocket::MachineInfo() const +/** + * Returns a reference to the MachineInfo retrieved from the PSL + * @return a reference to the MachineInfo + */ + {return iMachineInfo;} + +// -------- class TMMCPsu -------- + +inline void DMMCPsu::SetVoltage(TUint32 aVoltage) +/** + * Specifies the voltage setting to be used when the stack is next powered up. + * @param aVoltage The required voltage setting, in OCR register format. + */ + {iVoltageSetting=aVoltage;} + +// -------- Class TMMCCallBack -------- +/** + * Default constructor. Initializes the pointer to the callback function to NULL. + * @see iFunction + */ +inline TMMCCallBack::TMMCCallBack() + {iFunction=NULL;} + +/** + * Constructs the TMMCCallBack object with the specified callback function. + * @param aFunction Callback notification function. + */ +inline TMMCCallBack::TMMCCallBack(void (*aFunction)(TAny *aPtr)) + : iFunction(aFunction),iPtr(NULL) + {} +/** + * Constructs the TMMCCallBack object with the specified callback function and a pointer to any object. + * @param aFunction Callback notification function. + * @param aPtr Pointer to any data. + */ +inline TMMCCallBack::TMMCCallBack(void (*aFunction)(TAny *aPtr),TAny *aPtr) + : iFunction(aFunction),iPtr(aPtr) + {} +/** + * Calls the registered callback function. + */ +inline void TMMCCallBack::CallBack() const + { if(iFunction) (*iFunction)(iPtr); } + +// -------- class TMMCEraseInfo -------- + +inline TBool TMMCEraseInfo::EraseClassCmdsSupported() const +/** + * Returns ETrue if Erase Class commands are supported. + * @return ETrue if Erase Class commands are supported. + */ + {return(iEraseFlags&KMMCEraseClassCmdsSupported);} + +inline TBool TMMCEraseInfo::EraseGroupCmdsSupported() const +/** + * Returns ETrue if Erase Group commands are supported. + * @return ETrue if Erase Group commands are supported. + */ + {return(iEraseFlags&KMMCEraseGroupCmdsSupported);}