os/kernelhwsrv/userlibandfileserver/fileserver/smassstorage/cbulkonlytransportusbcscldd.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description:
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
/**
sl@0
    20
 @file
sl@0
    21
 @internalTechnology
sl@0
    22
*/
sl@0
    23
sl@0
    24
#include "cbulkonlytransport.h"
sl@0
    25
#include "cbulkonlytransportusbcscldd.h"
sl@0
    26
#include "usbmsshared.h"
sl@0
    27
#include "massstoragedebug.h"
sl@0
    28
#include "cusbmassstorageserver.h"
sl@0
    29
sl@0
    30
sl@0
    31
//This value defined in USB Mass Storage Bulk Only Transrt spec and not supposed to be changed
sl@0
    32
LOCAL_D const TInt KRequiredNumberOfEndpoints = 2; // in addition to endpoint 0.
sl@0
    33
sl@0
    34
LOCAL_D const TInt KUsbNumInterfacesOffset = 4;
sl@0
    35
sl@0
    36
#ifdef MSDC_MULTITHREADED
sl@0
    37
//Only used in DB. The first 2K of KMaxScBufferSize for sending CSW 
sl@0
    38
static const TUint32 KCswBufferSize = 2 * 1024;
sl@0
    39
#endif
sl@0
    40
sl@0
    41
////////////////////////////////////
sl@0
    42
/**
sl@0
    43
Called by CBulkOnlyTransportUsbcScLdd to create an instance of CControlInterfaceUsbcScLdd
sl@0
    44
sl@0
    45
@param aParent reference to the CBulkOnlyTransportUsbcScLdd
sl@0
    46
*/
sl@0
    47
sl@0
    48
sl@0
    49
CControlInterfaceUsbcScLdd* CControlInterfaceUsbcScLdd::NewL(CBulkOnlyTransportUsbcScLdd& aParent)
sl@0
    50
	{
sl@0
    51
	CControlInterfaceUsbcScLdd* self = new(ELeave) CControlInterfaceUsbcScLdd(aParent);
sl@0
    52
	CleanupStack::PushL(self);
sl@0
    53
	self->ConstructL();
sl@0
    54
	CActiveScheduler::Add(self);
sl@0
    55
	CleanupStack::Pop();
sl@0
    56
	return self;
sl@0
    57
	}
sl@0
    58
sl@0
    59
sl@0
    60
void CControlInterfaceUsbcScLdd::ConstructL()
sl@0
    61
	{
sl@0
    62
	}
sl@0
    63
sl@0
    64
sl@0
    65
/**
sl@0
    66
c'tor
sl@0
    67
sl@0
    68
@param aParent reference to the CBulkOnlyTransportUsbcScLdd
sl@0
    69
*/
sl@0
    70
CControlInterfaceUsbcScLdd::CControlInterfaceUsbcScLdd(CBulkOnlyTransportUsbcScLdd& aParent)
sl@0
    71
	:CActive(EPriorityStandard),
sl@0
    72
	 iParent(aParent),
sl@0
    73
	 iCurrentState(ENone)
sl@0
    74
	{
sl@0
    75
	}
sl@0
    76
sl@0
    77
sl@0
    78
/**
sl@0
    79
d'tor
sl@0
    80
*/
sl@0
    81
CControlInterfaceUsbcScLdd::~CControlInterfaceUsbcScLdd()
sl@0
    82
	{
sl@0
    83
	__FNLOG("CControlInterfaceUsbcScLdd::~CControlInterfaceUsbcScLdd ");
sl@0
    84
	Cancel();
sl@0
    85
	iEp0Buf.Close();
sl@0
    86
	}
sl@0
    87
sl@0
    88
TInt CControlInterfaceUsbcScLdd::OpenEp0()
sl@0
    89
	{
sl@0
    90
	TInt res = iParent.Ldd().OpenEndpoint(iEp0Buf,0);
sl@0
    91
	return res;
sl@0
    92
	}
sl@0
    93
sl@0
    94
/**
sl@0
    95
Called by CBulkOnlyTransport HwStart to start control interface
sl@0
    96
*/
sl@0
    97
TInt CControlInterfaceUsbcScLdd::Start()
sl@0
    98
	{
sl@0
    99
	__FNLOG("CControlInterfaceUsbcScLdd::Start ");
sl@0
   100
	TInt res = ReadEp0Data();
sl@0
   101
	return (res);
sl@0
   102
	}
sl@0
   103
sl@0
   104
sl@0
   105
/**
sl@0
   106
Called by desctructor of CBulkOnlyTransportUsbcScLdd to stop control interface
sl@0
   107
*/
sl@0
   108
void CControlInterfaceUsbcScLdd::Stop()
sl@0
   109
	{
sl@0
   110
	__FNLOG("CControlInterfaceUsbcScLdd::Stop ");
sl@0
   111
	if (!IsActive())
sl@0
   112
		{
sl@0
   113
		__PRINT(_L("Not active\n"));
sl@0
   114
		return;
sl@0
   115
		}
sl@0
   116
sl@0
   117
	__PRINT(_L("\nStopping...\n"));
sl@0
   118
sl@0
   119
sl@0
   120
	iCurrentState = ENone;
sl@0
   121
sl@0
   122
	Cancel();
sl@0
   123
	}
sl@0
   124
sl@0
   125
sl@0
   126
/**
sl@0
   127
Cancel outstanding request (if any)
sl@0
   128
*/
sl@0
   129
void CControlInterfaceUsbcScLdd::DoCancel()
sl@0
   130
	{
sl@0
   131
	__FNLOG("CControlInterfaceUsbcScLdd::DoCancel ");
sl@0
   132
	switch(iCurrentState)
sl@0
   133
		{
sl@0
   134
		case EReadEp0Data:
sl@0
   135
			iParent.Ldd().ReadCancel(KUsbcScEndpointZero);
sl@0
   136
			break;
sl@0
   137
		case ESendMaxLun:
sl@0
   138
			iParent.Ldd().WriteCancel(KUsbcScEndpointZero);
sl@0
   139
			break;
sl@0
   140
		default:
sl@0
   141
			__PRINT(_L("\nWrong state !\n"));
sl@0
   142
			__ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsControlInterfaceBadState));
