usbdrv/peripheral/ldd/perilddsc/appifwrapper/src/usbcsc_bil.cpp
author hgs
Fri, 23 Jul 2010 15:54:47 +0800
changeset 33 089413cdde3c
child 59 bbdce6bffaad
permissions -rw-r--r--
201028_02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
089413cdde3c 201028_02
hgs
parents:
diff changeset
     2
// All rights reserved.
089413cdde3c 201028_02
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
089413cdde3c 201028_02
hgs
parents:
diff changeset
     4
// under the terms of the License "Eclipse Public License v1.0"
089413cdde3c 201028_02
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
089413cdde3c 201028_02
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
089413cdde3c 201028_02
hgs
parents:
diff changeset
     7
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
     8
// Initial Contributors:
089413cdde3c 201028_02
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    10
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    11
// Contributors:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    12
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    13
// Description:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    14
// e32\drivers\usbcsc\usbcsc_bil.cpp
089413cdde3c 201028_02
hgs
parents:
diff changeset
    15
// 
089413cdde3c 201028_02
hgs
parents:
diff changeset
    16
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    17
089413cdde3c 201028_02
hgs
parents:
diff changeset
    18
#include <e32std.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    19
#include <e32std_private.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    20
#include <usb/d32usbcsc.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    21
#include <e32debug.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    22
089413cdde3c 201028_02
hgs
parents:
diff changeset
    23
