os/kernelhwsrv/userlibandfileserver/fileserver/smassstorage/inc/rwdrivethread.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2007-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
// Thread for reading and writing to a drive.
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
/**
sl@0
    19
 @file
sl@0
    20
 @internalTechnology
sl@0
    21
*/
sl@0
    22
sl@0
    23
#ifndef __RWDRIVETHREAD_H__
sl@0
    24
#define __RWDRIVETHREAD_H__
sl@0
    25
sl@0
    26
#ifdef MSDC_MULTITHREADED
sl@0
    27
sl@0
    28
typedef void (*ProcessWriteCompleteFunc)(TUint8* aAddress, TAny* aPtr);
sl@0
    29
sl@0
    30
sl@0
    31
/**
sl@0
    32
Class contains buffer for data with associated drive offset and length in bytes.
sl@0
    33
*/
sl@0
    34
sl@0
    35
class TBlockDesc
sl@0
    36
{
sl@0
    37
public:
sl@0
    38
sl@0
    39
	TBlockDesc();
sl@0
    40
	void SetPtr(TPtr8& aDes);
sl@0
    41
sl@0
    42
	TPtr8 GetReadBuffer();
sl@0
    43
	TPtr8 GetReadBuffer(TUint aLength, const TInt64& aOffset);
sl@0
    44
sl@0
    45
public:
sl@0
    46
	TInt64 iByteOffset;
sl@0
    47
	TUint iLength;
sl@0
    48
	TPtr8 iBuf;
sl@0
    49
};
sl@0
    50
sl@0
    51
sl@0
    52
/**
sl@0
    53
Class contains two buffers. Whilst one buffer is being read the
sl@0
    54
other buffer can be written to. The buffers should be accessed 
sl@0
    55
by the buffer pointers iDescReadPtr and iDescWritePtr.
sl@0
    56
*/
sl@0
    57
sl@0
    58
class TBlockDescBuffer
sl@0
    59
{
sl@0
    60
public:
sl@0
    61
	TBlockDescBuffer();
sl@0
    62
sl@0
    63
	void SwapDesc();
sl@0
    64
	TInt MaxLength() const {return iDesc2.iBuf.MaxLength();}
sl@0
    65
	TInt GetBufferNumber(const TPtr8* aBufferPtr) const;
sl@0
    66
	void SetUpReadBuf(TPtr8& aDes1, TPtr8& aDes2);
sl@0
    67
sl@0
    68
public:
sl@0
    69
	/** Points to block descriptor containing buffer to read from */
sl@0
    70
	TBlockDesc* iDescReadPtr;
sl@0
    71
	/** Points to block descriptor containing buffer to write to */
sl@0
    72
	TBlockDesc* iDescWritePtr;
sl@0
    73
	
sl@0
    74
private:
sl@0
    75
	/** Block descriptor for read/write operations */
sl@0
    76
	TBlockDesc iDesc1;
sl@0
    77
	/** Block descriptor for read/write operations */
sl@0
    78
	TBlockDesc iDesc2;
sl@0
    79
};
sl@0
    80
sl@0
    81
sl@0
    82
/**
sl@0
    83
Provides the common thread context used by CReadDriveThread and CWriteDriveThread 
sl@0
    84
classes.
sl@0
    85
*/
sl@0
    86
class CThreadContext : public CBase
sl@0
    87
{
sl@0
    88
public:
sl@0
    89
	static CThreadContext* NewL(const TDesC& aName,
sl@0
    90
								TThreadFunction aThreadFunction,
sl@0
    91
								TAny* aOwner);
sl@0
    92
	~CThreadContext();
sl@0
    93
sl@0
    94
private:
sl@0
    95
	CThreadContext();
sl@0
    96
	void ConstructL(const TDesC& aName, TThreadFunction aThreadFunction, TAny* aOwner);
sl@0
    97
sl@0
    98
sl@0
    99
public:
sl@0
   100
	void Resume() {iThread.Resume();}
sl@0
   101
sl@0
   102
	TInt MaxBufferLength() const {return iBuffer.MaxLength();} 
sl@0
   103
	TPtr8 GetReadBuffer();
sl@0
   104
	TPtr8 GetReadBuffer(TInt aLength);
sl@0
   105
sl@0
   106
	TPtrC8 WriteBuf();
sl@0
   107
sl@0
   108
public:
sl@0
   109
	/** Used to tell thread which drive to use */
sl@0
   110
	CMassStorageDrive* iDrive;
sl@0
   111
	/** Used by the thread to return error code */
sl@0
   112
	TInt iError;
sl@0
   113
	/** CS to regulate read/write buffer access */
sl@0
   114
	RCriticalSection iCritSect;
sl@0
   115
	
sl@0
   116
	/** buffer for reading and writing */
sl@0
   117
	TBlockDescBuffer iBuffer;
sl@0
   118
sl@0
   119
public:
sl@0
   120
	RThread iThread;
sl@0
   121
};
sl@0
   122