sl@0
   143
		}
sl@0
   144
	}
sl@0
   145
sl@0
   146
sl@0
   147
/**
sl@0
   148
Implement CControlInterfaceUsbcScLdd state machine
sl@0
   149
*/
sl@0
   150
void CControlInterfaceUsbcScLdd::RunL()
sl@0
   151
	{
sl@0
   152
	__FNLOG("CControlInterfaceUsbcScLdd::RunL ");
sl@0
   153
	if (iStatus != KErrNone)
sl@0
   154
		{
sl@0
   155
		__PRINT1(_L("Error %d in RunL\n"), iStatus.Int());
sl@0
   156
sl@0
   157
		//read EP0  again
sl@0
   158
		ReadEp0Data();
sl@0
   159
		return;
sl@0
   160
		}
sl@0
   161
sl@0
   162
	ReadEp0Data();
sl@0
   163
	}
sl@0
   164
sl@0
   165
/**
sl@0
   166
Actual Read to RDevUsbcScClient BIL
sl@0
   167
*/
sl@0
   168
TInt CControlInterfaceUsbcScLdd::ReadUsbEp0()
sl@0
   169
	{
sl@0
   170
	iCurrentState = EReadEp0Data;
sl@0
   171
	iStatus = KRequestPending;
sl@0
   172
	return iEp0Buf.GetBuffer (iEp0Packet,iEp0Size,iEp0Zlp,iStatus);
sl@0
   173
	}
sl@0
   174
sl@0
   175
sl@0
   176
/**
sl@0
   177
Post a read request to EEndpoint0 to read request header
sl@0
   178
*/
sl@0
   179
TInt CControlInterfaceUsbcScLdd::ReadEp0Data()
sl@0
   180
	{
sl@0
   181
	__FNLOG("CControlInterfaceUsbcScLdd::ReadEp0Data ");
sl@0
   182
	if (IsActive())
sl@0
   183
		{
sl@0
   184
		__PRINT(_L("Still active\n"));
sl@0
   185
		return KErrServerBusy;
sl@0
   186
		}
sl@0
   187
sl@0
   188
	TInt r = KErrNone;
sl@0
   189
	do
sl@0
   190
		{
sl@0
   191
		r = ReadUsbEp0();
sl@0
   192
		if (r == KErrCompletion)
sl@0
   193
			{
sl@0
   194
			iStatus = KErrNone;
sl@0
   195
			DecodeEp0Data();
sl@0
   196
			}
sl@0
   197
		else if (r == KErrNone)
sl@0
   198
			{
sl@0
   199
			SetActive();
sl@0
   200
			}
sl@0
   201
		} while (((r == KErrCompletion) || (r == TEndpointBuffer::KStateChange)) && (!IsActive()));
sl@0
   202
	return KErrNone;
sl@0
   203
	}
sl@0
   204
sl@0
   205
sl@0
   206
/**
sl@0
   207
Decode request header and do appropriate action - get max LUN info or post a reset request
sl@0
   208
*/
sl@0
   209
void CControlInterfaceUsbcScLdd::DecodeEp0Data()
sl@0
   210
	{
sl@0
   211
	__FNLOG("CControlInterfaceUsbcScLdd::DecodeEp0Data ");
sl@0
   212
sl@0
   213
	if (IsActive())
sl@0
   214
		{
sl@0
   215
		__PRINT(_L("Still active\n"));
sl@0
   216
		__ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsControlInterfaceStillActive));
sl@0
   217
		return;
sl@0
   218
		}
sl@0
   219
sl@0
   220
	TPtrC8 ep0ReadDataPtr((TUint8*)iEp0Packet, iEp0Size);
sl@0
   221
	TInt err = iRequestHeader.Decode(ep0ReadDataPtr);
sl@0
   222
sl@0
   223
	if(err != KErrNone)
sl@0
   224
		return;
sl@0
   225
sl@0
   226
    switch(iRequestHeader.iRequest)
sl@0
   227
		{
sl@0
   228
		//
sl@0
   229
		// GET MAX LUN (0xFE)
sl@0
   230
		//
sl@0
   231
		case TUsbRequestHdr::EReqGetMaxLun:
sl@0
   232
			{
sl@0
   233
			__PRINT1(_L("DecodeEp0Data : 'Get Max LUN' Request MaxLun = %d"),iParent.MaxLun() );
sl@0
   234
sl@0
   235
            if (   iRequestHeader.iRequestType != 0xA1 //value from USB MS BOT spec
sl@0
   236
                || iRequestHeader.iIndex > 15
sl@0
   237
                || iRequestHeader.iValue != 0
sl@0
   238
                || iRequestHeader.iLength != 1)
sl@0
   239
                {
sl@0
   240
    		    __PRINT(_L("GetMaxLun command packet check error"));
sl@0
   241
                iParent.Ldd().EndpointZeroRequestError();
sl@0
   242
                break;
sl@0
   243
                }
sl@0
   244
sl@0
   245
			TPtr8* ep0WriteDataPtr = NULL;
sl@0
   246
			TUint ep0Length;
sl@0
   247
			iEp0Buf.GetInBufferRange(((TAny*&)ep0WriteDataPtr),ep0Length);
sl@0
   248
			ep0WriteDataPtr->SetLength(1);	//Return only 1 byte to host
sl@0
   249
			ep0WriteDataPtr->Fill(0);
sl@0
   250
			ep0WriteDataPtr->Fill(iParent.MaxLun());	// Supported Units
sl@0
   251
			TInt length = ep0WriteDataPtr->Length();
sl@0
   252
			err = iEp0Buf.WriteBuffer((TPtr8*)(ep0WriteDataPtr->Ptr()),length,ETrue,iStatus);
sl@0
   253
sl@0
   254
			iCurrentState = ESendMaxLun;
sl@0
   255
			SetActive();
sl@0
   256
sl@0
   257
			return;
sl@0
   258
			}
sl@0
   259
		//
sl@0
   260
		// RESET (0xFF)
sl@0
   261
		//
sl@0
   262
		case TUsbRequestHdr::EReqReset:
sl@0
   263
			{
sl@0
   264
			__PRINT(_L("DecodeEp0Data : 'Mass Storage Reset' Request"));
sl@0
   265
sl@0
   266
            if (   iRequestHeader.iRequestType != 0x21 //value from USB MS BOT spec
sl@0
   267
                || iRequestHeader.iIndex > 15
sl@0
   268
                || iRequestHeader.iValue != 0
sl@0
   269
                || iRequestHeader.iLength != 0)
sl@0
   270
                {
sl@0
   271
			    __PRINT(_L("MSC Reset command packet check error"));
sl@0
   272
                iParent.Ldd().EndpointZeroRequestError();
sl@0
   273
                break;
sl@0
   274
                }
sl@0
   275
sl@0
   276
			iParent.HwStop();
sl@0
   277
			iParent.Controller().Reset();
sl@0
   278
			iParent.HwStart(ETrue);
sl@0
   279
sl@0
   280
            err = iParent.Ldd().SendEp0StatusPacket();
sl@0
   281
			return;
sl@0
   282
			}
sl@0
   283
		//
sl@0
   284
		// Unknown?
sl@0
   285
		//
sl@0
   286
		default:
sl@0
   287
			{
sl@0
   288
			__PRINT(_L("DecodeEp0Data : Unknown Request"));
sl@0
   289
sl@0
   290
			}
sl@0
   291
		}
