--- a/kernel/eka/drivers/usbcsc/usbcsc_bil.cpp Wed Jun 23 12:58:21 2010 +0100
+++ b/kernel/eka/drivers/usbcsc/usbcsc_bil.cpp Thu Jul 01 17:57:33 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -38,6 +38,31 @@
return r;
}
+// empty a endpoint buffer, this is called when device state enter undefined
+TInt RDevUsbcScClient::Empty(TUint aBufferOffset)
+{
+ TUint8* base = iSharedChunk.Base();
+ SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset + base);
+ TUint localTail = endpointHdr->iBilTail;
+ TUsbcScTransferHeader* currentTransfer;
+ TInt err=KErrNone;
+
+ while (ETrue)
+ {
+ if (localTail == (TUint) endpointHdr->iHead)
+ {
+ err = KErrNone;
+ break;
+ }
+ currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
+ localTail = currentTransfer->iNext;
+ } // end while
+ endpointHdr->iBilTail = localTail;
+ endpointHdr->iTail = localTail;
+ return err;
+}
+
+
EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk)
{
@@ -49,6 +74,35 @@
}
+EXPORT_C void RDevUsbcScClient::ResetAltSetting()
+ {
+ if (iAlternateSetting == 0)
+ return;
+ TUsbcScChunkHeader chunkHeader(iSharedChunk);
+
+ TInt ep;
+ TInt noEp;
+ TUint bufOff;
+ 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)
+ {
+ Empty(bufOff); // we need to remove anythng in the way, and get it ready for reading.
+ }
+ }
+
+ iAlternateSetting = 0;
+ }
+
+
EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI)
{
TUsbcScHdrEndpointRecord* endpointInf = NULL;
@@ -118,12 +172,14 @@
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;
+ TBool aZLP;
while (ETrue)
{
@@ -135,8 +191,13 @@
currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
if (currentTransfer->iAltSettingSeq == next)
- {
+ {
iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting
+ aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse;
+ if ((currentTransfer->iBytes==0) && (!aZLP)) // take empty packet which is for alternate setting change
+ {
+ localTail = currentTransfer->iNext;
+ }
break;
}
else
@@ -164,7 +225,7 @@
// if alternate setting has not changed
return KErrNotReady;
else
- {
+ {
iNewAltSetting=currentTransfer->iAltSetting;
return KErrNone;
}
@@ -405,6 +466,7 @@
TUsbcScTransferHeader* currentTransfer;
TInt r;
+ TInt aBilTail;
do // until we have a transfer with data.
{
iEndpointHdr->iTail = iEndpointHdr->iBilTail;
@@ -415,19 +477,22 @@
return r;
}
currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
-
+ aBilTail = 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
+ //this variable will reflect the latest requested AlternateSetting
+ }
if (iEndpointNumber != KEp0Number)
{
+ iEndpointHdr->iBilTail = aBilTail;
// iOutState = EEOF;
return KErrEof;
}
@@ -450,8 +515,10 @@
if (iOutState)
return iOutState;
+
TUsbcScTransferHeader* currentTransfer;
TInt r;
+ TInt aBilTail;
do // until we have a transfer with data.
{
if(iEndpointHdr->iBilTail == iEndpointHdr->iHead) //If no new data, create request
@@ -464,6 +531,7 @@
}
currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
+ aBilTail = iEndpointHdr->iBilTail;
iEndpointHdr->iBilTail = currentTransfer->iNext;
aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false
@@ -472,16 +540,19 @@
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)
{
+ iEndpointHdr->iBilTail = aBilTail;
// iOutState = EEOF;
return KErrEof;
}
else if ((currentTransfer->iBytes==0) && (!aZLP))
{
+ Expire(currentTransfer->iData.i);
return KErrAlternateSettingChanged;
}
+ Expire(currentTransfer->iData.i);
}
@@ -523,11 +594,12 @@
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)
@@ -547,7 +619,7 @@
}
prevTail = currentTail;
currentTail = currentTransfer->iNext;
- }
+ }
return found ? KErrNone : KErrNotFound;
}