/** @file usbcsc_bil.cpp
089413cdde3c 201028_02
hgs
parents:
diff changeset
    24
089413cdde3c 201028_02
hgs
parents:
diff changeset
    25
	Buffer Interface Layer for USB Client Device driver stack, using shared chunks.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    26
089413cdde3c 201028_02
hgs
parents:
diff changeset
    27
	@internalTechnology
089413cdde3c 201028_02
hgs
parents:
diff changeset
    28
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
    29
089413cdde3c 201028_02
hgs
parents:
diff changeset
    30
EXPORT_C TInt RDevUsbcScClient::FinalizeInterface()
089413cdde3c 201028_02
hgs
parents:
diff changeset
    31
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
    32
	TInt errorOrhandle = DoControl(EControlRealizeInterface); //returns a error value or chunk handle
089413cdde3c 201028_02
hgs
parents:
diff changeset
    33
	TInt r = iSharedChunk.SetReturnedHandle(errorOrhandle);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    34
	iEndpointStatus = 0x00; //all endpoints are closed at the moment
089413cdde3c 201028_02
hgs
parents:
diff changeset
    35
	iAlternateSetting = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    36
	iNewAltSetting = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    37
	iAltSettingSeq = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    38
	return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    39
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
    40
089413cdde3c 201028_02
hgs
parents:
diff changeset
    41
089413cdde3c 201028_02
hgs
parents:
diff changeset
    42
EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    43
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
    44
	TInt errorOrhandle = DoControl(EControlRealizeInterface);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    45
	iSharedChunk.SetReturnedHandle(errorOrhandle);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    46
	iEndpointStatus = 0x00; //all endpoints are closed at the moment
089413cdde3c 201028_02
hgs
parents:
diff changeset
    47
	iAlternateSetting = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    48
	return aChunk->SetReturnedHandle(errorOrhandle);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    49
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
    50
089413cdde3c 201028_02
hgs
parents:
diff changeset
    51
089413cdde3c 201028_02
hgs
parents:
diff changeset
    52
EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    53
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
    54
	TUsbcScHdrEndpointRecord* endpointInf = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    55
	TBuf8<KUsbDescSize_Endpoint> descriptor;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    56
	TUsbcScChunkHeader chunkHeader(iSharedChunk);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    57
	//Do some validity checks
089413cdde3c 201028_02
hgs
parents:
diff changeset
    58
	if((aEpB.iInState != TEndpointBuffer::ENotValid) && (aEpB.iOutState != TEndpointBuffer::ENotValid))
089413cdde3c 201028_02
hgs
parents:
diff changeset
    59
		return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    60
089413cdde3c 201028_02
hgs
parents:
diff changeset
    61
	TInt nEndpoints = chunkHeader.GetNumberOfEndpoints(iAlternateSetting);	
089413cdde3c 201028_02
hgs
parents:
diff changeset
    62
	if ((aEpI < KEp0Number) && (aEpI > nEndpoints)) // Check endpoint number range 
089413cdde3c 201028_02
hgs
parents:
diff changeset
    63
		return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    64
089413cdde3c 201028_02
hgs
parents:
diff changeset
    65
	if(iEndpointStatus & (1 << aEpI)) // Check that endpoint isn't already opene
089413cdde3c 201028_02
hgs
parents:
diff changeset
    66
		return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    67
089413cdde3c 201028_02
hgs
parents:
diff changeset
    68
	if(aEpI == KEp0Number) //endpoint 0
089413cdde3c 201028_02
hgs
parents:
diff changeset
    69
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
    70
		TUsbcScHdrEndpointRecord ep0=  TUsbcScHdrEndpointRecord(KUsbcScEndpointZero, KUsbScHdrEpDirectionBiDir | KUsbScHdrEpTypeControl);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    71
		aEpB.Construct(this,iSharedChunk.Base(), &ep0 ,aEpI, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
    72
		(SUsbcScBufferHeader*) ((TUint)iSharedChunk.Base() + (chunkHeader.iBuffers)->Ep0Out()->Offset()));
089413cdde3c 201028_02
hgs
parents:
diff changeset
    73
089413cdde3c 201028_02
hgs
parents:
diff changeset
    74
		aEpB.iBufferStartAddr = (TUint8*) ((TUint)iSharedChunk.Base() + (chunkHeader.iBuffers)->Ep0In()->Offset());
089413cdde3c 201028_02
hgs
parents:
diff changeset
    75
		aEpB.iSize = chunkHeader.iBuffers->Ep0In()->Size();
089413cdde3c 201028_02
hgs
parents:
diff changeset
    76
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
    77
	else  // If normal endpoint (!ep0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    78
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
    79
		TUsbcScBufferRecord* buf = 	chunkHeader.GetBuffer(iAlternateSetting,aEpI,endpointInf);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    80
		if (!buf)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    81
			return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    82
		// Set up endpoint members
089413cdde3c 201028_02
hgs
parents:
diff changeset
    83
		aEpB.iBufferStartAddr = (TUint8*)  (buf->Offset() + (TUint)iSharedChunk.Base());
089413cdde3c 201028_02
hgs
parents:
diff changeset
    84
		aEpB.iSize = buf->Size();
089413cdde3c 201028_02
hgs
parents:
diff changeset
    85
		TInt r = GetEndpointDescriptor(iAlternateSetting, aEpI, descriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    86
		if(r != KErrNone) // We need this to be able to calculate alignment
089413cdde3c 201028_02
hgs
parents:
diff changeset
    87
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
    88
			return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    89
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
    90
089413cdde3c 201028_02
hgs
parents:
diff changeset
    91
		if (endpointInf->Direction()&KUsbScHdrEpDirectionIn)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    92
			{  							//in case of IN endpoints, first endpoint buffer location points to end offset
089413cdde3c 201028_02
hgs
parents:
diff changeset
    93
			aEpB.Construct(this,iSharedChunk.Base(),endpointInf,aEpI);
089413cdde3c 201028_02
hgs
parents:
diff changeset
    94
			if (iInAltSetting==KErrEof)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    95
			aEpB.iInState=TEndpointBuffer::EEOF;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    96
089413cdde3c 201028_02
hgs
parents:
diff changeset
    97
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
    98
		else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    99
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   100
			SUsbcScBufferHeader *endpointHdr = (SUsbcScBufferHeader *) aEpB.iBufferStartAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   101
			//In this case,SUsbcScBufferHeader points to full OUT endpoint header 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   102
			aEpB.Construct(this,iSharedChunk.Base(),endpointInf,aEpI, endpointHdr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   103
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   104
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   105
	iEndpointStatus |= (1 << aEpI);	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   106
089413cdde3c 201028_02
hgs
parents:
diff changeset
   107
#ifdef _DEBUG
089413cdde3c 201028_02
hgs
parents:
diff changeset
   108
	aEpB.Dump();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   109
	RDebug::Printf("iEndpointStatus: %x \n",iEndpointStatus);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   110
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   111
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   112
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   113
089413cdde3c 201028_02
hgs
parents:
diff changeset
   114
089413cdde3c 201028_02
hgs
parents:
diff changeset
   115
//Internal, used by RDevUsbcScClient::StartNextOutAlternateSetting(...)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   116
//This drains any old data from an OUT buffer, and gets it ready for reading an ep.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   117
//aBufferOffset - The offset, into the chunk, that the buffer in question, may be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   118
 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   119
TInt RDevUsbcScClient::Drain(TUint aBufferOffset)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   120
{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   121
	TUint8* base = iSharedChunk.Base();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   122
	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   123
	TUint localTail = endpointHdr->iBilTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   124
	TUsbcScTransferHeader* currentTransfer;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   125
	TUint16 next = (iAltSettingSeq+1)&0xFFFF;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   126
	TInt err=KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   127
089413cdde3c 201028_02
hgs
parents:
diff changeset
   128
	while (ETrue)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   129
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   130
		if (localTail == (TUint) endpointHdr->iHead)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   131
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   132
			err = KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   133
			break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   134
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   135
		currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   136
089413cdde3c 201028_02
hgs
parents:
diff changeset
   137
		if (currentTransfer->iAltSettingSeq == next)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   138
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   139
			iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   140
			break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   141
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   142
		else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   143
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   144
			localTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   145
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   146
		} // end while
089413cdde3c 201028_02
hgs
parents:
diff changeset
   147
	endpointHdr->iBilTail = localTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   148
	endpointHdr->iTail = localTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   149
	return err;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   150
}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   151
089413cdde3c 201028_02
hgs
parents:
diff changeset
   152
//Internal, used by RDevUsbcScClient::StartNextOutAlternateSetting(...)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   153
//This method checks that the OUT buffer is ready for reading an ep.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   154
//aBufferOffset - The offset, into the chunk, that the buffer in question, may be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   155
089413cdde3c 201028_02
hgs
parents:
diff changeset
   156
TInt RDevUsbcScClient::Peek(TUint aBufferOffset)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   157
{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   158
	TUint8* base = iSharedChunk.Base();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   159
	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   160
	TUint localTail = endpointHdr->iBilTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   161
	TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   162
089413cdde3c 201028_02
hgs
parents:
diff changeset
   163
	if ((localTail == (TUint)endpointHdr->iHead) || (currentTransfer->iAltSettingSeq != (iAltSettingSeq+1)&0xFFFF))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   164
		// if alternate setting has not changed
089413cdde3c 201028_02
hgs
parents:
diff changeset
   165
		return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   166
	else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   167
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   168
		iNewAltSetting=currentTransfer->iAltSetting;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   169
		return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   170
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   171
}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   172
089413cdde3c 201028_02
hgs
parents:
diff changeset
   173
//Internal, used by RDevUsbcScClient::StartNextOutAlternateSetting(...)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   174
//This method is called if an alternate setting change happens from a set of ONLY IN endpoints.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   175
//Used to find the least possible alternate setting it can return to the user, stored in iNewAltSetting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   176
//Returns the sequence number of the 'latest' alternate setting it can switch to
089413cdde3c 201028_02
hgs
parents:
diff changeset
   177
089413cdde3c 201028_02
hgs
parents:
diff changeset
   178
TInt RDevUsbcScClient::FindNextAlternateSetting()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   179
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   180
	TUsbcScChunkHeader chunkHeader(iSharedChunk);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   181
	TUsbcScHdrEndpointRecord* endpointInf = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   182
	TUint bufOff;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   183
	TInt altSet;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   184
	TInt ep;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   185
	TInt bufNum;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   186
089413cdde3c 201028_02
hgs
parents:
diff changeset
   187
	RArray <TInt> bufferOffset;	// Array to contain all OUT enpoint buffer offsets
089413cdde3c 201028_02
hgs
parents:
diff changeset
   188
	// Populate array
089413cdde3c 201028_02
hgs
parents:
diff changeset
   189
	for (altSet = 0; altSet < chunkHeader.iAltSettings->iNumOfAltSettings ; altSet++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   190
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   191
		TInt numEndpoints = chunkHeader.GetNumberOfEndpoints(altSet);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   192
		for (ep =  1; ep  <= numEndpoints ; ep ++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   193
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   194
			bufOff = chunkHeader.GetBuffer(altSet, ep, endpointInf)->Offset();	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   195
			if ((endpointInf->Direction() & KUsbScHdrEpDirectionOut) && (bufferOffset.Find(bufOff) == KErrNotFound))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   196
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   197
				bufferOffset.Append(bufOff);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   198
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   199
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   200
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   201
089413cdde3c 201028_02
hgs
parents:
diff changeset
   202
	TInt err = KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   203
	TUint16 altSetSeqDelta = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   204
	TUint16 currentaltSetSeqDelta = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   205
	TBool noNewSettingFound = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   206
	TInt altSetSeq = iAltSettingSeq;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   207
	TUint8* base = iSharedChunk.Base();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   208
089413cdde3c 201028_02
hgs
parents:
diff changeset
   209
	for (bufNum = 0; bufNum < bufferOffset.Count(); bufNum++) // Scan all OUT buffers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   210
		{	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   211
		SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (bufferOffset[bufNum] + base);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   212
		TUint localTail = endpointHdr->iBilTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   213
		TUsbcScTransferHeader* currentTransfer;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   214
		TUint16 next = (iAltSettingSeq+1)&0xFFFF;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   215
		
089413cdde3c 201028_02
hgs
parents:
diff changeset
   216
		while (ETrue)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   217
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   218
			if (localTail == (TUint) endpointHdr->iHead)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   219
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   220
				break;	// This OUT endpoint buffer has no data, proceed checking with other OUT endpoint buffers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   221
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   222
			currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   223
089413cdde3c 201028_02
hgs
parents:
diff changeset
   224
			if (currentTransfer->iAltSettingSeq != iAltSettingSeq) 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   225
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   226
				if (currentTransfer->iAltSettingSeq == next)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   227
					{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   228
					altSetSeq = currentTransfer->iAltSettingSeq;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   229
					iNewAltSetting = currentTransfer->iAltSetting; // record new alt setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   230
					err = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   231
					break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   232
					}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   233
089413cdde3c 201028_02
hgs
parents:
diff changeset
   234
				if (noNewSettingFound)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   235
					{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   236
					altSetSeqDelta = Abs(iAltSettingSeq - currentTransfer->iAltSettingSeq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   237
					altSetSeq = currentTransfer->iAltSettingSeq;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   238
					iNewAltSetting = currentTransfer->iAltSetting; // record new alt setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   239
					noNewSettingFound = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   240
					}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   241
				else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   242
					{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   243
					currentaltSetSeqDelta = Abs(iAltSettingSeq - currentTransfer->iAltSettingSeq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   244
					if (currentaltSetSeqDelta < altSetSeqDelta)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   245
						{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   246
						altSetSeqDelta = currentaltSetSeqDelta;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   247
						altSetSeq = currentTransfer->iAltSettingSeq;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   248
						iNewAltSetting = currentTransfer->iAltSetting;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   249
						}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   250
					}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   251
				break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   252
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   253
			
089413cdde3c 201028_02
hgs
parents:
diff changeset
   254
			localTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   255
			} // end while
089413cdde3c 201028_02
hgs
parents:
diff changeset
   256
089413cdde3c 201028_02
hgs
parents:
diff changeset
   257
		if (!err) // Found an alt set sequence one after iAltSettingSeq
089413cdde3c 201028_02
hgs
parents:
diff changeset
   258
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   259
			break; // found 'the next' alternate setting, exit for loop
089413cdde3c 201028_02
hgs
parents:
diff changeset
   260
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   261
		
089413cdde3c 201028_02
hgs
parents:
diff changeset
   262
		}// for loop
089413cdde3c 201028_02
hgs
parents:
diff changeset
   263
089413cdde3c 201028_02
hgs
parents:
diff changeset
   264
	return altSetSeq;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   265
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   266
089413cdde3c 201028_02
hgs
parents:
diff changeset
   267
EXPORT_C TInt RDevUsbcScClient::StartNextOutAlternateSetting(TBool aFlush)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   268
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   269
	TUsbcScChunkHeader chunkHeader(iSharedChunk);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   270
	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   271
	//if endpoints are still open, return KErrInUse 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   272
	if((iEndpointStatus&~1) != 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   273
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   274
		return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   275
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   276
089413cdde3c 201028_02
hgs
parents:
diff changeset
   277
	TInt r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   278
	TInt ep;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   279
	TInt noEp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   280
	TUint bufOff;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   281
	TBool inEndpointSet = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   282
	TUsbcScHdrEndpointRecord* endpointInf = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   283
089413cdde3c 201028_02
hgs
parents:
diff changeset
   284
	// check if alternate setting contains all IN endpoints
089413cdde3c 201028_02
hgs
parents:
diff changeset
   285
	noEp = chunkHeader.GetNumberOfEndpoints(iAlternateSetting);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   286
089413cdde3c 201028_02
hgs
parents:
diff changeset
   287
	// for each used buffer. 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   288
	for (ep=1;ep<=noEp;ep++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   289
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   290
		bufOff = chunkHeader.GetBuffer(iAlternateSetting,ep,endpointInf)->Offset();	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   291
	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   292
		if (endpointInf->Direction() & KUsbScHdrEpDirectionOut) 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   293
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   294
			inEndpointSet = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   295
			if (aFlush)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   296
				r = Drain(bufOff); // we need to remove anythng in the way, and get it ready for reading.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   297
			else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   298
				r = Peek(bufOff); // we need to check it is ready for reading!
089413cdde3c 201028_02
hgs
parents:
diff changeset
   299
			if (r) 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   300
				return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   301
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   302
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   303
089413cdde3c 201028_02
hgs
parents:
diff changeset
   304
089413cdde3c 201028_02
hgs
parents:
diff changeset
   305
	TInt altSeq = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   306
	if (inEndpointSet)	// If all endpoints in the current alternate setting are IN endpoints
089413cdde3c 201028_02
hgs
parents:
diff changeset
   307
		{	// go through all OUT buffers for alternate setting change
089413cdde3c 201028_02
hgs
parents:
diff changeset
   308
		altSeq = FindNextAlternateSetting();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   309
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   310
089413cdde3c 201028_02
hgs
parents:
diff changeset
   311
	if((iNewAltSetting == iAlternateSetting) && (!inEndpointSet))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   312
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   313
			return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   314
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   315
089413cdde3c 201028_02
hgs
parents:
diff changeset
   316
	// Find/Set IN alternate setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   317
	TInt ret = StartNextInAlternateSetting();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   318
	SUsbcScAlternateSetting* altrec = ((SUsbcScAlternateSetting*) (&ret));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   319
089413cdde3c 201028_02
hgs
parents:
diff changeset
   320
	if (altrec->iSequence==iAltSettingSeq+1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   321
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   322
		if (altrec->iSetting!=iNewAltSetting)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   323
			return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   324
		iInAltSetting=iNewAltSetting;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   325
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   326
	else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   327
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   328
		if (inEndpointSet)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   329
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   330
			if ((altSeq == iAltSettingSeq) || (iAltSettingSeq == altrec->iSequence))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   331
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   332
				return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   333
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   334
			else if (altSeq != altrec->iSequence)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   335
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   336
				iInAltSetting=KErrEof;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   337
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   338
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   339
		iInAltSetting=KErrEof;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   340
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   341
089413cdde3c 201028_02
hgs
parents:
diff changeset
   342
	iAlternateSetting = iNewAltSetting;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   343
	iAltSettingSeq += 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   344
089413cdde3c 201028_02
hgs
parents:
diff changeset
   345
	return iAlternateSetting;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   346
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   347
089413cdde3c 201028_02
hgs
parents:
diff changeset
   348
089413cdde3c 201028_02
hgs
parents:
diff changeset
   349
EXPORT_C TInt RDevUsbcScClient::GetDataTransferChunk(RChunk* & aChunk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   350
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   351
	aChunk = &iSharedChunk;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   352
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   353
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   354
089413cdde3c 201028_02
hgs
parents:
diff changeset
   355
// Constructor
089413cdde3c 201028_02
hgs
parents:
diff changeset
   356
089413cdde3c 201028_02
hgs
parents:
diff changeset
   357
EXPORT_C TEndpointBuffer::TEndpointBuffer()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   358
		:iInState(ENotValid),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   359
		iOutState(ENotValid),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   360
		iEndpointNumber(-1),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   361
		iBufferNum(-1),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   362
		iBufferStartAddr(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   363
		iSize(0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   364
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   365
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   366
089413cdde3c 201028_02
hgs
parents:
diff changeset
   367
// Internal, called by RDevUsbcScClient::OpenEndpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   368
void TEndpointBuffer::Construct(RDevUsbcScClient* aClient, TUint8* aBaseAddr, const TUsbcScHdrEndpointRecord* aEpType , TInt aEndpointNumber,SUsbcScBufferHeader* aEndpointHdr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   369
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   370
	iClient		= aClient;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   371
	iBaseAddr	= (TUint) aBaseAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   372
	iInState 	= (((aEpType->Direction())&KUsbScHdrEpDirectionIn) ? EValid :  ENotValid);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   373
	iOutState	= (((aEpType->Direction())&KUsbScHdrEpDirectionOut) ? EValid :  ENotValid);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   374
	iBufferNum	= (aEpType->iBufferNo==(KUsbcScEndpointZero&0xFF))?KUsbcScEndpointZero:aEpType->iBufferNo;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   375
	iEndpointNumber = aEndpointNumber;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   376
089413cdde3c 201028_02
hgs
parents:
diff changeset
   377
	iEndpointHdr = aEndpointHdr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   378
	};
089413cdde3c 201028_02
hgs
parents:
diff changeset
   379
089413cdde3c 201028_02
hgs
parents:
diff changeset
   380
EXPORT_C TInt TEndpointBuffer::GetInBufferRange(TAny*& aStart, TUint& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   381
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   382
	if ((iInState))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   383
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   384
		return iInState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   385
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   386
	aStart= iBufferStartAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   387
	aSize= iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   388
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   389
	};
089413cdde3c 201028_02
hgs
parents:
diff changeset
   390
089413cdde3c 201028_02
hgs
parents:
diff changeset
   391
EXPORT_C TInt TEndpointBuffer::GetInBufferRange(TUint& aStart, TUint& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   392
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   393
	if ((iInState))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   394
		return iInState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   395
	aStart=	(TUint) iBufferStartAddr - iBaseAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   396
	aSize= iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   397
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   398
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   399
089413cdde3c 201028_02
hgs
parents:
diff changeset
   400
089413cdde3c 201028_02
hgs
parents:
diff changeset
   401
EXPORT_C TInt TEndpointBuffer::GetBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   402
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   403
	if (iOutState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   404
		return iOutState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   405
089413cdde3c 201028_02
hgs
parents:
diff changeset
   406
	TUsbcScTransferHeader* currentTransfer;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   407
	TInt r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   408
	do // until we have a transfer with data.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   409
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   410
		iEndpointHdr->iTail = iEndpointHdr->iBilTail; 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   411
		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
089413cdde3c 201028_02
hgs
parents:
diff changeset
   412
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   413
			r = iClient->ReadDataNotify(iBufferNum,aStatus);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   414
			if (r!=KErrCompletion)  // Data could arrive since we checked.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   415
				return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   416
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   417
		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   418
089413cdde3c 201028_02
hgs
parents:
diff changeset
   419
		iEndpointHdr->iBilTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   420
		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   421
089413cdde3c 201028_02
hgs
parents:
diff changeset
   422
		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
089413cdde3c 201028_02
hgs
parents:
diff changeset
   423
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   424
			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
089413cdde3c 201028_02
hgs
parents:
diff changeset
   425
				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
089413cdde3c 201028_02
hgs
parents:
diff changeset
   426
																	   //this variable will reflect the latest requested AlternateSetting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   427
089413cdde3c 201028_02
hgs
parents:
diff changeset
   428
089413cdde3c 201028_02
hgs
parents:
diff changeset
   429
			if (iEndpointNumber != KEp0Number)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   430
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   431
//				iOutState =  EEOF;	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   432
				return KErrEof;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   433
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   434
			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   435
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   436
				return KErrAlternateSettingChanged;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   437
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   438
			}						
089413cdde3c 201028_02
hgs
parents:
diff changeset
   439
089413cdde3c 201028_02
hgs
parents:
diff changeset
   440
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   441
	while ((currentTransfer->iBytes==0) && (!aZLP)); // ignore empty transfers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   442
089413cdde3c 201028_02
hgs
parents:
diff changeset
   443
	aBuffer = currentTransfer->iData.i;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   444
	aSize = currentTransfer->iBytes;	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   445
	return (currentTransfer->iFlags & KUsbcScStateChange)?KStateChange:KErrCompletion;	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   446
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   447
089413cdde3c 201028_02
hgs
parents:
diff changeset
   448
EXPORT_C TInt TEndpointBuffer::TakeBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   449
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   450
	if (iOutState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   451
		return iOutState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   452
089413cdde3c 201028_02
hgs
parents:
diff changeset
   453
	TUsbcScTransferHeader* currentTransfer;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   454
	TInt r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   455
	do // until we have a transfer with data.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   456
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   457
		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
089413cdde3c 201028_02
hgs
parents:
diff changeset
   458
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   459
			r = iClient->ReadDataNotify(iBufferNum,aStatus);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   460
			if (r!=KErrCompletion)  // Data could arrive since we checked.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   461
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   462
				return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   463
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   464
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   465
089413cdde3c 201028_02
hgs
parents:
diff changeset
   466
		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   467
		iEndpointHdr->iBilTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   468
		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   469
089413cdde3c 201028_02
hgs
parents:
diff changeset
   470
		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
089413cdde3c 201028_02
hgs
parents:
diff changeset
   471
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   472
			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
089413cdde3c 201028_02
hgs
parents:
diff changeset
   473
				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
089413cdde3c 201028_02
hgs
parents:
diff changeset
   474
																	   //this variable will reflect the latest requested AlternateSetting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   475
			Expire(currentTransfer->iData.i);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   476
			if (iEndpointNumber != KEp0Number)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   477
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   478
//				iOutState = EEOF;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   479
				return KErrEof;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   480
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   481
			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   482
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   483
				return KErrAlternateSettingChanged;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   484
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   485
089413cdde3c 201028_02
hgs
parents:
diff changeset
   486
			}	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   487
089413cdde3c 201028_02
hgs
parents:
diff changeset
   488
		if ((currentTransfer->iBytes==0) && (!aZLP)) // here , if empty transfer with alt setting information, Call expire 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   489
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   490
			Expire(currentTransfer->iData.i);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   491
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   492
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   493
	while ((currentTransfer->iBytes==0) && (!aZLP)); // ignore empty transfers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   494
089413cdde3c 201028_02
hgs
parents:
diff changeset
   495
	aBuffer = currentTransfer->iData.i;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   496
	aSize = currentTransfer->iBytes;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   497
	return (currentTransfer->iFlags & KUsbcScStateChange)?KStateChange:KErrCompletion;	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   498
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   499
089413cdde3c 201028_02
hgs
parents:
diff changeset
   500
EXPORT_C TInt TEndpointBuffer::Expire()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   501
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   502
	if (!(iOutState != ENotValid))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   503
		return iOutState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   504
089413cdde3c 201028_02
hgs
parents:
diff changeset
   505
	if (iEndpointHdr->iTail != iEndpointHdr->iBilTail)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   506
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   507
		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   508
		iEndpointHdr->iTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   509
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   510
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   511
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   512
089413cdde3c 201028_02
hgs
parents:
diff changeset
   513
EXPORT_C TInt TEndpointBuffer::Expire(TAny* aAddress)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   514
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   515
	if (!(iOutState != ENotValid))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   516
		return iOutState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   517
089413cdde3c 201028_02
hgs
parents:
diff changeset
   518
	TUint headerSize = sizeof(TUsbcScTransferHeader)-4; // TransferHeader includes 4 bytes of data.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   519
	TInt transferToExpire = ((TUint) aAddress - headerSize);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   520
	TInt offsetToExpire = transferToExpire - iBaseAddr; 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   521
089413cdde3c 201028_02
hgs
parents:
diff changeset
   522
	TInt currentTail = iEndpointHdr->iTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   523
089413cdde3c 201028_02
hgs
parents:
diff changeset
   524
	TInt prevTail = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   525
	TBool found = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   526
	while (currentTail != iEndpointHdr->iBilTail)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   527
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   528
		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + currentTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   529
		if (currentTail == offsetToExpire)		// found which to expire
089413cdde3c 201028_02
hgs
parents:
diff changeset
   530
			{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   531
			found = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   532
			// This offset is to be expired
089413cdde3c 201028_02
hgs
parents:
diff changeset
   533
			if (prevTail == NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   534
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   535
				// The offset is at the list head
089413cdde3c 201028_02
hgs
parents:
diff changeset
   536
				iEndpointHdr->iTail = currentTransfer->iNext;	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   537
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   538
			else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   539
				{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   540
				// The offset is NOT at the list head
089413cdde3c 201028_02
hgs
parents:
diff changeset
   541
				// This leaves a GAP in the buffer which will not be filled unless the 'transfers' before 'currentTail' are expired
089413cdde3c 201028_02
hgs
parents:
diff changeset
   542
				currentTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   543
				TUsbcScTransferHeader* prevTransfer = (TUsbcScTransferHeader*) (iBaseAddr + prevTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   544
				prevTransfer->iNext = currentTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   545
				}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   546
			break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   547
			}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   548
		prevTail = currentTail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   549
		currentTail = currentTransfer->iNext;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   550
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   551
	return found ? KErrNone : KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   552
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   553
089413cdde3c 201028_02
hgs
parents:
diff changeset
   554
	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   555
EXPORT_C TInt TEndpointBuffer::WriteBuffer(TAny* aBuffer,TUint aSize,TBool aZLP,TRequestStatus& aStatus)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   556
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   557
	if (iInState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   558
		return iInState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   559
089413cdde3c 201028_02
hgs
parents:
diff changeset
   560
	iClient->WriteData(iBufferNum, ((TUint)aBuffer - (TUint)iBaseAddr),aSize,aZLP,aStatus);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   561
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   562
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   563
089413cdde3c 201028_02
hgs
parents:
diff changeset
   564
089413cdde3c 201028_02
hgs
parents:
diff changeset
   565
EXPORT_C TInt TEndpointBuffer::WriteBuffer(TUint aOffset,TUint aSize,TBool aZLP,TRequestStatus& aStatus)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   566
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   567
	if (iInState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   568
		return iInState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   569
089413cdde3c 201028_02
hgs
parents:
diff changeset
   570
	iClient->WriteData(iBufferNum,aOffset,aSize,aZLP,aStatus);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   571
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   572
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   573
089413cdde3c 201028_02
hgs
parents:
diff changeset
   574
089413cdde3c 201028_02
hgs
parents:
diff changeset
   575
/**
089413cdde3c 201028_02
hgs
parents:
diff changeset
   576
Closes the endpoint buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   577
@return			KErrNone if close is successfull
089413cdde3c 201028_02
hgs
parents:
diff changeset
   578
*/	
089413cdde3c 201028_02
hgs
parents:
diff changeset
   579