sl@0
   292
		ReadEp0Data();  //try to get another request
sl@0
   293
	}
sl@0
   294
sl@0
   295
sl@0
   296
//
sl@0
   297
// --- class CBulkOnlyTransportUsbcScLdd ---------------------------------------------------------
sl@0
   298
//
sl@0
   299
sl@0
   300
CBulkOnlyTransportUsbcScLdd::CBulkOnlyTransportUsbcScLdd(TInt aNumDrives,CUsbMassStorageController& aController)
sl@0
   301
	:CBulkOnlyTransport(aNumDrives, aController)
sl@0
   302
	{
sl@0
   303
	__FNLOG("CBulkOnlyTransportUsbcScLdd::CBulkOnlyTransportUsbcScLdd");
sl@0
   304
	}
sl@0
   305
sl@0
   306
/**
sl@0
   307
Constructs the CBulkOnlyTransportUsbcScLdd object
sl@0
   308
*/
sl@0
   309
void CBulkOnlyTransportUsbcScLdd::ConstructL()
sl@0
   310
	{
sl@0
   311
	__FNLOG("CBulkOnlyTransportUsbcScLdd::ConstructL()");
sl@0
   312
	iControlInterface = CControlInterfaceUsbcScLdd::NewL(*this);
sl@0
   313
	iDeviceStateNotifier = CActiveDeviceStateNotifierBase::NewL(*this, *this);
sl@0
   314
	iChunk = new RChunk();
sl@0
   315
	CActiveScheduler::Add(this);
sl@0
   316
	}
sl@0
   317
sl@0
   318
sl@0
   319
CBulkOnlyTransportUsbcScLdd::~CBulkOnlyTransportUsbcScLdd()
sl@0
   320
	{
sl@0
   321
	__FNLOG("CBulkOnlyTransportUsbcScLdd::~CBulkOnlyTransportUsbcScLdd");
sl@0
   322
	if (iInterfaceConfigured)
sl@0
   323
		{
sl@0
   324
		TInt err = iSCReadEndpointBuf.Close(); 
sl@0
   325
		err = iSCWriteEndpointBuf.Close();
sl@0
   326
		delete iControlInterface ;
sl@0
   327
		delete iDeviceStateNotifier;
sl@0
   328
		delete iChunk;
sl@0
   329
		}
sl@0
   330
	}	
sl@0
   331
sl@0
   332
RDevUsbcScClient& CBulkOnlyTransportUsbcScLdd::Ldd()
sl@0
   333
	{
sl@0
   334
	return iLdd;
sl@0
   335
	}
sl@0
   336
sl@0
   337
/**
sl@0
   338
Set or unset configuration descriptor for USB MassStorage Bulk Only transport
sl@0
   339
sl@0
   340
@param aUnset indicate whether set or unset descriptor
sl@0
   341
@return KErrNone if operation was completed successfully, errorcode otherwise
sl@0
   342
*/
sl@0
   343
TInt CBulkOnlyTransportUsbcScLdd::SetupConfigurationDescriptor(TBool aUnset)
sl@0
   344
	{
sl@0
   345
	__FNLOG("CBulkOnlyTransportUsbcScLdd::SetupConfigurationDescriptor");
sl@0
   346
	TInt ret(KErrNone);
sl@0
   347
sl@0
   348
	if ((ret = iLdd.Open(0)) != KErrNone)
sl@0
   349
		return ret;
sl@0
   350
sl@0
   351
	TInt configDescriptorSize(0);
sl@0
   352
	iLdd.GetConfigurationDescriptorSize(configDescriptorSize);
sl@0
   353
	if (static_cast<TUint>(configDescriptorSize) != KUsbDescSize_Config)
sl@0
   354
		{
sl@0
   355
		return KErrCorrupt;
sl@0
   356
		}
sl@0
   357
sl@0
   358
	TBuf8<KUsbDescSize_Config> configDescriptor;
sl@0
   359
	ret = iLdd.GetConfigurationDescriptor(configDescriptor);
sl@0
   360
	if (ret != KErrNone)
sl@0
   361
		{
sl@0
   362
		return ret;
sl@0
   363
		}
sl@0
   364
sl@0
   365
	// I beleive that other fields setted up during LDD initialisation
sl@0
   366
	if (aUnset)
sl@0
   367
		{
sl@0
   368
		--configDescriptor[KUsbNumInterfacesOffset];
sl@0
   369
		}
sl@0
   370
	else
sl@0
   371
		{
sl@0
   372
		++configDescriptor[KUsbNumInterfacesOffset];
sl@0
   373
		}
sl@0
   374
	ret = iLdd.SetConfigurationDescriptor(configDescriptor);
sl@0
   375
sl@0
   376
	if (aUnset)
sl@0
   377
		{
sl@0
   378
		iLdd.Close();
sl@0
   379
		}
sl@0
   380
sl@0
   381
	return ret;
sl@0
   382
	}
sl@0
   383
sl@0
   384
