os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/session.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <drivers/mmc.h>
sl@0
    17
#include "OstTraceDefinitions.h"
sl@0
    18
#ifdef OST_TRACE_COMPILER_IN_USE
sl@0
    19
#include "locmedia_ost.h"
sl@0
    20
#ifdef __VC32__
sl@0
    21
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
sl@0
    22
#endif
sl@0
    23
#include "sessionTraces.h"
sl@0
    24
#endif
sl@0
    25
sl@0
    26
sl@0
    27
sl@0
    28
//	--------  class DMMCSession  --------
sl@0
    29
sl@0
    30
EXPORT_C DMMCSession::DMMCSession(const TMMCCallBack& aCallBack)
sl@0
    31
/**
sl@0
    32
 * Constructor - initializes callbacks and timers.
sl@0
    33
 * Once the session has been engaged, the completion of the request is signalled by calling 
sl@0
    34
 * the function provided in aCallback. A session will be completed in this way if it has completed
sl@0
    35
 * normally, an error has occurred or the session has been stopped by this or another client.
sl@0
    36
 * @param aCallBack reference to a TMMCCallback object to be called upon completion.
sl@0
    37
 */
sl@0
    38
	: iCallBack(aCallBack),
sl@0
    39
#ifdef __EPOC32__
sl@0
    40
	iPollTimer(DMMCSession::PollTimerCallBack, this),
sl@0
    41
	iRetryTimer(DMMCSession::RetryTimerCallBack, this),
sl@0
    42
	iProgramTimer(DMMCSession::ProgramTimerCallBack, this),
sl@0
    43
#endif	// #ifdef __EPOC32__
sl@0
    44
	iConfig()
sl@0
    45
	{
sl@0
    46
	OstTraceFunctionEntry1( DMMCSESSION_DMMCSESSION_ENTRY, this );
sl@0
    47
	}
sl@0
    48
sl@0
    49
EXPORT_C DMMCSession::~DMMCSession()
sl@0
    50
/**
sl@0
    51
 * Destructor.
sl@0
    52
 */
sl@0
    53
	{
sl@0
    54
	OstTraceFunctionEntry1( DUP1_DMMCSESSION_DMMCSESSION_ENTRY, this );
sl@0
    55
	// Ensure that the stack isn't currently running in another thread's context, otherwise this session won't be 
sl@0
    56
	// removed from the stack's workset until some time later - by which time the session will have been deleted
sl@0
    57
	__ASSERT_ALWAYS(!iStackP->StackRunning(), DMMCSocket::Panic(DMMCSocket::EMMCNotInDfcContext));
sl@0
    58
	Abort();
sl@0
    59
	UnlockStack();
sl@0
    60
	OstTraceFunctionExit1( DUP1_DMMCSESSION_DMMCSESSION_EXIT, this );
sl@0
    61
	}
sl@0
    62
sl@0
    63
EXPORT_C void DMMCSession::SetCard(TMMCard* aCardP)
sl@0
    64
/**
sl@0
    65
 * Assigns a card to the session. The card pointer would normally be obtained via a call of DMMCStack::CardP(). 
sl@0
    66
 * Assigning a card to the session is the means by which a particular card in the stack is targeted for a 
sl@0
    67
 * particular request. Some requests involve broadcasting to the entire stack. However, the majority involve 
sl@0
    68
 * an individual card at some stage of the process and so an attempt to engage the session before a card has 
sl@0
    69
 * been assigned to it will generally fail straight away. It is possible to change the card assigned to the 
sl@0
    70
 * session as long as this is not attempted while the session is engaged.
sl@0
    71
 * @param aCardP A pointer to the card to be assigned to the session.
sl@0
    72
 */
sl@0
    73
	{
sl@0
    74
	OstTraceFunctionEntryExt( DMMCSESSION_SETCARD_ENTRY, this );
sl@0
    75
	iCardP = aCardP;
sl@0
    76
	iCID = iCardP->CID();
sl@0
    77
	OstTraceFunctionExit1( DMMCSESSION_SETCARD_EXIT, this );
sl@0
    78
	}
sl@0
    79
sl@0
    80
EXPORT_C void DMMCSession::SetupCIMReadBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP)
sl@0
    81
/**
sl@0
    82
 * Sets the session up to perform the CIM_READ_BLOCK macro as outlined by the MMCA. 
sl@0
    83
 * Having set-up the session for this operation, the client must then engage the session before the operation can commence. 
sl@0
    84
 * The CIM_READ_BLOCK macro reads a single block from the card. It starts by setting the block length (CMD16) as specified 
sl@0
    85
 * in 'aLength'. It then reads a single block of data (CMD17) from the card at offset 'aDevAddr' on the card into system 
sl@0
    86
 * memory starting at address 'aMemoryP'.
sl@0
    87
 * @param aDevAddr Contains offset to the block to be read from the card
sl@0
    88
 * @param aLength Block length
sl@0
    89
 * @param aMemoryP host destination address
sl@0
    90
 */
sl@0
    91
	{
sl@0
    92
	OstTraceExt4(TRACE_FLOW, DMMCSESSION_SETUPCIMREADBLOCK_ENTRY, "DMMCSession::SetupCIMReadBlock;aDevAddr=%x;aLength=%x;aMemoryP=%x;this=%x", (TUint) aDevAddr, (TUint) aLength, (TUint) aMemoryP, (TUint) this);
sl@0
    93
	ResetCommandStack();
sl@0
    94
	FillCommandArgs(aDevAddr, aLength, aMemoryP, aLength);
sl@0
    95
	iSessionID = ECIMReadBlock;
sl@0
    96
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMREADBLOCK_EXIT, this );
sl@0
    97
	}
sl@0
    98
sl@0
    99
EXPORT_C void DMMCSession::SetupCIMWriteBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP)
sl@0
   100
/**
sl@0
   101
 * Set up the session to perform the CIM_WRITE_BLOCK macro as outlined by the MMCA.
sl@0
   102
 * Having set-up the session for this operation, the client must then engage the session before the operation can commence. 
sl@0
   103
 * The CIM_WRITE_BLOCK macro writes a single block to the card. It starts by setting the block length (CMD16) as specified 
sl@0
   104
 * in 'aLength'. It then writes a single block of data (CMD24) to the card at offset 'aDevAddr' on the card reading from system 
sl@0
   105
 * memory starting at address 'aMemoryP'.
sl@0
   106
 * @param aDevAddr Contains offset to the block to be written on the card
sl@0
   107
 * @param aLength Block length
sl@0
   108
 * @param aMemoryP Host source address
sl@0
   109
 */
sl@0
   110
	{
sl@0
   111
	OstTraceExt4(TRACE_FLOW, DMMCSESSION_SETUPCIMWRITEBLOCK_ENTRY, "DMMCSession::SetupCIMWriteBlock;aDevAddr=%x;aLength=%x;aMemoryP=%x;this=%x", (TUint) aDevAddr, (TUint) aLength, (TUint) aMemoryP, (TUint) this);
sl@0
   112
	ResetCommandStack();
sl@0
   113
	FillCommandArgs(aDevAddr, aLength, aMemoryP, aLength);
sl@0
   114
	iSessionID = ECIMWriteBlock;
sl@0
   115
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMWRITEBLOCK_EXIT, this );
sl@0
   116
	}