EXPORT_C TInt TEndpointBuffer::Close()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   580
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   581
	if ((iInState == ENotValid) && (iOutState == ENotValid))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   582
		return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   583
	if (iOutState != ENotValid)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   584
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   585
		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iTail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   586
		//Incase of AlternateSetting changes and using TEndpointBuffer::GetBuffer, iTail is always one 'transfer' behind iBilTail
089413cdde3c 201028_02
hgs
parents:
diff changeset
   587
		//Incase of AlternateSetting changes and using TEndpointBuffer::TakeBuffer, this shuold force the user to update iTail & only then closes the endpoint buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   588
		if (((TInt) currentTransfer->iNext != iEndpointHdr->iBilTail) && (iEndpointHdr->iTail != iEndpointHdr->iBilTail))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   589
			return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   590
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   591
	iClient->iEndpointStatus &= ~(1 << iEndpointNumber); //reset the bit corresponding to endpoint
089413cdde3c 201028_02
hgs
parents:
diff changeset
   592
	iInState = ENotValid;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   593
	iOutState = ENotValid;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   594
	return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   595
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   596
089413cdde3c 201028_02
hgs
parents:
diff changeset
   597
089413cdde3c 201028_02
hgs
parents:
diff changeset
   598
  
089413cdde3c 201028_02
hgs
parents:
diff changeset
   599