/**
sl@0
   385
Set up interface descriptor
sl@0
   386
sl@0
   387
@return KErrNone if operation was completed successfully, errorcode otherwise
sl@0
   388
*/
sl@0
   389
TInt CBulkOnlyTransportUsbcScLdd::SetupInterfaceDescriptors()
sl@0
   390
	{
sl@0
   391
	__FNLOG("CBulkOnlyTransportUsbcScLdd::SetupInterfaceDescriptors");
sl@0
   392
	// Device caps
sl@0
   393
	TUsbDeviceCaps d_caps;
sl@0
   394
	TInt ret = iLdd.DeviceCaps(d_caps);
sl@0
   395
	if (ret != KErrNone)
sl@0
   396
		{
sl@0
   397
		return ret;
sl@0
   398
		}
sl@0
   399
	TInt totalEndpoints = d_caps().iTotalEndpoints;
sl@0
   400
	if (totalEndpoints  < KRequiredNumberOfEndpoints)
sl@0
   401
		{
sl@0
   402
		return KErrHardwareNotAvailable;
sl@0
   403
		}
sl@0
   404
sl@0
   405
	// Endpoint caps
sl@0
   406
	TUsbcEndpointData data[KUsbcMaxEndpoints];
sl@0
   407
	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
sl@0
   408
	ret = iLdd.EndpointCaps(dataptr);
sl@0
   409
	if (ret != KErrNone)
sl@0
   410
		{
sl@0
   411
		return ret;
sl@0
   412
		}
sl@0
   413
sl@0
   414
	// Set the active interface
sl@0
   415
	TUsbcScInterfaceInfoBuf ifc;
sl@0
   416
	TInt ep_found = 0;
sl@0
   417
	TBool foundBulkIN = EFalse;
sl@0
   418
	TBool foundBulkOUT = EFalse;
sl@0
   419
sl@0
   420
	for (TInt i = 0; i < totalEndpoints ; i++)
sl@0
   421
		{
sl@0
   422
		const TUsbcEndpointCaps* caps = &data[i].iCaps;
sl@0
   423
		const TInt maxPacketSize = caps->MaxPacketSize();
sl@0
   424
		if (!foundBulkIN &&
sl@0
   425
			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) == (KUsbEpTypeBulk | KUsbEpDirIn))
sl@0
   426
			{
sl@0
   427
			// InEndpoint is going to be our TX (IN, write) endpoint
sl@0
   428
			ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
sl@0
   429
			if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) == KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
sl@0
   430
				ifc().iEndpointData[0].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
sl@0
   431
			ifc().iEndpointData[0].iDir  = KUsbEpDirIn;
sl@0
   432
			ifc().iEndpointData[0].iSize = maxPacketSize;
sl@0
   433
			ifc().iEndpointData[0].iInterval_Hs = 0;
sl@0
   434
			ifc().iEndpointData[0].iBufferSize = KMaxScBufferSize;
sl@0
   435
			foundBulkIN = ETrue;
sl@0
   436
			if (++ep_found == KRequiredNumberOfEndpoints)
sl@0
   437
				{
sl@0
   438
				break;
sl@0
   439
				}
sl@0
   440
			continue;
sl@0
   441
			}
sl@0
   442
		if (!foundBulkOUT &&
sl@0
   443
			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) == (KUsbEpTypeBulk | KUsbEpDirOut))
sl@0
   444
			{
sl@0
   445
			// OutEndpoint is going to be our RX (OUT, read) endpoint
sl@0
   446
			ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
sl@0
   447
			if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) == KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
sl@0
   448
				ifc().iEndpointData[1].iFeatureWord1  = KUsbcEndpointInfoFeatureWord1_DMA|KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
sl@0
   449
			ifc().iEndpointData[1].iDir  = KUsbEpDirOut;
sl@0
   450
			ifc().iEndpointData[1].iSize = maxPacketSize;
sl@0
   451
			ifc().iEndpointData[1].iInterval_Hs = 0;
sl@0
   452
			ifc().iEndpointData[1].iBufferSize = KMaxScBufferSize;
sl@0
   453
			ifc().iEndpointData[1].iReadSize = KMaxScReadSize;
sl@0
   454
sl@0
   455
			foundBulkOUT = ETrue;
sl@0
   456
			if (++ep_found == KRequiredNumberOfEndpoints)
sl@0
   457
				{
sl@0
   458
				break;
sl@0
   459
				}
sl@0
   460
			continue;
sl@0
   461
			}
sl@0
   462
		}
sl@0
   463
	if (ep_found != KRequiredNumberOfEndpoints)
sl@0
   464
		{
sl@0
   465
		return KErrHardwareNotAvailable;
sl@0
   466
		}
sl@0
   467
sl@0
   468
	_LIT16(string, "USB Mass Storage Interface");
sl@0
   469
	ifc().iString = const_cast<TDesC16*>(&string);
sl@0
   470
	ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
sl@0
   471
	ifc().iClass.iClassNum    = 0x08;	// Mass Storage
sl@0
   472
	ifc().iClass.iSubClassNum = 0x06;	// SCSI Transparent Command Set
sl@0
   473
	ifc().iClass.iProtocolNum = 0x50;	// Bulk Only Transport
sl@0
   474
sl@0
   475
	if (d_caps().iHighSpeed)
sl@0
   476
		{
sl@0
   477
		// Tell the Protocol about it, because it might want to do some
sl@0
   478
		// optimizing too.
sl@0
   479
		iProtocol->ReportHighSpeedDevice();
sl@0
   480
		}
sl@0
   481
sl@0
   482
	if ((ret = iLdd.SetInterface(0, ifc)) == KErrNone)
sl@0
   483
		{
sl@0
   484
		return (iLdd.FinalizeInterface(iChunk));
sl@0
   485
		}
sl@0
   486
	return ret;
sl@0
   487
	}
sl@0
   488
sl@0
   489
void CBulkOnlyTransportUsbcScLdd::ReleaseInterface()
sl@0
   490
	{
sl@0
   491
	iLdd.ReleaseInterface(0);
sl@0
   492
	}
sl@0
   493
sl@0
   494
sl@0
   495
TInt CBulkOnlyTransportUsbcScLdd::StartControlInterface()
sl@0
   496
	{
sl@0
   497
	return iControlInterface->Start();
sl@0
   498
	}