sl@0
   117
sl@0
   118
EXPORT_C void DMMCSession::SetupCIMReadMBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP, TUint32 aBlkLen)
sl@0
   119
/**
sl@0
   120
 * Set up the session to perform the CIM_READ_MBLOCK macro as outlined by the MMCA.
sl@0
   121
 * Having set-up the session for this operation, the client must then engage the session before the operation can commence. 
sl@0
   122
 * The CIM_READ_MBLOCK macro reads a series of blocks from the card. It starts by setting the block length (CMD16) as specified 
sl@0
   123
 * in 'aBlkLen'. It then issues the read multiple block command (CMD18) to continually transfer blocks from the card to host 
sl@0
   124
 * starting at offset 'aDevAddr' on the card into system memory starting at address 'aMemoryP'. This continues until 'aLength'
sl@0
   125
 * bytes have been read at which point the Controller issues the stop command (CMD12) to halt the transfer.
sl@0
   126
 * @param aDevAddr Contains offset to the block to be read from the card
sl@0
   127
 * @param aLength Total number of bytes to read.
sl@0
   128
 * @param aMemoryP Host destination address
sl@0
   129
 * @param aBlkLen Block length
sl@0
   130
 */
sl@0
   131
	{
sl@0
   132
	OstTraceExt5(TRACE_FLOW, DMMCSESSION_SETUPCIMREADMBLOCK_ENTRY, "DMMCSession::SetupCIMReadMBlock;aDevAddr=%x;aLength=%x;aMemoryP=%x;aBlkLen=%x;this=%x", (TUint) aDevAddr, (TUint) aLength, (TUint) aMemoryP, (TUint) aBlkLen,(TUint) this);
sl@0
   133
	ResetCommandStack();
sl@0
   134
	FillCommandArgs(aDevAddr, aLength, aMemoryP, aBlkLen);
sl@0
   135
	iSessionID = ECIMReadMBlock;
sl@0
   136
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMREADMBLOCK_EXIT, this );
sl@0
   137
	}
sl@0
   138
sl@0
   139
EXPORT_C void DMMCSession::SetupCIMWriteMBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP, TUint32 aBlkLen)
sl@0
   140
/**
sl@0
   141
 * Set up the session to perform the CIM_WRITE_MBLOCK macro as outlined by the MMCA.
sl@0
   142
 * Having set-up the session for this operation, the client must then engage the session before the operation can commence. 
sl@0
   143
 * The CIM_WRITE_MBLOCK macro writes a series of blocks to the card. It starts by setting the block length (CMD16) as specified 
sl@0
   144
 * in 'aBlkLen'. It then issues the write multiple block command (CMD25) to continually transfer blocks from host to the card 
sl@0
   145
 * starting at address 'aMemoryP' in system memory and offset 'aDevAddr' on the card.. This continues until 'aLength' bytes have 
sl@0
   146
 * been written at which point the Controller issues the stop command (CMD12) to halt the transfer
sl@0
   147
 * @param aDevAddr Contains offset to the block to be written on the card
sl@0
   148
 * @param aLength Total number of bytes to write.
sl@0
   149
 * @param aMemoryP Host source address
sl@0
   150
 * @param aBlkLen Block length
sl@0
   151
 */
sl@0
   152
	{
sl@0
   153
	OstTraceExt5(TRACE_FLOW, DMMCSESSION_SETUPCIMWRITEMBLOCK_ENTRY, "DMMCSession::SetupCIMWriteMBlock;aDevAddr=%x;aLength=%x;aMemoryP=%x;aBlkLen=%x;this=%x", (TUint) aDevAddr, (TUint) aLength, (TUint) aMemoryP, (TUint) aBlkLen,(TUint) this);
sl@0
   154
	ResetCommandStack();
sl@0
   155
	FillCommandArgs(aDevAddr, aLength, aMemoryP, aBlkLen);
sl@0
   156
	iSessionID = ECIMWriteMBlock;
sl@0
   157
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMWRITEMBLOCK_EXIT, this );
sl@0
   158
	}
sl@0
   159
sl@0
   160
EXPORT_C void DMMCSession::SetupCIMEraseSector(TMMCArgument aDevAddr, TUint32 aLength)
sl@0
   161
/**
sl@0
   162
 * Set up the session to perform the CIM_ERASE_SECTOR macro broadly as outlined by the MMCA. 
sl@0
   163
 * However, the macro only performs a sector erase of a contiguous area and doesn't support the un-tagging of particular sectors 
sl@0
   164
 * within the initial tagged area. Having set-up the session for this operation, the client must then engage the session before 
sl@0
   165
 * the operation can commence. 
sl@0
   166
 * The CIM_ERASE_SECTOR macro erases a range of sectors on the card starting at offset 'aDevAddr' on the card and ending at offset 
sl@0
   167
 * 'aDevAdd'+'aLength'. The entire area specified must lie within a single erase group. (The erase group size can be read from the CSD).
sl@0
   168
 * The specified start offset and end offset need not coincide exactly with a sector boundary since the card will ignore LSBs below 
sl@0
   169
 * the sector size. The tag sector start command (CMD32) is first issued setting the address of the first sector to be erased. 
sl@0
   170
 * 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
   171
 * sectors are tagged, the erase command (CMD38) is sent followed by a send status command (CMD13) to read any additional status 
sl@0
   172
 * information from the card.
sl@0
   173
 * @param aDevAddr Contains offset to the first block to be erased
sl@0
   174
 * @param aLength Total number of bytes to erase
sl@0
   175
 */
sl@0
   176
	{
sl@0
   177
	OstTraceExt3(TRACE_FLOW, DMMCSESSION_SETUPCIMERASESECTOR_ENTRY, "DMMCSession::SetupCIMEraseSector;aDevAddr=%x;aLength=%x;this=%x", (TUint) aDevAddr, (TUint) aLength, (TUint) this);
sl@0
   178
	ResetCommandStack();
sl@0
   179
	FillCommandArgs(aDevAddr, aLength, NULL, 0);
sl@0
   180
	iSessionID = ECIMEraseSector;
sl@0
   181
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMERASESECTOR_EXIT, this );
sl@0
   182
	}
sl@0
   183
sl@0
   184
EXPORT_C void DMMCSession::SetupCIMEraseGroup(TMMCArgument aDevAddr, TUint32 aLength)
sl@0
   185
/**
sl@0
   186
 * Set up the session to perform the CIM_ERASE_GROUP macro broadly as outlined by the MMCA. 
sl@0
   187
 * However, the macro only performs an erase group erase of a contiguous area and doesn't support the un-tagging of particular 
sl@0
   188
 * erase groups within the initial tagged area. Having set-up the session for this operation, the client must then engage the 
sl@0
   189
 * session before the operation can commence. 
sl@0
   190
 * The CIM_ERASE_GROUP macro erases a range of erase groups on the card starting at offset 'aDevAddr' on the card and ending at 
sl@0
   191
 * offset 'aDevAdd'+'aLength'. The specified start offset and end offset need not coincide exactly with an erase group boundary 
sl@0
   192
 * since the card will ignore LSBs below the erase group size. The tag ease group start command (CMD35) is first issued setting 
sl@0
   193
 * 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
   194
 * 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
   195
 * by a send status command (CMD13) to read any additional status information from the card.
sl@0
   196
 * @param aDevAddr Contains offset to the first block to be erased
sl@0
   197
 * @param aLength Total number of bytes to erase
sl@0
   198
 */
