kernel/eka/drivers/usbcsc/usbcsc_bil.cpp
changeset 247 d8d70de2bd36
parent 0 a41df078684a
child 253 d37db4dcc88d
equal deleted inserted replaced
201:43365a9b78a3 247:d8d70de2bd36
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    36 	iNewAltSetting = 0;
    36 	iNewAltSetting = 0;
    37 	iAltSettingSeq = 0;
    37 	iAltSettingSeq = 0;
    38 	return r;
    38 	return r;
    39 	}
    39 	}
    40 
    40 
       
    41 // empty a endpoint buffer, this is called when device state enter undefined
       
    42 TInt RDevUsbcScClient::Empty(TUint aBufferOffset)
       
    43 {
       
    44 	TUint8* base = iSharedChunk.Base();
       
    45 	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset + base);
       
    46 	TUint localTail = endpointHdr->iBilTail;
       
    47 	TUsbcScTransferHeader* currentTransfer;
       
    48 	TInt err=KErrNone;
       
    49 
       
    50 	while (ETrue)
       
    51 		{
       
    52 		if (localTail == (TUint) endpointHdr->iHead)
       
    53 			{
       
    54 			err = KErrNone;			
       
    55 			break;
       
    56 			}
       
    57 		currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
       
    58 		localTail = currentTransfer->iNext;
       
    59 		} // end while
       
    60 	endpointHdr->iBilTail = localTail;
       
    61 	endpointHdr->iTail = localTail;
       
    62 	return err;
       
    63 }
       
    64 
       
    65 
    41 
    66 
    42 EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk)
    67 EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk)
    43 	{
    68 	{
    44 	TInt errorOrhandle = DoControl(EControlRealizeInterface);
    69 	TInt errorOrhandle = DoControl(EControlRealizeInterface);
    45 	iSharedChunk.SetReturnedHandle(errorOrhandle);
    70 	iSharedChunk.SetReturnedHandle(errorOrhandle);
    46 	iEndpointStatus = 0x00; //all endpoints are closed at the moment
    71 	iEndpointStatus = 0x00; //all endpoints are closed at the moment
    47 	iAlternateSetting = 0;
    72 	iAlternateSetting = 0;
    48 	return aChunk->SetReturnedHandle(errorOrhandle);
    73 	return aChunk->SetReturnedHandle(errorOrhandle);
       
    74 	}
       
    75 
       
    76 
       
    77 EXPORT_C void RDevUsbcScClient::ResetAltSetting()
       
    78 	{
       
    79 	if (iAlternateSetting == 0)
       
    80 		return;
       
    81 	TUsbcScChunkHeader chunkHeader(iSharedChunk);
       
    82 	
       
    83 	TInt ep;
       
    84 	TInt noEp;
       
    85 	TUint bufOff;
       
    86 	TUsbcScHdrEndpointRecord* endpointInf = NULL;
       
    87 
       
    88 	// check if alternate setting contains all IN endpoints
       
    89 	noEp = chunkHeader.GetNumberOfEndpoints(iAlternateSetting);
       
    90 
       
    91 	// for each used buffer. 
       
    92 	for (ep=1;ep<=noEp;ep++)
       
    93 		{
       
    94 		bufOff = chunkHeader.GetBuffer(iAlternateSetting,ep,endpointInf)->Offset();	
       
    95 	
       
    96 		if (endpointInf->Direction() & KUsbScHdrEpDirectionOut) 
       
    97 			{
       
    98 			Empty(bufOff); // we need to remove anythng in the way, and get it ready for reading.
       
    99 			}
       
   100 		}
       
   101 	
       
   102 	iAlternateSetting = 0;
    49 	}
   103 	}
    50 
   104 
    51 
   105 
    52 EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI)
   106 EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI)
    53 	{
   107 	{
   116 //This drains any old data from an OUT buffer, and gets it ready for reading an ep.
   170 //This drains any old data from an OUT buffer, and gets it ready for reading an ep.
   117 //aBufferOffset - The offset, into the chunk, that the buffer in question, may be found.
   171 //aBufferOffset - The offset, into the chunk, that the buffer in question, may be found.
   118  
   172  
   119 TInt RDevUsbcScClient::Drain(TUint aBufferOffset)
   173 TInt RDevUsbcScClient::Drain(TUint aBufferOffset)
   120 {
   174 {
       
   175 
   121 	TUint8* base = iSharedChunk.Base();
   176 	TUint8* base = iSharedChunk.Base();
   122 	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base);
   177 	SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base);
   123 	TUint localTail = endpointHdr->iBilTail;
   178 	TUint localTail = endpointHdr->iBilTail;
   124 	TUsbcScTransferHeader* currentTransfer;
   179 	TUsbcScTransferHeader* currentTransfer;
   125 	TUint16 next = (iAltSettingSeq+1)&0xFFFF;
   180 	TUint16 next = (iAltSettingSeq+1)&0xFFFF;
   126 	TInt err=KErrNone;
   181 	TInt err=KErrNone;
       
   182 	TBool aZLP;
   127 
   183 
   128 	while (ETrue)
   184 	while (ETrue)
   129 		{
   185 		{
   130 		if (localTail == (TUint) endpointHdr->iHead)
   186 		if (localTail == (TUint) endpointHdr->iHead)
   131 			{
   187 			{
   133 			break;
   189 			break;
   134 			}
   190 			}
   135 		currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
   191 		currentTransfer = (TUsbcScTransferHeader*) (base + localTail);
   136 
   192 
   137 		if (currentTransfer->iAltSettingSeq == next)
   193 		if (currentTransfer->iAltSettingSeq == next)
   138 			{
   194 			{			
   139 			iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting
   195 			iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting
       
   196 			aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse;
       
   197 			if ((currentTransfer->iBytes==0) && (!aZLP)) // take empty packet which is for alternate setting change
       
   198 				{
       
   199 				localTail = currentTransfer->iNext;
       
   200 				}
   140 			break;
   201 			break;
   141 			}
   202 			}
   142 		else
   203 		else
   143 			{
   204 			{
   144 			localTail = currentTransfer->iNext;
   205 			localTail = currentTransfer->iNext;
   162 
   223 
   163 	if ((localTail == (TUint)endpointHdr->iHead) || (currentTransfer->iAltSettingSeq != (iAltSettingSeq+1)&0xFFFF))
   224 	if ((localTail == (TUint)endpointHdr->iHead) || (currentTransfer->iAltSettingSeq != (iAltSettingSeq+1)&0xFFFF))
   164 		// if alternate setting has not changed
   225 		// if alternate setting has not changed
   165 		return KErrNotReady;
   226 		return KErrNotReady;
   166 	else
   227 	else
   167 		{
   228 		{		
   168 		iNewAltSetting=currentTransfer->iAltSetting;
   229 		iNewAltSetting=currentTransfer->iAltSetting;
   169 		return KErrNone;
   230 		return KErrNone;
   170 		}
   231 		}
   171 }
   232 }
   172 
   233 
   403 	if (iOutState)
   464 	if (iOutState)
   404 		return iOutState;
   465 		return iOutState;
   405 
   466 
   406 	TUsbcScTransferHeader* currentTransfer;
   467 	TUsbcScTransferHeader* currentTransfer;
   407 	TInt r;
   468 	TInt r;
       
   469 	TInt aBilTail;
   408 	do // until we have a transfer with data.
   470 	do // until we have a transfer with data.
   409 		{
   471 		{
   410 		iEndpointHdr->iTail = iEndpointHdr->iBilTail; 
   472 		iEndpointHdr->iTail = iEndpointHdr->iBilTail; 
   411 		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
   473 		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
   412 			{
   474 			{
   413 			r = iClient->ReadDataNotify(iBufferNum,aStatus);
   475 			r = iClient->ReadDataNotify(iBufferNum,aStatus);
   414 			if (r!=KErrCompletion)  // Data could arrive since we checked.
   476 			if (r!=KErrCompletion)  // Data could arrive since we checked.
   415 				return r;
   477 				return r;
   416 			}
   478 			}
   417 		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
   479 		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
   418 
   480 		aBilTail = iEndpointHdr->iBilTail;
   419 		iEndpointHdr->iBilTail = currentTransfer->iNext;
   481 		iEndpointHdr->iBilTail = currentTransfer->iNext;
   420 		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse;
   482 		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse;
       
   483 
       
   484 		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
       
   485 			{
       
   486 			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
       
   487 				{
       
   488 				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
       
   489 																	   //this variable will reflect the latest requested AlternateSetting		
       
   490 				}													   
       
   491 
       
   492 
       
   493 			if (iEndpointNumber != KEp0Number)
       
   494 				{
       
   495 				iEndpointHdr->iBilTail = aBilTail;
       
   496 //				iOutState =  EEOF;	
       
   497 				return KErrEof;
       
   498 				}
       
   499 			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
       
   500 				{
       
   501 				return KErrAlternateSettingChanged;
       
   502 				}
       
   503 			}						
       
   504 
       
   505 		}
       
   506 	while ((currentTransfer->iBytes==0) && (!aZLP)); // ignore empty transfers
       
   507 
       
   508 	aBuffer = currentTransfer->iData.i;
       
   509 	aSize = currentTransfer->iBytes;	
       
   510 	return (currentTransfer->iFlags & KUsbcScStateChange)?KStateChange:KErrCompletion;	
       
   511 	}
       
   512 
       
   513 EXPORT_C TInt TEndpointBuffer::TakeBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength)
       
   514 	{
       
   515 	if (iOutState)
       
   516 		return iOutState;
       
   517 
       
   518 
       
   519 	TUsbcScTransferHeader* currentTransfer;
       
   520 	TInt r;
       
   521 	TInt aBilTail;
       
   522 	do // until we have a transfer with data.
       
   523 		{
       
   524 		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
       
   525 			{
       
   526 			r = iClient->ReadDataNotify(iBufferNum,aStatus);
       
   527 			if (r!=KErrCompletion)  // Data could arrive since we checked.
       
   528 				{
       
   529 				return r;
       
   530 				}
       
   531 			}
       
   532 
       
   533 		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
       
   534 		aBilTail = iEndpointHdr->iBilTail;
       
   535 		iEndpointHdr->iBilTail = currentTransfer->iNext;
       
   536 		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false 
   421 
   537 
   422 		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
   538 		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
   423 			{
   539 			{
   424 			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
   540 			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
   425 				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
   541 				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
   426 																	   //this variable will reflect the latest requested AlternateSetting
   542 																	   //this variable will reflect the latest requested AlternateSetting
   427 
   543 			
   428 
       
   429 			if (iEndpointNumber != KEp0Number)
   544 			if (iEndpointNumber != KEp0Number)
   430 				{
   545 				{
   431 //				iOutState =  EEOF;	
   546 				iEndpointHdr->iBilTail = aBilTail;
   432 				return KErrEof;
       
   433 				}
       
   434 			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
       
   435 				{
       
   436 				return KErrAlternateSettingChanged;
       
   437 				}
       
   438 			}						
       
   439 
       
   440 		}
       
   441 	while ((currentTransfer->iBytes==0) && (!aZLP)); // ignore empty transfers
       
   442 
       
   443 	aBuffer = currentTransfer->iData.i;
       
   444 	aSize = currentTransfer->iBytes;	
       
   445 	return (currentTransfer->iFlags & KUsbcScStateChange)?KStateChange:KErrCompletion;	
       
   446 	}
       
   447 
       
   448 EXPORT_C TInt TEndpointBuffer::TakeBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength)
       
   449 	{
       
   450 	if (iOutState)
       
   451 		return iOutState;
       
   452 
       
   453 	TUsbcScTransferHeader* currentTransfer;
       
   454 	TInt r;
       
   455 	do // until we have a transfer with data.
       
   456 		{
       
   457 		if(iEndpointHdr->iBilTail == iEndpointHdr->iHead)  //If no new data, create request
       
   458 			{
       
   459 			r = iClient->ReadDataNotify(iBufferNum,aStatus);
       
   460 			if (r!=KErrCompletion)  // Data could arrive since we checked.
       
   461 				{
       
   462 				return r;
       
   463 				}
       
   464 			}
       
   465 
       
   466 		currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail);
       
   467 		iEndpointHdr->iBilTail = currentTransfer->iNext;
       
   468 		aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false 
       
   469 
       
   470 		if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq))  // if alternate setting has changed
       
   471 			{
       
   472 			if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1))	   //Note- KIS ATM, if multiple alternate setting changes happen
       
   473 				iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, 		   
       
   474 																	   //this variable will reflect the latest requested AlternateSetting
       
   475 			Expire(currentTransfer->iData.i);
       
   476 			if (iEndpointNumber != KEp0Number)
       
   477 				{
       
   478 //				iOutState = EEOF;
   547 //				iOutState = EEOF;
   479 				return KErrEof;
   548 				return KErrEof;
   480 				}
   549 				}
   481 			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
   550 			else if ((currentTransfer->iBytes==0) && (!aZLP)) 
   482 				{
   551 				{
       
   552 				Expire(currentTransfer->iData.i);
   483 				return KErrAlternateSettingChanged;
   553 				return KErrAlternateSettingChanged;
   484 				}
   554 				}
       
   555 			Expire(currentTransfer->iData.i);
   485 
   556 
   486 			}	
   557 			}	
   487 
   558 
   488 		if ((currentTransfer->iBytes==0) && (!aZLP)) // here , if empty transfer with alt setting information, Call expire 
   559 		if ((currentTransfer->iBytes==0) && (!aZLP)) // here , if empty transfer with alt setting information, Call expire 
   489 			{
   560 			{
   521 
   592 
   522 	TInt currentTail = iEndpointHdr->iTail;
   593 	TInt currentTail = iEndpointHdr->iTail;
   523 
   594 
   524 	TInt prevTail = NULL;
   595 	TInt prevTail = NULL;
   525 	TBool found = EFalse;
   596 	TBool found = EFalse;
       
   597 	
   526 	while (currentTail != iEndpointHdr->iBilTail)
   598 	while (currentTail != iEndpointHdr->iBilTail)
   527 		{
   599 		{			
   528 		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + currentTail);
   600 		TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + currentTail);
   529 		if (currentTail == offsetToExpire)		// found which to expire
   601 		if (currentTail == offsetToExpire)		// found which to expire
   530 			{
   602 			{			
   531 			found = ETrue;
   603 			found = ETrue;
   532 			// This offset is to be expired
   604 			// This offset is to be expired
   533 			if (prevTail == NULL)
   605 			if (prevTail == NULL)
   534 				{
   606 				{
   535 				// The offset is at the list head
   607 				// The offset is at the list head
   545 				}
   617 				}
   546 			break;
   618 			break;
   547 			}
   619 			}
   548 		prevTail = currentTail;
   620 		prevTail = currentTail;
   549 		currentTail = currentTransfer->iNext;
   621 		currentTail = currentTransfer->iNext;
   550 		}
   622 		}	
   551 	return found ? KErrNone : KErrNotFound;
   623 	return found ? KErrNone : KErrNotFound;
   552 	}
   624 	}
   553 
   625 
   554 	
   626 	
   555 EXPORT_C TInt TEndpointBuffer::WriteBuffer(TAny* aBuffer,TUint aSize,TBool aZLP,TRequestStatus& aStatus)
   627 EXPORT_C TInt TEndpointBuffer::WriteBuffer(TAny* aBuffer,TUint aSize,TBool aZLP,TRequestStatus& aStatus)