sl@0
   499
sl@0
   500
void CBulkOnlyTransportUsbcScLdd::CancelControlInterface()
sl@0
   501
	{
sl@0
   502
	iControlInterface->Cancel();
sl@0
   503
	}
sl@0
   504
sl@0
   505
void CBulkOnlyTransportUsbcScLdd::ActivateDeviceStateNotifier()
sl@0
   506
	{
sl@0
   507
	iDeviceStateNotifier->Activate();
sl@0
   508
	}
sl@0
   509
sl@0
   510
void CBulkOnlyTransportUsbcScLdd::CancelDeviceStateNotifier()
sl@0
   511
	{
sl@0
   512
	iDeviceStateNotifier->Cancel();
sl@0
   513
	}
sl@0
   514
sl@0
   515
sl@0
   516
void CBulkOnlyTransportUsbcScLdd::CancelReadWriteRequests()
sl@0
   517
	{
sl@0
   518
	__FNLOG("CBulkOnlyTransportUsbcScLdd::CancelReadWriteRequests");
sl@0
   519
	TUsbcScChunkHeader chunkHeader(*iChunk);
sl@0
   520
	for (TInt i = 0; i < chunkHeader.iAltSettings->iNumOfAltSettings; i++)
sl@0
   521
		{
sl@0
   522
		TInt8* endpoint = (TInt8*) (chunkHeader.iAltSettings->iAltTableOffset[i] + (TInt) iChunk->Base());
sl@0
   523
		TInt numOfEps = chunkHeader.GetNumberOfEndpoints(i);
sl@0
   524
        __ASSERT_DEBUG(numOfEps >= 0, User::Invariant());
sl@0
   525
		for (TInt j = 1; j <= numOfEps; j++)
sl@0
   526
			{
sl@0
   527
			TUsbcScHdrEndpointRecord* endpointInf = (TUsbcScHdrEndpointRecord*) &(endpoint[j * chunkHeader.iAltSettings->iEpRecordSize]);
sl@0
   528
			if (endpointInf->Direction() == KUsbScHdrEpDirectionOut)
sl@0
   529
				{
sl@0
   530
				iLdd.ReadCancel(endpointInf->iBufferNo);
sl@0
   531
				}
sl@0
   532
			if (endpointInf->Direction() == KUsbScHdrEpDirectionIn)
sl@0
   533
				{
sl@0
   534
				iLdd.WriteCancel(endpointInf->iBufferNo);
sl@0
   535
				}
sl@0
   536
			}
sl@0
   537
		}
sl@0
   538
	}
sl@0
   539
sl@0
   540