sl@0
   199
	{
sl@0
   200
	OstTraceExt3(TRACE_FLOW, DMMCSESSION_SETUPCIMERASEGROUP_ENTRY, "DMMCSession::SetupCIMEraseGroup;aDevAddr=%x;aLength=%x;this=%x", (TUint) aDevAddr, (TUint) aLength, (TUint) this);
sl@0
   201
	ResetCommandStack();
sl@0
   202
	FillCommandArgs(aDevAddr, aLength, NULL, 0);
sl@0
   203
	iSessionID = ECIMEraseGroup;
sl@0
   204
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMERASEGROUP_EXIT, this );
sl@0
   205
	}
sl@0
   206
sl@0
   207
EXPORT_C void DMMCSession::SetupCIMReadIO(TUint8 aRegAddr, TUint32 aLength, TUint8* aMemoryP)
sl@0
   208
/** 
sl@0
   209
 * Set up the session to perform the read i/o macro (CMD39).
sl@0
   210
 * This macro reads a stream of bytes from an I/O register on a MultiMediaCard. This makes use of the fast i/o (CMD39) command, 
sl@0
   211
 * reading 'aLength' bytes of data from I/O register 'aRegAddr' on the card into system memory starting at address 'aMemoryP'. 
sl@0
   212
 * Having set-up the session for this operation, the client must then engage the session before the operation can commence. 
sl@0
   213
 * @param aRegAddr Address of IO register
sl@0
   214
 * @param aLength Total number of bytes to read
sl@0
   215
 * @param aMemoryP Host destination address
sl@0
   216
 */
sl@0
   217
	{
sl@0
   218
	OstTraceFunctionEntryExt( DMMCSESSION_SETUPCIMREADIO_ENTRY, this );
sl@0
   219
	ResetCommandStack();
sl@0
   220
	FillCommandArgs(aRegAddr, aLength, aMemoryP, 0);
sl@0
   221
	iSessionID = ECIMReadIO;
sl@0
   222
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMREADIO_EXIT, this );
sl@0
   223
	}
sl@0
   224
sl@0
   225
EXPORT_C void DMMCSession::SetupCIMWriteIO(TUint8 aRegAddr, TUint32 aLength, TUint8* aMemoryP)
sl@0
   226
/** 
sl@0
   227
 * Set up the session to perform the write i/o macro (CMD39). 
sl@0
   228
 * This macro writes a stream of bytes to an I/O register on a MultiMediaCard. This makes use of the fast i/o (CMD39) command,
sl@0
   229
 * writing 'aLength' bytes of data to I/O register 'aRegAddr' on the card from system memory starting at address 'aMemoryP'. 
sl@0
   230
 * Having set-up the session for this operation, the client must then engage the session before the operation can commence. 
sl@0
   231
 * @param aRegAddr Address of IO register
sl@0
   232
 * @param aLength Total number of bytes to write
sl@0
   233
 * @param aMemoryP Host source address
sl@0
   234
 */
sl@0
   235
	{
sl@0
   236
	OstTraceFunctionEntryExt( DMMCSESSION_SETUPCIMWRITEIO_ENTRY, this );
sl@0
   237
	ResetCommandStack();
sl@0
   238
	FillCommandArgs(aRegAddr, aLength, aMemoryP, 0);
sl@0
   239
	iSessionID = ECIMWriteIO;
sl@0
   240
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMWRITEIO_EXIT, this );
sl@0
   241
	}
sl@0
   242
sl@0
   243
EXPORT_C void DMMCSession::SetupCIMLockUnlock(TUint32 aLength, TUint8* aMemoryP)
sl@0
   244
/**
sl@0
   245
 * Set up the session to perform the lock-unlock macro (CMD42). 
sl@0
   246
 * This macro is used to manage the password protection feature (if supported) on a MultiMediaCard. 
sl@0
   247
 * This same macro is used to lock or unlock a card, set or clear a password or force erase a card.  
sl@0
   248
 * Having set-up the session for the required operation, the client must then engage the session before 
sl@0
   249
 * the operation can commence. 
sl@0
   250
 * The block length (CMD16) as specified in 'aLength' is first set. The lock unlock command (CMD42) is 
sl@0
   251
 * then issued. This command has the same structure as a regular single block write command. 
sl@0
   252
 * A data block is written to the card from system memory starting at address 'aMemoryP'. The transferred 
sl@0
   253
 * data block should contain the password setting mode, the password length and the password data if appropriate.
sl@0
   254
 * @param aLength Block length
sl@0
   255
 * @param aMemoryP Host source address containing password data
sl@0
   256
 */
sl@0
   257
	{
sl@0
   258
	OstTraceFunctionEntryExt( DMMCSESSION_SETUPCIMLOCKUNLOCK_ENTRY, this );
sl@0
   259
	__KTRACE_OPT(KPBUS1, Kern::Printf("ms:slu%08x", aLength));
sl@0
   260
sl@0
   261
	ResetCommandStack();
sl@0
   262
	FillCommandDesc(ECmdLockUnlock);
sl@0
   263
	FillCommandArgs(0, aLength, aMemoryP, aLength);
sl@0
   264
	iSessionID = ECIMLockUnlock;
sl@0
   265
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMLOCKUNLOCK_EXIT, this );
sl@0
   266
	}
sl@0
   267
sl@0
   268
EXPORT_C void DMMCSession::SetupCommand(TMMCCommandEnum aCommand, TMMCArgument anArgument)
sl@0
   269
/** 
sl@0
   270
 * Set up the session to issue a raw command to the card. 
sl@0
   271
 * This raw command function should be used when issuing a known command with or without an argument. 
sl@0
   272
 * Having set-up the session for this operation, the client must then engage this session before 
sl@0
   273
 * the operation can commence.
sl@0
   274
 * @param aCommand Command to be sent
sl@0
   275
 * @param anArgument Associated argument
sl@0
   276
 */
sl@0
   277
	{
sl@0
   278
	OstTraceExt3(TRACE_FLOW, DMMCSESSION_SETUPCOMMAND_ENTRY, "DMMCSession::SetupCommand;aCommand=%d;anArgument=%x;this=%x", (TInt) aCommand, (TUint) anArgument, (TUint) this);
sl@0
   279
	ResetCommandStack();
sl@0
   280
	FillCommandDesc(aCommand, anArgument);
sl@0
   281
	iSessionID = ECIMNakedSession;
sl@0
   282
	OstTraceFunctionExit1( DMMCSESSION_SETUPCOMMAND_EXIT, this );
sl@0
   283
	}
sl@0
   284
sl@0
   285