EXPORT_C TUsbcScChunkHeader::TUsbcScChunkHeader(RChunk aChunk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   600
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   601
	iChunk = aChunk;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   602
	iBuffers     = (TUsbcScChunkBuffersHeader*)    (aChunk.Base()+((TUsbcScChunkHdrOffs*)iChunk.Base())->iBuffers);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   603
	iAltSettings = (TUsbcScChunkAltSettingHeader*) (aChunk.Base()+((TUsbcScChunkHdrOffs*)iChunk.Base())->iAltSettings);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   604
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   605
089413cdde3c 201028_02
hgs
parents:
diff changeset
   606
EXPORT_C TInt TUsbcScChunkHeader::GetNumberOfEndpoints(TInt aAltSetting)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   607
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   608
	if ((aAltSetting<0) || (aAltSetting>=iAltSettings->iNumOfAltSettings))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   609
		return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   610
	return  *((TInt*) (iAltSettings->iAltTableOffset[aAltSetting] + (TInt) iChunk.Base()));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   611
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   612
089413cdde3c 201028_02
hgs
parents:
diff changeset
   613
089413cdde3c 201028_02
hgs
parents:
diff changeset
   614
EXPORT_C TUsbcScBufferRecord* TUsbcScChunkHeader::GetBuffer(TInt aAltSetting, TInt aEndpoint, TUsbcScHdrEndpointRecord*& aEndpointInf)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   615
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   616
	if ((aAltSetting<0) || (aAltSetting>=iAltSettings->iNumOfAltSettings))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   617
		return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   618
	TInt8* iEndpoint = (TInt8*) (iAltSettings->iAltTableOffset[aAltSetting] + (TInt) iChunk.Base());
089413cdde3c 201028_02
hgs
parents:
diff changeset
   619
	if ((aEndpoint<=0) || (aEndpoint>*iEndpoint))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   620
		return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   621
	aEndpointInf = (TUsbcScHdrEndpointRecord*) &(iEndpoint[aEndpoint*iAltSettings->iEpRecordSize]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   622
	return iBuffers->Buffers(aEndpointInf->iBufferNo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   623
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   624
089413cdde3c 201028_02
hgs
parents:
diff changeset
   625
089413cdde3c 201028_02
hgs
parents:
diff changeset
   626
/* Debug functions */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   627
089413cdde3c 201028_02
hgs
parents:
diff changeset
   628
EXPORT_C void TEndpointBuffer::Dump()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   629
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
   630
	RDebug::Printf("TEndpointBuffer::Dump iBufferStart: 0x%x, iSize: 0x%x, iEndpointNumber: 0x%x, iBufferNum: %d, iInState: 0x%x iOutState: 0x%x\n",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   631
							iBufferStartAddr,iSize,iEndpointNumber,iBufferNum,iInState,iOutState);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   632
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
   633