1 // Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2008-2009 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". |
17 |
17 |
18 #include <e32std.h> |
18 #include <e32std.h> |
19 #include <e32std_private.h> |
19 #include <e32std_private.h> |
20 #include <d32usbcsc.h> |
20 #include <d32usbcsc.h> |
21 #include <e32debug.h> |
21 #include <e32debug.h> |
22 #include "OstTraceDefinitions.h" |
22 |
23 #ifdef OST_TRACE_COMPILER_IN_USE |
|
24 #include "usbcsc_bilTraces.h" |
|
25 #endif |
|
26 /** @file usbcsc_bil.cpp |
23 /** @file usbcsc_bil.cpp |
27 |
24 |
28 Buffer Interface Layer for USB Client Device driver stack, using shared chunks. |
25 Buffer Interface Layer for USB Client Device driver stack, using shared chunks. |
29 |
26 |
30 @internalTechnology |
27 @internalTechnology |
39 iNewAltSetting = 0; |
36 iNewAltSetting = 0; |
40 iAltSettingSeq = 0; |
37 iAltSettingSeq = 0; |
41 return r; |
38 return r; |
42 } |
39 } |
43 |
40 |
44 // empty a endpoint buffer, this is called when device state enter undefined |
|
45 TInt RDevUsbcScClient::Empty(TUint aBufferOffset) |
|
46 { |
|
47 TUint8* base = iSharedChunk.Base(); |
|
48 SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset + base); |
|
49 TUint localTail = endpointHdr->iBilTail; |
|
50 TUsbcScTransferHeader* currentTransfer; |
|
51 TInt err=KErrNone; |
|
52 |
|
53 while (ETrue) |
|
54 { |
|
55 if (localTail == (TUint) endpointHdr->iHead) |
|
56 { |
|
57 err = KErrNone; |
|
58 break; |
|
59 } |
|
60 currentTransfer = (TUsbcScTransferHeader*) (base + localTail); |
|
61 localTail = currentTransfer->iNext; |
|
62 } // end while |
|
63 endpointHdr->iBilTail = localTail; |
|
64 endpointHdr->iTail = localTail; |
|
65 return err; |
|
66 } |
|
67 |
|
68 |
|
69 |
41 |
70 EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk) |
42 EXPORT_C TInt RDevUsbcScClient::FinalizeInterface(RChunk*& aChunk) |
71 { |
43 { |
72 TInt errorOrhandle = DoControl(EControlRealizeInterface); |
44 TInt errorOrhandle = DoControl(EControlRealizeInterface); |
73 iSharedChunk.SetReturnedHandle(errorOrhandle); |
45 iSharedChunk.SetReturnedHandle(errorOrhandle); |
74 iEndpointStatus = 0x00; //all endpoints are closed at the moment |
46 iEndpointStatus = 0x00; //all endpoints are closed at the moment |
75 iAlternateSetting = 0; |
47 iAlternateSetting = 0; |
76 return aChunk->SetReturnedHandle(errorOrhandle); |
48 return aChunk->SetReturnedHandle(errorOrhandle); |
77 } |
|
78 |
|
79 |
|
80 EXPORT_C void RDevUsbcScClient::ResetAltSetting() |
|
81 { |
|
82 if (iAlternateSetting == 0) |
|
83 return; |
|
84 TUsbcScChunkHeader chunkHeader(iSharedChunk); |
|
85 |
|
86 TInt ep; |
|
87 TInt noEp; |
|
88 TUint bufOff; |
|
89 TUsbcScHdrEndpointRecord* endpointInf = NULL; |
|
90 |
|
91 // check if alternate setting contains all IN endpoints |
|
92 noEp = chunkHeader.GetNumberOfEndpoints(iAlternateSetting); |
|
93 |
|
94 // for each used buffer. |
|
95 for (ep=1;ep<=noEp;ep++) |
|
96 { |
|
97 bufOff = chunkHeader.GetBuffer(iAlternateSetting,ep,endpointInf)->Offset(); |
|
98 |
|
99 if (endpointInf->Direction() & KUsbScHdrEpDirectionOut) |
|
100 { |
|
101 Empty(bufOff); // we need to remove anythng in the way, and get it ready for reading. |
|
102 } |
|
103 } |
|
104 |
|
105 iAlternateSetting = 0; |
|
106 } |
49 } |
107 |
50 |
108 |
51 |
109 EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI) |
52 EXPORT_C TInt RDevUsbcScClient::OpenEndpoint(TEndpointBuffer& aEpB, TInt aEpI) |
110 { |
53 { |
173 //This drains any old data from an OUT buffer, and gets it ready for reading an ep. |
116 //This drains any old data from an OUT buffer, and gets it ready for reading an ep. |
174 //aBufferOffset - The offset, into the chunk, that the buffer in question, may be found. |
117 //aBufferOffset - The offset, into the chunk, that the buffer in question, may be found. |
175 |
118 |
176 TInt RDevUsbcScClient::Drain(TUint aBufferOffset) |
119 TInt RDevUsbcScClient::Drain(TUint aBufferOffset) |
177 { |
120 { |
178 |
|
179 TUint8* base = iSharedChunk.Base(); |
121 TUint8* base = iSharedChunk.Base(); |
180 SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base); |
122 SUsbcScBufferHeader* endpointHdr = (SUsbcScBufferHeader*) (aBufferOffset+base); |
181 TUint localTail = endpointHdr->iBilTail; |
123 TUint localTail = endpointHdr->iBilTail; |
182 TUsbcScTransferHeader* currentTransfer; |
124 TUsbcScTransferHeader* currentTransfer; |
183 TUint16 next = (iAltSettingSeq+1)&0xFFFF; |
125 TUint16 next = (iAltSettingSeq+1)&0xFFFF; |
184 TInt err=KErrNone; |
126 TInt err=KErrNone; |
185 TBool aZLP; |
|
186 |
127 |
187 while (ETrue) |
128 while (ETrue) |
188 { |
129 { |
189 if (localTail == (TUint) endpointHdr->iHead) |
130 if (localTail == (TUint) endpointHdr->iHead) |
190 { |
131 { |
192 break; |
133 break; |
193 } |
134 } |
194 currentTransfer = (TUsbcScTransferHeader*) (base + localTail); |
135 currentTransfer = (TUsbcScTransferHeader*) (base + localTail); |
195 |
136 |
196 if (currentTransfer->iAltSettingSeq == next) |
137 if (currentTransfer->iAltSettingSeq == next) |
197 { |
138 { |
198 iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting |
139 iNewAltSetting=currentTransfer->iAltSetting; // record new alt setting |
199 aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; |
|
200 if ((currentTransfer->iBytes==0) && (!aZLP)) // take empty packet which is for alternate setting change |
|
201 { |
|
202 localTail = currentTransfer->iNext; |
|
203 } |
|
204 break; |
140 break; |
205 } |
141 } |
206 else |
142 else |
207 { |
143 { |
208 localTail = currentTransfer->iNext; |
144 localTail = currentTransfer->iNext; |
467 if (iOutState) |
403 if (iOutState) |
468 return iOutState; |
404 return iOutState; |
469 |
405 |
470 TUsbcScTransferHeader* currentTransfer; |
406 TUsbcScTransferHeader* currentTransfer; |
471 TInt r; |
407 TInt r; |
472 TInt aBilTail; |
|
473 do // until we have a transfer with data. |
408 do // until we have a transfer with data. |
474 { |
409 { |
475 iEndpointHdr->iTail = iEndpointHdr->iBilTail; |
410 iEndpointHdr->iTail = iEndpointHdr->iBilTail; |
476 if(iEndpointHdr->iBilTail == iEndpointHdr->iHead) //If no new data, create request |
411 if(iEndpointHdr->iBilTail == iEndpointHdr->iHead) //If no new data, create request |
477 { |
412 { |
478 r = iClient->ReadDataNotify(iBufferNum,aStatus); |
413 r = iClient->ReadDataNotify(iBufferNum,aStatus); |
479 if (r!=KErrCompletion) // Data could arrive since we checked. |
414 if (r!=KErrCompletion) // Data could arrive since we checked. |
480 return r; |
415 return r; |
481 } |
416 } |
482 currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail); |
417 currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail); |
483 aBilTail = iEndpointHdr->iBilTail; |
418 |
484 iEndpointHdr->iBilTail = currentTransfer->iNext; |
419 iEndpointHdr->iBilTail = currentTransfer->iNext; |
485 aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; |
420 aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; |
486 |
421 |
487 if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq)) // if alternate setting has changed |
422 if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq)) // if alternate setting has changed |
488 { |
423 { |
489 if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1)) //Note- KIS ATM, if multiple alternate setting changes happen |
424 if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1)) //Note- KIS ATM, if multiple alternate setting changes happen |
490 { |
|
491 iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, |
425 iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, |
492 //this variable will reflect the latest requested AlternateSetting |
426 //this variable will reflect the latest requested AlternateSetting |
493 } |
|
494 |
427 |
495 |
428 |
496 if (iEndpointNumber != KEp0Number) |
429 if (iEndpointNumber != KEp0Number) |
497 { |
430 { |
498 iEndpointHdr->iBilTail = aBilTail; |
|
499 // iOutState = EEOF; |
431 // iOutState = EEOF; |
500 return KErrEof; |
432 return KErrEof; |
501 } |
433 } |
502 else if ((currentTransfer->iBytes==0) && (!aZLP)) |
434 else if ((currentTransfer->iBytes==0) && (!aZLP)) |
503 { |
435 { |
516 EXPORT_C TInt TEndpointBuffer::TakeBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength) |
448 EXPORT_C TInt TEndpointBuffer::TakeBuffer(TAny*& aBuffer,TUint& aSize,TBool& aZLP,TRequestStatus& aStatus,TUint aLength) |
517 { |
449 { |
518 if (iOutState) |
450 if (iOutState) |
519 return iOutState; |
451 return iOutState; |
520 |
452 |
521 |
|
522 TUsbcScTransferHeader* currentTransfer; |
453 TUsbcScTransferHeader* currentTransfer; |
523 TInt r; |
454 TInt r; |
524 TInt aBilTail; |
|
525 do // until we have a transfer with data. |
455 do // until we have a transfer with data. |
526 { |
456 { |
527 if(iEndpointHdr->iBilTail == iEndpointHdr->iHead) //If no new data, create request |
457 if(iEndpointHdr->iBilTail == iEndpointHdr->iHead) //If no new data, create request |
528 { |
458 { |
529 r = iClient->ReadDataNotify(iBufferNum,aStatus); |
459 r = iClient->ReadDataNotify(iBufferNum,aStatus); |
532 return r; |
462 return r; |
533 } |
463 } |
534 } |
464 } |
535 |
465 |
536 currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail); |
466 currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + iEndpointHdr->iBilTail); |
537 aBilTail = iEndpointHdr->iBilTail; |
|
538 iEndpointHdr->iBilTail = currentTransfer->iNext; |
467 iEndpointHdr->iBilTail = currentTransfer->iNext; |
539 aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false |
468 aZLP = (currentTransfer->iFlags & KUsbcScShortPacket)!=EFalse; // True if short packet else false |
540 |
469 |
541 if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq)) // if alternate setting has changed |
470 if(currentTransfer->iAltSettingSeq != (iClient->iAltSettingSeq)) // if alternate setting has changed |
542 { |
471 { |
543 if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1)) //Note- KIS ATM, if multiple alternate setting changes happen |
472 if (currentTransfer->iAltSettingSeq == (iClient->iAltSettingSeq+1)) //Note- KIS ATM, if multiple alternate setting changes happen |
544 iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, |
473 iClient->iNewAltSetting = currentTransfer->iAltSetting; //before StartNextOutAlternateSetting is called, |
545 //this variable will reflect the latest requested AlternateSetting |
474 //this variable will reflect the latest requested AlternateSetting |
546 |
475 Expire(currentTransfer->iData.i); |
547 if (iEndpointNumber != KEp0Number) |
476 if (iEndpointNumber != KEp0Number) |
548 { |
477 { |
549 iEndpointHdr->iBilTail = aBilTail; |
|
550 // iOutState = EEOF; |
478 // iOutState = EEOF; |
551 return KErrEof; |
479 return KErrEof; |
552 } |
480 } |
553 else if ((currentTransfer->iBytes==0) && (!aZLP)) |
481 else if ((currentTransfer->iBytes==0) && (!aZLP)) |
554 { |
482 { |
555 Expire(currentTransfer->iData.i); |
|
556 return KErrAlternateSettingChanged; |
483 return KErrAlternateSettingChanged; |
557 } |
484 } |
558 Expire(currentTransfer->iData.i); |
|
559 |
485 |
560 } |
486 } |
561 |
487 |
562 if ((currentTransfer->iBytes==0) && (!aZLP)) // here , if empty transfer with alt setting information, Call expire |
488 if ((currentTransfer->iBytes==0) && (!aZLP)) // here , if empty transfer with alt setting information, Call expire |
563 { |
489 { |
595 |
521 |
596 TInt currentTail = iEndpointHdr->iTail; |
522 TInt currentTail = iEndpointHdr->iTail; |
597 |
523 |
598 TInt prevTail = NULL; |
524 TInt prevTail = NULL; |
599 TBool found = EFalse; |
525 TBool found = EFalse; |
600 |
|
601 while (currentTail != iEndpointHdr->iBilTail) |
526 while (currentTail != iEndpointHdr->iBilTail) |
602 { |
527 { |
603 TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + currentTail); |
528 TUsbcScTransferHeader* currentTransfer = (TUsbcScTransferHeader*) (iBaseAddr + currentTail); |
604 if (currentTail == offsetToExpire) // found which to expire |
529 if (currentTail == offsetToExpire) // found which to expire |
605 { |
530 { |
606 found = ETrue; |
531 found = ETrue; |
607 // This offset is to be expired |
532 // This offset is to be expired |
608 if (prevTail == NULL) |
533 if (prevTail == NULL) |
609 { |
534 { |
610 // The offset is at the list head |
535 // The offset is at the list head |
620 } |
545 } |
621 break; |
546 break; |
622 } |
547 } |
623 prevTail = currentTail; |
548 prevTail = currentTail; |
624 currentTail = currentTransfer->iNext; |
549 currentTail = currentTransfer->iNext; |
625 } |
550 } |
626 return found ? KErrNone : KErrNotFound; |
551 return found ? KErrNone : KErrNotFound; |
627 } |
552 } |
628 |
553 |
629 |
554 |
630 EXPORT_C TInt TEndpointBuffer::WriteBuffer(TAny* aBuffer,TUint aSize,TBool aZLP,TRequestStatus& aStatus) |
555 EXPORT_C TInt TEndpointBuffer::WriteBuffer(TAny* aBuffer,TUint aSize,TBool aZLP,TRequestStatus& aStatus) |
700 |
625 |
701 /* Debug functions */ |
626 /* Debug functions */ |
702 |
627 |
703 EXPORT_C void TEndpointBuffer::Dump() |
628 EXPORT_C void TEndpointBuffer::Dump() |
704 { |
629 { |
705 OstTraceDefExt5(OST_TRACE_CATEGORY_RND, TRACE_NORMAL, TENDPOINTBUFFER_DUMP, "TEndpointBuffer::Dump iBufferStart: 0x%x, iSize: 0x%x, iEndpointNumber: 0x%x, iBufferNum: %d, iInState: 0x%x", |
630 RDebug::Printf("TEndpointBuffer::Dump iBufferStart: 0x%x, iSize: 0x%x, iEndpointNumber: 0x%x, iBufferNum: %d, iInState: 0x%x iOutState: 0x%x\n", |
706 (TUint)iBufferStartAddr,iSize,iEndpointNumber,iBufferNum, (TUint)iInState); |
631 iBufferStartAddr,iSize,iEndpointNumber,iBufferNum,iInState,iOutState); |
707 |
632 } |
708 OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_NORMAL, TENDPOINTBUFFER_DUMP_DUP1, " iOutState: 0x%x\n", iOutState); |
633 |
709 } |
|
710 |
|