EXPORT_C void DMMCSession::SetupRSCommand(TMMCCommandEnum aCommand, TMMCArgument anArgument,
sl@0
   286
							TUint32 aResponseLength, TMMCCommandTypeEnum aCommandType,
sl@0
   287
							TMMCResponseTypeEnum aResponseType,
sl@0
   288
							TUint32 aCommandClass)
sl@0
   289
/**
sl@0
   290
 * Set up the session to issue a raw command to the card. 
sl@0
   291
 * This raw command function should be used when issuing an unknown command, an argument and an unknown response type.
sl@0
   292
 * Having set-up the session for this operation, the client must then engage this session before the operation can commence.
sl@0
   293
 * @param aCommand
sl@0
   294
 * @param anArgument
sl@0
   295
 * @param aResponseLength
sl@0
   296
 * @param aCommandType
sl@0
   297
 * @param aResponseType
sl@0
   298
 * @param aCommandClass
sl@0
   299
 * @todo Complete the parameter descriptions
sl@0
   300
 */
sl@0
   301
	{
sl@0
   302
	OstTraceExt4( TRACE_FLOW, DMMCSESSION_SETUPRSCOMMAND_ENTRY1, "DMMCSession::SetupRSCommand;aCommand=%d;anArgument=%x;aResponseLength=%x;this=%x", (TInt) aCommand, (TUint) anArgument, (TUint) aResponseLength, (TUint) this );
sl@0
   303
	OstTraceExt4( TRACE_FLOW, DMMCSESSION_SETUPRSCOMMAND_ENTRY2, "DMMCSession::SetupRSCommand;aCommandType=%d;aResponseType=%d;aCommandClass=%x;this=%x", (TInt) aCommandType, (TInt) aResponseType, (TUint) aCommandClass, (TUint) this );
sl@0
   304
	ResetCommandStack();
sl@0
   305
	FillCommandDesc(aCommand, anArgument);
sl@0
   306
	TMMCCommandSpec& cmdSpec = Command().iSpec;
sl@0
   307
	cmdSpec.iDirection = EDirNone;
sl@0
   308
sl@0
   309
	if( aResponseLength <= KMMCMaxResponseLength )
sl@0
   310
		cmdSpec.iResponseLength = aResponseLength;
sl@0
   311
sl@0
   312
	if( aCommandType != ECmdTypeUK )
sl@0
   313
		cmdSpec.iCommandType = aCommandType;
sl@0
   314
sl@0
   315
	if( aResponseType != ERespTypeUnknown )
sl@0
   316
		cmdSpec.iResponseType = aResponseType;
sl@0
   317
sl@0
   318
	if( aCommandClass != KMMCCmdClassNone )
sl@0
   319
		cmdSpec.iCommandClass = aCommandClass;
sl@0
   320
sl@0
   321
	iSessionID = ECIMNakedSession;
sl@0
   322
	OstTraceFunctionExit1( DMMCSESSION_SETUPRSCOMMAND_EXIT, this );
sl@0
   323
	}
sl@0
   324
sl@0
   325
EXPORT_C void DMMCSession::SetupDTCommand(TMMCCommandEnum aCommand, TMMCArgument anArgument,
sl@0
   326
							TUint32 aTotalLength, TUint8* aMemoryAddress, TUint32 aBlockLength,
sl@0
   327
							TBool aStopTransmission, TMMCCmdDirEnum aDir,
sl@0
   328
							TUint32 aCommandClass)
sl@0
   329
/**
sl@0
   330
 * Set up the session to issue a raw command to the card. 
sl@0
   331
 * This raw command function should be used when issuing a generic transfer command and argument.
sl@0
   332
 * Having set-up the session for this operation, the client must then engage this session before
sl@0
   333
 * the operation can commence.
sl@0
   334
 * @param aCommand
sl@0
   335
 * @param anArgument
sl@0
   336
 * @param aTotalLength
sl@0
   337
 * @param aMemoryAddress
sl@0
   338
 * @param aBlockLength
sl@0
   339
 * @param aStopTransmission
sl@0
   340
 * @param aDir
sl@0
   341
 * @param aCommandClass
sl@0
   342
 * @todo Complete the parameter descriptions
sl@0
   343
 */
sl@0
   344
	{
sl@0
   345
	OstTraceExt5( TRACE_FLOW, DMMCSESSION_SETUPDTCOMMAND_ENTRY1, "DMMCSession::SetupDTCommand;aCommand=%d;anArgument=%x;aTotalLength=%x;aMemoryAddress=%x;this=%x", (TInt) aCommand, (TUint) anArgument, (TUint) aTotalLength, (TUint) aMemoryAddress, (TUint) this );
sl@0
   346
	OstTraceExt5( TRACE_FLOW, DMMCSESSION_SETUPDTCOMMAND_ENTRY2, "DMMCSession::SetupDTCommand;aBlockLength=%x;aStopTransmission=%d;aDir=%d;aCommandClass=%x;this=%x", (TUint) aBlockLength, (TInt) aStopTransmission, (TInt) aDir, (TUint) aCommandClass , (TUint) this );
sl@0
   347
	ResetCommandStack();
sl@0
   348
	FillCommandDesc(aCommand);
sl@0
   349
	FillCommandArgs(anArgument, aTotalLength, aMemoryAddress, aBlockLength);
sl@0
   350
	TMMCCommandDesc& cmd = Command();
sl@0
   351
sl@0
   352
	if( aBlockLength == 0 )
sl@0
   353
		cmd.iBlockLength = aTotalLength;
sl@0
   354
sl@0
   355
	cmd.iSpec.iMultipleBlocks = (cmd.iBlockLength != aTotalLength);
sl@0
   356
sl@0
   357
	if( aStopTransmission )
sl@0
   358
		cmd.iSpec.iUseStopTransmission = ETrue;
sl@0
   359
sl@0
   360
	if( aDir != EDirNone )
sl@0
   361
		{
sl@0
   362
		cmd.iSpec.iUseStopTransmission = aStopTransmission;
sl@0
   363
		cmd.iSpec.iDirection = aDir;
sl@0
   364
		}
sl@0
   365
sl@0
   366
	if( aCommandClass != KMMCCmdClassNone )
sl@0
   367
		cmd.iSpec.iCommandClass = aCommandClass;
sl@0
   368
sl@0
   369
	iSessionID = ECIMNakedSession;
sl@0
   370
	OstTraceFunctionExit1( DMMCSESSION_SETUPDTCOMMAND_EXIT, this );
sl@0
   371
	}
sl@0
   372
sl@0
   373
void DMMCSession::SetupCIMControl(TInt aSessID)
sl@0
   374
//
sl@0
   375
// find matching macro function for supplied session
sl@0
   376