void CBulkOnlyTransportUsbcScLdd::AllocateEndpointResources()
sl@0
   541
	{
sl@0
   542
	TUsbcScChunkHeader chunkHeader(*iChunk);
sl@0
   543
	for (TInt i = 0; i < chunkHeader.iAltSettings->iNumOfAltSettings; i++)
sl@0
   544
		{
sl@0
   545
		TInt8* endpoint = (TInt8*) (chunkHeader.iAltSettings->iAltTableOffset[i] + (TInt) iChunk->Base()); 
sl@0
   546
sl@0
   547
		for (TInt j = 1; j <= chunkHeader.GetNumberOfEndpoints(i); j++) 
sl@0
   548
			{
sl@0
   549
			TUsbcScHdrEndpointRecord* endpointInf = (TUsbcScHdrEndpointRecord*) &(endpoint[j * chunkHeader.iAltSettings->iEpRecordSize]);
sl@0
   550
			if (endpointInf->Direction() == KUsbScHdrEpDirectionOut)
sl@0
   551
				{
sl@0
   552
				iOutEndpoint = j;
sl@0
   553
				}
sl@0
   554
			if (endpointInf->Direction() == KUsbScHdrEpDirectionIn)
sl@0
   555
				{
sl@0
   556
				iInEndpoint = j;
sl@0
   557
				}
sl@0
   558
			}
sl@0
   559
		}
sl@0
   560
sl@0
   561
	TUsbDeviceCaps d_caps;
sl@0
   562
	TInt err;
sl@0
   563
	TInt ret = iLdd.DeviceCaps(d_caps);
sl@0
   564
	if (ret == KErrNone)
sl@0
   565
		{
sl@0
   566
		if((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != KUsbDevCapsFeatureWord1_EndpointResourceAllocV2)
sl@0
   567
			{		
sl@0
   568
			__PRINT(_L("CBulkOnlyTransportUsbcScLdd::Start  - Setting up DMA and double buffering\n"));
sl@0
   569
				// Set up DMA if possible (errors are non-critical)
sl@0
   570
			err = iLdd.AllocateEndpointResource(iOutEndpoint, EUsbcEndpointResourceDMA);
sl@0
   571
			if (err != KErrNone)
sl@0
   572
				{
sl@0
   573
				__PRINT1(_L("Set DMA on OUT endpoint failed with error code: %d"), err);
sl@0
   574
				}
sl@0
   575
			err = iLdd.AllocateEndpointResource(iInEndpoint, EUsbcEndpointResourceDMA);
sl@0
   576
			if (err != KErrNone)
sl@0
   577
				{
sl@0
   578
				__PRINT1(_L("Set DMA on IN endpoint failed with error code: %d"), err);
sl@0
   579
				}
sl@0
   580
sl@0
   581
				// Set up Double Buffering if possible (errors are non-critical)
sl@0
   582
			err = iLdd.AllocateEndpointResource(iOutEndpoint, EUsbcEndpointResourceDoubleBuffering);
sl@0
   583
			if (err != KErrNone)
sl@0
   584
				{
sl@0
   585
				__PRINT1(_L("Set Double Buffering on OUT endpoint failed with error code: %d"), err);
sl@0
   586
				}
sl@0
   587
			err = iLdd.AllocateEndpointResource(iInEndpoint, EUsbcEndpointResourceDoubleBuffering);
sl@0
   588
				if (err != KErrNone)
sl@0
   589
				{
sl@0
   590
				__PRINT1(_L("Set Double Buffering on IN endpoint failed with error code: %d"), err);
sl@0
   591
				}
sl@0
   592
			}
sl@0
   593
		}
sl@0
   594
	
sl@0
   595
	err = OpenEndpoints();
sl@0
   596
	}
sl@0
   597
sl@0
   598
TInt CBulkOnlyTransportUsbcScLdd::OpenEndpoints()
sl@0
   599
	{
sl@0
   600
	TInt res = iLdd.OpenEndpoint(iSCReadEndpointBuf, iOutEndpoint);
sl@0
   601
	if (res == KErrNone)
sl@0
   602
		{
sl@0
   603
		res = iLdd.OpenEndpoint(iSCWriteEndpointBuf, iInEndpoint);
sl@0
   604
		if (res == KErrNone)
sl@0
   605
			{
sl@0
   606
			iSCWriteEndpointBuf.GetInBufferRange((TAny*&)iDataPtr, iInBufferLength);
sl@0
   607
			res = iControlInterface->OpenEp0();
sl@0
   608
			}
sl@0
   609
		return res;
sl@0
   610
		}
sl@0
   611
sl@0
   612
	return res;
sl@0
   613
	}
sl@0
   614
sl@0
   615
sl@0
   616
TInt CBulkOnlyTransportUsbcScLdd::GetDeviceStatus(TUsbcDeviceState& deviceStatus)
sl@0
   617
	{
sl@0
   618
	return iLdd.DeviceStatus(deviceStatus);
sl@0
   619
	}
sl@0
   620
sl@0
   621
void CBulkOnlyTransportUsbcScLdd::FlushData()
sl@0
   622
	{
sl@0
   623
	// Intentionally Left Blank Do Nothing 
sl@0
   624
	}
sl@0
   625
sl@0
   626
/**
sl@0
   627
 * Read out rest data from OutEndpoint and discard them
sl@0
   628
 */
sl@0
   629
void CBulkOnlyTransportUsbcScLdd::ReadAndDiscardData(TInt /*aBytes*/)
sl@0
   630
	{
sl@0
   631
	__FNLOG("CBulkOnlyTransport::ReadAndDiscardData");
sl@0
   632
	TRequestStatus status;
sl@0
   633
	TInt r = KErrNone; // Lets assume there is no data
sl@0
   634
	do
sl@0
   635
		{
sl@0
   636
		iSCReadSize = 0;
sl@0
   637
		status = KErrNone;
sl@0
   638
		r = iSCReadEndpointBuf.TakeBuffer(iSCReadData,iSCReadSize,iReadZlp,status);
sl@0
   639
		iSCReadEndpointBuf.Expire();
sl@0
   640
		}
sl@0
   641
	while (r == KErrCompletion);
sl@0
   642
sl@0
   643
	if (r == KErrNone)
sl@0
   644
		{
sl@0
   645
		TRequestStatus* stat = &status;
sl@0
   646
		User::RequestComplete(stat, KErrNone);
sl@0
   647
		}
sl@0
   648
	}
sl@0
   649
sl@0
   650
/**
sl@0
   651
Called by the protocol to determine how many bytes of data are available in the read buffer.
sl@0
   652
sl@0
   653
@return The number of bytes available in the read buffer
sl@0
   654
*/
sl@0
   655
TInt CBulkOnlyTransportUsbcScLdd::BytesAvailable()
sl@0
   656
	{
sl@0
   657
	// Intentionally Left Blank Do Nothing 
sl@0
   658
	return 0;
sl@0
   659
	}
sl@0
   660
sl@0
   661
void CBulkOnlyTransportUsbcScLdd::StallEndpointAndWaitForClear()
sl@0
   662
	{
sl@0
   663
	__FNLOG("CBulkOnlyTransportUsbcScLdd::StallEndpointAndWaitForClear");
sl@0
   664
sl@0
   665
	// Now stall this endpoint
sl@0
   666
	__PRINT1(_L("Stalling endpoint %d"), iInEndpoint);
sl@0
   667
	TInt r = iLdd.HaltEndpoint(iInEndpoint);
sl@0
   668
	if (r != KErrNone)
sl@0
   669
		{
sl@0
   670
		__PRINT2(_L("Error: stalling ep %d failed: %d"), iInEndpoint, r);
sl@0
   671
		}
sl@0
   672
	TEndpointState ep_state;
sl@0
   673
	TInt i = 0;
sl@0
   674
	do
sl@0
   675
		{
sl@0
   676
		// Wait for 10ms before checking the ep status
sl@0
   677
		User::After(10000);
sl@0
   678
		iLdd.EndpointStatus(iInEndpoint, ep_state);
sl@0
   679
		if (++i >= 550)
sl@0
   680
			{
sl@0
   681
			// 5.5 secs should be enough (see 9.2.6.1 Request Processing Timing)
sl@0
   682
			__PRINT1(_L("Error: Checked for ep %d de-stall for 5.5s - giving up now"), iInEndpoint);
sl@0
   683
			// We can now only hope for a Reset Recovery
sl@0
   684
			return;
sl@0
   685
			}
sl@0
   686
		} while ((ep_state == EEndpointStateStalled) && iStarted);
sl@0
   687
	__PRINT2(_L("Checked for ep %d de-stall: %d time(s)"), iInEndpoint, i);
sl@0
   688
	}
sl@0
   689
sl@0
   690
/**
sl@0
   691
Read CBW data from the host and decode it.
sl@0
   692
*/
sl@0
   693
void CBulkOnlyTransportUsbcScLdd::ReadCBW()
sl@0
   694
	{
sl@0
   695
	__FNLOG("CBulkOnlyTransportUsbcScLdd::ReadCBW");
sl@0
   696
	if (IsActive())
sl@0
   697
		{
sl@0
   698
		__PRINT(_L("Still active\n"));
sl@0
   699
		__ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive)); 
sl@0
   700
		return;
sl@0
   701
		}
sl@0
   702
	TInt r = KErrNone;
sl@0
   703
	do