sl@0
   123
sl@0
   124
/**
sl@0
   125
Separate disk writer thread, used to implement OUT transfer double-buffering.
sl@0
   126
*/
sl@0
   127
class CWriteDriveThread : public CBase
sl@0
   128
	{
sl@0
   129
public:
sl@0
   130
	static CWriteDriveThread* NewL();
sl@0
   131
	~CWriteDriveThread();
sl@0
   132
sl@0
   133
private:
sl@0
   134
	CWriteDriveThread();
sl@0
   135
	void ConstructL();
sl@0
   136
sl@0
   137
public:
sl@0
   138
	TBlockDesc* GetReadDesc();
sl@0
   139
sl@0
   140
	TInt WriteDriveData(CMassStorageDrive* aDrive, const TInt64& aOffset, TPtrC8& aDes, ProcessWriteCompleteFunc aFunc, TAny* aPtr);
sl@0
   141
sl@0
   142
	TUint WriteBufferLength() const {return iThreadContext->iBuffer.iDescWritePtr->iBuf.Length();}
sl@0
   143
	TUint ReadBufferLength() const {return iThreadContext->iBuffer.iDescReadPtr->iBuf.Length();}
sl@0
   144
sl@0
   145
	TInt DeferredError() const {return iThreadContext->iError;}
sl@0
   146
	void ClearDeferredError() {iThreadContext->iError = KErrNone;}
sl@0
   147
	void WaitForWriteEmpty();
sl@0
   148
sl@0
   149
	TBool IsRecentlyWritten(TInt64 aOffset, TInt aLength);
sl@0
   150
	inline void SetCommandWrite10(TBool aIsWriteCommand) {iIsCommandWrite10 = aIsWriteCommand;};
sl@0
   151
sl@0
   152
private:
sl@0
   153
	static TInt ThreadFunction(TAny* aSelf);
sl@0
   154
	TInt WriteToDrive();
sl@0
   155
sl@0
   156
public:
sl@0
   157
	/** Thread context */
sl@0
   158
	CThreadContext* iThreadContext;
sl@0
   159
sl@0
   160
	TInt iWriteCounter;
sl@0
   161
private:
sl@0
   162
	/** Semaphore for reading USB */
sl@0
   163
	RSemaphore iProducerSem;
sl@0
   164
	/** Semaphore for writing to drive */
sl@0
   165
	RSemaphore iConsumerSem;
sl@0
   166
	/* Call back to tell transport that 'transfer' was written and the corresponding buffer can be overwriiten (mainly for SC LDD) */
sl@0
   167
	ProcessWriteCompleteFunc iCallback;
sl@0
   168
	TAny* iCallbackParameter;
sl@0
   169
	/* Flag set to true if the command is Write10. Used in Read10 to ignore pre-read if the previous command was Write10 */
sl@0
   170
	TBool iIsCommandWrite10;
sl@0
   171
	};
sl@0
   172
sl@0
   173
sl@0
   174
/**
sl@0
   175
Separate disk reader thread, used to implement IN transfer double-buffering.
sl@0
   176
*/
sl@0
   177
