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