Update contrib.
1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32/drivers/usbcc/descriptors.cpp
15 // Platform independent layer (PIL) of the USB Device controller driver:
16 // USB descriptor handling and management.
25 #include <kernel/kern_priv.h>
26 #include <drivers/usbc.h>
30 static const char KUsbPanicCat[] = "USB PIL";
33 // --- TUsbcDescriptorBase
35 TUsbcDescriptorBase::TUsbcDescriptorBase()
37 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
42 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::TUsbcDescriptorBase()"));
46 TUsbcDescriptorBase::~TUsbcDescriptorBase()
48 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::~TUsbcDescriptorBase()"));
52 void TUsbcDescriptorBase::SetByte(TInt aPosition, TUint8 aValue)
54 iBufPtr[aPosition] = aValue;
58 void TUsbcDescriptorBase::SetWord(TInt aPosition, TUint16 aValue)
60 *reinterpret_cast<TUint16*>(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue);
64 TUint8 TUsbcDescriptorBase::Byte(TInt aPosition) const
66 return iBufPtr[aPosition];
70 TUint16 TUsbcDescriptorBase::Word(TInt aPosition) const
72 return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition]));
76 void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const
82 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
84 memcpy(aBuffer, iBufPtr.Ptr(), Size());
89 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const
91 if (aMaxSize < Size())
93 // No use to copy only half a descriptor
96 return GetDescriptorData(aBuffer);
100 const TDes8& TUsbcDescriptorBase::DescriptorData() const
106 TDes8& TUsbcDescriptorBase::DescriptorData()
112 TUint TUsbcDescriptorBase::Size() const
114 return iBufPtr.Size();
118 TUint8 TUsbcDescriptorBase::Type() const
124 void TUsbcDescriptorBase::UpdateFs()
126 // virtual function can be overridden in derived classes.
131 void TUsbcDescriptorBase::UpdateHs()
133 // virtual function can be overridden in derived classes.
138 void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes)
140 iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
144 // --- TUsbcDeviceDescriptor
146 TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()
149 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()"));
153 TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
154 TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
155 TUint16 aVendorId, TUint16 aProductId,
156 TUint16 aDeviceRelease, TUint8 aNumConfigurations)
158 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::New()"));
159 TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor();
162 if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId,
163 aProductId, aDeviceRelease, aNumConfigurations) != KErrNone)
173 TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
174 TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
175 TUint16 aDeviceRelease, TUint8 aNumConfigurations)
177 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::Construct()"));
179 SetBufferPointer(iBuf);
180 iBuf[0] = iBuf.Size(); // bLength
181 iBuf[1] = KUsbDescType_Device; // bDescriptorType
182 SetWord(2, KUsbcUsbVersion); // bcdUSB
183 iBuf[4] = aDeviceClass; // bDeviceClass
184 iBuf[5] = aDeviceSubClass; // bDeviceSubClass
185 iBuf[6] = aDeviceProtocol; // bDeviceProtocol
186 iBuf[7] = aMaxPacketSize0; // bMaxPacketSize0
187 SetWord(8, aVendorId); // idVendor
188 SetWord(10, aProductId); // idProduct
189 SetWord(12, aDeviceRelease); // bcdDevice
190 iBuf[14] = 0; // iManufacturer
191 iBuf[15] = 0; // iProduct
192 iBuf[16] = 0; // iSerialNumber
193 iBuf[17] = aNumConfigurations; // bNumConfigurations
194 iEp0Size_Fs = aMaxPacketSize0;
199 void TUsbcDeviceDescriptor::UpdateFs()
201 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateFs()"));
202 SetByte(7, iEp0Size_Fs); // bMaxPacketSize0
206 void TUsbcDeviceDescriptor::UpdateHs()
208 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateHs()"));
209 SetByte(7, 64); // bMaxPacketSize0
213 // --- TUsbcDeviceQualifierDescriptor
215 TUsbcDeviceQualifierDescriptor::TUsbcDeviceQualifierDescriptor()
218 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceQualifierDescriptor()"));
222 TUsbcDeviceQualifierDescriptor* TUsbcDeviceQualifierDescriptor::New(TUint8 aDeviceClass,
223 TUint8 aDeviceSubClass,
224 TUint8 aDeviceProtocol,
225 TUint8 aMaxPacketSize0,
226 TUint8 aNumConfigurations,
229 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::New()"));
230 TUsbcDeviceQualifierDescriptor* self = new TUsbcDeviceQualifierDescriptor();
233 if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0,
234 aNumConfigurations, aReserved) != KErrNone)
244 TInt TUsbcDeviceQualifierDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
245 TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
246 TUint8 aNumConfigurations, TUint8 aReserved)
248 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::Construct()"));
250 SetBufferPointer(iBuf);
251 iBuf[0] = iBuf.Size(); // bLength
252 iBuf[1] = KUsbDescType_DeviceQualifier; // bDescriptorType
253 SetWord(2, KUsbcUsbVersion); // bcdUSB
254 iBuf[4] = aDeviceClass; // bDeviceClass
255 iBuf[5] = aDeviceSubClass; // bDeviceSubClass
256 iBuf[6] = aDeviceProtocol; // bDeviceProtocol
257 iBuf[7] = aMaxPacketSize0; // bMaxPacketSize0
258 iBuf[8] = aNumConfigurations; // bNumConfigurations
259 if (aReserved) aReserved = 0;
260 iBuf[9] = aReserved; // Reserved for future use, must be zero
261 iEp0Size_Fs = aMaxPacketSize0;
266 void TUsbcDeviceQualifierDescriptor::UpdateFs()
268 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateFs()"));
269 // Here we do exactly the opposite of what's done in the Device descriptor (as this one's
270 // documenting the 'other than the current speed').
271 SetByte(7, 64); // bMaxPacketSize0
275 void TUsbcDeviceQualifierDescriptor::UpdateHs()
277 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateHs()"));
278 // Here we do exactly the opposite of what's done in the Device descriptor (as this one's
279 // documenting the 'other than the current speed').
280 SetByte(7, iEp0Size_Fs); // bMaxPacketSize0
284 // --- TUsbcConfigDescriptor
286 TUsbcConfigDescriptor::TUsbcConfigDescriptor()
289 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::TUsbcConfigDescriptor()"));
293 TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered,
294 TBool aRemoteWakeup, TUint16 aMaxPower)
296 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::New()"));
297 TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor();
300 if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone)
310 TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered,
311 TBool aRemoteWakeup, TUint16 aMaxPower)
313 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::Construct()"));
315 SetBufferPointer(iBuf);
316 iBuf[0] = iBuf.Size(); // bLength
317 iBuf[1] = KUsbDescType_Config; // bDescriptorType
318 SetWord(2, KUsbDescSize_Config); // wTotalLength
319 iBuf[4] = 0; // bNumInterfaces
320 iBuf[5] = aConfigurationValue; // bConfigurationValue
321 iBuf[6] = 0; // iConfiguration
323 (aSelfPowered ? KUsbDevAttr_SelfPowered : 0) |
324 (aRemoteWakeup ? KUsbDevAttr_RemoteWakeup : 0); // bmAttributes (bit 7 always 1)
326 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Invalid value for bMaxPower: %d", aMaxPower));
327 iBuf[8] = aMaxPower / 2; // bMaxPower (2mA units!)
332 // --- TUsbcInterfaceDescriptor
334 TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()
337 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()"));
341 TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
342 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
344 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::New()"));
345 TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor();
348 if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone)
358 TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
359 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
361 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::Construct()"));
363 SetBufferPointer(iBuf);
364 iBuf[0] = iBuf.Size(); // bLength
365 iBuf[1] = KUsbDescType_Interface; // bDescriptorType
366 iBuf[2] = aInterfaceNumber; // bInterfaceNumber
367 iBuf[3] = aAlternateSetting; // bAlternateSetting
368 iBuf[4] = aNumEndpoints; // bNumEndpoints
369 iBuf[5] = aClassInfo.iClassNum; // bInterfaceClass
370 iBuf[6] = aClassInfo.iSubClassNum; // bInterfaceSubClass
371 iBuf[7] = aClassInfo.iProtocolNum; // bInterfaceProtocol
372 iBuf[8] = 0; // iInterface
377 // --- TUsbcEndpointDescriptorBase
379 TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()
381 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()"));
385 TInt TUsbcEndpointDescriptorBase::Construct(const TUsbcEndpointInfo& aEpInfo)
387 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::Construct()"));
388 // Adjust FS/HS endpoint sizes
389 if (aEpInfo.AdjustEpSizes(iEpSize_Fs, iEpSize_Hs) != KErrNone)
391 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Unknown endpoint type: %d", aEpInfo.iType));
393 __KTRACE_OPT(KUSB, Kern::Printf(" Now set: iEpSize_Fs=%d iEpSize_Hs=%d (aEpInfo.iSize=%d)",
394 iEpSize_Fs, iEpSize_Hs, aEpInfo.iSize));
396 // Adjust HS endpoint size for additional transactions
397 if ((aEpInfo.iType == KUsbEpTypeIsochronous) || (aEpInfo.iType == KUsbEpTypeInterrupt))
399 if ((aEpInfo.iTransactions > 0) && (aEpInfo.iTransactions < 3))
401 // Bits 12..11 specify the number of additional transactions per microframe
402 iEpSize_Hs |= (aEpInfo.iTransactions << 12);
403 __KTRACE_OPT(KUSB, Kern::Printf(" Adjusted for add. transact.: iEpSize_Hs=0x%02x "
404 "(aEpInfo.iTransactions=%d)",
405 iEpSize_Hs, aEpInfo.iTransactions));
407 else if (aEpInfo.iTransactions != 0)
409 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Invalid iTransactions value: %d (ignored)",
410 aEpInfo.iTransactions));
414 // Adjust HS polling interval
415 TUsbcEndpointInfo info(aEpInfo); // create local writeable copy
416 if (info.AdjustPollInterval() != KErrNone)
418 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Unknown ep type (%d) or invalid interval value (%d)",
419 info.iType, info.iInterval));
421 iInterval_Fs = info.iInterval;
422 iInterval_Hs = info.iInterval_Hs;
423 __KTRACE_OPT(KUSB, Kern::Printf(" Now set: iInterval_Fs=%d iInterval_Hs=%d",
424 iInterval_Fs, iInterval_Hs));
429 void TUsbcEndpointDescriptorBase::UpdateFs()
431 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateFs()"));
432 // (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values got
433 // adjusted in its Construct() method.)
434 SetWord(4, iEpSize_Fs); // wMaxPacketSize
435 SetByte(6, iInterval_Fs); // bInterval
439 void TUsbcEndpointDescriptorBase::UpdateHs()
441 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateHs()"));
442 // (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values get
443 // adjusted in its Construct() method.)
444 SetWord(4, iEpSize_Hs); // wMaxPacketSize
445 SetByte(6, iInterval_Hs); // bInterval
449 // --- TUsbcEndpointDescriptor
451 TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()
454 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()"));
458 TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress,
459 const TUsbcEndpointInfo& aEpInfo)
461 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::New()"));
462 TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor();
465 if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
475 TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
477 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::Construct()"));
478 (void) TUsbcEndpointDescriptorBase::Construct(aEpInfo); // Init Base class
480 SetBufferPointer(iBuf);
481 iBuf[0] = iBuf.Size(); // bLength
482 iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType
483 iBuf[2] = aEndpointAddress; // bEndpointAddress
484 iBuf[3] = EpTypeMask2Value(aEpInfo.iType); // bmAttributes
485 SetWord(4, iEpSize_Fs); // wMaxPacketSize (default is FS)
486 iBuf[6] = iInterval_Fs; // bInterval (default is FS)
491 // --- TUsbcAudioEndpointDescriptor
493 TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()
496 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()"));
500 TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress,
501 const TUsbcEndpointInfo& aEpInfo)
503 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::New()"));
504 TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor();
507 if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
517 TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
519 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::Construct()"));
520 (void) TUsbcEndpointDescriptorBase::Construct(aEpInfo); // Init Base class
522 SetBufferPointer(iBuf);
523 iBuf[0] = iBuf.Size(); // bLength
524 iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType
525 iBuf[2] = aEndpointAddress; // bEndpointAddress
526 iBuf[3] = EpTypeMask2Value(aEpInfo.iType); // bmAttributes
527 SetWord(4, iEpSize_Fs); // wMaxPacketSize (default is FS)
528 iBuf[6] = iInterval_Fs; // bInterval (default is FS)
535 // --- TUsbcOtgDescriptor
537 TUsbcOtgDescriptor* TUsbcOtgDescriptor::New(TBool aHnpSupport, TBool aSrpSupport)
539 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::New()"));
540 TUsbcOtgDescriptor* self = new TUsbcOtgDescriptor();
541 if (self && (self->Construct(aHnpSupport, aSrpSupport) != KErrNone))
550 TUsbcOtgDescriptor::TUsbcOtgDescriptor()
553 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::TUsbcOtgDescriptor()"));
557 TInt TUsbcOtgDescriptor::Construct(TBool aHnpSupport, TBool aSrpSupport)
559 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::Construct()"));
561 SetBufferPointer(iBuf);
562 iBuf[0] = iBuf.Size(); // bLength
563 iBuf[1] = KUsbDescType_Otg; // bDescriptorType
564 iBuf[2] = (aHnpSupport ? KUsbOtgAttr_HnpSupp : 0) |
565 (aSrpSupport ? KUsbOtgAttr_SrpSupp : 0); // bmAttributes
570 // --- TUsbcClassSpecificDescriptor
572 TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()
575 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()"));
579 TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()
581 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()"));
586 TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize)
588 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::New()"));
589 TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor();
592 if (self->Construct(aType, aSize) != KErrNone)
602 TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize)
604 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::Construct()"));
605 iBuf = HBuf8::New(aSize);
608 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Allocation of CS desc buffer failed"));
612 SetBufferPointer(*iBuf);
613 SetByte(1, aType); // bDescriptorType
618 // --- TUsbcStringDescriptorBase
620 TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()
621 : /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0)
623 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()"));
627 TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()
629 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()"));
633 TUint16 TUsbcStringDescriptorBase::Word(TInt aPosition) const
637 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Word(%d) in string descriptor "
638 "(TUsbcStringDescriptorBase::Word)", aPosition));
643 // since iBufPtr[0] is actually string descriptor byte index 2,
644 // we have to subtract 2 from the absolute position.
645 return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition - 2]));
650 void TUsbcStringDescriptorBase::SetWord(TInt aPosition, TUint16 aValue)
654 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetWord(%d) in string descriptor "
655 "(TUsbcStringDescriptorBase::SetWord)", aPosition));
660 // since iBufPtr[0] is actually string descriptor byte index 2,
661 // we have to subtract 2 from the absolute position.
662 *reinterpret_cast<TUint16*>(&iBufPtr[aPosition - 2]) = SWAP_BYTES_16(aValue);
667 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
669 aBuffer[0] = iSBuf[0];
670 aBuffer[1] = iSBuf[1];
671 memcpy(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size());
676 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const
678 if (aMaxSize < Size())
680 // No use to copy only half a string
683 return GetDescriptorData(aBuffer);
687 const TDes8& TUsbcStringDescriptorBase::StringData() const
693 TDes8& TUsbcStringDescriptorBase::StringData()
699 TUint TUsbcStringDescriptorBase::Size() const
705 void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes)
707 iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
711 // --- TUsbcStringDescriptor
713 TUsbcStringDescriptor::TUsbcStringDescriptor()
716 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::TUsbcStringDescriptor()"));
720 TUsbcStringDescriptor::~TUsbcStringDescriptor()
722 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::~TUsbcStringDescriptor()"));
727 TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString)
729 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::New"));
730 TUsbcStringDescriptor* self = new TUsbcStringDescriptor();
733 if (self->Construct(aString) != KErrNone)
743 TInt TUsbcStringDescriptor::Construct(const TDesC8& aString)
745 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::Construct"));
746 iBuf = HBuf8::New(aString.Size()); // bytes, not UNICODE chars
749 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Allocation of string buffer failed"));
753 SetBufferPointer(*iBuf);
754 iBufPtr.Copy(aString);
756 iSBuf[0] = iBuf->Size() + 2; // Bytes
757 iSBuf[1] = KUsbDescType_String;
762 // --- TUsbcLangIdDescriptor
764 TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()
767 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()"));
771 TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()
773 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()"));
777 TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId)
779 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::New"));
780 TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor();
783 if (self->Construct(aLangId) != KErrNone)
793 TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId)
795 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::Construct"));
797 SetBufferPointer(iBuf);
798 iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId)); // Language ID value
799 iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId));
801 iSBuf[0] = iBuf.Size() + 2; // Bytes
802 iSBuf[1] = KUsbDescType_String;
807 // --- TUsbcDescriptorPool
809 TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf)
811 // The constructor for this class.
813 : iDescriptors(), iStrings(), iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf), iHighSpeed(EFalse)
815 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::TUsbcDescriptorPool()"));
819 TUsbcDescriptorPool::~TUsbcDescriptorPool()
821 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::~TUsbcDescriptorPool()"));
822 // The destructor of each <class T> object is called before the objects themselves are destroyed.
823 __KTRACE_OPT(KUSB, Kern::Printf(" iDescriptors.Count(): %d", iDescriptors.Count()));
824 iDescriptors.ResetAndDestroy();
825 __KTRACE_OPT(KUSB, Kern::Printf(" iStrings.Count(): %d", iStrings.Count()));
826 iStrings.ResetAndDestroy();
830 TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
831 TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
832 TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
833 TUsbcStringDescriptor* aConfig, TUsbcOtgDescriptor* aOtgDesc)
835 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::Init()"));
836 if (!aDeviceDesc || !aConfigDesc)
838 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Device or Config descriptor specified"));
841 for (TInt n = 0; n < KDescPosition_FirstAvailable; n++)
843 iDescriptors.Append(NULL);
845 __ASSERT_DEBUG((iDescriptors.Count() == KDescPosition_FirstAvailable),
846 Kern::Printf(" Error: iDescriptors.Count() (%d) != KDescPosition_FirstAvailable (%d)",
847 iDescriptors.Count(), KDescPosition_FirstAvailable));
848 iDescriptors[KDescPosition_Device] = aDeviceDesc;
849 iDescriptors[KDescPosition_Config] = aConfigDesc;
852 iDescriptors[KDescPosition_Otg] = aOtgDesc;
853 // Update the config descriptor's wTotalLength field
854 UpdateConfigDescriptorLength(KUsbDescSize_Otg);
858 // USB spec 9.6.7 says: "String index zero for all languages returns a string descriptor
859 // that contains an array of two-byte LANGID codes supported by the device. ...
860 // USB devices that omit all string descriptors must not return an array of LANGID codes."
861 // So if we have at least one string descriptor, we must also have a LANGID descriptor.
862 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No LANGID string descriptor specified"));
865 iStrings.Insert(aLangId, KStringPosition_Langid);
866 iStrings.Insert(aManufacturer, KStringPosition_Manufact);
867 iStrings.Insert(aProduct, KStringPosition_Product);
868 iStrings.Insert(aSerialNum, KStringPosition_Serial);
869 iStrings.Insert(aConfig, KStringPosition_Config);
870 __ASSERT_DEBUG((iStrings.Count() == 5),
871 Kern::Printf(" Error: iStrings.Count() != 5 (%d)", iStrings.Count()));
873 for (TInt i = KStringPosition_Langid; i <= KStringPosition_Config; i++)
875 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool.iStrings[%d] = 0x%x", i, iStrings[i]));
878 // Set string indices
880 iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Manufact,
881 KStringPosition_Manufact);
883 iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Product,
884 KStringPosition_Product);
886 iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Serial,
887 KStringPosition_Serial);
889 iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config,
890 KStringPosition_Config);
895 TInt TUsbcDescriptorPool::InitHs()
897 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InitHs()"));
898 __ASSERT_DEBUG((iDescriptors.Count() >= KDescPosition_FirstAvailable),
899 Kern::Printf(" Error: Call Init() first)"));
901 TUsbcDeviceQualifierDescriptor* const dq_desc = TUsbcDeviceQualifierDescriptor::New(
902 iDescriptors[KDescPosition_Device]->Byte(4), // aDeviceClass
903 iDescriptors[KDescPosition_Device]->Byte(5), // aDeviceSubClass
904 iDescriptors[KDescPosition_Device]->Byte(6), // aDeviceProtocol
905 iDescriptors[KDescPosition_Device]->Byte(7), // aMaxPacketSize0
906 iDescriptors[KDescPosition_Device]->Byte(17)); // aNumConfigurations
909 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev qualif desc failed."));
912 iDescriptors[KDescPosition_DeviceQualifier] = dq_desc;
914 TUsbcOtherSpeedConfigDescriptor* const osc_desc = TUsbcOtherSpeedConfigDescriptor::New(
915 iDescriptors[KDescPosition_Config]->Byte(5), // aConfigurationValue
916 iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_SelfPowered, // aSelfPowered
917 iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_RemoteWakeup, // aRemoteWakeup
918 iDescriptors[KDescPosition_Config]->Byte(8) * 2); // aMaxPower (mA)
921 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for other speed conf desc failed."));
925 // We need to set the bDescriptorType field manually, as that's the only one
926 // that differs from a Configuration descriptor.
927 osc_desc->SetByte(1, KUsbDescType_OtherSpeedConfig);
929 // Also, initially we set the iConfiguration string index to the same value as
930 // in the Configuration descriptor.
931 osc_desc->SetByte(KUsbDescStringIndex_Config,
932 iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config));
934 iDescriptors[KDescPosition_OtherSpeedConfig] = osc_desc;
940 TInt TUsbcDescriptorPool::UpdateDescriptorsFs()
942 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsFs()"));
943 const TInt count = iDescriptors.Count();
944 for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
946 TUsbcDescriptorBase* const ptr = iDescriptors[i];
954 TInt TUsbcDescriptorPool::UpdateDescriptorsHs()
956 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsHs()"));
957 const TInt count = iDescriptors.Count();
958 for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
960 TUsbcDescriptorBase* const ptr = iDescriptors[i];
969 // An error can be indicated by either a return value != KErrNone or by a descriptor size == 0.
971 TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const
973 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindDescriptor()"));
974 TInt result = KErrGeneral;
977 case KUsbDescType_Device:
980 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid));
984 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad device index: %d", aIndex));
988 aSize = GetDeviceDescriptor(KDescPosition_Device);
992 case KUsbDescType_Config:
995 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid));
999 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad config index: %d", aIndex));
1003 aSize = GetConfigurationDescriptor(KDescPosition_Config);
1007 case KUsbDescType_DeviceQualifier:
1010 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid));
1012 else if (aIndex > 0)
1014 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad device index: %d", aIndex));
1018 aSize = GetDeviceDescriptor(KDescPosition_DeviceQualifier);
1022 case KUsbDescType_OtherSpeedConfig:
1025 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid));
1027 else if (aIndex > 0)
1029 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad config index: %d", aIndex));
1033 aSize = GetConfigurationDescriptor(KDescPosition_OtherSpeedConfig);
1037 case KUsbDescType_Otg:
1038 aSize = GetOtgDescriptor();
1041 case KUsbDescType_String:
1042 if (aIndex == 0) // 0 addresses the LangId array
1044 if (AnyStringDescriptors())
1046 aSize = GetStringDescriptor(aIndex);
1051 __KTRACE_OPT(KUSB, Kern::Printf(" No string descriptors: not returning LANGID array"));
1059 Kern::Printf(" Strange: LANGID=0 for a $ descriptor (ignoring LANGID)"));
1060 // The USB spec doesn't really say what to do in this case, but as there are host apps
1061 // that fail if we return an error here, we choose to ignore the issue.
1063 else if (aLangid != iStrings[KStringPosition_Langid]->Word(2))
1065 // We have only one (this) language
1067 Kern::Printf(" Bad LANGID: 0x%04X requested, 0x%04X supported (ignoring LANGID)",
1068 aLangid, iStrings[KStringPosition_Langid]->Word(2)));
1069 // We could return an error here, but rather choose to ignore the discrepancy
1070 // (the USB spec is not very clear what to do in such a case anyway).
1072 aSize = GetStringDescriptor(aIndex);
1076 case KUsbDescType_CS_Interface:
1078 case KUsbDescType_CS_Endpoint:
1079 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: finding of class specific descriptors not supported"));
1082 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: unknown descriptor type requested: %d", aType));
1089 void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc)
1091 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertDescriptor()"));
1092 switch (aDesc->Type())
1094 case KUsbDescType_Interface:
1095 InsertIfcDesc(aDesc);
1097 case KUsbDescType_Endpoint:
1098 InsertEpDesc(aDesc);
1101 __KTRACE_OPT(KUSB, Kern::Printf(" Error: unsupported descriptor type"));
1106 void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting)
1108 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetIfcDescriptor(%d, %d)", aNumber, aSetting));
1109 const TInt i = FindIfcDescriptor(aNumber, aSetting);
1112 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Ifc descriptor not found (%d, %d)",
1113 aNumber, aSetting));
1116 // Try to find available NULL postition
1117 TInt str_idx = FindAvailableStringPos();
1120 // Insert string descriptor for specified interface
1121 ExchangeStringDescriptor(str_idx, aDesc);
1125 // No NULL found - expand array
1126 str_idx = iStrings.Count();
1129 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: $ descriptor array full (idx=%d)", str_idx));
1132 while (str_idx < KStringPosition_FirstAvailable)
1134 iStrings.Append(NULL);
1135 str_idx = iStrings.Count();
1137 // Append string descriptor for specified interface
1138 iStrings.Append(aDesc);
1140 // Update this ifc descriptor's string index field
1141 iDescriptors[i]->SetByte(8, str_idx);
1142 __KTRACE_OPT(KUSB, Kern::Printf(" String for ifc %d/%d (@ pos %d): \"%S\"", aNumber, aSetting, str_idx,
1143 &iStrings[str_idx]->StringData()));
1147 void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting)
1149 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)", aNumber, aSetting));
1150 const TInt i = FindIfcDescriptor(aNumber, aSetting);
1153 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DeleteIfcDescriptor - descriptor not found (%d, %d)",
1154 aNumber, aSetting));
1157 // Delete (if necessary) specified interface's string descriptor
1158 const TInt si = iDescriptors[i]->Byte(8);
1161 ExchangeStringDescriptor(si, NULL);
1163 // Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors:
1164 // find position of the next interface descriptor: we need to delete everything in between
1165 const TInt count = iDescriptors.Count();
1167 while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface)
1169 DeleteDescriptors(i, n);
1170 // Update all the following interfaces' bInterfaceNumber field if required
1171 // (because those descriptors might have moved down by one position)
1172 UpdateIfcNumbers(aNumber);
1173 iIfcIdx = 0; // ifc index no longer valid
1177 // The TC in many of the following functions stands for 'ThreadCopy',
1178 // because that's what's happening there.
1180 TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const
1182 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptorTC()"));
1183 return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Device]->DescriptorData(), 0);
1187 TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer)
1189 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceDescriptorTC()"));
1190 TBuf8<KUsbDescSize_Device> device;
1191 const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0);
1196 iDescriptors[KDescPosition_Device]->SetByte(2, device[2]); // bcdUSB
1197 iDescriptors[KDescPosition_Device]->SetByte(3, device[3]); // bcdUSB (part II)
1198 iDescriptors[KDescPosition_Device]->SetByte(4, device[4]); // bDeviceClass
1199 iDescriptors[KDescPosition_Device]->SetByte(5, device[5]); // bDeviceSubClass
1200 iDescriptors[KDescPosition_Device]->SetByte(6, device[6]); // bDeviceProtocol
1201 iDescriptors[KDescPosition_Device]->SetByte(8, device[8]); // idVendor
1202 iDescriptors[KDescPosition_Device]->SetByte(9, device[9]); // idVendor (part II)
1203 iDescriptors[KDescPosition_Device]->SetByte(10, device[10]); // idProduct
1204 iDescriptors[KDescPosition_Device]->SetByte(11, device[11]); // idProduct (part II)
1205 iDescriptors[KDescPosition_Device]->SetByte(12, device[12]); // bcdDevice
1206 iDescriptors[KDescPosition_Device]->SetByte(13, device[13]); // bcdDevice (part II)
1211 TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
1213 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigurationDescriptorTC()"));
1214 return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Config]->DescriptorData(), 0);
1218 TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
1220 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetConfigurationDescriptorTC()"));
1221 TBuf8<KUsbDescSize_Config> config;
1222 const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0);
1227 iDescriptors[KDescPosition_Config]->SetByte(7, config[7]); // bmAttributes
1228 iDescriptors[KDescPosition_Config]->SetByte(8, config[8]); // bMaxPower
1233 TInt TUsbcDescriptorPool::GetOtgDescriptorTC(DThread* aThread, TDes8& aBuffer) const
1235 return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Otg]->DescriptorData(), 0);
1239 TInt TUsbcDescriptorPool::SetOtgDescriptor(const TDesC8& aBuffer)
1241 iDescriptors[KDescPosition_Otg]->SetByte(2, aBuffer[2]); // bmAttributes
1246 TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
1247 TInt aInterface, TInt aSetting) const
1249 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetInterfaceDescriptorTC()"));
1250 const TInt i = FindIfcDescriptor(aInterface, aSetting);
1253 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1254 return KErrNotFound;
1256 return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
1260 TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting)
1262 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetInterfaceDescriptor()"));
1263 const TInt i = FindIfcDescriptor(aInterface, aSetting);
1266 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1267 return KErrNotFound;
1269 iDescriptors[i]->SetByte(2, aBuffer[2]); // bInterfaceNumber
1270 iDescriptors[i]->SetByte(5, aBuffer[5]); // bInterfaceClass
1271 iDescriptors[i]->SetByte(6, aBuffer[6]); // bInterfaceSubClass
1272 iDescriptors[i]->SetByte(7, aBuffer[7]); // bInterfaceProtocol
1277 TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer,
1278 TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const
1280 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorTC()"));
1281 const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1284 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1285 return KErrNotFound;
1287 return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
1291 TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer,
1292 TInt aInterface, TInt aSetting, TUint8 aEndpointAddress)
1294 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetEndpointDescriptorTC()"));
1295 const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1298 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1299 return KErrNotFound;
1301 TBuf8<KUsbDescSize_AudioEndpoint> ep; // it could be an audio endpoint
1302 const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, ep, 0);
1307 iDescriptors[i]->SetByte(3, ep[3]); // bmAttributes
1308 iDescriptors[i]->SetByte(6, ep[6]); // bInterval
1309 if (iDescriptors[i]->Size() == KUsbDescSize_AudioEndpoint)
1311 iDescriptors[i]->SetByte(7, ep[7]); // bRefresh
1312 iDescriptors[i]->SetByte(8, ep[8]); // bSynchAddress
1318 TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress,
1321 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorSize()"));
1322 const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1325 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1326 return KErrNotFound;
1328 aSize = iDescriptors[i]->Size();
1333 TInt TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC(DThread* aThread, TDes8& aBuffer) const
1335 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC()"));
1336 if (iDescriptors[KDescPosition_DeviceQualifier] == NULL)
1338 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Device_Qualifier descriptor not supported"));
1339 return KErrNotSupported;
1341 return Kern::ThreadDesWrite(aThread, &aBuffer,
1342 iDescriptors[KDescPosition_DeviceQualifier]->DescriptorData(), 0);
1346 TInt TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC(DThread* aThread, const TDes8& aBuffer)
1348 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC()"));
1349 if (iDescriptors[KDescPosition_DeviceQualifier] == NULL)
1351 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Device_Qualifier descriptor not supported"));
1352 return KErrNotSupported;
1354 TBuf8<KUsbDescSize_DeviceQualifier> device;
1355 const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0);
1360 iDescriptors[KDescPosition_DeviceQualifier]->SetByte(2, device[2]); // bcdUSB
1361 iDescriptors[KDescPosition_DeviceQualifier]->SetByte(3, device[3]); // bcdUSB (part II)
1362 iDescriptors[KDescPosition_DeviceQualifier]->SetByte(4, device[4]); // bDeviceClass
1363 iDescriptors[KDescPosition_DeviceQualifier]->SetByte(5, device[5]); // bDeviceSubClass
1364 iDescriptors[KDescPosition_DeviceQualifier]->SetByte(6, device[6]); // bDeviceProtocol
1369 TInt TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
1371 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC()"));
1372 if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL)
1374 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Other_Speed_Configuration descriptor not supported"));
1375 return KErrNotSupported;
1377 return Kern::ThreadDesWrite(aThread, &aBuffer,
1378 iDescriptors[KDescPosition_OtherSpeedConfig]->DescriptorData(), 0);
1382 TInt TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
1384 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC()"));
1385 if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL)
1387 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Other_Speed_Configuration descriptor not supported"));
1388 return KErrNotSupported;
1390 TBuf8<KUsbDescSize_OtherSpeedConfig> config;
1391 const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0);
1396 iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(7, config[7]); // bmAttributes
1397 iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(8, config[8]); // bMaxPower
1402 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
1403 TInt aInterface, TInt aSetting) const
1405 // first find the interface
1406 TInt i = FindIfcDescriptor(aInterface, aSetting);
1409 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1410 return KErrNotFound;
1412 TInt r = KErrNotFound;
1414 const TInt count = iDescriptors.Count();
1415 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
1417 r = Kern::ThreadDesWrite(aThread, &aBuffer,
1418 iDescriptors[i]->DescriptorData(), offset);
1421 offset += iDescriptors[i]->Size();
1427 TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer,
1428 TInt aInterface, TInt aSetting, TInt aSize)
1430 // First find the interface
1431 TInt i = FindIfcDescriptor(aInterface, aSetting);
1434 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1435 return KErrNotFound;
1437 // Find a position where to insert the new class specific interface descriptor(s)
1438 const TInt count = iDescriptors.Count();
1439 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
1441 // Create a new cs descriptor
1442 TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize);
1445 return KErrNoMemory;
1447 __KTRACE_OPT(KUSB, Kern::Printf(" inserting descriptor at position %d", i));
1448 iDescriptors.Insert(desc, i);
1450 // Update the config descriptor's wTotalLength field
1451 UpdateConfigDescriptorLength(aSize);
1453 // Copy contents from the user side
1454 return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
1458 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const
1460 // first find the interface
1461 TInt i = FindIfcDescriptor(aInterface, aSetting);
1464 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1465 return KErrNotFound;
1467 TInt r = KErrNotFound;
1469 const TInt count = iDescriptors.Count();
1470 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
1472 size += iDescriptors[i]->Size();
1481 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface,
1482 TInt aSetting, TUint8 aEndpointAddress) const
1484 // first find the endpoint
1485 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1488 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1489 return KErrNotFound;
1491 TInt r = KErrNotFound;
1493 const TInt count = iDescriptors.Count();
1494 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
1496 r = Kern::ThreadDesWrite(aThread, &aBuffer,
1497 iDescriptors[i]->DescriptorData(), offset);
1500 offset += iDescriptors[i]->Size();
1506 TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface,
1507 TInt aSetting, TUint8 aEndpointAddress, TInt aSize)
1509 // first find the endpoint
1510 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1513 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1514 return KErrNotFound;
1516 // find a position where to insert the new class specific endpoint descriptor(s)
1517 const TInt count = iDescriptors.Count();
1518 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
1520 // create a new cs descriptor
1521 TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize);
1524 return KErrNoMemory;
1526 iDescriptors.Insert(desc, i);
1527 // update the config descriptor's wTotalLength field
1528 UpdateConfigDescriptorLength(aSize);
1529 // copy contents from user side
1530 return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
1534 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting,
1535 TUint8 aEndpointAddress, TInt& aSize) const
1537 // first find the endpoint
1538 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1541 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1542 return KErrNotFound;
1544 TInt r = KErrNotFound;
1546 const TInt count = iDescriptors.Count();
1547 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
1549 size += iDescriptors[i]->Size();
1558 TInt TUsbcDescriptorPool::GetStringDescriptorLangIdTC(DThread* aThread, TDes8& aLangId) const
1560 const TUint16 id = iStrings[KStringPosition_Langid]->Word(2);
1561 const TPtrC8 id_des(reinterpret_cast<const TUint8*>(&id), sizeof(id));
1562 return Kern::ThreadDesWrite(aThread, &aLangId, id_des, 0);
1566 TInt TUsbcDescriptorPool::SetStringDescriptorLangId(TUint16 aLangId)
1568 iStrings[KStringPosition_Langid]->SetWord(2, aLangId);
1573 TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const
1575 return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact,
1576 KStringPosition_Manufact);
1580 TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString)
1582 return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact,
1583 KStringPosition_Manufact);
1587 TInt TUsbcDescriptorPool::RemoveManufacturerStringDescriptor()
1589 return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Manufact, KStringPosition_Manufact);
1593 TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const
1595 return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product,
1596 KStringPosition_Product);
1600 TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString)
1602 return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product,
1603 KStringPosition_Product);
1607 TInt TUsbcDescriptorPool::RemoveProductStringDescriptor()
1609 return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Product, KStringPosition_Product);
1613 TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const
1615 return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial,
1616 KStringPosition_Serial);
1620 TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString)
1622 return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial,
1623 KStringPosition_Serial);
1627 TInt TUsbcDescriptorPool::RemoveSerialNumberStringDescriptor()
1629 return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Serial, KStringPosition_Serial);
1633 TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const
1635 const TInt str_idx = iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config);
1638 __ASSERT_ALWAYS((str_idx == KStringPosition_Config), Kern::Fault(KUsbPanicCat, __LINE__));
1639 __KTRACE_OPT(KUSB, Kern::Printf(" String @ pos %d (conf $): \"%S\"",
1640 str_idx, &iStrings[str_idx]->StringData()));
1641 return Kern::ThreadDesWrite(aThread, &aString,
1642 iStrings[str_idx]->StringData(), 0);
1646 __KTRACE_OPT(KUSB, Kern::Printf(" No config string descriptor @ pos %d", str_idx));
1647 return KErrNotFound;
1652 TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString)
1654 // we don't know the length of the string, so we have to allocate memory dynamically
1655 TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
1656 if (strlen > KUsbStringDescStringMaxSize)
1658 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: config $ descriptor too long - will be truncated"));
1659 strlen = KUsbStringDescStringMaxSize;
1661 HBuf8* const strbuf = HBuf8::New(strlen);
1664 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config $ desc string failed (1)"));
1665 return KErrNoMemory;
1668 // the aString points to data that lives in user memory, so we have to copy it:
1669 const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
1672 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Thread read error"));
1676 TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
1679 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config $ desc failed (2)"));
1681 return KErrNoMemory;
1683 // Delete old string, put in new one
1684 ExchangeStringDescriptor(KStringPosition_Config, sd);
1685 // Update Config descriptor string index field
1686 iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, KStringPosition_Config);
1687 // Update Other_Speed_Config descriptor string index field as well, if applicable
1688 if (iDescriptors[KDescPosition_OtherSpeedConfig])
1689 iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config,
1690 KStringPosition_Config);
1696 TInt TUsbcDescriptorPool::RemoveConfigurationStringDescriptor()
1698 if (iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config) == 0)
1700 __KTRACE_OPT(KUSB, Kern::Printf(" RemoveConfigurationStringDescriptor: no $ desc @ index %d",
1701 KUsbDescStringIndex_Config));
1702 return KErrNotFound;
1704 // Delete old string, put in NULL pointer
1705 ExchangeStringDescriptor(KStringPosition_Config, NULL);
1706 // Update Config descriptor string index field
1707 iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, 0);
1708 // Update Other_Speed_Config descriptor string index field as well, if applicable
1709 if (iDescriptors[KDescPosition_OtherSpeedConfig])
1710 iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config, 0);
1715 TInt TUsbcDescriptorPool::GetStringDescriptorTC(DThread* aThread, TInt aIndex, TDes8& aString) const
1717 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptorTC()"));
1718 if (!StringDescriptorExists(aIndex))
1720 return KErrNotFound;
1722 __KTRACE_OPT(KUSB, Kern::Printf(" String @ pos %d: \"%S\"",
1723 aIndex, &iStrings[aIndex]->StringData()));
1724 return Kern::ThreadDesWrite(aThread, &aString, iStrings[aIndex]->StringData(), 0);
1728 TInt TUsbcDescriptorPool::SetStringDescriptorTC(DThread* aThread, TInt aIndex, const TDes8& aString)
1730 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetStringDescriptorTC()"));
1731 // we don't know the length of the string, so we have to allocate memory dynamically
1732 TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
1733 if (strlen > KUsbStringDescStringMaxSize)
1735 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: $ descriptor too long - will be truncated"));
1736 strlen = KUsbStringDescStringMaxSize;
1738 HBuf8* strbuf = HBuf8::New(strlen);
1741 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Mem alloc for $ desc string failed (1)"));
1742 return KErrNoMemory;
1745 // the aString points to data that lives in user memory, so we have to copy it over:
1746 const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
1749 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Thread read error"));
1753 TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf);
1756 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Mem alloc for $ desc failed (2)"));
1758 return KErrNoMemory;
1760 if (aIndex < iStrings.Count())
1762 ExchangeStringDescriptor(aIndex, sd);
1764 else // if (aIndex >= iStrings.Count())
1766 while (aIndex > iStrings.Count())
1768 iStrings.Append(NULL);
1770 iStrings.Append(sd);
1777 TInt TUsbcDescriptorPool::RemoveStringDescriptor(TInt aIndex)
1779 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveStringDescriptor()"));
1780 if (!StringDescriptorExists(aIndex))
1782 return KErrNotFound;
1784 __KTRACE_OPT(KUSB, Kern::Printf(" Removing string @ pos %d: \"%S\"",
1785 aIndex, &iStrings[aIndex]->StringData()));
1786 ExchangeStringDescriptor(aIndex, NULL);
1788 // Make sure there's no $ after aIndex.
1789 const TInt n = iStrings.Count();
1790 for (TInt i = aIndex; i < n; i++)
1792 if (iStrings[i] != NULL)
1794 __KTRACE_OPT(KUSB, Kern::Printf(" Found $ @ idx %d - not compressing", i));
1799 __KTRACE_OPT(KUSB, Kern::Printf(" No $ found after idx %d - compressing array", aIndex));
1800 // Move aIndex back just before the first !NULL element.
1801 while (iStrings[--aIndex] == NULL)
1803 // Let aIndex point to first NULL.
1805 __KTRACE_OPT(KUSB, Kern::Printf(" Starting at index %d", aIndex));
1806 // Now remove NULL pointers until (Count() == aIndex).
1807 __KTRACE_OPT(KUSB, Kern::Printf(" iStrings.Count() before: %d", iStrings.Count()));
1810 iStrings.Remove(aIndex);
1811 __KTRACE_OPT(KUSB, Kern::Printf(" Removing $"));
1813 while (iStrings.Count() > aIndex);
1814 __KTRACE_OPT(KUSB, Kern::Printf(" iStrings.Count() after: %d", iStrings.Count()));
1816 // Regain some memory.
1817 iStrings.Compress();
1823 // ===================================================================
1825 // ===================================================================
1828 // Insert an Interface descriptor into the descriptor array at the appropriate index.
1830 void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc)
1832 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertIfcDesc()"));
1834 const TInt count = iDescriptors.Count();
1835 TBool ifc_exists = EFalse; // set to 'true' if we're adding an alternate
1836 // setting to an already existing interface
1837 TInt i = KDescPosition_FirstAvailable;
1840 __KTRACE_OPT(KUSB, Kern::Printf(" already descriptors there (%d)...", count));
1841 if (iDescriptors[i]->Type() == KUsbDescType_Interface)
1843 if (iDescriptors[i]->Byte(2) > aDesc->Byte(2))
1845 // our interface number is less than the one's just found => insert before it (= here)
1848 else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2))
1851 // same interface number => look at settings number
1852 if (iDescriptors[i]->Byte(3) > aDesc->Byte(3))
1854 // our setting number is less than the one's found => insert before (= here)
1857 else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3))
1859 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: first delete old desc "
1860 "(TUsbcDescriptorPool::InsertIfcDesc)"));
1867 // In any case: put the new descriptor at position i.
1868 __KTRACE_OPT(KUSB, Kern::Printf(" inserting descriptor at position %d", i));
1869 iDescriptors.Insert(aDesc, i);
1871 // Update the config descriptor's wTotalLength field.
1872 UpdateConfigDescriptorLength(KUsbDescSize_Interface);
1876 // If this is the first setting for the interface, increment bNumInterfaces.
1877 UpdateConfigDescriptorNumIfcs(1);
1885 // Insert an Endpoint descriptor into the descriptor array at the appropriate index.
1887 void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc)
1889 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertEpDesc()"));
1892 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: only after interface "
1893 "(TUsbcDescriptorPool::InsertEpDesc)"));
1896 const TInt count = iDescriptors.Count();
1897 TInt i = iIfcIdx + 1;
1900 if (iDescriptors[i]->Type() != KUsbDescType_Endpoint)
1904 // put the new descriptor at position i
1905 iDescriptors.Insert(aDesc, i);
1906 // update the config descriptor's wTotalLength field
1907 UpdateConfigDescriptorLength(aDesc->Size());
1912 // Find the index of the Interface descriptor for a given interface setting.
1914 TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const
1916 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)",
1917 aIfcNumber, aIfcSetting));
1918 const TInt count = iDescriptors.Count();
1919 for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
1921 if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
1922 (iDescriptors[i]->Byte(2) == aIfcNumber) &&
1923 (iDescriptors[i]->Byte(3) == aIfcSetting))
1928 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1934 // Find the index of the Endpoint descriptor for a given endpoint on a given interface setting.
1936 TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const
1938 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)",
1939 aIfcNumber, aIfcSetting, aEpAddress));
1940 // first find the interface
1941 const TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting);
1944 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface"));
1947 const TInt count = iDescriptors.Count();
1948 // then, before the next interface, try to locate the endpoint
1949 for (TInt i = ifc + 1; i < count; i++)
1951 if (iDescriptors[i]->Type() == KUsbDescType_Interface)
1953 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint before next interface"));
1956 else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) &&
1957 (iDescriptors[i]->Byte(2) == aEpAddress))
1963 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint"));
1969 // Delete n descriptors starting from aIndex and remove their pointers from the array.
1971 void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount)
1973 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteDescriptors()"));
1974 if (aIndex < KDescPosition_FirstAvailable)
1976 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: aIndex < KDescPosition_FirstAvailable"));
1981 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: aCount <= 0"));
1984 __KTRACE_OPT(KUSB, Kern::Printf(" Removing descriptors at index %d:", aIndex));
1985 // Try to update wTotalLength field in Config descriptor
1988 // In this loop we don't decrement aIndex, because after deleting an element
1989 // aIndex is already indexing the next one.
1990 TUsbcDescriptorBase* const ptr = iDescriptors[aIndex];
1991 switch (ptr->Type())
1993 case KUsbDescType_Interface:
1994 __KTRACE_OPT(KUSB, Kern::Printf(" - an interface descriptor"));
1995 UpdateConfigDescriptorLength(-KUsbDescSize_Interface);
1997 case KUsbDescType_Endpoint:
1998 __KTRACE_OPT(KUSB, Kern::Printf(" - an endpoint descriptor"));
1999 UpdateConfigDescriptorLength(-ptr->Size());
2001 case KUsbDescType_CS_Interface:
2003 case KUsbDescType_CS_Endpoint:
2004 __KTRACE_OPT(KUSB, Kern::Printf(" - a class specific descriptor"));
2005 UpdateConfigDescriptorLength(-ptr->Size());
2008 __KTRACE_OPT(KUSB, Kern::Printf(" - an unknown descriptor"));
2009 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: unknown descriptor type"));
2011 iDescriptors.Remove(aIndex);
2018 // Update the wTotalLength field in the Configuration descriptor (aLength can be negative).
2020 void TUsbcDescriptorPool::UpdateConfigDescriptorLength(TInt aLength)
2022 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorLength(%d)", aLength));
2023 TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config];
2024 __KTRACE_OPT(KUSB, Kern::Printf(" wTotalLength old: %d", cnf->Word(2)));
2025 // Update Config descriptor
2026 cnf->SetWord(2, cnf->Word(2) + aLength);
2027 __KTRACE_OPT(KUSB, Kern::Printf(" wTotalLength new: %d", cnf->Word(2)));
2028 // Update Other_Speed_Config descriptor as well, if applicable
2029 if (iDescriptors[KDescPosition_OtherSpeedConfig])
2030 iDescriptors[KDescPosition_OtherSpeedConfig]->SetWord(2, cnf->Word(2));
2035 // Update the bNumInterfaces field in the Configuration descriptor (aNumber can be negative).
2037 void TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(TInt aNumber)
2039 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(%d)", aNumber));
2040 TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config];
2041 __KTRACE_OPT(KUSB, Kern::Printf(" bNumInterfaces old: %d", cnf->Byte(4)));
2042 const TInt n = cnf->Byte(4) + aNumber;
2045 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bNumInterfaces + aNumber < 0"));
2048 // Update Config descriptor
2050 __KTRACE_OPT(KUSB, Kern::Printf(" bNumInterfaces new: %d", cnf->Byte(4)));
2051 // Update Other_Speed_Config descriptor as well, if applicable
2052 if (iDescriptors[KDescPosition_OtherSpeedConfig])
2053 iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(4, n);
2058 // Update the bNumInterfaces field in the Configuration descriptor if necessary.
2060 void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber)
2062 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateIfcNumbers(%d)", aNumber));
2063 const TInt count = iDescriptors.Count();
2064 for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
2066 if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
2067 (iDescriptors[i]->Byte(2) == aNumber))
2069 // there's still an interface with 'number' so we don't need to update anything
2073 // if we haven't returned yet, we decrement bNumInterfaces
2074 UpdateConfigDescriptorNumIfcs(-1);
2079 // Put the current Device or Device_Qualifier descriptor in the Ep0 Tx buffer.
2080 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
2082 TInt TUsbcDescriptorPool::GetDeviceDescriptor(TInt aIndex) const
2084 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptor()"));
2085 __ASSERT_DEBUG((aIndex == KDescPosition_Device) || (aIndex == KDescPosition_DeviceQualifier),
2086 Kern::Printf(" Error: invalid descriptor index: %d", aIndex));
2087 if (iDescriptors[aIndex] == NULL)
2089 // This doesn't have to be an error - we might get asked here for the Device_Qualifier descriptor
2090 // on a FS-only device.
2091 __KTRACE_OPT(KUSB, Kern::Printf(" Descriptor #%d requested but not available", aIndex));
2094 return iDescriptors[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
2099 // Put the current Configuration or Other_Speed_Configuration descriptor + all the following
2100 // descriptors in the Ep0 Tx buffer.
2101 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
2103 TInt TUsbcDescriptorPool::GetConfigurationDescriptor(TInt aIndex) const
2105 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigDescriptor(%d)", aIndex));
2106 __ASSERT_DEBUG((aIndex == KDescPosition_Config) || (aIndex == KDescPosition_OtherSpeedConfig),
2107 Kern::Printf(" Error: invalid descriptor index: %d", aIndex));
2108 if (iDescriptors[aIndex] == NULL)
2110 // This is always an error: We should always have a Configuration descriptor and we should never
2111 // get asked for the Other_Speed_Configuration descriptor if we don't have one (9.6.2).
2112 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Descriptor %d requested but not available", aIndex));
2115 const TInt count = iDescriptors.Count();
2117 TUint8* buf = iEp0_TxBuf;
2118 for (TInt i = aIndex; i < count; i++)
2120 TUsbcDescriptorBase* const ptr = iDescriptors[i];
2121 if ((aIndex == KDescPosition_OtherSpeedConfig) && (i == KDescPosition_Config))
2123 // Skip Config descriptor when returning Other_Speed_Config
2126 if ((i == KDescPosition_Otg) && (iDescriptors[i] == NULL))
2128 __KTRACE_OPT(KUSB, Kern::Printf(" no OTG descriptor -> next"));
2131 // We need to edit endpoint descriptors on the fly because we have only one copy
2132 // of each and that copy has to contain different information, depending on the
2133 // current speed and the type of descriptor requested.
2134 if (ptr->Type() == KUsbDescType_Endpoint)
2136 if ((iHighSpeed && (aIndex == KDescPosition_Config)) ||
2137 (!iHighSpeed && (aIndex == KDescPosition_OtherSpeedConfig)))
2146 __KTRACE_OPT(KUSB, Kern::Printf(" desc[%02d]: type = 0x%02x size = %d ",
2147 i, ptr->Type(), ptr->Size()));
2148 const TInt size = ptr->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied);
2151 __KTRACE_OPT(KPANIC,
2152 Kern::Printf(" Error: No Tx buffer space to copy this descriptor -> exiting"));
2156 if (copied >= KUsbcBufSz_Ep0Tx)
2158 __KTRACE_OPT(KPANIC,
2159 Kern::Printf(" Error: No Tx buffer space left -> stopping here"));
2164 __KTRACE_OPT(KUSB, Kern::Printf(" copied %d bytes", copied));
2170 // Put the current OTG descriptor in the Ep0 Tx buffer.
2171 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
2173 TInt TUsbcDescriptorPool::GetOtgDescriptor() const
2175 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtgDescriptor()"));
2176 if (iDescriptors[KDescPosition_Otg] == NULL)
2178 __KTRACE_OPT(KUSB, Kern::Printf(" OTG Descriptor not set"));
2181 return iDescriptors[KDescPosition_Otg]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
2186 // Put a specific String descriptor in the Ep0 Tx buffer.
2187 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
2189 TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const
2191 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptor(%d)", aIndex));
2192 // I really would have liked to display the descriptor contents here, but without trailing zero
2193 // we got a problem: how can we tell printf where the string ends? We would have to
2194 // dynamically allocate memory (since we don't know the size in advance), copy the descriptor
2195 // contents there, append a zero, and give this to printf. That's a bit too much effort...
2196 if (!StringDescriptorExists(aIndex))
2200 return iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
2205 // Write a String descriptor pointed to by the Device descriptor to the user side
2206 // (one of Manufacturer, Product, SerialNumber).
2208 TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString,
2209 TInt aIndex, TInt aPosition) const
2211 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceStringDescriptorTC()"));
2212 const TInt str_idx = iDescriptors[KDescPosition_Device]->Byte(aIndex);
2215 __ASSERT_ALWAYS((str_idx == aPosition), Kern::Fault(KUsbPanicCat, __LINE__));
2216 __KTRACE_OPT(KUSB, Kern::Printf(" String @ pos %d (device $): \"%S\"",
2217 str_idx, &iStrings[str_idx]->StringData()));
2218 return Kern::ThreadDesWrite(aThread, &aString,
2219 iStrings[str_idx]->StringData(), 0);
2223 __KTRACE_OPT(KUSB, Kern::Printf(" No string descriptor @ pos %d", aIndex));
2224 return KErrNotFound;
2230 // Read a Device String descriptor from the user side and put in the descriptor arrays
2231 // (one of Manufacturer, Product, SerialNumber).
2233 TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString,
2234 TInt aIndex, TInt aPosition)
2236 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceStringDescriptorTC()"));
2237 // we don't know the length of the string, so we have to allocate memory dynamically
2238 TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
2239 if (strlen > KUsbStringDescStringMaxSize)
2241 __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: $ descriptor too long - will be truncated"));
2242 strlen = KUsbStringDescStringMaxSize;
2244 HBuf8* const strbuf = HBuf8::New(strlen);
2247 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev $ desc string failed (1)"));
2248 return KErrNoMemory;
2251 // the aString points to data that lives in user memory, so we have to copy it:
2252 const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
2255 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Thread read error"));
2259 TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf);
2262 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev $ desc failed (2)"));
2264 return KErrNoMemory;
2266 ExchangeStringDescriptor(aPosition, sd);
2267 iDescriptors[KDescPosition_Device]->SetByte(aIndex, aPosition);
2274 // Remove a Device String descriptor from the descriptor arrays
2275 // (one of Manufacturer, Product, SerialNumber).
2277 TInt TUsbcDescriptorPool::RemoveDeviceStringDescriptor(TInt aIndex, TInt aPosition)
2279 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveDeviceStringDescriptor()"));
2280 if (iDescriptors[KDescPosition_Device]->Byte(aIndex) == 0)
2282 __KTRACE_OPT(KUSB, Kern::Printf(" RemoveDeviceStringDescriptor: no $ desc @ index %d", aIndex));
2283 return KErrNotFound;
2285 ExchangeStringDescriptor(aPosition, NULL);
2286 iDescriptors[KDescPosition_Device]->SetByte(aIndex, 0);
2292 // Puts aDesc at postion aIndex in the string descriptor array, after deleting what was (possibly) there.
2294 void TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc)
2296 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::ExchangeStringDescriptor()"));
2297 TUsbcStringDescriptorBase* const ptr = iStrings[aIndex];
2298 __KTRACE_OPT(KUSB, Kern::Printf(" Deleting string descriptor at index %d: 0x%x", aIndex, ptr));
2299 iStrings.Remove(aIndex);
2301 __KTRACE_OPT(KUSB, Kern::Printf(" Inserting string descriptor at index %d: 0x%x", aIndex, aDesc));
2302 iStrings.Insert(aDesc, aIndex);
2307 // Checks whether there are any string descriptors in the array (apart from LangID).
2309 TBool TUsbcDescriptorPool::AnyStringDescriptors() const
2311 const TInt n = iStrings.Count();
2312 for (TInt i = 1; i < n; i++)
2314 if (iStrings[i] != NULL)
2322 // Returns true if aIndex exists and what is at that positition is not a NULL pointer.
2324 TBool TUsbcDescriptorPool::StringDescriptorExists(TInt aIndex) const
2326 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::StringDescriptorExists()"));
2327 if (aIndex >= iStrings.Count())
2329 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Bad string index: %d", aIndex));
2332 else if (iStrings[aIndex] == NULL)
2334 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No $ descriptor @ pos %d", aIndex));
2344 TInt TUsbcDescriptorPool::FindAvailableStringPos() const
2346 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindAvailableStringPos()"));
2347 const TInt n = iStrings.Count();
2348 // We don't start from 0 because the first few locations are 'reserved'.
2349 for (TInt i = KStringPosition_FirstAvailable; i < n; i++)
2351 if (iStrings[i] == NULL)
2353 __KTRACE_OPT(KUSB, Kern::Printf(" Found available NULL position: %d", i));