//
sl@0
   377
	{
sl@0
   378
	OstTraceFunctionEntryExt( DMMCSESSION_SETUPCIMCONTROL_ENTRY, this );
sl@0
   379
	TMMCSMSTFunc f = GetMacro(aSessID);
sl@0
   380
sl@0
   381
	if (f == 0)
sl@0
   382
		f = DMMCStack::NoSessionSMST;
sl@0
   383
sl@0
   384
	iSessionID = (TMMCSessionTypeEnum) aSessID;
sl@0
   385
	iBytesTransferred = 0;
sl@0
   386
	iMMCExitCode = KMMCErrNone;
sl@0
   387
	iState = 0;
sl@0
   388
	iInitContext = 0;
sl@0
   389
	iGlobalRetries = 0;
sl@0
   390
	iDoAbort = iDoStop = iDoComplete = EFalse;
sl@0
   391
	iBlockOn = 0;
sl@0
   392
sl@0
   393
	ResetCommandStack();
sl@0
   394
sl@0
   395
	iMachine.Setup(f, iStackP);
sl@0
   396
	OstTraceFunctionExit1( DMMCSESSION_SETUPCIMCONTROL_EXIT, this );
sl@0
   397
	}
sl@0
   398
sl@0
   399
EXPORT_C TMMCSMSTFunc DMMCSession::GetMacro(TInt aSessNum) const
sl@0
   400
	{
sl@0
   401
	TMMCSMSTFunc f = 0;
sl@0
   402
sl@0
   403
	static const TMMCSMSTFunc macros[KMMCMaxSessionTypeNumber] =
sl@0
   404
		{
sl@0
   405
		DMMCStack::NakedSessionSMST,
sl@0
   406
		DMMCStack::CIMUpdateAcqSMST,
sl@0
   407
		DMMCStack::CIMInitStackSMST,
sl@0
   408
		DMMCStack::CIMCheckStackSMST,
sl@0
   409
		DMMCStack::CIMSetupCardSMST,
sl@0
   410
		DMMCStack::CIMReadWriteBlocksSMST,			// CIMReadBlock
sl@0
   411
		DMMCStack::CIMReadWriteBlocksSMST,			// CIMWriteBlock
sl@0
   412
		DMMCStack::CIMReadWriteBlocksSMST,			// CIMReadMBlock
sl@0
   413
		DMMCStack::CIMReadWriteBlocksSMST,			// CIMWriteMBlock
sl@0
   414
		DMMCStack::CIMEraseSMST,
sl@0
   415
		DMMCStack::CIMEraseSMST,
sl@0
   416
		DMMCStack::CIMReadWriteIOSMST,
sl@0
   417
		DMMCStack::CIMReadWriteIOSMST,
sl@0
   418
		DMMCStack::CIMLockUnlockSMST,				// CIMLockUnlock
sl@0
   419
		DMMCStack::NoSessionSMST,					// CIMLockStack is never really executed as a session
sl@0
   420
		DMMCStack::InitStackAfterUnlockSMST,
sl@0
   421
		DMMCStack::CIMAutoUnlockSMST,
sl@0
   422
		DMMCStack::ExecSleepCommandSMST				// CIMSleep
sl@0
   423
		};
sl@0
   424
sl@0
   425
	if (aSessNum >= 0 && aSessNum < (TInt) KMMCMaxSessionTypeNumber)
sl@0
   426
		f = macros[aSessNum];
sl@0
   427
sl@0
   428
	return f;
sl@0
   429
	}
sl@0
   430
sl@0
   431
EXPORT_C TInt DMMCSession::Engage()
sl@0
   432
/**
sl@0
   433
 * Enque this session for execution on the DMMCStack object which is serving it.
sl@0
   434
 * @return KErrBadDriver if no stack is associated with the session
sl@0
   435
 * @return KErrServerBusy if the stack is currently locked (and KMMCModeEnqueIfLocked flag is cleared)
sl@0
   436
 * @return KErrNotReady if the media is not present
sl@0
   437
 * @return KErrNone if successful
sl@0
   438
 */
sl@0
   439
	{
sl@0
   440
	OstTraceFunctionEntry1( DMMCSESSION_ENGAGE_ENTRY, this );
sl@0
   441
	__KTRACE_OPT(KPBUS1,Kern::Printf(">ms:eng"));
sl@0
   442
sl@0
   443
	if( iStackP == NULL )
sl@0
   444
	    {
sl@0
   445
		OstTraceFunctionExitExt( DMMCSESSION_ENGAGE_EXIT, this, KErrBadDriver );
sl@0
   446
		return KErrBadDriver;
sl@0
   447
	    }
sl@0
   448
sl@0
   449
	if( iStackP->iLockingSessionP != NULL && iStackP->iLockingSessionP != this &&
sl@0
   450
		(iStackP->EffectiveModes(iConfig) & KMMCModeEnqueIfLocked) == 0 )
sl@0
   451
	    {
sl@0
   452
		OstTraceFunctionExitExt( DUP1_DMMCSESSION_ENGAGE_EXIT, this, KErrServerBusy );
sl@0
   453
		return KErrServerBusy;
sl@0
   454
	    }
sl@0
   455
sl@0
   456
	const TMediaState doorState=iStackP->MMCSocket()->iMediaChange->MediaState();
sl@0
   457
sl@0
   458
	__KTRACE_OPT(KPBUS1,Kern::Printf(">MMC:Eng ds = %x", doorState));
sl@0
   459
	OstTrace1( TRACE_INTERNALS, DMMCSESSION_ENGAGE, "doorState = 0x%x", doorState);
sl@0
   460
sl@0
   461
	if (doorState == EDoorOpen)
sl@0
   462
	    {
sl@0
   463
		OstTraceFunctionExitExt( DUP2_DMMCSESSION_ENGAGE_EXIT, this, KErrNotReady );
sl@0
   464
		return KErrNotReady;
sl@0
   465
	    }
sl@0
   466
sl@0
   467
	SetupCIMControl(iSessionID);
sl@0
   468
sl@0
   469
	iStackP->Add(this);
sl@0
   470
sl@0
   471
	__KTRACE_OPT(KPBUS1,Kern::Printf("<ms:eng"));
sl@0
   472
	OstTraceFunctionExitExt( DUP3_DMMCSESSION_ENGAGE_EXIT, this, KErrNone );
sl@0
   473
	return KErrNone;
sl@0
   474
	}
sl@0
   475
sl@0
   476
// Command specification table for standard MMC commands (CMD0 - CMD63)
sl@0
   477
extern const TMMCCommandSpec CommandTable[KMMCCommandMask+1] =
sl@0
   478
	{//  Class				  Type			Dir			MBlk	StopT	Rsp Type		  Len	Cmd No
sl@0
   479
	{KMMCCmdClassBasic,		ECmdTypeBC,		EDirNone,	EFalse, EFalse, ERespTypeNone,		0}, //CMD0
sl@0
   480
	{KMMCCmdClassBasic,		ECmdTypeBCR,	EDirNone,	EFalse, EFalse, ERespTypeR3,		4}, //CMD1
sl@0
   481
	{KMMCCmdClassBasic,		ECmdTypeBCR,	EDirNone,	EFalse, EFalse, ERespTypeR2,		16},//CMD2
sl@0
   482
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD3
sl@0
   483
	{KMMCCmdClassBasic,		ECmdTypeBC,		EDirNone,	EFalse, EFalse, ERespTypeNone,		0}, //CMD4
sl@0
   484
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR1B,		0}, //CMD5 - SLEEP/AWAKE
sl@0
   485
	{KMMCCmdClassBasic,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1B,		0}, //CMD6
