usbdrv/peripheral/ldd/perilddsc/appifwrapper/src/usbcsc_bil.cpp
changeset 33 089413cdde3c
child 59 bbdce6bffaad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbdrv/peripheral/ldd/perilddsc/appifwrapper/src/usbcsc_bil.cpp	Fri Jul 23 15:54:47 2010 +0800
@@ -0,0 +1,633 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\drivers\usbcsc\usbcsc_bil.cpp
+// 
+//
+
+#include <e32std.h>
+#include <e32std_private.h>
+#include <usb/d32usbcsc.h>
+#include <e32debug.h>
+
+/** @file usbcsc_bil.cpp
+
+	Buffer Interface Layer for USB Client Device driver stack, using shared chunks.
+
+	@internalTechnology
+*/
+
+EXPORT_C TInt RDevUsbcScClient::FinalizeInterface()
+	{
+	TInt errorOrhandle = DoControl(EControlRealizeInterface); //returns a error value or chunk handle
+	TInt r = iSharedChunk.SetReturnedHandle(errorOrhandle);
+	iEndpointStatus = 0x00; //all endpoints are closed at the moment
+	iAlternateSetting = 0;
+	iNewAltSetting = 0;
+	iAltSettingSeq = 0;
+	return r;
+	}
+
+
+EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk)
+	{
+	TInt errorOrhandle = DoControl(EControlRealizeInterface);
+	iSharedChunk.SetReturnedHandle(errorOrhandle);
+	iEndpointStatus = 0x00; //all endpoints are closed at the moment
+	iAlternateSetting = 0;
+	return aChunk->SetReturnedHandle(errorOrhandle);
+	}
+
+
+EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI)
+	{
+	TUsbcScHdrEndpointRecord* endpointInf = NULL;
+	TBuf8<KUsbDescSize_Endpoint> descriptor;
+	TUsbcScChunkHeader chunkHeader(iSharedChunk);
+	//Do some validity checks
+	if((aEpB.iInState != TEndpointBuffer::ENotValid) && (aEpB.iOutState != TEndpointBuffer::ENotValid))
+		return KErrArgument;
+
+	TInt nEndpoints = chunkHeader.GetNumberOfEndpoints(iAlternateSetting);	
+	if ((aEpI < KEp0Number) && (aEpI > nEndpoints)) // Check endpoint number range 
+		return KErrNotFound;
+
+	if(iEndpointStatus & (1 << aEpI)) // Check that endpoint isn't already opene
+		return KErrInUse;
+
+	if(aEpI == KEp0Number) //endpoint 0
+		{
+		TUsbcScHdrEndpointRecord ep0=  TUsbcScHdrEndpointRecord(KUsbcScEndpointZero, KUsbScHdrEpDirectionBiDir | KUsbScHdrEpTypeControl);
+		aEpB.Construct(this,iSharedChunk.Base(), &ep0 ,aEpI, 
+		(SUsbcScBufferHeader*) ((TUint)iSharedChunk.Base() + (chunkHeader.iBuffers)->Ep0Out()->Offset()));
+
+		aEpB.iBufferStartAddr = (TUint8*) ((TUint)iSharedChunk.Base() + (chunkHeader.iBuffers)->Ep0In()->Offset());
+		aEpB.iSize = chunkHeader.iBuffers->Ep0In()->Size();
+		}
+	else  // If normal endpoint (!ep0)
+		{
+		TUsbcScBufferRecord* buf = 	chunkHeader.GetBuffer(iAlternateSetting,aEpI,endpointInf);
+		if (!buf)
+			return KErrGeneral;
+		// Set up endpoint members
+		aEpB.iBufferStartAddr = (TUint8*)  (buf->Offset() + (TUint)iSharedChunk.Base());
+		aEpB.iSize = buf->Size();
+		TInt r = GetEndpointDescriptor(iAlternateSetting, aEpI, descriptor);
+		if(r != KErrNone) // We need this to be able to calculate alignment
+			{
+			return r;
+			}
+
+		if (endpointInf->Direction()&KUsbScHdrEpDirectionIn)
+			{  							//in case of IN endpoints, first endpoint buffer location points to end offset
+			aEpB.Construct(this,iSharedChunk.Base(),endpointInf,aEpI);
+			if (iInAltSetting==KErrEof)
+			aEpB.iInState=TEndpointBuffer::EEOF;
+
+			}
+		else
+			{
+			SUsbcScBufferHeader *endpointHdr = (SUsbcScBufferHeader *) aEpB.iBufferStartAddr;
+			//In this case,SUsbcScBufferHeader points to full OUT endpoint header 
+			aEpB.Construct(this,iSharedChunk.Base(),endpointInf,aEpI, endpointHdr);
+			}
+		}
+	iEndpointStatus |= (1 << aEpI);	
+
+#ifdef _DEBUG
+	aEpB.Dump();
+	RDebug::Printf("iEndpointStatus: %x \n",iEndpointStatus);
+#endif
+	return KErrNone;
+	}
+
+
+//Internal, used by RDevUsbcScClient::StartNextOutAlternateSetting(...)
+//This drains any old data from an OUT buffer, and gets it ready for reading an ep.
+//aBufferOffset - The offset, into the chunk, that the buffer in question, may be found.
+ 
+TInt RDevUsbcScClient::Drain(TUint aBufferOffset)
+{
+	TUint8* base = iSharedChunk.Base();
+	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base);
+	TUint localTail = endpointHdr->iBilTail;
+	TUsbcScTransferHeader* currentTransfer;
+	TUint16 next = (iAltSettingSeq+1)&0xFFFF;
+	TInt err=KErrNone;
+
+	while (ETrue)
+		{
+		if (localTail == (TUint) endpointHdr->iHead)
+			{
+			err = KErrNotReady;
+			break;
+			}
+		currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
+
+		if (currentTransfer->iAltSettingSeq == next)
+			{
+			iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting
+			break;
+			}
+		else
+			{
+			localTail = currentTransfer->iNext;
+			}
+		} // end while
+	endpointHdr->iBilTail = localTail;
+	endpointHdr->iTail = localTail;
+	return err;
+}
+
+//Internal, used by RDevUsbcScClient::StartNextOutAlternateSetting(...)
+//This method checks that the OUT buffer is ready for reading an ep.
+//aBufferOffset - The offset, into the chunk, that the buffer in question, may be found.
+
+TInt RDevUsbcScClient::Peek(TUint aBufferOffset)
+{
+	TUint8* base = iSharedChunk.Base();
+	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base);
+	TUint localTail = endpointHdr->iBilTail;
+	TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
+
+	if ((localTail == (TUint)endpointHdr->iHead) || (currentTransfer->iAltSettingSeq != (iAltSettingSeq+1)&0xFFFF))
+		// if alternate setting has not changed
+		return KErrNotReady;
+	else
+		{
+		iNewAltSetting=currentTransfer->iAltSetting;
+		return KErrNone;
+		}
+}
+
+//Internal, used by RDevUsbcScClient::StartNextOutAlternateSetting(...)
+//This method is called if an alternate setting change happens from a set of ONLY IN endpoints.
+//Used to find the least possible alternate setting it can return to the user, stored in iNewAltSetting
+//Returns the sequence number of the 'latest' alternate setting it can switch to
+
+TInt RDevUsbcScClient::FindNextAlternateSetting()
+	{
+	TUsbcScChunkHeader chunkHeader(iSharedChunk);
+	TUsbcScHdrEndpointRecord* endpointInf = NULL;
+	TUint bufOff;
+	TInt altSet;
+	TInt ep;
+	TInt bufNum;
+
+	RArray <TInt> bufferOffset;	// Array to contain all OUT enpoint buffer offsets
+	// Populate array
+	for (altSet = 0; altSet < chunkHeader.iAltSettings->iNumOfAltSettings ; altSet++)
+		{
+		TInt numEndpoints = chunkHeader.GetNumberOfEndpoints(altSet);
+		for (ep =  1; ep  <= numEndpoints ; ep ++)
+			{
+			bufOff = chunkHeader.GetBuffer(altSet, ep, endpointInf)->Offset();	
+			if ((endpointInf->Direction() & KUsbScHdrEpDirectionOut) && (bufferOffset.Find(bufOff) == KErrNotFound))
+				{
+				bufferOffset.Append(bufOff);
+				}
+			}
+		}
+
+	TInt err = KErrNotFound;
+	TUint16 altSetSeqDelta = 0;
+	TUint16 currentaltSetSeqDelta = 0;
+	TBool noNewSettingFound = ETrue;
+	TInt altSetSeq = iAltSettingSeq;
+	TUint8* base = iSharedChunk.Base();
+
+	for (bufNum = 0; bufNum < bufferOffset.Count(); bufNum++) // Scan all OUT buffers
+		{	
+		SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (bufferOffset[bufNum] + base);
+		TUint localTail = endpointHdr->iBilTail;
+		TUsbcScTransferHeader* currentTransfer;
+		TUint16 next = (iAltSettingSeq+1)&0xFFFF;
+		
+		while (ETrue)
+			{
+			if (localTail == (TUint) endpointHdr->iHead)
+				{
+				break;	// This OUT endpoint buffer has no data, proceed checking with other OUT endpoint buffers
+				}
+			currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
+
+			if (currentTransfer->iAltSettingSeq != iAltSettingSeq) 
+				{
+				if (currentTransfer->iAltSettingSeq == next)
+					{
+					altSetSeq = currentTransfer->iAltSettingSeq;
+					iNewAltSetting = currentTransfer->iAltSetting; // record new alt setting
+					err = KErrNone;
+					break;
+					}
+
+				if (noNewSettingFound)
+					{
+					altSetSeqDelta = Abs(iAltSettingSeq - currentTransfer->iAltSettingSeq);
+					altSetSeq = currentTransfer->iAltSettingSeq;
+					iNewAltSetting = currentTransfer->iAltSetting; // record new alt setting
+					noNewSettingFound = EFalse;
+					}
+				else
+					{
+					currentaltSetSeqDelta = Abs(iAltSettingSeq - currentTransfer->iAltSettingSeq);
+					if (currentaltSetSeqDelta < altSetSeqDelta)
+						{
+						altSetSeqDelta = currentaltSetSeqDelta;
+						altSetSeq = currentTransfer->iAltSettingSeq;
+						iNewAltSetting = currentTransfer->iAltSetting;
+						}
+					}
+				break;
+				}
+			
+			localTail = currentTransfer->iNext;
+			} // end while
+
+		if (!err) // Found an alt set sequence one after iAltSettingSeq
+			{
+			break; // found 'the next' alternate setting, exit for loop
+			}
+		
+		}// for loop
+
+	return altSetSeq;
+	}
+
+EXPORT_C TInt RDevUsbcScClient::StartNextOutAlternateSetting(TBool aFlush)
+	{
+	TUsbcScChunkHeader chunkHeader(iSharedChunk);
+	
+	//if endpoints are still open, return KErrInUse 
+	if((iEndpointStatus&~1) != 0)
+		{
+		return KErrInUse;
+		}
+
+	TInt r;
+	TInt ep;
+	TInt noEp;
+	TUint bufOff;
+	TBool inEndpointSet = ETrue;
+	TUsbcScHdrEndpointRecord* endpointInf = NULL;
+
+	// check if alternate setting contains all IN endpoints
+	noEp = chunkHeader.GetNumberOfEndpoints(iAlternateSetting);
+
+	// for each used buffer. 
+	for (ep=1;ep<=noEp;ep++)
+		{
+		bufOff = chunkHeader.GetBuffer(iAlternateSetting,ep,endpointInf)->Offset();	
+	
+		if (endpointInf->Direction() & KUsbScHdrEpDirectionOut) 
+			{
+			inEndpointSet = EFalse;
+			if (aFlush)
+				r = Drain(bufOff); // we need to remove anythng in the way, and get it ready for reading.
+			else
+				r = Peek(bufOff); // we need to check it is ready for reading!
+			if (r) 
+				return r;
+			}
+		}
+
+
+	TInt altSeq = 0;
+	if (inEndpointSet)	// If all endpoints in the current alternate setting are IN endpoints
+		{	// go through all OUT buffers for alternate setting change
+		altSeq = FindNextAlternateSetting();
+		}
+
+	if((iNewAltSetting == iAlternateSetting) && (!inEndpointSet))
+			{
+			return KErrNotReady;
+			}
+
+	// Find/Set IN alternate setting
+	TInt ret = StartNextInAlternateSetting();
+	SUsbcScAlternateSetting* altrec = ((SUsbcScAlternateSetting*) (&ret));
+
+	if (altrec->iSequence==iAltSettingSeq+1)
+		{
+		if (altrec->iSetting!=iNewAltSetting)
+			return KErrGeneral;
+		iInAltSetting=iNewAltSetting;
+		}
+	else
+		{
+		if (inEndpointSet)
+			{
+			if ((altSeq == iAltSettingSeq) || (iAltSettingSeq == altrec->iSequence))
+				{
+				return KErrNotReady;
+				}
+			else if (altSeq != altrec->iSequence)
+				{
+				iInAltSetting=KErrEof;
+				}
+			}
+		iInAltSetting=KErrEof;
+		}
+
+	iAlternateSetting = iNewAltSetting;
+	iAltSettingSeq += 1;
+
+	return iAlternateSetting;
+	}
+
+
+EXPORT_C TInt RDevUsbcScClient::GetDataTransferChunk(RChunk* & aChunk)
+	{
+	aChunk = &iSharedChunk;
+	return KErrNone;
+	}
+
+// Constructor
+
+EXPORT_C TEndpointBuffer::TEndpointBuffer()
+		:iInState(ENotValid),
+		iOutState(ENotValid),
+		iEndpointNumber(-1),
+		iBufferNum(-1),
+		iBufferStartAddr(0),
+		iSize(0)
+	{
+	}
+
+// Internal, called by RDevUsbcScClient::OpenEndpoint.
+void TEndpointBuffer::Construct(RDevUsbcScClient* aClient, TUint8* aBaseAddr, const TUsbcScHdrEndpointRecord* aEpType , TInt aEndpointNumber,SUsbcScBufferHeader* aEndpointHdr)
+	{
+	iClient		= aClient;
+	iBaseAddr	= (TUint) aBaseAddr;
+	iInState 	= (((aEpType->Direction())&KUsbScHdrEpDirectionIn) ? EValid :  ENotValid);
+	iOutState	= (((aEpType->Direction())&KUsbScHdrEpDirectionOut) ? EValid :  ENotValid);
+	iBufferNum	= (aEpType->iBufferNo==(KUsbcScEndpointZero&0xFF))?KUsbcScEndpointZero:aEpType->iBufferNo;
+	iEndpointNumber = aEndpointNumber;
+
+	iEndpointHdr = aEndpointHdr;
+	};
+
+EXPORT_C TInt TEndpointBuffer::GetInBufferRange(TAny*& aStart, TUint& aSize)
+	{
+	if ((iInState))
+		{
+		return iInState;
+		}
+	aStart= iBufferStartAddr;
+	aSize= iSize;
+	return KErrNone;
+	};
+
+EXPORT_C TInt TEndpointBuffer::GetInBufferRange(TUint& aStart, TUint& aSize)
+	{
+	if ((iInState))
+		return iInState;
+	aStart=	(TUint) iBufferStartAddr - iBaseAddr;
+	aSize= iSize;
+	return KErrNone;
+	}
+
+
+EXPORT_C TInt TEndpointBuffer::GetBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength)
+	{
+	if (iOutState)
+		return iOutState;
+
+	TUsbcScTransferHeader* currentTransfer;
+	TInt r;
+	do // until we have a transfer with data.
+		{
+		iEndpointHdr->iTail = iEndpointHdr->iBilTail; 
+		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
+			{
+			r = iClient->ReadDataNotify(iBufferNum,aStatus);
+			if (r!=KErrCompletion)  // Data could arrive since we checked.
+				return r;
+			}
+		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
+
+		iEndpointHdr->iBilTail = currentTransfer->iNext;
+		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse;
+
+		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
+			{
+			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
+				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
+																	   //this variable will reflect the latest requested AlternateSetting
+
+
+			if (iEndpointNumber != KEp0Number)
+				{
+//				iOutState =  EEOF;	
+				return KErrEof;
+				}
+			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
+				{
+				return KErrAlternateSettingChanged;
+				}
+			}						
+
+		}
+	while ((currentTransfer->iBytes==0) && (!aZLP)); // ignore empty transfers
+
+	aBuffer = currentTransfer->iData.i;
+	aSize = currentTransfer->iBytes;	
+	return (currentTransfer->iFlags & KUsbcScStateChange)?KStateChange:KErrCompletion;	
+	}
+
+EXPORT_C TInt TEndpointBuffer::TakeBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength)
+	{
+	if (iOutState)
+		return iOutState;
+
+	TUsbcScTransferHeader* currentTransfer;
+	TInt r;
+	do // until we have a transfer with data.
+		{
+		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
+			{
+			r = iClient->ReadDataNotify(iBufferNum,aStatus);
+			if (r!=KErrCompletion)  // Data could arrive since we checked.
+				{
+				return r;
+				}
+			}
+
+		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
+		iEndpointHdr->iBilTail = currentTransfer->iNext;
+		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false 
+
+		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
+			{
+			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
+				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
+																	   //this variable will reflect the latest requested AlternateSetting
+			Expire(currentTransfer->iData.i);
+			if (iEndpointNumber != KEp0Number)
+				{
+//				iOutState = EEOF;
+				return KErrEof;
+				}
+			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
+				{
+				return KErrAlternateSettingChanged;
+				}
+
+			}	
+
+		if ((currentTransfer->iBytes==0) && (!aZLP)) // here , if empty transfer with alt setting information, Call expire 
+			{
+			Expire(currentTransfer->iData.i);
+			}
+		}
+	while ((currentTransfer->iBytes==0) && (!aZLP)); // ignore empty transfers
+
+	aBuffer = currentTransfer->iData.i;
+	aSize = currentTransfer->iBytes;
+	return (currentTransfer->iFlags & KUsbcScStateChange)?KStateChange:KErrCompletion;	
+	}
+
+EXPORT_C TInt TEndpointBuffer::Expire()
+	{
+	if (!(iOutState != ENotValid))
+		return iOutState;
+
+	if (iEndpointHdr->iTail != iEndpointHdr->iBilTail)
+		{
+		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iTail);
+		iEndpointHdr->iTail = currentTransfer->iNext;
+		}
+	return KErrNone;
+	}
+
+EXPORT_C TInt TEndpointBuffer::Expire(TAny* aAddress)
+	{
+	if (!(iOutState != ENotValid))
+		return iOutState;
+
+	TUint headerSize = sizeof(TUsbcScTransferHeader)-4; // TransferHeader includes 4 bytes of data.
+	TInt transferToExpire = ((TUint) aAddress - headerSize);
+	TInt offsetToExpire = transferToExpire - iBaseAddr; 
+
+	TInt currentTail = iEndpointHdr->iTail;
+
+	TInt prevTail = NULL;
+	TBool found = EFalse;
+	while (currentTail != iEndpointHdr->iBilTail)
+		{
+		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + currentTail);
+		if (currentTail == offsetToExpire)		// found which to expire
+			{
+			found = ETrue;
+			// This offset is to be expired
+			if (prevTail == NULL)
+				{
+				// The offset is at the list head
+				iEndpointHdr->iTail = currentTransfer->iNext;	
+				}
+			else
+				{
+				// The offset is NOT at the list head
+				// This leaves a GAP in the buffer which will not be filled unless the 'transfers' before 'currentTail' are expired
+				currentTail = currentTransfer->iNext;
+				TUsbcScTransferHeader* prevTransfer = (TUsbcScTransferHeader*) (iBaseAddr + prevTail);
+				prevTransfer->iNext = currentTail;
+				}
+			break;
+			}
+		prevTail = currentTail;
+		currentTail = currentTransfer->iNext;
+		}
+	return found ? KErrNone : KErrNotFound;
+	}
+
+	
+EXPORT_C TInt TEndpointBuffer::WriteBuffer(TAny* aBuffer,TUint aSize,TBool aZLP,TRequestStatus& aStatus)
+	{
+	if (iInState)
+		return iInState;
+
+	iClient->WriteData(iBufferNum, ((TUint)aBuffer - (TUint)iBaseAddr),aSize,aZLP,aStatus);
+	return KErrNone;
+	}
+
+
+EXPORT_C TInt TEndpointBuffer::WriteBuffer(TUint aOffset,TUint aSize,TBool aZLP,TRequestStatus& aStatus)
+	{
+	if (iInState)
+		return iInState;
+
+	iClient->WriteData(iBufferNum,aOffset,aSize,aZLP,aStatus);
+	return KErrNone;
+	}
+
+
+/**
+Closes the endpoint buffer
+@return			KErrNone if close is successfull
+*/	
+EXPORT_C TInt TEndpointBuffer::Close()
+	{
+	if ((iInState == ENotValid) && (iOutState == ENotValid))
+		return KErrNotFound;
+	if (iOutState != ENotValid)
+		{
+		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iTail);
+		//Incase of AlternateSetting changes and using TEndpointBuffer::GetBuffer, iTail is always one 'transfer' behind iBilTail
+		//Incase of AlternateSetting changes and using TEndpointBuffer::TakeBuffer, this shuold force the user to update iTail & only then closes the endpoint buffer
+		if (((TInt) currentTransfer->iNext != iEndpointHdr->iBilTail) && (iEndpointHdr->iTail != iEndpointHdr->iBilTail))
+			return KErrNotReady;
+		}
+	iClient->iEndpointStatus &= ~(1 << iEndpointNumber); //reset the bit corresponding to endpoint
+	iInState = ENotValid;
+	iOutState = ENotValid;
+	return KErrNone;
+	}
+
+
+  
+EXPORT_C TUsbcScChunkHeader::TUsbcScChunkHeader(RChunk aChunk)
+	{
+	iChunk = aChunk;
+	iBuffers     = (TUsbcScChunkBuffersHeader*)    (aChunk.Base()+((TUsbcScChunkHdrOffs*)iChunk.Base())->iBuffers);
+	iAltSettings = (TUsbcScChunkAltSettingHeader*) (aChunk.Base()+((TUsbcScChunkHdrOffs*)iChunk.Base())->iAltSettings);
+	}
+
+EXPORT_C TInt TUsbcScChunkHeader::GetNumberOfEndpoints(TInt aAltSetting)
+	{
+	if ((aAltSetting<0) || (aAltSetting>=iAltSettings->iNumOfAltSettings))
+		return KErrArgument;
+	return  *((TInt*) (iAltSettings->iAltTableOffset[aAltSetting] + (TInt) iChunk.Base()));
+	}
+
+
+EXPORT_C TUsbcScBufferRecord* TUsbcScChunkHeader::GetBuffer(TInt aAltSetting, TInt aEndpoint, TUsbcScHdrEndpointRecord*& aEndpointInf)
+	{
+	if ((aAltSetting<0) || (aAltSetting>=iAltSettings->iNumOfAltSettings))
+		return NULL;
+	TInt8* iEndpoint = (TInt8*) (iAltSettings->iAltTableOffset[aAltSetting] + (TInt) iChunk.Base());
+	if ((aEndpoint<=0) || (aEndpoint>*iEndpoint))
+		return NULL;
+	aEndpointInf = (TUsbcScHdrEndpointRecord*) &(iEndpoint[aEndpoint*iAltSettings->iEpRecordSize]);
+	return iBuffers->Buffers(aEndpointInf->iBufferNo);
+	}
+
+
+/* Debug functions */
+
+EXPORT_C void TEndpointBuffer::Dump()
+	{
+	RDebug::Printf("TEndpointBuffer::Dump iBufferStart: 0x%x, iSize: 0x%x, iEndpointNumber: 0x%x, iBufferNum: %d, iInState: 0x%x iOutState: 0x%x\n",
+							iBufferStartAddr,iSize,iEndpointNumber,iBufferNum,iInState,iOutState);
+	}
+