sl@0
   704
		{
sl@0
   705
		r = ReadUsb();
sl@0
   706
		if ((r == KErrCompletion) && (iSCReadSize == KCbwLength))  
sl@0
   707
			{
sl@0
   708
			iCurrentState = EWaitForCBW;
sl@0
   709
			iStatus = KErrNone;
sl@0
   710
			DecodeCBW();
sl@0
   711
			iSCReadSize = 0;
sl@0
   712
			}
sl@0
   713
		else if (r == KErrNone)
sl@0
   714
			{
sl@0
   715
			iCurrentState = EWaitForCBW;
sl@0
   716
			SetActive();
sl@0
   717
			}
sl@0
   718
		else if ((r == KErrCompletion) && (iSCReadSize != KCbwLength))
sl@0
   719
			{
sl@0
   720
			ExpireData(iSCReadData);
sl@0
   721
			}
sl@0
   722
		}while ((r == KErrCompletion) && (!IsActive()));
sl@0
   723
	}
sl@0
   724
sl@0
   725
void CBulkOnlyTransportUsbcScLdd::ExpireData(TAny* aAddress)
sl@0
   726
	{
sl@0
   727
	if (aAddress)
sl@0
   728
		{
sl@0
   729
		iSCReadEndpointBuf.Expire(aAddress);
sl@0
   730
		}
sl@0
   731
	else
sl@0
   732
		{
sl@0
   733
		iSCReadEndpointBuf.Expire();
sl@0
   734
		}
sl@0
   735
	}
sl@0
   736
sl@0
   737
void CBulkOnlyTransportUsbcScLdd::ProcessCbwEvent()
sl@0
   738
	{
sl@0
   739
	ReadCBW();
sl@0
   740
	}
sl@0
   741
sl@0
   742
/**
sl@0
   743
Request data form the host for the protocol
sl@0
   744
sl@0
   745
@param aLength amount of data (in bytes) to be received from the host
sl@0
   746
*/
sl@0
   747
void CBulkOnlyTransportUsbcScLdd::ReadData(TUint /*aLength*/)
sl@0
   748
	{
sl@0
   749
	__FNLOG("CBulkOnlyTransportUsbcScLdd::ReadData");
sl@0
   750
	if (IsActive())
sl@0
   751
		{
sl@0
   752
		__PRINT(_L("Still active\n"));
sl@0
   753
		__ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
sl@0
   754
		return;
sl@0
   755
		}
sl@0
   756
	TInt r = KErrNone;
sl@0
   757
	do
sl@0
   758
		{
sl@0
   759
		r = ReadUsb();
sl@0
   760
		iCurrentState = EReadingData;
sl@0
   761
		if (r == KErrCompletion)
sl@0
   762
			{
sl@0
   763
			iReadBufPtr.Set((TUint8*) iSCReadData, iSCReadSize, iSCReadSize);
sl@0
   764
			iStatus = KErrNone;
sl@0
   765
			ProcessDataFromHost();
sl@0
   766
			iSCReadSize = 0;
sl@0
   767
			}
sl@0
   768
		else if (r == KErrNone)
sl@0
   769
			{
sl@0
   770
			iSCReadSize = 0;
sl@0
   771
			SetActive();
sl@0
   772
			}
sl@0
   773
sl@0
   774
		}while ((r == KErrCompletion) && (!IsActive()));
sl@0
   775
	}
sl@0
   776
sl@0
   777
void CBulkOnlyTransportUsbcScLdd::ProcessDataFromHost()
sl@0
   778
	{
sl@0
   779
	TInt ret = KErrNone;
sl@0
   780
		{
sl@0
   781
		if (iReadSetUp)
sl@0
   782
			{
sl@0
   783
			ret = iProtocol->ReadComplete(KErrNone);
sl@0
   784
			}
sl@0
   785
#ifndef MSDC_MULTITHREADED
sl@0
   786
		ExpireData(iSCReadData);
sl@0
   787
#endif
sl@0
   788
		TUint deviceDataLength = iSCReadSize; // What was written to the disk // static_cast<TUint>(iReadBuf.Length());
sl@0
   789
		if(ret == KErrCompletion)
sl@0
   790
			{
sl@0
   791
			// The protocol has indicated with KErrCompletion that sufficient
sl@0
   792
			// data is available in the buffer to process the transfer immediately.
sl@0
   793
sl@0
   794
			//iDataResidue is initially set to host data length as we do not know how much data is there in the 'LDD transfer'. 
sl@0
   795
			//After a TakeBuffer call, iSCReadSize in updated and set to deviceDataLength
sl@0
   796
			iDataResidue -= deviceDataLength;
sl@0
   797
			}
sl@0
   798
		else
sl@0
   799
			{
sl@0
   800
			iDataResidue -= deviceDataLength;
sl@0
   801
sl@0
   802
			// The protocol has indicated that transfer is
sl@0
   803
			// complete, so send the CSW response to the host.
sl@0
   804
			iReadSetUp = EFalse;
sl@0
   805
sl@0
   806
			if (ret != KErrNone)
sl@0
   807
				{
sl@0
   808
				iCmdStatus = ECommandFailed;
sl@0
   809
				}
sl@0
   810
sl@0
   811
			if (iDataResidue)
sl@0
   812
				{
sl@0
   813
				__PRINT(_L("Discarding residue"));
sl@0
   814
				// we have to read as much data as available that host PC sends;
sl@0
   815
				// otherwise, bulk-out endpoint will need to keep sending NAK back.
sl@0
   816
				ReadAndDiscardData(iDataResidue); 
sl@0
   817
				}
sl@0
   818
sl@0
   819
			SendCSW(iCbwTag, iDataResidue, iCmdStatus);
sl@0
   820
			}
sl@0
   821
		}
sl@0
   822
	}
sl@0
   823
sl@0
   824
void CBulkOnlyTransportUsbcScLdd::WriteUsb(TRequestStatus& aStatus, TPtrC8& aDes, TUint aLength, TBool aZlpRequired)
sl@0
   825
	{
sl@0
   826
	TUint aOffset = (TUint) aDes.Ptr() - (TUint) iChunk->Base();
sl@0
   827
	iSCWriteEndpointBuf.WriteBuffer(aOffset, aLength, aZlpRequired, aStatus);
sl@0
   828
	}
sl@0
   829
sl@0
   830
void CBulkOnlyTransportUsbcScLdd::SetCbwPtr()
sl@0
   831
	{
sl@0
   832
	iCbwBufPtr.Set((TUint8*)iSCReadData, iSCReadSize);
sl@0
   833
	}
sl@0
   834
sl@0
   835