class CReadDriveThread : public CBase
sl@0
   178
	{
sl@0
   179
public:
sl@0
   180
	static CReadDriveThread* NewL();
sl@0
   181
	~CReadDriveThread();
sl@0
   182
sl@0
   183
private:
sl@0
   184
	CReadDriveThread();
sl@0
   185
	void ConstructL();
sl@0
   186
sl@0
   187
public:
sl@0
   188
	TBool ReadDriveData(CMassStorageDrive* aDrive, const TInt64& aOffset, TUint32 aLength, TBool aIgnoreCache);
sl@0
   189
	void DiscardRead();
sl@0
   190
sl@0
   191
private:
sl@0
   192
	static TInt ThreadFunction(TAny* aSelf);
sl@0
   193
	TInt ReadFromDrive();
sl@0
   194
sl@0
   195
public:
sl@0
   196
	/** Thread context */
sl@0
   197
	CThreadContext* iThreadContext;
sl@0
   198
	TBool iCompleted;
sl@0
   199
sl@0
   200
private:
sl@0
   201
	TBool iThreadRunning;
sl@0
   202
	};
sl@0
   203
sl@0
   204
sl@0
   205
//-----------------------------------------------
sl@0
   206
sl@0
   207
/**
sl@0
   208
Swap the buffer which the read and write buffer pointers are pointing to.
sl@0
   209
*/
sl@0
   210
inline void TBlockDescBuffer::SwapDesc()
sl@0
   211
{
sl@0
   212
	TBlockDesc* const tmp = iDescReadPtr;
sl@0
   213
	iDescReadPtr = iDescWritePtr;
sl@0
   214
	iDescWritePtr = tmp;
sl@0
   215
}
sl@0
   216
sl@0
   217
inline TPtr8 TBlockDesc::GetReadBuffer()
sl@0
   218
{
sl@0
   219
	return iBuf.LeftTPtr(iBuf.Length());
sl@0
   220
}
sl@0
   221
sl@0
   222
sl@0
   223
inline TPtr8 TBlockDesc::GetReadBuffer(TUint aLength, const TInt64& aOffset)
sl@0
   224
{
sl@0
   225
	iByteOffset = aOffset;
sl@0
   226
	iLength = aLength;
sl@0
   227
	iBuf.SetLength(aLength);
sl@0
   228
	
sl@0
   229
	return GetReadBuffer();
sl@0
   230
}
sl@0
   231
sl@0
   232
//-----------------------------------------------
sl@0
   233
sl@0
   234
/**
sl@0
   235
Returns the id of the buffer
sl@0
   236
sl@0
   237
@param bufferPtr pointer to the buffer.
sl@0
   238
@return  returns the buffer ID or -1 if the buffer is not found.
sl@0
   239
*/
sl@0
   240
inline TInt TBlockDescBuffer::GetBufferNumber(const TPtr8* aBufferPtr) const
sl@0
   241
{
sl@0
   242
	TInt no = -1;
sl@0
   243
	if (aBufferPtr == &iDesc1.iBuf)
sl@0
   244
		no = 1;
sl@0
   245
	else if (aBufferPtr == &iDesc2.iBuf)
sl@0
   246
		no = 2;
sl@0
   247
	return no;
sl@0
   248
}
sl@0
   249
sl@0
   250
sl@0
   251
//-----------------------------------------------
sl@0
   252
sl@0
   253
inline TPtr8 CThreadContext::GetReadBuffer()
sl@0
   254
{
sl@0
   255
	TInt len = iBuffer.iDescReadPtr->iBuf.Length();
sl@0
   256
	return iBuffer.iDescReadPtr->iBuf.LeftTPtr(len);
sl@0
   257
}
sl@0
   258
sl@0
   259
sl@0
   260
inline TPtr8 CThreadContext::GetReadBuffer(TInt aLength)
sl@0
   261
{
sl@0
   262
	iBuffer.iDescReadPtr->iBuf.SetLength(aLength);
sl@0
   263
	return GetReadBuffer();
sl@0
   264
}
sl@0
   265
sl@0
   266
sl@0
   267
inline TPtrC8 CThreadContext::WriteBuf()
sl@0
   268
{
sl@0
   269
	return iBuffer.iDescWritePtr->iBuf;
sl@0
   270
}
sl@0
   271
sl@0
   272
//-----------------------------------------------
sl@0
   273
sl@0
   274
inline TBlockDesc* CWriteDriveThread::GetReadDesc()
sl@0
   275
{
sl@0
   276
	return iThreadContext->iBuffer.iDescReadPtr;
sl@0
   277
}
sl@0
   278
sl@0
   279
//-----------------------------------------------
sl@0
   280
sl@0
   281
#endif //  MSDC_MULTITHREADED
sl@0
   282
sl@0
   283
#endif // __RWDRIVETHREAD_H__