kernel/eka/drivers/rpmb/rpmbdevice.cpp
author hgs
Mon, 11 Oct 2010 19:11:06 +0100
changeset 287 ddfd5aa0d58f
permissions -rw-r--r--
201041_01
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
287
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     1
// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     2
// All rights reserved.
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     4
// under the terms of the License "Eclipse Public License v1.0"
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     7
//
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     8
// Initial Contributors:
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    10
//
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    11
// Contributors:
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    12
//
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    13
// Description:
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    14
// /os/kernelhwsrv/kernel/eka/drivers/rpmb/rpmbdevice.cpp
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    15
// Kernel extension entry point for RPMB driver.
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    16
// 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    17
//
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    18
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    19
/**
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    20
 @file
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    21
 @internalTechnology
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    22
*/
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    23
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    24
#include "OstTraceDefinitions.h"
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    25
#ifdef OST_TRACE_COMPILER_IN_USE
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    26
#include "../../include/drivers/locmedia_ost.h"
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    27
#ifdef __VC32__
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    28
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    29
#endif
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    30
#include "rpmbdeviceTraces.h"
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    31
#endif
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    32
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    33
#include <kernel/kernel.h>
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    34
#include <drivers/rpmbdevice.h>
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    35
#include <drivers/sdcard.h>
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    36
#include <drivers/sdio/sdio.h>
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    37
#include <drivers/mmc.h>
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    38
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    39
DRpmbDevice * DRpmbDevice::DRpmbDevicePtrs[KMaxPBusSockets*4] = {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    40
	NULL, NULL, NULL, NULL,
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    41
	NULL, NULL, NULL, NULL,
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    42
	NULL, NULL, NULL, NULL,
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    43
	NULL, NULL, NULL, NULL};
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    44
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    45
EXPORT_C DRpmbDevice::DRpmbDevice():
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    46
	iSessionEndCallBack(DRpmbDevice::SessionEndCallBack, this),
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    47
	iDeviceIndex(KIndexNotAssigned)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    48
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    49
	}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    50
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    51
EXPORT_C DRpmbDevice::~DRpmbDevice()
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    52
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    53
    Close();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    54
	}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    55
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    56
void DRpmbDevice::SessionEndCallBack(TAny* aSelf)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    57
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    58
    DRpmbDevice& self = *static_cast<DRpmbDevice*>(aSelf);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    59
    self.DoSessionEndCallBack();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    60
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    61
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    62
void DRpmbDevice::DoSessionEndCallBack()
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    63
    {   
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    64
    iSocket->EndInCritical();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    65
    Kern::SemaphoreSignal(*iRequestSemaphore);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    66
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    67
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    68
void DRpmbDevice::BusCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    69
{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    70
    DRpmbDevice* device = (DRpmbDevice*)aPtr;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    71
    TPBusState busState = (TPBusState) (TInt) a1;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    72
	TInt busError = (TInt) a2;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    73
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    74
    if(aReason == TPBusCallBack::EPBusStateChange 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    75
		&& busState == EPBusOn && busError == KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    76
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    77
		Kern::SemaphoreSignal(*(device->iPowerUpSemaphore));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    78
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    79
}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    80
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    81
TInt DRpmbDevice::PowerUpStack()
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    82
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    83
    //
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    84
    // Power up the socket - This ensures that the socket is powered up 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    85
    // and the functions are re-enumerated.
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    86
    //  
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    87
    iBusCallBack.iFunction = BusCallBack;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    88
    iBusCallBack.iPtr=this;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    89
    iBusCallBack.SetSocket(iSocket->iSocketNumber);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    90
    iBusCallBack.Add();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    91
	NKern::ThreadEnterCS();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    92
    TInt r = Kern::SemaphoreCreate(iPowerUpSemaphore,_L("RPMBPowerUpSem"), 0);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    93
    if(r == KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    94
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    95
		TInt r = iSocket->PowerUp();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    96
        if(r==KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    97
            {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    98
            Kern::SemaphoreWait(*iPowerUpSemaphore);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
    99
            }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   100
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   101
	NKern::ThreadLeaveCS();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   102
    return r;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   103
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   104
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   105
void DRpmbDevice::SetSynchronisationParms(TUint8 aDeviceIndex)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   106
	{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   107
	// Mark this instance as being associated with the requested index 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   108
	iDeviceIndex = aDeviceIndex;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   109
	// Mark the requested index as being associated with this instance
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   110
	// Atomic operation ensures store is flushed from cache and committed 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   111
	// to global memory
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   112
	__e32_atomic_store_ord_ptr(&(DRpmbDevicePtrs[iDeviceIndex]),this);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   113
	}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   114
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   115
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   116
void DRpmbDevice::ClearSynchronisationParms()
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   117
	{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   118
	// Serialise access to global pointer array and it's local index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   119
	NKern::FMWait(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   120
	if (iDeviceIndex < KMaxPBusSockets*4)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   121
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   122
		// Atomic operation for load from global memory and not from cache
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   123
		DRpmbDevice * ptrTableEntry = 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   124
			(DRpmbDevice *)__e32_atomic_load_acq_ptr(&(DRpmbDevicePtrs[iDeviceIndex]));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   125
		// This instance of DRpmbDevice is associated with an index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   126
		// The associated index MUST be associated with this instance
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   127
		__ASSERT_ALWAYS((ptrTableEntry == this), Kern::Fault(__FILE__, __LINE__));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   128
		// Disassociate index and instance
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   129
		// Atomic operation ensures store is flushed from cache and committed 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   130
		// to global memory
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   131
		__e32_atomic_store_ord_ptr(&(DRpmbDevicePtrs[iDeviceIndex]),NULL);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   132
		iDeviceIndex = KIndexNotAssigned;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   133
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   134
	// Serialise access to global pointer array and it's local index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   135
	NKern::FMSignal(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   136
	}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   137
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   138
EXPORT_C TInt DRpmbDevice::Open(TUint aDeviceIndex)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   139
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   140
    //
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   141
    //eMMC4.4+ devices have RPMB partitions and each MMC device may be configured as having an RPMB 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   142
	//partition in the baseport
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   143
	//This function creates an MMC stack session for device aDeviceIndex
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   144
	//This is used to access the RPMB partition on that device
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   145
	//Extensions that use this interface during system startup should be located AFTER the RPMB and MMC
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   146
	//extesnions in the system ROM and should not call this interface synchronously from a system
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   147
	//startup initialisation routine
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   148
	//aDeviceIndex the index of the device supporting the RPMB partition
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   149
	//Returns KerrNone if successful
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   150
	//Returns KErrNotReady if the baseport configuration hasn't been read yet
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   151
    //Returns KErrNotSupported if the baseport configuration does not have a valid RPMB partition 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   152
	//or RPMB is not supported by the media device
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   153
	//Otherwise retruns a systemwide error code
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   154
    //
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   155
    OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_1, "RPMB: >DrpmbDevice::Open");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   156
    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: >DrpmbDevice::Open"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   157
	
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   158
	TRpmbDeviceParms params;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   159
	params.iCardNumber = 0;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   160
	params.iSocketPtr = NULL;	
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   161
    MRpmbInfo* rpmbInterface = NULL;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   162
	
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   163
	TInt r = MMCGetExtInterface(KInterfaceRpmb, (MMCMExtInterface*&) rpmbInterface);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   164
	// MMCGetExtInterface currently returns KErrNotReady with rpmbInterface == NULL if the RPMB parameters 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   165
	// haven't yet been populated
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   166
	// proveided any calling extension is located AFTER the RPMB and MMC extesnions in the system ROM and 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   167
	// does not call this interface synchronously from a system initialisation routine the following 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   168
	// shouldn't be asserted 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   169
	OstTrace1(TRACE_FLOW, DRPMBDEVICE_OPEN_2, "RPMB: DrpmbDevice Get Interface err = %d", r);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   170
	__KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice Get Interface err = %d", r));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   171
	__ASSERT_ALWAYS(r == KErrNone, Kern::Fault(__FILE__, __LINE__));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   172
		
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   173
	if (rpmbInterface == NULL)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   174
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   175
		// unexpected error since MMCGetExtInterface didn't return an error
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   176
	    OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_3, "RPMB: DrpmbDevice Null rpmbInterface");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   177
	    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice Null rpmbInterface"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   178
		return KErrGeneral;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   179
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   180
		
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   181
	// Interface currently supports a single device, device index = 0   
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   182
	r = rpmbInterface->RpmbInfo(aDeviceIndex, params);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   183
    if(r != KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   184
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   185
		// requested index non zero or baseport not configured with RPMB capable MMC device
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   186
        OstTrace1(TRACE_FLOW, DRPMBDEVICE_OPEN_4, "RPMB: DrpmbDevice requested index non zero or baseport not configured, err = %d", r);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   187
        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice requested index non zero or baseport not configured, err = %d", r));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   188
		return r;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   189
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   190
   
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   191
    iSocket = params.iSocketPtr;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   192
	// iSocket cannot be NULL 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   193
	// TMMCardControllerInterface::RegisterMediaDevices ensures that the assigned value is not NULL
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   194
	__ASSERT_ALWAYS((iSocket!=NULL), Kern::Fault(__FILE__, __LINE__));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   195
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   196
	// Serialise access to global pointer array and it's local index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   197
	NKern::FMWait(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   198
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   199
	if (iDeviceIndex != KIndexNotAssigned)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   200
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   201
		// This instance of DRpmbDevice is already open
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   202
		if (iDeviceIndex == aDeviceIndex)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   203
			{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   204
			// Serialise access to global pointer array and it's local index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   205
			NKern::FMSignal(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   206
			// Already open with requested index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   207
		    OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_5, "RPMB: DrpmbDevice already open with requested index");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   208
		    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice already open with requested index"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   209
			return KErrNone;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   210
			}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   211
		else
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   212
			{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   213
			// Serialise access to global pointer array and it's local index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   214
			NKern::FMSignal(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   215
			// Already open with other index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   216
	        OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_6, "RPMB: DrpmbDevice already open with other index");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   217
	        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice already open with other index"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   218
			return KErrInUse;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   219
			}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   220
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   221
	else
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   222
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   223
		// This instance of DRpmbDevice is not open
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   224
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   225
		// Atomic operation for load from global memory and not from cache
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   226
		DRpmbDevice * ptrTableEntry = 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   227
			(DRpmbDevice *)__e32_atomic_load_acq_ptr(&(DRpmbDevicePtrs[aDeviceIndex]));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   228
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   229
		if (ptrTableEntry == NULL)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   230
			{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   231
			SetSynchronisationParms((TUint8)(aDeviceIndex));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   232
			}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   233
		else
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   234
			{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   235
			// Requested index cannot be associated with this instance of DRpmbdevice  
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   236
			__ASSERT_ALWAYS(ptrTableEntry != this, Kern::Fault(__FILE__, __LINE__));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   237
			// Serialise access to global pointer array and it's local index
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   238
			NKern::FMSignal(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   239
			// Requested index already associated with a different instance of DRpmbDevice
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   240
	        OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_7, "RPMB: DrpmbDevice requested index already associated with a different instance of DrpmbDevice");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   241
	        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice requested index already associated with a different instance of DrpmbDevice"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   242
			return KErrInUse;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   243
			}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   244
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   245
	NKern::FMSignal(&iSynchronisationParmsMutex);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   246
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   247
	r = PowerUpStack();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   248
    if (r != KErrNone && r != KErrCompletion)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   249
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   250
        // Stack wasn't already powered up and failed to power up
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   251
		ClearSynchronisationParms();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   252
	    OstTrace1(TRACE_FLOW, DRPMBDEVICE_OPEN_8, "RPMB: DrpmbDevice wasn't already powered up and failed with err = %d", r);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   253
	    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DrpmbDevice wasn't already powered up and failed with err = %d", r));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   254
		return r;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   255
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   256
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   257
    DMMCStack* stack = iSocket->Stack(KBusNumber);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   258
    if(stack == NULL)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   259
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   260
		// KBusNumber = 0 so iSocket->Stack() returns iSocket->iStack 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   261
		// Expect this to have been pre-assigned
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   262
		// Expect a socket to be bound to a stack
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   263
        ClearSynchronisationParms();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   264
        OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_9, "RPMB: stack is NULL");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   265
        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: stack is NULL"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   266
        return KErrNoMemory;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   267
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   268
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   269
    iCard = stack->CardP(params.iCardNumber);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   270
    if(iCard == NULL) 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   271
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   272
		// stack->CardP() returns stack->iCardArray->CardP(params.iCardNumber)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   273
		// Expect this to have been pre-assigned
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   274
		// Expect card array to point to a card
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   275
        ClearSynchronisationParms();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   276
        OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_10, "RPMB: card pointer is NULL");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   277
        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: card pointer is NULL"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   278
        return KErrNoMemory;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   279
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   280
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   281
	NKern::ThreadEnterCS(); 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   282
    iSession = stack->AllocSession(iSessionEndCallBack);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   283
	NKern::ThreadLeaveCS(); 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   284
    if (iSession == NULL)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   285
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   286
		// DMMCStack::AllocSession() failed to create a new instance off DMMCSession
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   287
        OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_11, "RPMB: failed to create a new instance of DMMCSession");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   288
        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: failed to create a new instance of DMMCSession"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   289
        return KErrNoMemory; 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   290
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   291
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   292
    iSession->SetStack(stack);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   293
    iSession->SetCard(iCard);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   294
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   295
    TInt bufLen, minorBufLen;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   296
    stack->BufferInfo(iIntBuf, bufLen, minorBufLen);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   297
	// mmc media driver reserved the first KRpmbOneFramePacketLength bytes of the 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   298
	// PSL buffer to be used for RPMB requests / responses
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   299
	iIntBuf += minorBufLen;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   300
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   301
    if(iCard->ExtendedCSD().ExtendedCSDRev() < 5 || iCard->ExtendedCSD().RpmbSize() == 0)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   302
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   303
		// RPMB is not supported on selected hardware
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   304
        ClearSynchronisationParms();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   305
        OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_12, "RPMB: feature is not supported on selected hardware");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   306
        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: feature is not supported on selected hardware"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   307
        return KErrNotSupported;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   308
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   309
    OstTrace0(TRACE_FLOW, DRPMBDEVICE_OPEN_13, "RPMB: <DrpmbDevice::Open");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   310
    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: <DrpmbDevice::Open"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   311
    return KErrNone;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   312
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   313
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   314
EXPORT_C void DRpmbDevice::Close()
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   315
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   316
	//
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   317
    //Closes an interaction with an RPMB configured device 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   318
    //
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   319
    OstTrace0(TRACE_FLOW, DRPMBDEVICE_CLOSE_1, "RPMB: >DrpmbDevice::Close");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   320
    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: >DrpmbDevice::Close"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   321
 	
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   322
	ClearSynchronisationParms();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   323
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   324
	iBusCallBack.Remove();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   325
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   326
	NKern::ThreadEnterCS();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   327
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   328
    if(iPowerUpSemaphore)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   329
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   330
        iPowerUpSemaphore->Close(NULL);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   331
		iPowerUpSemaphore = NULL;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   332
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   333
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   334
	if (iSession)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   335
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   336
		delete iSession;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   337
		iSession = NULL;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   338
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   339
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   340
	if(iRequestSemaphore)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   341
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   342
        iRequestSemaphore->Close(NULL);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   343
		iRequestSemaphore = NULL;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   344
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   345
   
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   346
	NKern::ThreadLeaveCS();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   347
	OstTrace0(TRACE_FLOW, DRPMBDEVICE_CLOSE_2, "RPMB: <DrpmbDevice::Close");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   348
	__KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: <DrpmbDevice::Close"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   349
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   350
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   351
EXPORT_C TInt DRpmbDevice::SendAccessRequest(TDes8& aRpmbRequest, TDes8& aRpmbResponse)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   352
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   353
    //
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   354
    //sends a request to be handled by the RPMB partition
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   355
    //aRpmbRequest - the physically contiguous region of memory containg the request to be handled
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   356
    //aRpmbResponse - the physically contiguous region memory to where the response from the hardware will be written
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   357
	//returns KErrNone if successful
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   358
	//returns system wide epoc error code if set on call back from stack
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   359
	//returns KErrArgument for invalid descriptor argument length
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   360
	//returns KErrNotReady if not opened
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   361
	//retruns KErrNotready if MMC stack is processing a posponed power down or a postponed media change event
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   362
	//otherwise returns system wide error code 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   363
	//
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   364
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   365
    OstTrace0(TRACE_FLOW, DRPMBDEVICE_SENDACCESSREQUEST_1, "RPMB: >DrpmbDevice::SendAccessRequest");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   366
    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: >DrpmbDevice::SendAccessRequest"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   367
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   368
	if ((aRpmbRequest.Length() != KRpmbOneFramePacketLength) || (aRpmbResponse.Length() != KRpmbOneFramePacketLength))
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   369
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   370
		// insist on single frame access as mutiple read and multiple write (reliable write) notb yet supported
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   371
		return KErrArgument;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   372
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   373
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   374
	if (iSession == NULL)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   375
        {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   376
		// DRpmbDevice::Open not called at all
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   377
		// or not called after DRpmbDevice::Close
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   378
	    OstTrace0(TRACE_FLOW, DRPMBDEVICE_SENDACCESSREQUEST_2, "RPMB: DMMCSession is NULL");
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   379
	    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: DMMCSession is NULL"));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   380
        return KErrNotReady;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   381
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   382
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   383
	if (iRequestSemaphore == NULL)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   384
		{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   385
		// iRequestSemaphore zero filled prior to contruction
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   386
		// create semaphore for waiting on stack
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   387
		NKern::ThreadEnterCS();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   388
		TInt r = Kern::SemaphoreCreate(iRequestSemaphore,_L("RPMBRequestSemaphore"), 0);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   389
		NKern::ThreadLeaveCS();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   390
		if (r != KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   391
			{
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   392
			// failed to create semaphore 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   393
		    OstTrace1(TRACE_FLOW, DRPMBDEVICE_SENDACCESSREQUEST_3, "RPMB: failed to create semaphore err = %d", r);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   394
		    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: failed to create semaphore err = %d", r));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   395
			return r;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   396
			}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   397
		}
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   398
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   399
    memcpy(iIntBuf, aRpmbRequest.Ptr(), KRpmbOneFramePacketLength);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   400
     
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   401
    TInt r = iSocket->InCritical();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   402
	// may be KErrNotready if MMC stack is processing a posponed power down event or a postponed media change event
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   403
	if (r == KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   404
       {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   405
    iSession->SetPartition(TExtendedCSD::ESelectRPMB);            //Set RPMB Partition
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   406
    iSession->ResetCommandStack();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   407
    iSession->FillCommandArgs(KDeviceAddress, KRpmbOneFramePacketLength, iIntBuf, KRpmbOneFramePacketLength);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   408
    iSession->iSessionID = ECIMRpmbAccess;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   409
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   410
        r = iSession->Engage();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   411
        if(r == KErrNone)
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   412
            {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   413
			Kern::SemaphoreWait(*iRequestSemaphore);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   414
			memcpy((TUint8 *)aRpmbResponse.Ptr(), iIntBuf, KRpmbOneFramePacketLength);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   415
		    OstTrace1(TRACE_FLOW, DRPMBDEVICE_SENDACCESSREQUEST_4, "RPMB: request complete with %d", iSession->EpocErrorCode());
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   416
		    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: request complete with %d", iSession->EpocErrorCode()));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   417
			return iSession->EpocErrorCode();  
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   418
            }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   419
        }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   420
 
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   421
    iSocket->EndInCritical();
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   422
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   423
    OstTrace1(TRACE_FLOW, DRPMBDEVICE_SENDACCESSREQUEST_5, "RPMB: <DrpmbDevice::SendAccessRequest complete %d", r);
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   424
    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: <DrpmbDevice::SendAccessRequest complete %d", r));
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   425
    
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   426
    return r;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   427
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   428
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   429
DECLARE_STANDARD_EXTENSION()
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   430
    {
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   431
    __KTRACE_OPT(KBOOT,Kern::Printf("RPMBEXT.DLL DECLARE_STANDARD_EXTENSION entry point"));      
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   432
	return KErrNone;
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   433
    }
ddfd5aa0d58f 201041_01
hgs
parents:
diff changeset
   434