TPtr8& CBulkOnlyTransportUsbcScLdd::SetCommandBufPtr(TUint aLength)
sl@0
   836
	{
sl@0
   837
	TPtr8 writeBuf((TUint8*) iDataPtr, aLength);
sl@0
   838
	iCommandBufPtr.Set(writeBuf);
sl@0
   839
	return iCommandBufPtr;
sl@0
   840
	}
sl@0
   841
sl@0
   842
void CBulkOnlyTransportUsbcScLdd::SetReadDataBufPtr(TUint /*aLength*/)
sl@0
   843
	{
sl@0
   844
	// Do nothing for now 
sl@0
   845
	}
sl@0
   846
sl@0
   847
TPtr8& CBulkOnlyTransportUsbcScLdd::SetDataBufPtr()
sl@0
   848
	{
sl@0
   849
	TPtr8 writeBuf((TUint8*) iDataPtr, iInBufferLength);
sl@0
   850
	iDataBufPtr.Set(writeBuf);
sl@0
   851
	return iDataBufPtr;
sl@0
   852
	}
sl@0
   853
sl@0
   854
void CBulkOnlyTransportUsbcScLdd::SetPaddingBufPtr(TUint aLength)
sl@0
   855
	{
sl@0
   856
	TPtr8 writeBuf((TUint8*) iDataPtr, aLength, aLength);
sl@0
   857
	iPaddingBufPtr.Set(writeBuf);
sl@0
   858
	}
sl@0
   859
sl@0
   860
void CBulkOnlyTransportUsbcScLdd::SetCswBufPtr(TUint aLength)
sl@0
   861
	{
sl@0
   862
	TPtr8 writeBuf((TUint8*) iDataPtr, aLength, aLength);
sl@0
   863
	iCswBufPtr.Set(writeBuf);
sl@0
   864
	}
sl@0
   865
sl@0
   866
void CBulkOnlyTransportUsbcScLdd::ProcessReadingDataEvent()
sl@0
   867
	{
sl@0
   868
	ReadData();
sl@0
   869
	}
sl@0
   870
sl@0
   871
TInt CBulkOnlyTransportUsbcScLdd::ReadUsb(TUint /*aLength*/)
sl@0
   872
	{
sl@0
   873
	__FNLOG("CBulkOnlyTransportUsbcScLdd::ReadUSB");
sl@0
   874
	return iSCReadEndpointBuf.TakeBuffer(iSCReadData,iSCReadSize,iReadZlp,iStatus);
sl@0
   875
	}
sl@0
   876
sl@0
   877
void CBulkOnlyTransportUsbcScLdd::DiscardData(TUint aLength)
sl@0
   878
	{
sl@0
   879
	TUint c = 0;
sl@0
   880
	TRequestStatus status;
sl@0
   881
	TInt r = KErrNone;
sl@0
   882
	while (c < aLength)
sl@0
   883
		{
sl@0
   884
		iSCReadSize = 0;
sl@0
   885
		status = KErrNone;
sl@0
   886
		r = iSCReadEndpointBuf.TakeBuffer(iSCReadData,iSCReadSize,iReadZlp,status);
sl@0
   887
		c += iSCReadSize;
sl@0
   888
		if (r == KErrNone)
sl@0
   889
			User::WaitForRequest(status);
sl@0
   890
		if (r == KErrCompletion)
sl@0
   891
			{
sl@0
   892
			iSCReadEndpointBuf.Expire();
sl@0
   893
			}
sl@0
   894
		iSCReadSize = 0;
sl@0
   895
		}
sl@0
   896
	}
sl@0
   897
sl@0
   898
void CBulkOnlyTransportUsbcScLdd::WriteToClient(TUint aLength)
sl@0
   899
	{
sl@0
   900
	TUint c = 0;
sl@0
   901
	TRequestStatus status;
sl@0
   902
	TInt r = KErrNone;
sl@0
   903
	while (c < aLength)
sl@0
   904
		{
sl@0
   905
		iSCReadSize = 0;
sl@0
   906
		status = KErrNone;
sl@0
   907
		r = iSCReadEndpointBuf.TakeBuffer(iSCReadData,iSCReadSize,iReadZlp,status);
sl@0
   908
		c += iSCReadSize;
sl@0
   909
		iProtocol->ReadComplete(KErrGeneral);
sl@0
   910
		if (r == KErrNone)
sl@0
   911
			User::WaitForRequest(status);
sl@0
   912
		if (r == KErrCompletion)
sl@0
   913
			{
sl@0
   914
			iSCReadEndpointBuf.Expire();
sl@0
   915
			}
sl@0
   916
		iSCReadSize = 0;
sl@0
   917
		}
sl@0
   918
	}
sl@0
   919
sl@0
   920
#ifdef MSDC_MULTITHREADED
sl@0
   921
void CBulkOnlyTransportUsbcScLdd::GetBufferPointers(TPtr8& aDes1, TPtr8& aDes2)
sl@0
   922
	{
sl@0
   923
	//for DB
sl@0
   924
	TUint length = (TUint) (iInBufferLength - KCswBufferSize) / 2;
sl@0
   925
sl@0
   926
	TUint8* start = (TUint8*) (iDataPtr) + KCswBufferSize ; // 'first' buffer
sl@0
   927
	aDes1.Set(start, length, length);
sl@0
   928
sl@0
   929
	start = (TUint8*) (iDataPtr) + KCswBufferSize + length; // 'second' buffer
sl@0
   930
	aDes2.Set(start, length, length);
sl@0
   931
	}
sl@0
   932
#endif
sl@0
   933
sl@0
   934
void CBulkOnlyTransportUsbcScLdd::Activate(TRequestStatus& aStatus, TUint& aDeviceState)
sl@0
   935
    {
sl@0
   936
	iLdd.AlternateDeviceStatusNotify(aStatus, aDeviceState);
sl@0
   937
    }
sl@0
   938
sl@0
   939
sl@0
   940
void CBulkOnlyTransportUsbcScLdd::Cancel()
sl@0
   941
    {
sl@0
   942
	iLdd.AlternateDeviceStatusNotifyCancel();
sl@0
   943
    }
sl@0
   944
sl@0
   945
sl@0
   946
sl@0
   947