sl@0
   486
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD7
sl@0
   487
	{KMMCCmdClassBasic,		ECmdTypeADTCS,	EDirRead,	EFalse, EFalse, ERespTypeR1,		512}, //CMD8
sl@0
   488
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR2,		16},//CMD9
sl@0
   489
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR2,		16},//CMD10
sl@0
   490
	{KMMCCmdClassStreamRead,ECmdTypeADTCS,	EDirRead,	EFalse, ETrue,	ERespTypeR1,		4}, //CMD11
sl@0
   491
	{KMMCCmdClassBasic,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD12
sl@0
   492
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD13
sl@0
   493
	{KMMCCmdClassBlockRead,	ECmdTypeADTCS,	EDirRead,	EFalse, EFalse, ERespTypeR1,		4}, //CMD14 - BUSTEST_R
sl@0
   494
	{KMMCCmdClassBasic,		ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeNone,		0}, //CMD15
sl@0
   495
	{KMMCCmdClassBlockRead,	ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD16
sl@0
   496
	{KMMCCmdClassBlockRead,	ECmdTypeADTCS,	EDirRead,	EFalse, EFalse, ERespTypeR1,		4}, //CMD17
sl@0
   497
	{KMMCCmdClassBlockRead,	ECmdTypeADTCS,	EDirRead,	ETrue,	ETrue,	ERespTypeR1,		4}, //CMD18
sl@0
   498
	{KMMCCmdClassBlockWrite,ECmdTypeADTCS,	EDirWrite,	EFalse, EFalse, ERespTypeR1,		4}, //CMD19 - BUSTEST_W
sl@0
   499
	{KMMCCmdClassStreamWrite,ECmdTypeADTCS, EDirWrite,	EFalse, ETrue,	ERespTypeR1,		4}, //CMD20
sl@0
   500
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD21
sl@0
   501
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD22
sl@0
   502
	{KMMCCmdClassBlockRead | 
sl@0
   503
	 KMMCCmdClassBlockWrite,ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,	4}, //CMD23
sl@0
   504
	{KMMCCmdClassBlockWrite,ECmdTypeADTCS,	EDirWrite,	EFalse, EFalse, ERespTypeR1,		4}, //CMD24
sl@0
   505
	{KMMCCmdClassBlockWrite,ECmdTypeADTCS,	EDirWrite,	ETrue,	ETrue,	ERespTypeR1,		4}, //CMD25
sl@0
   506
	{KMMCCmdClassBlockWrite,ECmdTypeADTCS,	EDirWrite,	EFalse, EFalse, ERespTypeR1,		4}, //CMD26
sl@0
   507
	{KMMCCmdClassBlockWrite,ECmdTypeADTCS,	EDirWrite,	EFalse, EFalse, ERespTypeR1,		4}, //CMD27
sl@0
   508
	{KMMCCmdClassWriteProtection,ECmdTypeACS,EDirNone,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD28
sl@0
   509
	{KMMCCmdClassWriteProtection,ECmdTypeACS,EDirNone,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD29
sl@0
   510
	{KMMCCmdClassWriteProtection,ECmdTypeADTCS,EDirRead,EFalse, EFalse, ERespTypeR1,		4}, //CMD30
sl@0
   511
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD31
sl@0
   512
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD32
sl@0
   513
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD33
sl@0
   514
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD34
sl@0
   515
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD35
sl@0
   516
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD36
sl@0
   517
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD37
sl@0
   518
	{KMMCCmdClassErase,		ECmdTypeACS,	EDirNone,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD38
sl@0
   519
	{KMMCCmdClassIOMode,	ECmdTypeAC,		EDirNone,	EFalse, EFalse, ERespTypeR4,		4}, //CMD39
sl@0
   520
	{KMMCCmdClassIOMode,	ECmdTypeBCR,	EDirNone,	EFalse, EFalse, ERespTypeR5,		4}, //CMD40
sl@0
   521
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD41
sl@0
   522
	{KMMCCmdClassLockCard,	ECmdTypeADTCS,	EDirWrite,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD42
sl@0
   523
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD43
sl@0
   524
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD44
sl@0
   525
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD45
sl@0
   526
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD46
sl@0
   527
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD47
sl@0
   528
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD48
sl@0
   529
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD49
sl@0
   530
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD50
sl@0
   531
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD51
sl@0
   532
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD52
sl@0
   533
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD53
sl@0
   534
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD54
sl@0
   535
	{KMMCCmdClassApplication,ECmdTypeAC,	EDirNone,	EFalse, EFalse, ERespTypeR1,		4}, //CMD55
sl@0
   536
	{KMMCCmdClassApplication,ECmdTypeADTCS,	EDirRBit0,	EFalse, EFalse, ERespTypeR1B,		4}, //CMD56
sl@0
   537
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD57
sl@0
   538
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD58
sl@0
   539
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD59
sl@0
   540
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD60
sl@0
   541
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD61
sl@0
   542
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}, //CMD62
sl@0
   543
	{KMMCCmdClassNone,		ECmdTypeUK,		EDirNone,	EFalse, EFalse, ERespTypeUnknown,	0}	//CMD63
sl@0
   544
	};
sl@0
   545
sl@0
   546
sl@0
   547
EXPORT_C void DMMCSession::FillCommandDesc()
sl@0
   548
/**
sl@0
   549
 * Fills the current command descriptor with the default data according to MMC spec V2.1
sl@0
   550
 */
sl@0
   551
	{
sl@0
   552
	OstTraceFunctionEntry1( DMMCSESSION_FILLCOMMANDDESC1_ENTRY, this );
sl@0
   553
	TMMCCommandDesc& cmd = Command();
sl@0
   554
	cmd.iSpec = CommandTable[cmd.iCommand & KMMCCommandMask];
sl@0
   555
sl@0
   556
	cmd.iFlags = 0;
sl@0
   557
	cmd.iBytesDone = 0;
sl@0
   558
	OstTraceFunctionExit1( DMMCSESSION_FILLCOMMANDDESC1_EXIT, this );
sl@0
   559
	}
sl@0
   560
sl@0
   561
EXPORT_C void DMMCSession::FillCommandDesc(TMMCCommandEnum aCommand)
sl@0
   562
/**
sl@0
   563
 * Initialises the current command according to whether it is a normal
sl@0
   564
 * or an application command.
sl@0
   565
 * @param aCommand Contains the command.
sl@0
   566
 */
sl@0
   567
	{
sl@0
   568
	OstTraceExt2(TRACE_FLOW, DMMCSESSION_FILLCOMMANDDESC2_ENTRY, "DMMCSession::FillCommandDesc;aCommand=%d;this=%x", (TInt) aCommand, (TUint) this);
sl@0
   569
	Command().iCommand = aCommand;
sl@0
   570
	Command().iArgument = 0;					// set stuff bits to zero
sl@0
   571
	FillCommandDesc();
sl@0
   572
	OstTraceFunctionExit1( DMMCSESSION_FILLCOMMANDDESC2_EXIT, this );
sl@0
   573
	}
sl@0
   574
sl@0
   575
EXPORT_C void DMMCSession::FillCommandDesc(TMMCCommandEnum aCommand, TMMCArgument anArgument)
sl@0
   576
/**
sl@0
   577
 * Initialises the current command with an argument according to whether
sl@0
   578
 * it is a normal or an application command.
sl@0
   579
 * @param aCommand Contains the command.
sl@0
   580
 * @param anArgument Specifies the argument.
sl@0
   581
 */
sl@0
   582
	{
sl@0
   583
	OstTraceExt3(TRACE_FLOW, DMMCSESSION_FILLCOMMANDDESC3_ENTRY, "DMMCSession::FillCommandDesc;aCommand=%d;anArgument=%x;this=%x", (TInt) aCommand, (TUint) anArgument, (TUint) this);
sl@0
   584
	TMMCCommandDesc& cmd = Command();
sl@0
   585
	cmd.iCommand = aCommand;
sl@0
   586
	FillCommandDesc();
sl@0
   587
	cmd.iArgument = anArgument;
sl@0
   588
	OstTraceFunctionExit1( DMMCSESSION_FILLCOMMANDDESC3_EXIT, this );
sl@0
   589
	}
sl@0
   590
sl@0
   591
EXPORT_C void DMMCSession::FillCommandArgs(TMMCArgument anArgument, TUint32 aLength, TUint8* aMemoryP,
sl@0
   592
								  TUint32 aBlkLen)
sl@0
   593
/**
sl@0
   594
 * Initialises the current commands arguments with the specified parameters
sl@0
   595
 * It is necessary to have set the command arguments with this command prior
sl@0
   596
 * to engaging a read/write macro or command.
sl@0
   597
 * @param anArgument Command specific argument.
sl@0
   598
 * @param aLength aLength Total number of bytes to read/write.
sl@0
   599
 * @param aMemoryP Host source/destination address
sl@0
   600
 * @param aBlkLen Block length
sl@0
   601
 */
sl@0
   602
	{
sl@0
   603
	OstTraceExt5(TRACE_FLOW, DMMCSESSION_FILLCOMMANDARGS_ENTRY ,"DMMCSession::FillCommandArgs;anArgument=%x;aLength=%x;aMemoryP=%x;aBlkLen=%x;this=%x", (TUint) anArgument, (TUint) aLength, (TUint) aMemoryP, (TUint) aBlkLen, (TUint) this);
sl@0
   604
	TMMCCommandDesc& cmd = Command();
sl@0
   605
sl@0
   606
	cmd.iArgument = anArgument;
sl@0
   607
	cmd.iTotalLength = aLength;
sl@0
   608
	cmd.iDataMemoryP = aMemoryP;
sl@0
   609
	cmd.iBlockLength = aBlkLen;
sl@0
   610
	cmd.iFlags = 0;
sl@0
   611
	OstTraceFunctionExit1( DMMCSESSION_FILLCOMMANDARGS_EXIT, this );
sl@0
   612
	}
sl@0
   613
sl@0
   614
const TMMCCommandSpec& DMMCSession::FindCommandSpec(const TMMCIdxCommandSpec aSpecs[], TInt aIdx)
sl@0
   615
/**
sl@0
   616
 * Searches the supplied command specification list for the specification corresponding to the
sl@0
   617
 * supplied command.
sl@0
   618
 * @param aSpecs The command specification list to be searched.
sl@0
   619
 * @param aIdx The requested command.
sl@0
   620
 */
sl@0
   621
	{
sl@0
   622
	OstTraceFunctionEntry0( DMMCSESSION_FINDCOMMANDSPEC_ENTRY );	
sl@0
   623
	TInt i = 0;
sl@0
   624
	while (aSpecs[i].iIdx != aIdx)
sl@0
   625
		++i;
sl@0
   626
	OstTraceFunctionExit0( DMMCSESSION_FINDCOMMANDSPEC_EXIT );
sl@0
   627
	return aSpecs[i].iSpec;
sl@0
   628
	}
sl@0
   629
sl@0
   630
void DMMCSession::SynchBlock(TUint32 aFlag)
sl@0
   631
//
sl@0
   632
// Blocks a session synchronously (within scheduler context)
sl@0
   633
//
sl@0
   634
	{
sl@0
   635
	OstTraceFunctionEntryExt( DMMCSESSION_SYNCHBLOCK_ENTRY, this );
sl@0
   636
	(void)__e32_atomic_ior_ord32(&iBlockOn, aFlag);
sl@0
   637
	OstTraceFunctionExit1( DMMCSESSION_SYNCHBLOCK_EXIT, this );
sl@0
   638
	}
sl@0
   639
sl@0
   640
void DMMCSession::SynchUnBlock(TUint32 aFlag)
sl@0
   641
//
sl@0
   642
// Unblocks a session synchronously (within scheduler context)
sl@0
   643
//
sl@0
   644
	{
sl@0
   645
	OstTraceFunctionEntryExt( DMMCSESSION_SYNCHUNBLOCK_ENTRY, this );
sl@0
   646
	if( (iBlockOn & aFlag) == 0 )
sl@0
   647
	    {
sl@0
   648
		OstTraceFunctionExit1( DMMCSESSION_SYNCHUNBLOCK_EXIT, this );
sl@0
   649
		return;
sl@0
   650
	    }
sl@0
   651
sl@0
   652
	(void)__e32_atomic_and_ord32(&iBlockOn, ~aFlag);
sl@0
   653
	OstTraceFunctionExit1( DUP1_DMMCSESSION_SYNCHUNBLOCK_EXIT, this );
sl@0
   654
	}
sl@0
   655
sl@0
   656
EXPORT_C TRCA DMMCSession::CardRCA()
sl@0
   657
/**
sl@0
   658
 * Checks that the card is still the same and ready
sl@0
   659
 * @return A TRCA object containing the card's RCA (or 0 if the card is not ready)
sl@0
   660
 */
sl@0
   661
	{
sl@0
   662
sl@0
   663
	// Rely on 'CardIsGone' bit rather than a CID comparison	
sl@0
   664
	if ( iCardP != NULL && iCardP->IsPresent() && !(iState & KMMCSessStateCardIsGone) ) 
sl@0
   665
		return( iCardP->RCA() );
sl@0
   666
	return(0);
sl@0
   667
	}
sl@0
   668
sl@0
   669
#ifdef __EPOC32__
sl@0
   670
void DMMCSession::ProgramTimerCallBack(TAny* aSessP)
sl@0
   671
	{
sl@0
   672
	OstTraceFunctionEntry0( DMMCSESSION_PROGRAMTIMERCALLBACK_ENTRY );
sl@0
   673
	__KTRACE_OPT(KPBUS1,Kern::Printf("=mss:pgtcb"));
sl@0
   674
	
sl@0
   675
    static_cast<DMMCSession *>(aSessP)->iState |= KMMCSessStateDoDFC;
sl@0
   676
	static_cast<DMMCSession *>(aSessP)->UnBlock(KMMCBlockOnPgmTimer, KMMCErrNone);
sl@0
   677
	OstTraceFunctionExit0( DMMCSESSION_PROGRAMTIMERCALLBACK_EXIT );
sl@0
   678
	}
sl@0
   679
sl@0
   680
void DMMCSession::PollTimerCallBack(TAny* aSessP)
sl@0
   681
	{
sl@0
   682
	OstTraceFunctionEntry0( DMMCSESSION_POLLTIMERCALLBACK_ENTRY );
sl@0
   683
	__KTRACE_OPT(KPBUS1,Kern::Printf("=mss:ptcb"));
sl@0
   684
sl@0
   685
    static_cast<DMMCSession *>(aSessP)->iState |= KMMCSessStateDoDFC;
sl@0
   686
	static_cast<DMMCSession *>(aSessP)->UnBlock(KMMCBlockOnPollTimer, KMMCErrNone);
sl@0
   687
	OstTraceFunctionExit0( DMMCSESSION_POLLTIMERCALLBACK_EXIT );
sl@0
   688
	}
sl@0
   689
sl@0
   690
void DMMCSession::RetryTimerCallBack(TAny* aSessP)
sl@0
   691
	{
sl@0
   692
	OstTraceFunctionEntry0( DMMCSESSION_RETRYTIMERCALLBACK_ENTRY );
sl@0
   693
	__KTRACE_OPT(KPBUS1,Kern::Printf("=mss:rtcb"));
sl@0
   694
sl@0
   695
    static_cast<DMMCSession *>(aSessP)->iState |= KMMCSessStateDoDFC;
sl@0
   696
	static_cast<DMMCSession *>(aSessP)->UnBlock(KMMCBlockOnRetryTimer, KMMCErrNone);
sl@0
   697
	OstTraceFunctionExit0( DMMCSESSION_RETRYTIMERCALLBACK_EXIT );
sl@0
   698
	}
sl@0
   699
sl@0
   700
#endif	// #ifdef __EPOC32__
sl@0
   701
sl@0
   702
EXPORT_C TInt DMMCSession::EpocErrorCode() const
sl@0
   703
/**
sl@0
   704
 * Returns the last Symbian OS style error code returned in this session. 
sl@0
   705
 * The Symbian OS error code is derived from both the last MMC specific exit code MMCExitCode()
sl@0
   706
 * and the last status information from the card (iLastStatus).
sl@0
   707
 * @return Standard Symbian OS error code
sl@0
   708
 */
sl@0
   709
	{
sl@0
   710
	OstTraceFunctionEntry1( DMMCSESSION_EPOCERRORCODE_ENTRY, this );
sl@0
   711
	__KTRACE_OPT(KPBUS1,Kern::Printf("=mss:eee:%08x,%08x", MMCExitCode(), LastStatus().State() ));
sl@0
   712
	OstTraceExt2( TRACE_INTERNALS, DMMCSESSION_EPOCERRORCODE, "MMCExitCode = 0x%08x; LastStatus State = 0x%08x", (TUint) MMCExitCode(), (TUint) LastStatus().State());
sl@0
   713
	
sl@0
   714
	struct errorTableEntry
sl@0
   715
		{
sl@0
   716
		TUint32 iMask;
sl@0
   717
		TInt iErrorCode;
sl@0
   718
		};
sl@0
   719
sl@0
   720
	static const errorTableEntry mmcTable[] = 
sl@0
   721
		{
sl@0
   722
		{KMMCErrNotSupported,									KErrNotSupported},
sl@0
   723
		{KMMCErrStackNotReady,									KErrBadPower},
sl@0
   724
		{KMMCErrArgument,										KErrArgument},
sl@0
   725
		{KMMCErrBrokenLock | KMMCErrPowerDown | KMMCErrAbort,	KErrAbort},
sl@0
   726
		{KMMCErrNoCard | KMMCErrResponseTimeOut | KMMCErrDataTimeOut |
sl@0
   727
			KMMCErrBusyTimeOut | KMMCErrBusTimeOut,				KErrNotReady},
sl@0
   728
		{KMMCErrResponseCRC|KMMCErrDataCRC|KMMCErrCommandCRC,	KErrCorrupt},
sl@0
   729
		{KMMCErrLocked,											KErrLocked},
sl@0
   730
		{KMMCErrNotFound,										KErrNotFound},
sl@0
   731
		{KMMCErrAlreadyExists,									KErrAlreadyExists},
sl@0
   732
		{KMMCErrGeneral,										KErrGeneral},
sl@0
   733
		{~0UL,													KErrUnknown}
sl@0
   734
		};
sl@0
   735
sl@0
   736
	static const errorTableEntry statusTable[] = 
sl@0
   737
		{
sl@0
   738
		{KMMCStatErrOverrun|KMMCStatErrUnderrun|
sl@0
   739
			KMMCStatErrCardECCFailed|KMMCStatErrComCRCError,	KErrGeneral},
sl@0
   740
		{KMMCStatErrCSDOverwrite|KMMCStatErrWPViolation,		KErrWrite},
sl@0
   741
		{KMMCStatErrLockUnlock,									KErrLocked},
sl@0
   742
		{KMMCStatErrIllegalCommand,								KErrNotSupported},
sl@0
   743
		{KMMCStatErrEraseParam|KMMCStatErrEraseSeqError|
sl@0
   744
			KMMCStatErrBlockLenError|KMMCStatErrAddressError|
sl@0
   745
			KMMCStatErrOutOfRange,								KErrArgument},
sl@0
   746
		{~0UL,													KErrUnknown}
sl@0
   747
		};
sl@0
   748
sl@0
   749
	TUint32 errCode = MMCExitCode();
sl@0
   750
sl@0
   751
	if( errCode == 0 )
sl@0
   752
	    {
sl@0
   753
		OstTraceFunctionExitExt( DMMCSESSION_EPOCERRORCODE_EXIT, this, KErrNone );
sl@0
   754
		return KErrNone;
sl@0
   755
	    }
sl@0
   756
sl@0
   757
	const errorTableEntry* ptr = &mmcTable[0];
sl@0
   758
sl@0
   759
	if( errCode == KMMCErrStatus )
sl@0
   760
		{
sl@0
   761
		ptr = &statusTable[0];
sl@0
   762
sl@0
   763
		if( (errCode = LastStatus()) == 0 )
sl@0
   764
		    {
sl@0
   765
			OstTraceFunctionExitExt( DUP1_DMMCSESSION_EPOCERRORCODE_EXIT, this, KErrUnknown );
sl@0
   766
			return KErrUnknown;
sl@0
   767
		    }
sl@0
   768
		}
sl@0
   769
sl@0
   770
	for( ;; )
sl@0
   771
		if( (errCode & ptr->iMask) != 0 )
sl@0
   772
		    {
sl@0
   773
		    TInt ret = ptr->iErrorCode; 
sl@0
   774
			OstTraceFunctionExitExt( DUP2_DMMCSESSION_EPOCERRORCODE_EXIT, this, ret );
sl@0
   775
			return ret;
sl@0
   776
		    }
sl@0
   777
		else
sl@0
   778
			ptr++;
sl@0
   779
	}