usbdrv/peripheral/pdd/pil/src/descriptors.cpp
branchRCL_3
changeset 15 f92a4f87e424
equal deleted inserted replaced
14:d3e8e7d462dd 15:f92a4f87e424
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32/drivers/usbcc/descriptors.cpp
       
    15 // Platform independent layer (PIL) of the USB Device controller driver:
       
    16 // USB descriptor handling and management.
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file descriptors.cpp
       
    22  @internalTechnology
       
    23 */
       
    24 
       
    25 #include <kernel/kern_priv.h>
       
    26 // #include <drivers/usbc.h>
       
    27 #include <usb/usbc.h>
       
    28 
       
    29 
       
    30 // Debug Support
       
    31 static const char KUsbPanicCat[] = "USB PIL";
       
    32 
       
    33 
       
    34 // --- TUsbcDescriptorBase
       
    35 
       
    36 TUsbcDescriptorBase::TUsbcDescriptorBase()
       
    37     :
       
    38 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
       
    39     iIndex(0),
       
    40 #endif
       
    41     iBufPtr(NULL, 0)
       
    42     {
       
    43     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::TUsbcDescriptorBase()"));
       
    44     }
       
    45 
       
    46 
       
    47 TUsbcDescriptorBase::~TUsbcDescriptorBase()
       
    48     {
       
    49     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::~TUsbcDescriptorBase()"));
       
    50     }
       
    51 
       
    52 
       
    53 void TUsbcDescriptorBase::SetByte(TInt aPosition, TUint8 aValue)
       
    54     {
       
    55     iBufPtr[aPosition] = aValue;
       
    56     }
       
    57 
       
    58 
       
    59 void TUsbcDescriptorBase::SetWord(TInt aPosition, TUint16 aValue)
       
    60     {
       
    61     *reinterpret_cast<TUint16*>(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue);
       
    62     }
       
    63 
       
    64 
       
    65 TUint8 TUsbcDescriptorBase::Byte(TInt aPosition) const
       
    66     {
       
    67     return iBufPtr[aPosition];
       
    68     }
       
    69 
       
    70 
       
    71 TUint16 TUsbcDescriptorBase::Word(TInt aPosition) const
       
    72     {
       
    73     return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition]));
       
    74     }
       
    75 
       
    76 
       
    77 void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const
       
    78     {
       
    79     aBuffer = iBufPtr;
       
    80     }
       
    81 
       
    82 
       
    83 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
       
    84     {
       
    85     memcpy(aBuffer, iBufPtr.Ptr(), Size());
       
    86     return Size();
       
    87     }
       
    88 
       
    89 
       
    90 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const
       
    91     {
       
    92     if (aMaxSize < Size())
       
    93         {
       
    94         // No use to copy only half a descriptor
       
    95         return 0;
       
    96         }
       
    97     return GetDescriptorData(aBuffer);
       
    98     }
       
    99 
       
   100 
       
   101 const TDes8& TUsbcDescriptorBase::DescriptorData() const
       
   102     {
       
   103     return iBufPtr;
       
   104     }
       
   105 
       
   106 
       
   107 TDes8& TUsbcDescriptorBase::DescriptorData()
       
   108     {
       
   109     return iBufPtr;
       
   110     }
       
   111 
       
   112 
       
   113 TUint TUsbcDescriptorBase::Size() const
       
   114     {
       
   115     return iBufPtr.Size();
       
   116     }
       
   117 
       
   118 
       
   119 TUint8 TUsbcDescriptorBase::Type() const
       
   120     {
       
   121     return iBufPtr[1];
       
   122     }
       
   123 
       
   124 
       
   125 void TUsbcDescriptorBase::UpdateFs()
       
   126     {
       
   127     // virtual function can be overridden in derived classes.
       
   128     return;
       
   129     }
       
   130 
       
   131 
       
   132 void TUsbcDescriptorBase::UpdateHs()
       
   133     {
       
   134     // virtual function can be overridden in derived classes.
       
   135     return;
       
   136     }
       
   137 
       
   138 
       
   139 void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes)
       
   140     {
       
   141     iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
       
   142     }
       
   143 
       
   144 
       
   145 // --- TUsbcDeviceDescriptor
       
   146 
       
   147 TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()
       
   148     : iBuf()
       
   149     {
       
   150     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()"));
       
   151     }
       
   152 
       
   153 
       
   154 TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
       
   155                                                   TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
       
   156                                                   TUint16 aVendorId, TUint16 aProductId,
       
   157                                                   TUint16 aDeviceRelease, TUint8 aNumConfigurations)
       
   158     {
       
   159     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::New()"));
       
   160     TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor();
       
   161     if (self)
       
   162         {
       
   163         if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId,
       
   164                             aProductId, aDeviceRelease, aNumConfigurations) != KErrNone)
       
   165             {
       
   166             delete self;
       
   167             return NULL;
       
   168             }
       
   169         }
       
   170     return self;
       
   171     }
       
   172 
       
   173 
       
   174 TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
       
   175                                       TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
       
   176                                       TUint16 aDeviceRelease, TUint8 aNumConfigurations)
       
   177     {
       
   178     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::Construct()"));
       
   179     iBuf.SetMax();
       
   180     SetBufferPointer(iBuf);
       
   181     iBuf[0] = iBuf.Size();                                    // bLength
       
   182     iBuf[1] = KUsbDescType_Device;                            // bDescriptorType
       
   183     SetWord(2, KUsbcUsbVersion);                            // bcdUSB
       
   184     iBuf[4] = aDeviceClass;                                    // bDeviceClass
       
   185     iBuf[5] = aDeviceSubClass;                                // bDeviceSubClass
       
   186     iBuf[6] = aDeviceProtocol;                                // bDeviceProtocol
       
   187     iBuf[7] = aMaxPacketSize0;                                // bMaxPacketSize0
       
   188     SetWord(8, aVendorId);                                    // idVendor
       
   189     SetWord(10, aProductId);                                // idProduct
       
   190     SetWord(12, aDeviceRelease);                            // bcdDevice
       
   191     iBuf[14] = 0;                                            // iManufacturer
       
   192     iBuf[15] = 0;                                            // iProduct
       
   193     iBuf[16] = 0;                                            // iSerialNumber
       
   194     iBuf[17] = aNumConfigurations;                            // bNumConfigurations
       
   195     iEp0Size_Fs = aMaxPacketSize0;
       
   196     return KErrNone;
       
   197     }
       
   198 
       
   199 
       
   200 void TUsbcDeviceDescriptor::UpdateFs()
       
   201     {
       
   202     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateFs()"));
       
   203     SetByte(7, iEp0Size_Fs);                                // bMaxPacketSize0
       
   204     }
       
   205 
       
   206 
       
   207 void TUsbcDeviceDescriptor::UpdateHs()
       
   208     {
       
   209     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateHs()"));
       
   210     SetByte(7, 64);                                            // bMaxPacketSize0
       
   211     }
       
   212 
       
   213 
       
   214 // --- TUsbcDeviceQualifierDescriptor
       
   215 
       
   216 TUsbcDeviceQualifierDescriptor::TUsbcDeviceQualifierDescriptor()
       
   217     : iBuf()
       
   218     {
       
   219     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceQualifierDescriptor()"));
       
   220     }
       
   221 
       
   222 
       
   223 TUsbcDeviceQualifierDescriptor* TUsbcDeviceQualifierDescriptor::New(TUint8 aDeviceClass,
       
   224                                                                     TUint8 aDeviceSubClass,
       
   225                                                                     TUint8 aDeviceProtocol,
       
   226                                                                     TUint8 aMaxPacketSize0,
       
   227                                                                     TUint8 aNumConfigurations,
       
   228                                                                     TUint8 aReserved)
       
   229     {
       
   230     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::New()"));
       
   231     TUsbcDeviceQualifierDescriptor* self = new TUsbcDeviceQualifierDescriptor();
       
   232     if (self)
       
   233         {
       
   234         if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0,
       
   235                             aNumConfigurations, aReserved) != KErrNone)
       
   236             {
       
   237             delete self;
       
   238             return NULL;
       
   239             }
       
   240         }
       
   241     return self;
       
   242     }
       
   243 
       
   244 
       
   245 TInt TUsbcDeviceQualifierDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
       
   246                                                TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
       
   247                                                TUint8 aNumConfigurations, TUint8 aReserved)
       
   248     {
       
   249     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::Construct()"));
       
   250     iBuf.SetMax();
       
   251     SetBufferPointer(iBuf);
       
   252     iBuf[0] = iBuf.Size();                                    // bLength
       
   253     iBuf[1] = KUsbDescType_DeviceQualifier;                    // bDescriptorType
       
   254     SetWord(2, KUsbcUsbVersion);                            // bcdUSB
       
   255     iBuf[4] = aDeviceClass;                                    // bDeviceClass
       
   256     iBuf[5] = aDeviceSubClass;                                // bDeviceSubClass
       
   257     iBuf[6] = aDeviceProtocol;                                // bDeviceProtocol
       
   258     iBuf[7] = aMaxPacketSize0;                                // bMaxPacketSize0
       
   259     iBuf[8] = aNumConfigurations;                            // bNumConfigurations
       
   260     if (aReserved) aReserved = 0;
       
   261     iBuf[9] = aReserved;                                    // Reserved for future use, must be zero
       
   262     iEp0Size_Fs = aMaxPacketSize0;
       
   263     return KErrNone;
       
   264     }
       
   265 
       
   266 
       
   267 void TUsbcDeviceQualifierDescriptor::UpdateFs()
       
   268     {
       
   269     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateFs()"));
       
   270     // Here we do exactly the opposite of what's done in the Device descriptor (as this one's
       
   271     // documenting the 'other than the current speed').
       
   272     SetByte(7, 64);                                            // bMaxPacketSize0
       
   273     }
       
   274 
       
   275 
       
   276 void TUsbcDeviceQualifierDescriptor::UpdateHs()
       
   277     {
       
   278     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateHs()"));
       
   279     // Here we do exactly the opposite of what's done in the Device descriptor (as this one's
       
   280     // documenting the 'other than the current speed').
       
   281     SetByte(7, iEp0Size_Fs);                                // bMaxPacketSize0
       
   282     }
       
   283 
       
   284 
       
   285 // --- TUsbcConfigDescriptor
       
   286 
       
   287 TUsbcConfigDescriptor::TUsbcConfigDescriptor()
       
   288     : iBuf()
       
   289     {
       
   290     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::TUsbcConfigDescriptor()"));
       
   291     }
       
   292 
       
   293 
       
   294 TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered,
       
   295                                                   TBool aRemoteWakeup, TUint16 aMaxPower)
       
   296     {
       
   297     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::New()"));
       
   298     TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor();
       
   299     if (self)
       
   300         {
       
   301         if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone)
       
   302             {
       
   303             delete self;
       
   304             return NULL;
       
   305             }
       
   306         }
       
   307     return self;
       
   308     }
       
   309 
       
   310 
       
   311 TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered,
       
   312                                        TBool aRemoteWakeup, TUint16 aMaxPower)
       
   313     {
       
   314     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::Construct()"));
       
   315     iBuf.SetMax();
       
   316     SetBufferPointer(iBuf);
       
   317     iBuf[0] = iBuf.Size();                                    // bLength
       
   318     iBuf[1] = KUsbDescType_Config;                            // bDescriptorType
       
   319     SetWord(2, KUsbDescSize_Config);                        // wTotalLength
       
   320     iBuf[4] = 0;                                            // bNumInterfaces
       
   321     iBuf[5] = aConfigurationValue;                            // bConfigurationValue
       
   322     iBuf[6] = 0;                                            // iConfiguration
       
   323     iBuf[7] = 0x80 |
       
   324         (aSelfPowered ? KUsbDevAttr_SelfPowered : 0) |
       
   325         (aRemoteWakeup ? KUsbDevAttr_RemoteWakeup : 0);        // bmAttributes (bit 7 always 1)
       
   326     if (aMaxPower > 510)
       
   327         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid value for bMaxPower: %d", aMaxPower));
       
   328     iBuf[8] = aMaxPower / 2;                                // bMaxPower (2mA units!)
       
   329     return KErrNone;
       
   330     }
       
   331 
       
   332 
       
   333 // --- TUsbcInterfaceDescriptor
       
   334 
       
   335 TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()
       
   336     : iBuf()
       
   337     {
       
   338     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()"));
       
   339     }
       
   340 
       
   341 
       
   342 TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
       
   343                                                         TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
       
   344     {
       
   345     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::New()"));
       
   346     TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor();
       
   347     if (self)
       
   348         {
       
   349         if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone)
       
   350             {
       
   351             delete self;
       
   352             return NULL;
       
   353             }
       
   354         }
       
   355     return self;
       
   356     }
       
   357 
       
   358 
       
   359 TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
       
   360                                          TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
       
   361     {
       
   362     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::Construct()"));
       
   363     iBuf.SetMax();
       
   364     SetBufferPointer(iBuf);
       
   365     iBuf[0] = iBuf.Size();                                    // bLength
       
   366     iBuf[1] = KUsbDescType_Interface;                        // bDescriptorType
       
   367     iBuf[2] = aInterfaceNumber;                                // bInterfaceNumber
       
   368     iBuf[3] = aAlternateSetting;                            // bAlternateSetting
       
   369     iBuf[4] = aNumEndpoints;                                // bNumEndpoints
       
   370     iBuf[5] = aClassInfo.iClassNum;                            // bInterfaceClass
       
   371     iBuf[6] = aClassInfo.iSubClassNum;                        // bInterfaceSubClass
       
   372     iBuf[7] = aClassInfo.iProtocolNum;                        // bInterfaceProtocol
       
   373     iBuf[8] = 0;                                            // iInterface
       
   374     return KErrNone;
       
   375     }
       
   376 
       
   377 
       
   378 // --- TUsbcEndpointDescriptorBase
       
   379 
       
   380 TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()
       
   381     {
       
   382     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()"));
       
   383     }
       
   384 
       
   385 
       
   386 TInt TUsbcEndpointDescriptorBase::Construct(const TUsbcEndpointInfo& aEpInfo)
       
   387     {
       
   388     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::Construct()"));
       
   389     //  Adjust FS/HS endpoint sizes
       
   390     if (aEpInfo.AdjustEpSizes(iEpSize_Fs, iEpSize_Hs) != KErrNone)
       
   391         {
       
   392         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown endpoint type: %d", aEpInfo.iType));
       
   393         }
       
   394     __KTRACE_OPT(KUSB, Kern::Printf("  Now set: iEpSize_Fs=%d iEpSize_Hs=%d (aEpInfo.iSize=%d)",
       
   395                                     iEpSize_Fs, iEpSize_Hs, aEpInfo.iSize));
       
   396 
       
   397     //  Adjust HS endpoint size for additional transactions
       
   398     if ((aEpInfo.iType == UsbShai::KUsbEpTypeIsochronous) || (aEpInfo.iType == UsbShai::KUsbEpTypeInterrupt))
       
   399         {
       
   400         if ((aEpInfo.iTransactions > 0) && (aEpInfo.iTransactions < 3))
       
   401             {
       
   402             // Bits 12..11 specify the number of additional transactions per microframe
       
   403             iEpSize_Hs |= (aEpInfo.iTransactions << 12);
       
   404             __KTRACE_OPT(KUSB, Kern::Printf("  Adjusted for add. transact.: iEpSize_Hs=0x%02x "
       
   405                                             "(aEpInfo.iTransactions=%d)",
       
   406                                             iEpSize_Hs, aEpInfo.iTransactions));
       
   407             }
       
   408         else if (aEpInfo.iTransactions != 0)
       
   409             {
       
   410             __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Invalid iTransactions value: %d (ignored)",
       
   411                                               aEpInfo.iTransactions));
       
   412             }
       
   413         }
       
   414 
       
   415     //  Adjust HS polling interval
       
   416     TUsbcEndpointInfo info(aEpInfo);                        // create local writeable copy
       
   417     if (info.AdjustPollInterval() != KErrNone)
       
   418         {
       
   419         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown ep type (%d) or invalid interval value (%d)",
       
   420                                           info.iType, info.iInterval));
       
   421         }
       
   422     iInterval_Fs = info.iInterval;
       
   423     iInterval_Hs = info.iInterval_Hs;
       
   424     __KTRACE_OPT(KUSB, Kern::Printf("  Now set: iInterval_Fs=%d iInterval_Hs=%d",
       
   425                                     iInterval_Fs, iInterval_Hs));
       
   426     return KErrNone;
       
   427     }
       
   428 
       
   429 
       
   430 void TUsbcEndpointDescriptorBase::UpdateFs()
       
   431     {
       
   432     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateFs()"));
       
   433     // (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values got
       
   434     //  adjusted in its Construct() method.)
       
   435     SetWord(4, iEpSize_Fs);                                    // wMaxPacketSize
       
   436     SetByte(6, iInterval_Fs);                                // bInterval
       
   437     }
       
   438 
       
   439 
       
   440 void TUsbcEndpointDescriptorBase::UpdateHs()
       
   441     {
       
   442     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateHs()"));
       
   443     // (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values get
       
   444     //  adjusted in its Construct() method.)
       
   445     SetWord(4, iEpSize_Hs);                                    // wMaxPacketSize
       
   446     SetByte(6, iInterval_Hs);                                // bInterval
       
   447     }
       
   448 
       
   449 
       
   450 // --- TUsbcEndpointDescriptor
       
   451 
       
   452 TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()
       
   453     : iBuf()
       
   454     {
       
   455     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()"));
       
   456     }
       
   457 
       
   458 
       
   459 TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress,
       
   460                                                       const TUsbcEndpointInfo& aEpInfo)
       
   461     {
       
   462     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::New()"));
       
   463     TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor();
       
   464     if (self)
       
   465         {
       
   466         if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
       
   467             {
       
   468             delete self;
       
   469             return NULL;
       
   470             }
       
   471         }
       
   472     return self;
       
   473     }
       
   474 
       
   475 
       
   476 TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
       
   477     {
       
   478     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::Construct()"));
       
   479     (void) TUsbcEndpointDescriptorBase::Construct(aEpInfo);    // Init Base class
       
   480     iBuf.SetMax();
       
   481     SetBufferPointer(iBuf);
       
   482     iBuf[0] = iBuf.Size();                                    // bLength
       
   483     iBuf[1] = KUsbDescType_Endpoint;                        // bDescriptorType
       
   484     iBuf[2] = aEndpointAddress;                                // bEndpointAddress
       
   485     iBuf[3] = EpTypeMask2Value(aEpInfo.iType);                // bmAttributes
       
   486     SetWord(4, iEpSize_Fs);                                    // wMaxPacketSize (default is FS)
       
   487     iBuf[6] = iInterval_Fs;                                    // bInterval (default is FS)
       
   488     return KErrNone;
       
   489     }
       
   490 
       
   491 
       
   492 // --- TUsbcAudioEndpointDescriptor
       
   493 
       
   494 TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()
       
   495     : iBuf()
       
   496     {
       
   497     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()"));
       
   498     }
       
   499 
       
   500 
       
   501 TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress,
       
   502                                                                 const TUsbcEndpointInfo& aEpInfo)
       
   503     {
       
   504     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::New()"));
       
   505     TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor();
       
   506     if (self)
       
   507         {
       
   508         if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
       
   509             {
       
   510             delete self;
       
   511             return NULL;
       
   512             }
       
   513         }
       
   514     return self;
       
   515     }
       
   516 
       
   517 
       
   518 TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
       
   519     {
       
   520     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::Construct()"));
       
   521     (void) TUsbcEndpointDescriptorBase::Construct(aEpInfo);    // Init Base class
       
   522     iBuf.SetMax();
       
   523     SetBufferPointer(iBuf);
       
   524     iBuf[0] = iBuf.Size();                                    // bLength
       
   525     iBuf[1] = KUsbDescType_Endpoint;                        // bDescriptorType
       
   526     iBuf[2] = aEndpointAddress;                                // bEndpointAddress
       
   527     iBuf[3] = EpTypeMask2Value(aEpInfo.iType);                // bmAttributes
       
   528     SetWord(4, iEpSize_Fs);                                    // wMaxPacketSize (default is FS)
       
   529     iBuf[6] = iInterval_Fs;                                    // bInterval (default is FS)
       
   530     iBuf[7] = 0;
       
   531     iBuf[8] = 0;
       
   532     return KErrNone;
       
   533     }
       
   534 
       
   535 
       
   536 // --- TUsbcOtgDescriptor
       
   537 
       
   538 TUsbcOtgDescriptor* TUsbcOtgDescriptor::New(TBool aHnpSupport, TBool aSrpSupport)
       
   539     {
       
   540     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::New()"));
       
   541     TUsbcOtgDescriptor* self = new TUsbcOtgDescriptor();
       
   542     if (self && (self->Construct(aHnpSupport, aSrpSupport) != KErrNone))
       
   543         {
       
   544         delete self;
       
   545         return NULL;
       
   546         }
       
   547     return self;
       
   548     }
       
   549 
       
   550 
       
   551 TUsbcOtgDescriptor::TUsbcOtgDescriptor()
       
   552     : iBuf()
       
   553     {
       
   554     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::TUsbcOtgDescriptor()"));
       
   555     }
       
   556 
       
   557 
       
   558 TInt TUsbcOtgDescriptor::Construct(TBool aHnpSupport, TBool aSrpSupport)
       
   559     {
       
   560     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::Construct()"));
       
   561     iBuf.SetMax();
       
   562     SetBufferPointer(iBuf);
       
   563     iBuf[0] = iBuf.Size();                                    // bLength
       
   564     iBuf[1] = KUsbDescType_Otg;                                // bDescriptorType
       
   565     iBuf[2] = (aHnpSupport ? KUsbOtgAttr_HnpSupp : 0) |
       
   566         (aSrpSupport ? KUsbOtgAttr_SrpSupp : 0);            // bmAttributes
       
   567     return KErrNone;
       
   568     }
       
   569 
       
   570 
       
   571 // --- TUsbcClassSpecificDescriptor
       
   572 
       
   573 TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()
       
   574     : iBuf(NULL)
       
   575     {
       
   576     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()"));
       
   577     }
       
   578 
       
   579 
       
   580 TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()
       
   581     {
       
   582     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()"));
       
   583     delete iBuf;
       
   584     }
       
   585 
       
   586 
       
   587 TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize)
       
   588     {
       
   589     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::New()"));
       
   590     TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor();
       
   591     if (self)
       
   592         {
       
   593         if (self->Construct(aType, aSize) != KErrNone)
       
   594             {
       
   595             delete self;
       
   596             return NULL;
       
   597             }
       
   598         }
       
   599     return self;
       
   600     }
       
   601 
       
   602 
       
   603 TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize)
       
   604     {
       
   605     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::Construct()"));
       
   606     iBuf = HBuf8::New(aSize);
       
   607     if (!iBuf)
       
   608         {
       
   609         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Allocation of CS desc buffer failed"));
       
   610         return KErrNoMemory;
       
   611         }
       
   612     iBuf->SetMax();
       
   613     SetBufferPointer(*iBuf);
       
   614     SetByte(1, aType);                                        // bDescriptorType
       
   615     return KErrNone;
       
   616     }
       
   617 
       
   618 
       
   619 // --- TUsbcStringDescriptorBase
       
   620 
       
   621 TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()
       
   622     : /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0)
       
   623     {
       
   624     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()"));
       
   625     }
       
   626 
       
   627 
       
   628 TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()
       
   629     {
       
   630     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()"));
       
   631     }
       
   632 
       
   633 
       
   634 TUint16 TUsbcStringDescriptorBase::Word(TInt aPosition) const
       
   635     {
       
   636     if (aPosition <= 1)
       
   637         {
       
   638         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Word(%d) in string descriptor "
       
   639                                           "(TUsbcStringDescriptorBase::Word)", aPosition));
       
   640         return 0;
       
   641         }
       
   642     else
       
   643         {
       
   644         // since iBufPtr[0] is actually string descriptor byte index 2,
       
   645         // we have to subtract 2 from the absolute position.
       
   646         return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition - 2]));
       
   647         }
       
   648     }
       
   649 
       
   650 
       
   651 void TUsbcStringDescriptorBase::SetWord(TInt aPosition, TUint16 aValue)
       
   652     {
       
   653     if (aPosition <= 1)
       
   654         {
       
   655         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: SetWord(%d) in string descriptor "
       
   656                                           "(TUsbcStringDescriptorBase::SetWord)", aPosition));
       
   657         return;
       
   658         }
       
   659     else
       
   660         {
       
   661         // since iBufPtr[0] is actually string descriptor byte index 2,
       
   662         // we have to subtract 2 from the absolute position.
       
   663         *reinterpret_cast<TUint16*>(&iBufPtr[aPosition - 2]) = SWAP_BYTES_16(aValue);
       
   664         }
       
   665     }
       
   666 
       
   667 
       
   668 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
       
   669     {
       
   670     aBuffer[0] = iSBuf[0];
       
   671     aBuffer[1] = iSBuf[1];
       
   672     memcpy(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size());
       
   673     return Size();
       
   674     }
       
   675 
       
   676 
       
   677 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const
       
   678     {
       
   679     if (aMaxSize < Size())
       
   680         {
       
   681         // No use to copy only half a string
       
   682         return 0;
       
   683         }
       
   684     return GetDescriptorData(aBuffer);
       
   685     }
       
   686 
       
   687 
       
   688 const TDes8& TUsbcStringDescriptorBase::StringData() const
       
   689     {
       
   690     return iBufPtr;
       
   691     }
       
   692 
       
   693 
       
   694 TDes8& TUsbcStringDescriptorBase::StringData()
       
   695     {
       
   696     return iBufPtr;
       
   697     }
       
   698 
       
   699 
       
   700 TUint TUsbcStringDescriptorBase::Size() const
       
   701     {
       
   702     return iSBuf[0];
       
   703     }
       
   704 
       
   705 
       
   706 void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes)
       
   707     {
       
   708     iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
       
   709     }
       
   710 
       
   711 
       
   712 // --- TUsbcStringDescriptor
       
   713 
       
   714 TUsbcStringDescriptor::TUsbcStringDescriptor()
       
   715     : iBuf(NULL)
       
   716     {
       
   717     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::TUsbcStringDescriptor()"));
       
   718     }
       
   719 
       
   720 
       
   721 TUsbcStringDescriptor::~TUsbcStringDescriptor()
       
   722     {
       
   723     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::~TUsbcStringDescriptor()"));
       
   724     delete iBuf;
       
   725     }
       
   726 
       
   727 
       
   728 TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString)
       
   729     {
       
   730     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::New"));
       
   731     TUsbcStringDescriptor* self = new TUsbcStringDescriptor();
       
   732     if (self)
       
   733         {
       
   734         if (self->Construct(aString) != KErrNone)
       
   735             {
       
   736             delete self;
       
   737             return NULL;
       
   738             }
       
   739         }
       
   740     return self;
       
   741     }
       
   742 
       
   743 
       
   744 TInt TUsbcStringDescriptor::Construct(const TDesC8& aString)
       
   745     {
       
   746     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::Construct"));
       
   747     iBuf = HBuf8::New(aString.Size());                        // bytes, not UNICODE chars
       
   748     if (!iBuf)
       
   749         {
       
   750         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Allocation of string buffer failed"));
       
   751         return KErrNoMemory;
       
   752         }
       
   753     iBuf->SetMax();
       
   754     SetBufferPointer(*iBuf);
       
   755     iBufPtr.Copy(aString);
       
   756     iSBuf.SetMax();
       
   757     iSBuf[0] = iBuf->Size() + 2;                            // Bytes
       
   758     iSBuf[1] = KUsbDescType_String;
       
   759     return KErrNone;
       
   760     }
       
   761 
       
   762 
       
   763 // --- TUsbcLangIdDescriptor
       
   764 
       
   765 TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()
       
   766     : iBuf(NULL)
       
   767     {
       
   768     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()"));
       
   769     }
       
   770 
       
   771 
       
   772 TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()
       
   773     {
       
   774     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()"));
       
   775     }
       
   776 
       
   777 
       
   778 TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId)
       
   779     {
       
   780     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::New"));
       
   781     TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor();
       
   782     if (self)
       
   783         {
       
   784         if (self->Construct(aLangId) != KErrNone)
       
   785             {
       
   786             delete self;
       
   787             return NULL;
       
   788             }
       
   789         }
       
   790     return self;
       
   791     }
       
   792 
       
   793 
       
   794 TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId)
       
   795     {
       
   796     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::Construct"));
       
   797     iBuf.SetMax();
       
   798     SetBufferPointer(iBuf);
       
   799     iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId));            // Language ID value
       
   800     iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId));
       
   801     iSBuf.SetMax();
       
   802     iSBuf[0] = iBuf.Size() + 2;                                // Bytes
       
   803     iSBuf[1] = KUsbDescType_String;
       
   804     return KErrNone;
       
   805     }
       
   806 
       
   807 
       
   808 // --- TUsbcDescriptorPool
       
   809 
       
   810 TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf)
       
   811 //
       
   812 //    The constructor for this class.
       
   813 //
       
   814     : iDescriptors(), iStrings(), iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf), iHighSpeed(EFalse)
       
   815     {
       
   816     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::TUsbcDescriptorPool()"));
       
   817     }
       
   818 
       
   819 
       
   820 TUsbcDescriptorPool::~TUsbcDescriptorPool()
       
   821     {
       
   822     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::~TUsbcDescriptorPool()"));
       
   823     // The destructor of each <class T> object is called before the objects themselves are destroyed.
       
   824     __KTRACE_OPT(KUSB, Kern::Printf("  iDescriptors.Count(): %d", iDescriptors.Count()));
       
   825     iDescriptors.ResetAndDestroy();
       
   826     __KTRACE_OPT(KUSB, Kern::Printf("  iStrings.Count(): %d", iStrings.Count()));
       
   827     iStrings.ResetAndDestroy();
       
   828     }
       
   829 
       
   830 
       
   831 TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
       
   832                                TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
       
   833                                TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
       
   834                                TUsbcStringDescriptor* aConfig, TUsbcOtgDescriptor* aOtgDesc)
       
   835     {
       
   836     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::Init()"));
       
   837     if (!aDeviceDesc || !aConfigDesc)
       
   838         {
       
   839         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: No Device or Config descriptor specified"));
       
   840         return KErrArgument;
       
   841         }
       
   842     for (TInt n = 0; n < KDescPosition_FirstAvailable; n++)
       
   843         {
       
   844         iDescriptors.Append(NULL);
       
   845         }
       
   846     __ASSERT_DEBUG((iDescriptors.Count() == KDescPosition_FirstAvailable),
       
   847                    Kern::Printf("  Error: iDescriptors.Count() (%d) != KDescPosition_FirstAvailable (%d)",
       
   848                                 iDescriptors.Count(), KDescPosition_FirstAvailable));
       
   849     iDescriptors[KDescPosition_Device] = aDeviceDesc;
       
   850     iDescriptors[KDescPosition_Config] = aConfigDesc;
       
   851     if (aOtgDesc)
       
   852         {
       
   853         iDescriptors[KDescPosition_Otg] = aOtgDesc;
       
   854         // Update the config descriptor's wTotalLength field
       
   855         UpdateConfigDescriptorLength(KUsbDescSize_Otg);
       
   856         }
       
   857     if (!aLangId)
       
   858         {
       
   859         // USB spec 9.6.7 says: "String index zero for all languages returns a string descriptor
       
   860         // that contains an array of two-byte LANGID codes supported by the device. ...
       
   861         // USB devices that omit all string descriptors must not return an array of LANGID codes."
       
   862         // So if we have at least one string descriptor, we must also have a LANGID descriptor.
       
   863         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: No LANGID string descriptor specified"));
       
   864         return KErrArgument;
       
   865         }
       
   866     iStrings.Insert(aLangId, KStringPosition_Langid);
       
   867     iStrings.Insert(aManufacturer, KStringPosition_Manufact);
       
   868     iStrings.Insert(aProduct, KStringPosition_Product);
       
   869     iStrings.Insert(aSerialNum, KStringPosition_Serial);
       
   870     iStrings.Insert(aConfig, KStringPosition_Config);
       
   871     __ASSERT_DEBUG((iStrings.Count() == 5),
       
   872                    Kern::Printf("  Error: iStrings.Count() != 5 (%d)", iStrings.Count()));
       
   873 #ifdef _DEBUG
       
   874     for (TInt i = KStringPosition_Langid; i <= KStringPosition_Config; i++)
       
   875         {
       
   876         __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool.iStrings[%d] = 0x%x", i, iStrings[i]));
       
   877         }
       
   878 #endif
       
   879     // Set string indices
       
   880     if (aManufacturer)
       
   881         iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Manufact,
       
   882                                                     KStringPosition_Manufact);
       
   883     if (aProduct)
       
   884         iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Product,
       
   885                                                     KStringPosition_Product);
       
   886     if (aSerialNum)
       
   887         iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Serial,
       
   888                                                     KStringPosition_Serial);
       
   889     if (aConfig)
       
   890         iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config,
       
   891                                                     KStringPosition_Config);
       
   892     return KErrNone;
       
   893     }
       
   894 
       
   895 
       
   896 TInt TUsbcDescriptorPool::InitHs()
       
   897     {
       
   898     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InitHs()"));
       
   899     __ASSERT_DEBUG((iDescriptors.Count() >= KDescPosition_FirstAvailable),
       
   900                    Kern::Printf("  Error: Call Init() first)"));
       
   901 
       
   902     TUsbcDeviceQualifierDescriptor* const dq_desc = TUsbcDeviceQualifierDescriptor::New(
       
   903         iDescriptors[KDescPosition_Device]->Byte(4),        // aDeviceClass
       
   904         iDescriptors[KDescPosition_Device]->Byte(5),        // aDeviceSubClass
       
   905         iDescriptors[KDescPosition_Device]->Byte(6),        // aDeviceProtocol
       
   906         iDescriptors[KDescPosition_Device]->Byte(7),        // aMaxPacketSize0
       
   907         iDescriptors[KDescPosition_Device]->Byte(17));        // aNumConfigurations
       
   908     if (!dq_desc)
       
   909         {
       
   910         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for dev qualif desc failed."));
       
   911         return KErrGeneral;
       
   912         }
       
   913     iDescriptors[KDescPosition_DeviceQualifier] = dq_desc;
       
   914 
       
   915     TUsbcOtherSpeedConfigDescriptor* const osc_desc = TUsbcOtherSpeedConfigDescriptor::New(
       
   916         iDescriptors[KDescPosition_Config]->Byte(5),        // aConfigurationValue
       
   917         iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_SelfPowered, // aSelfPowered
       
   918         iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_RemoteWakeup,    // aRemoteWakeup
       
   919         iDescriptors[KDescPosition_Config]->Byte(8) * 2);    // aMaxPower (mA)
       
   920     if (!osc_desc)
       
   921         {
       
   922         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for other speed conf desc failed."));
       
   923         return KErrGeneral;
       
   924         }
       
   925 
       
   926     // We need to set the bDescriptorType field manually, as that's the only one
       
   927     // that differs from a Configuration descriptor.
       
   928     osc_desc->SetByte(1, KUsbDescType_OtherSpeedConfig);
       
   929 
       
   930     // Also, initially we set the iConfiguration string index to the same value as
       
   931     // in the Configuration descriptor.
       
   932     osc_desc->SetByte(KUsbDescStringIndex_Config,
       
   933                       iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config));
       
   934 
       
   935     iDescriptors[KDescPosition_OtherSpeedConfig] = osc_desc;
       
   936 
       
   937     return KErrNone;
       
   938     }
       
   939 
       
   940 
       
   941 TInt TUsbcDescriptorPool::UpdateDescriptorsFs()
       
   942     {
       
   943     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsFs()"));
       
   944     const TInt count = iDescriptors.Count();
       
   945     for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
       
   946         {
       
   947         TUsbcDescriptorBase* const ptr = iDescriptors[i];
       
   948         ptr->UpdateFs();
       
   949         }
       
   950     iHighSpeed = EFalse;
       
   951     return KErrNone;
       
   952     }
       
   953 
       
   954 
       
   955 TInt TUsbcDescriptorPool::UpdateDescriptorsHs()
       
   956     {
       
   957     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsHs()"));
       
   958     const TInt count = iDescriptors.Count();
       
   959     for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
       
   960         {
       
   961         TUsbcDescriptorBase* const ptr = iDescriptors[i];
       
   962         ptr->UpdateHs();
       
   963         }
       
   964     iHighSpeed = ETrue;
       
   965     return KErrNone;
       
   966     }
       
   967 
       
   968 
       
   969 //
       
   970 // An error can be indicated by either a return value != KErrNone or by a descriptor size == 0.
       
   971 //
       
   972 TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const
       
   973     {
       
   974     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindDescriptor()"));
       
   975     TInt result = KErrGeneral;
       
   976     switch (aType)
       
   977         {
       
   978     case KUsbDescType_Device:
       
   979         if (aLangid != 0)
       
   980             {
       
   981             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
       
   982             }
       
   983         else if (aIndex > 0)
       
   984             {
       
   985             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad device index: %d", aIndex));
       
   986             }
       
   987         else
       
   988             {
       
   989             aSize = GetDeviceDescriptor(KDescPosition_Device);
       
   990             result = KErrNone;
       
   991             }
       
   992         break;
       
   993     case KUsbDescType_Config:
       
   994         if (aLangid != 0)
       
   995             {
       
   996             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
       
   997             }
       
   998         else if (aIndex > 0)
       
   999             {
       
  1000             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad config index: %d", aIndex));
       
  1001             }
       
  1002         else
       
  1003             {
       
  1004             aSize = GetConfigurationDescriptor(KDescPosition_Config);
       
  1005             result = KErrNone;
       
  1006             }
       
  1007         break;
       
  1008     case KUsbDescType_DeviceQualifier:
       
  1009         if (aLangid != 0)
       
  1010             {
       
  1011             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
       
  1012             }
       
  1013         else if (aIndex > 0)
       
  1014             {
       
  1015             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad device index: %d", aIndex));
       
  1016             }
       
  1017         else
       
  1018             {
       
  1019             aSize = GetDeviceDescriptor(KDescPosition_DeviceQualifier);
       
  1020             result = KErrNone;
       
  1021             }
       
  1022         break;
       
  1023     case KUsbDescType_OtherSpeedConfig:
       
  1024         if (aLangid != 0)
       
  1025             {
       
  1026             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
       
  1027             }
       
  1028         else if (aIndex > 0)
       
  1029             {
       
  1030             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad config index: %d", aIndex));
       
  1031             }
       
  1032         else
       
  1033             {
       
  1034             aSize = GetConfigurationDescriptor(KDescPosition_OtherSpeedConfig);
       
  1035             result = KErrNone;
       
  1036             }
       
  1037         break;
       
  1038     case KUsbDescType_Otg:
       
  1039         aSize = GetOtgDescriptor();
       
  1040         result = KErrNone;
       
  1041         break;
       
  1042     case KUsbDescType_String:
       
  1043         if (aIndex == 0)                                    // 0 addresses the LangId array
       
  1044             {
       
  1045             if (AnyStringDescriptors())
       
  1046                 {
       
  1047                 aSize = GetStringDescriptor(aIndex);
       
  1048                 result = KErrNone;
       
  1049                 }
       
  1050             else
       
  1051                 {
       
  1052                 __KTRACE_OPT(KUSB, Kern::Printf("  No string descriptors: not returning LANGID array"));
       
  1053                 }
       
  1054             }
       
  1055         else
       
  1056             {
       
  1057                if (!aLangid)
       
  1058                    {
       
  1059                    __KTRACE_OPT(KUSB,
       
  1060                               Kern::Printf("  Strange: LANGID=0 for a $ descriptor (ignoring LANGID)"));
       
  1061                 // The USB spec doesn't really say what to do in this case, but as there are host apps
       
  1062                 // that fail if we return an error here, we choose to ignore the issue.
       
  1063                    }
       
  1064             else if (aLangid != iStrings[KStringPosition_Langid]->Word(2))
       
  1065                 {
       
  1066                 // We have only one (this) language
       
  1067                 __KTRACE_OPT(KUSB,
       
  1068                              Kern::Printf("  Bad LANGID: 0x%04X requested, 0x%04X supported (ignoring LANGID)",
       
  1069                                           aLangid, iStrings[KStringPosition_Langid]->Word(2)));
       
  1070                 // We could return an error here, but rather choose to ignore the discrepancy
       
  1071                 // (the USB spec is not very clear what to do in such a case anyway).
       
  1072                 }
       
  1073             aSize = GetStringDescriptor(aIndex);
       
  1074             result = KErrNone;
       
  1075             }
       
  1076         break;
       
  1077     case KUsbDescType_CS_Interface:
       
  1078         /* fall through */
       
  1079     case KUsbDescType_CS_Endpoint:
       
  1080         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: finding of class specific descriptors not supported"));
       
  1081         break;
       
  1082     default:
       
  1083         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: unknown descriptor type requested: %d", aType));
       
  1084         break;
       
  1085         }
       
  1086     return result;
       
  1087     }
       
  1088 
       
  1089 
       
  1090 void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc)
       
  1091     {
       
  1092     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertDescriptor()"));
       
  1093     switch (aDesc->Type())
       
  1094         {
       
  1095     case KUsbDescType_Interface:
       
  1096         InsertIfcDesc(aDesc);
       
  1097         break;
       
  1098     case KUsbDescType_Endpoint:
       
  1099         InsertEpDesc(aDesc);
       
  1100         break;
       
  1101     default:
       
  1102         __KTRACE_OPT(KUSB, Kern::Printf("  Error: unsupported descriptor type"));
       
  1103         }
       
  1104     }
       
  1105 
       
  1106 
       
  1107 void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting)
       
  1108     {
       
  1109     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetIfcDescriptor(%d, %d)", aNumber, aSetting));
       
  1110     const TInt i = FindIfcDescriptor(aNumber, aSetting);
       
  1111     if (i < 0)
       
  1112         {
       
  1113         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ifc descriptor not found (%d, %d)",
       
  1114                                           aNumber, aSetting));
       
  1115         return;
       
  1116         }
       
  1117     // Try to find available NULL postition
       
  1118     TInt str_idx = FindAvailableStringPos();
       
  1119     if (str_idx >= 0)
       
  1120         {
       
  1121         // Insert string descriptor for specified interface
       
  1122         ExchangeStringDescriptor(str_idx, aDesc);
       
  1123         }
       
  1124     else
       
  1125         {
       
  1126         // No NULL found - expand array
       
  1127         str_idx = iStrings.Count();
       
  1128         if (str_idx > 0xff)
       
  1129             {
       
  1130             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: $ descriptor array full (idx=%d)", str_idx));
       
  1131             return;
       
  1132             }
       
  1133         while (str_idx < KStringPosition_FirstAvailable)
       
  1134             {
       
  1135             iStrings.Append(NULL);
       
  1136             str_idx = iStrings.Count();
       
  1137             }
       
  1138         // Append string descriptor for specified interface
       
  1139         iStrings.Append(aDesc);
       
  1140         }
       
  1141     // Update this ifc descriptor's string index field
       
  1142     iDescriptors[i]->SetByte(8, str_idx);
       
  1143     __KTRACE_OPT(KUSB, Kern::Printf("  String for ifc %d/%d (@ pos %d): \"%S\"", aNumber, aSetting, str_idx,
       
  1144                                     &iStrings[str_idx]->StringData()));
       
  1145     }
       
  1146 
       
  1147 
       
  1148 void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting)
       
  1149     {
       
  1150     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)", aNumber, aSetting));
       
  1151     const TInt i = FindIfcDescriptor(aNumber, aSetting);
       
  1152     if (i < 0)
       
  1153         {
       
  1154         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DeleteIfcDescriptor - descriptor not found (%d, %d)",
       
  1155                                           aNumber, aSetting));
       
  1156         return;
       
  1157         }
       
  1158     // Delete (if necessary) specified interface's string descriptor
       
  1159     const TInt si = iDescriptors[i]->Byte(8);
       
  1160     if (si != 0)
       
  1161         {
       
  1162         ExchangeStringDescriptor(si, NULL);
       
  1163         }
       
  1164     // Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors:
       
  1165     // find position of the next interface descriptor: we need to delete everything in between
       
  1166     const TInt count = iDescriptors.Count();
       
  1167     TInt j = i, n = 1;
       
  1168     while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface)
       
  1169         ++n;
       
  1170     DeleteDescriptors(i, n);
       
  1171     // Update all the following interfaces' bInterfaceNumber field if required
       
  1172     // (because those descriptors might have moved down by one position)
       
  1173     UpdateIfcNumbers(aNumber);
       
  1174     iIfcIdx = 0;                                            // ifc index no longer valid
       
  1175     }
       
  1176 
       
  1177 
       
  1178 // The TC in many of the following functions stands for 'ThreadCopy',
       
  1179 // because that's what's happening there.
       
  1180 
       
  1181 TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
  1182     {
       
  1183     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptorTC()"));
       
  1184     return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Device]->DescriptorData(), 0);
       
  1185     }
       
  1186 
       
  1187 
       
  1188 TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer)
       
  1189     {
       
  1190     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceDescriptorTC()"));
       
  1191     TBuf8<KUsbDescSize_Device> device;
       
  1192     const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0);
       
  1193     if (r != KErrNone)
       
  1194         {
       
  1195         return r;
       
  1196         }
       
  1197     iDescriptors[KDescPosition_Device]->SetByte(2, device[2]); // bcdUSB
       
  1198     iDescriptors[KDescPosition_Device]->SetByte(3, device[3]); // bcdUSB (part II)
       
  1199     iDescriptors[KDescPosition_Device]->SetByte(4, device[4]); // bDeviceClass
       
  1200     iDescriptors[KDescPosition_Device]->SetByte(5, device[5]); // bDeviceSubClass
       
  1201     iDescriptors[KDescPosition_Device]->SetByte(6, device[6]); // bDeviceProtocol
       
  1202     iDescriptors[KDescPosition_Device]->SetByte(8, device[8]); // idVendor
       
  1203     iDescriptors[KDescPosition_Device]->SetByte(9, device[9]); // idVendor (part II)
       
  1204     iDescriptors[KDescPosition_Device]->SetByte(10, device[10]); // idProduct
       
  1205     iDescriptors[KDescPosition_Device]->SetByte(11, device[11]); // idProduct (part II)
       
  1206     iDescriptors[KDescPosition_Device]->SetByte(12, device[12]); // bcdDevice
       
  1207     iDescriptors[KDescPosition_Device]->SetByte(13, device[13]); // bcdDevice (part II)
       
  1208     return KErrNone;
       
  1209     }
       
  1210 
       
  1211 
       
  1212 TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
  1213     {
       
  1214     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigurationDescriptorTC()"));
       
  1215     return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Config]->DescriptorData(), 0);
       
  1216     }
       
  1217 
       
  1218 
       
  1219 TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
       
  1220     {
       
  1221     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetConfigurationDescriptorTC()"));
       
  1222     TBuf8<KUsbDescSize_Config> config;
       
  1223     const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0);
       
  1224     if (r != KErrNone)
       
  1225         {
       
  1226         return r;
       
  1227         }
       
  1228     iDescriptors[KDescPosition_Config]->SetByte(7, config[7]); // bmAttributes
       
  1229     iDescriptors[KDescPosition_Config]->SetByte(8, config[8]); // bMaxPower
       
  1230     return KErrNone;
       
  1231     }
       
  1232 
       
  1233 
       
  1234 TInt TUsbcDescriptorPool::GetOtgDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
  1235     {
       
  1236     return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Otg]->DescriptorData(), 0);
       
  1237     }
       
  1238 
       
  1239 
       
  1240 TInt TUsbcDescriptorPool::SetOtgDescriptor(const TDesC8& aBuffer)
       
  1241     {
       
  1242     iDescriptors[KDescPosition_Otg]->SetByte(2, aBuffer[2]); // bmAttributes
       
  1243     return KErrNone;
       
  1244     }
       
  1245 
       
  1246 
       
  1247 TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
       
  1248                                                    TInt aInterface, TInt aSetting) const
       
  1249     {
       
  1250     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetInterfaceDescriptorTC()"));
       
  1251     const TInt i = FindIfcDescriptor(aInterface, aSetting);
       
  1252     if (i < 0)
       
  1253         {
       
  1254         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1255         return KErrNotFound;
       
  1256         }
       
  1257     return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
       
  1258     }
       
  1259 
       
  1260 
       
  1261 TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting)
       
  1262     {
       
  1263     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetInterfaceDescriptor()"));
       
  1264     const TInt i = FindIfcDescriptor(aInterface, aSetting);
       
  1265     if (i < 0)
       
  1266         {
       
  1267         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1268         return KErrNotFound;
       
  1269         }
       
  1270     iDescriptors[i]->SetByte(2, aBuffer[2]);                // bInterfaceNumber
       
  1271     iDescriptors[i]->SetByte(5, aBuffer[5]);                // bInterfaceClass
       
  1272     iDescriptors[i]->SetByte(6, aBuffer[6]);                // bInterfaceSubClass
       
  1273     iDescriptors[i]->SetByte(7, aBuffer[7]);                // bInterfaceProtocol
       
  1274     return KErrNone;
       
  1275     }
       
  1276 
       
  1277 
       
  1278 TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer,
       
  1279                                                   TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const
       
  1280     {
       
  1281     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorTC()"));
       
  1282     const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1283     if (i < 0)
       
  1284         {
       
  1285         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1286         return KErrNotFound;
       
  1287         }
       
  1288     return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
       
  1289     }
       
  1290 
       
  1291 
       
  1292 TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer,
       
  1293                                                   TInt aInterface, TInt aSetting, TUint8 aEndpointAddress)
       
  1294     {
       
  1295     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetEndpointDescriptorTC()"));
       
  1296     const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1297     if (i < 0)
       
  1298         {
       
  1299         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1300         return KErrNotFound;
       
  1301         }
       
  1302     TBuf8<KUsbDescSize_AudioEndpoint> ep;                    // it could be an audio endpoint
       
  1303     const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, ep, 0);
       
  1304     if (r != KErrNone)
       
  1305         {
       
  1306         return r;
       
  1307         }
       
  1308     iDescriptors[i]->SetByte(3, ep[3]);                        // bmAttributes
       
  1309     iDescriptors[i]->SetByte(6, ep[6]);                        // bInterval
       
  1310     if (iDescriptors[i]->Size() == KUsbDescSize_AudioEndpoint)
       
  1311         {
       
  1312         iDescriptors[i]->SetByte(7, ep[7]);                    // bRefresh
       
  1313         iDescriptors[i]->SetByte(8, ep[8]);                    // bSynchAddress
       
  1314         }
       
  1315     return KErrNone;
       
  1316     }
       
  1317 
       
  1318 
       
  1319 TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress,
       
  1320                                                     TInt& aSize) const
       
  1321     {
       
  1322     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorSize()"));
       
  1323     const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1324     if (i < 0)
       
  1325         {
       
  1326         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1327         return KErrNotFound;
       
  1328         }
       
  1329     aSize = iDescriptors[i]->Size();
       
  1330     return KErrNone;
       
  1331     }
       
  1332 
       
  1333 
       
  1334 TInt TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
  1335     {
       
  1336     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC()"));
       
  1337     if (iDescriptors[KDescPosition_DeviceQualifier] == NULL)
       
  1338         {
       
  1339         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Device_Qualifier descriptor not supported"));
       
  1340         return KErrNotSupported;
       
  1341         }
       
  1342     return Kern::ThreadDesWrite(aThread, &aBuffer,
       
  1343                                 iDescriptors[KDescPosition_DeviceQualifier]->DescriptorData(), 0);
       
  1344     }
       
  1345 
       
  1346 
       
  1347 TInt TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC(DThread* aThread, const TDes8& aBuffer)
       
  1348     {
       
  1349     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC()"));
       
  1350     if (iDescriptors[KDescPosition_DeviceQualifier] == NULL)
       
  1351         {
       
  1352         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Device_Qualifier descriptor not supported"));
       
  1353         return KErrNotSupported;
       
  1354         }
       
  1355     TBuf8<KUsbDescSize_DeviceQualifier> device;
       
  1356     const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0);
       
  1357     if (r != KErrNone)
       
  1358         {
       
  1359         return r;
       
  1360         }
       
  1361     iDescriptors[KDescPosition_DeviceQualifier]->SetByte(2, device[2]); // bcdUSB
       
  1362     iDescriptors[KDescPosition_DeviceQualifier]->SetByte(3, device[3]); // bcdUSB (part II)
       
  1363     iDescriptors[KDescPosition_DeviceQualifier]->SetByte(4, device[4]); // bDeviceClass
       
  1364     iDescriptors[KDescPosition_DeviceQualifier]->SetByte(5, device[5]); // bDeviceSubClass
       
  1365     iDescriptors[KDescPosition_DeviceQualifier]->SetByte(6, device[6]); // bDeviceProtocol
       
  1366     return KErrNone;
       
  1367     }
       
  1368 
       
  1369 
       
  1370 TInt TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
  1371     {
       
  1372     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC()"));
       
  1373     if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL)
       
  1374         {
       
  1375         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Other_Speed_Configuration descriptor not supported"));
       
  1376         return KErrNotSupported;
       
  1377         }
       
  1378     return Kern::ThreadDesWrite(aThread, &aBuffer,
       
  1379                                 iDescriptors[KDescPosition_OtherSpeedConfig]->DescriptorData(), 0);
       
  1380     }
       
  1381 
       
  1382 
       
  1383 TInt TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
       
  1384     {
       
  1385     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC()"));
       
  1386     if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL)
       
  1387         {
       
  1388         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Other_Speed_Configuration descriptor not supported"));
       
  1389         return KErrNotSupported;
       
  1390         }
       
  1391     TBuf8<KUsbDescSize_OtherSpeedConfig> config;
       
  1392     const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0);
       
  1393     if (r != KErrNone)
       
  1394         {
       
  1395         return r;
       
  1396         }
       
  1397     iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(7, config[7]); // bmAttributes
       
  1398     iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(8, config[8]); // bMaxPower
       
  1399     return KErrNone;
       
  1400     }
       
  1401 
       
  1402 
       
  1403 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
       
  1404                                                      TInt aInterface, TInt aSetting) const
       
  1405     {
       
  1406     // first find the interface
       
  1407     TInt i = FindIfcDescriptor(aInterface, aSetting);
       
  1408     if (i < 0)
       
  1409         {
       
  1410         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1411         return KErrNotFound;
       
  1412         }
       
  1413     TInt r = KErrNotFound;
       
  1414     TInt offset = 0;
       
  1415     const TInt count = iDescriptors.Count();
       
  1416     while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
       
  1417         {
       
  1418         r = Kern::ThreadDesWrite(aThread, &aBuffer,
       
  1419                                  iDescriptors[i]->DescriptorData(), offset);
       
  1420         if (r != KErrNone)
       
  1421             break;
       
  1422         offset += iDescriptors[i]->Size();
       
  1423         }
       
  1424     return r;
       
  1425     }
       
  1426 
       
  1427 
       
  1428 TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer,
       
  1429                                                      TInt aInterface, TInt aSetting, TInt aSize)
       
  1430     {
       
  1431     // First find the interface
       
  1432     TInt i = FindIfcDescriptor(aInterface, aSetting);
       
  1433     if (i < 0)
       
  1434         {
       
  1435         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1436         return KErrNotFound;
       
  1437         }
       
  1438     // Find a position where to insert the new class specific interface descriptor(s)
       
  1439     const TInt count = iDescriptors.Count();
       
  1440     while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
       
  1441         ;
       
  1442     // Create a new cs descriptor
       
  1443     TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize);
       
  1444     if (!desc)
       
  1445         {
       
  1446         return KErrNoMemory;
       
  1447         }
       
  1448     __KTRACE_OPT(KUSB, Kern::Printf("  inserting descriptor at position %d", i));
       
  1449     iDescriptors.Insert(desc, i);
       
  1450 
       
  1451     // Update the config descriptor's wTotalLength field
       
  1452     UpdateConfigDescriptorLength(aSize);
       
  1453 
       
  1454     // Copy contents from the user side
       
  1455     return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
       
  1456     }
       
  1457 
       
  1458 
       
  1459 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const
       
  1460     {
       
  1461     // first find the interface
       
  1462     TInt i = FindIfcDescriptor(aInterface, aSetting);
       
  1463     if (i < 0)
       
  1464         {
       
  1465         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1466         return KErrNotFound;
       
  1467         }
       
  1468     TInt r = KErrNotFound;
       
  1469     TInt size = 0;
       
  1470     const TInt count = iDescriptors.Count();
       
  1471     while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
       
  1472         {
       
  1473         size += iDescriptors[i]->Size();
       
  1474         r = KErrNone;
       
  1475         }
       
  1476     if (r == KErrNone)
       
  1477         aSize = size;
       
  1478     return r;
       
  1479     }
       
  1480 
       
  1481 
       
  1482 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface,
       
  1483                                                     TInt aSetting, TUint8 aEndpointAddress) const
       
  1484     {
       
  1485     // first find the endpoint
       
  1486     TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1487     if (i < 0)
       
  1488         {
       
  1489         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1490         return KErrNotFound;
       
  1491         }
       
  1492     TInt r = KErrNotFound;
       
  1493     TInt offset = 0;
       
  1494     const TInt count = iDescriptors.Count();
       
  1495     while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
       
  1496         {
       
  1497         r = Kern::ThreadDesWrite(aThread, &aBuffer,
       
  1498                                  iDescriptors[i]->DescriptorData(), offset);
       
  1499         if (r != KErrNone)
       
  1500             break;
       
  1501         offset += iDescriptors[i]->Size();
       
  1502         }
       
  1503     return r;
       
  1504     }
       
  1505 
       
  1506 
       
  1507 TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface,
       
  1508                                                     TInt aSetting, TUint8 aEndpointAddress, TInt aSize)
       
  1509     {
       
  1510     // first find the endpoint
       
  1511     TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1512     if (i < 0)
       
  1513         {
       
  1514         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1515         return KErrNotFound;
       
  1516         }
       
  1517     // find a position where to insert the new class specific endpoint descriptor(s)
       
  1518     const TInt count = iDescriptors.Count();
       
  1519     while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
       
  1520         ;
       
  1521     // create a new cs descriptor
       
  1522     TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize);
       
  1523     if (!desc)
       
  1524         {
       
  1525         return KErrNoMemory;
       
  1526         }
       
  1527     iDescriptors.Insert(desc, i);
       
  1528     // update the config descriptor's wTotalLength field
       
  1529     UpdateConfigDescriptorLength(aSize);
       
  1530     // copy contents from user side
       
  1531     return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
       
  1532     }
       
  1533 
       
  1534 
       
  1535 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting,
       
  1536                                                       TUint8 aEndpointAddress, TInt& aSize) const
       
  1537     {
       
  1538     // first find the endpoint
       
  1539     TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1540     if (i < 0)
       
  1541         {
       
  1542         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1543         return KErrNotFound;
       
  1544         }
       
  1545     TInt r = KErrNotFound;
       
  1546     TInt size = 0;
       
  1547     const TInt count = iDescriptors.Count();
       
  1548     while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
       
  1549         {
       
  1550         size += iDescriptors[i]->Size();
       
  1551         r = KErrNone;
       
  1552         }
       
  1553     if (r == KErrNone)
       
  1554         aSize = size;
       
  1555     return r;
       
  1556     }
       
  1557 
       
  1558 
       
  1559 TInt TUsbcDescriptorPool::GetStringDescriptorLangIdTC(DThread* aThread, TDes8& aLangId) const
       
  1560     {
       
  1561     const TUint16 id = iStrings[KStringPosition_Langid]->Word(2);
       
  1562     const TPtrC8 id_des(reinterpret_cast<const TUint8*>(&id), sizeof(id));
       
  1563     return Kern::ThreadDesWrite(aThread, &aLangId, id_des, 0);
       
  1564     }
       
  1565 
       
  1566 
       
  1567 TInt TUsbcDescriptorPool::SetStringDescriptorLangId(TUint16 aLangId)
       
  1568     {
       
  1569     iStrings[KStringPosition_Langid]->SetWord(2, aLangId);
       
  1570     return KErrNone;
       
  1571     }
       
  1572 
       
  1573 
       
  1574 TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1575     {
       
  1576     return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact,
       
  1577                                        KStringPosition_Manufact);
       
  1578     }
       
  1579 
       
  1580 
       
  1581 TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1582     {
       
  1583     return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact,
       
  1584                                        KStringPosition_Manufact);
       
  1585     }
       
  1586 
       
  1587 
       
  1588 TInt TUsbcDescriptorPool::RemoveManufacturerStringDescriptor()
       
  1589     {
       
  1590     return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Manufact, KStringPosition_Manufact);
       
  1591     }
       
  1592 
       
  1593 
       
  1594 TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1595     {
       
  1596     return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product,
       
  1597                                        KStringPosition_Product);
       
  1598     }
       
  1599 
       
  1600 
       
  1601 TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1602     {
       
  1603     return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product,
       
  1604                                        KStringPosition_Product);
       
  1605     }
       
  1606 
       
  1607 
       
  1608 TInt TUsbcDescriptorPool::RemoveProductStringDescriptor()
       
  1609     {
       
  1610     return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Product, KStringPosition_Product);
       
  1611     }
       
  1612 
       
  1613 
       
  1614 TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1615     {
       
  1616     return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial,
       
  1617                                        KStringPosition_Serial);
       
  1618     }
       
  1619 
       
  1620 
       
  1621 TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1622     {
       
  1623     return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial,
       
  1624                                        KStringPosition_Serial);
       
  1625     }
       
  1626 
       
  1627 
       
  1628 TInt TUsbcDescriptorPool::RemoveSerialNumberStringDescriptor()
       
  1629     {
       
  1630     return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Serial, KStringPosition_Serial);
       
  1631     }
       
  1632 
       
  1633 
       
  1634 TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1635     {
       
  1636     const TInt str_idx = iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config);
       
  1637     if (str_idx)
       
  1638         {
       
  1639         __ASSERT_ALWAYS((str_idx == KStringPosition_Config), Kern::Fault(KUsbPanicCat, __LINE__));
       
  1640         __KTRACE_OPT(KUSB, Kern::Printf("  String @ pos %d (conf $): \"%S\"",
       
  1641                                         str_idx, &iStrings[str_idx]->StringData()));
       
  1642         return Kern::ThreadDesWrite(aThread, &aString,
       
  1643                                     iStrings[str_idx]->StringData(), 0);
       
  1644         }
       
  1645     else
       
  1646         {
       
  1647         __KTRACE_OPT(KUSB, Kern::Printf("  No config string descriptor @ pos %d", str_idx));
       
  1648         return KErrNotFound;
       
  1649         }
       
  1650     }
       
  1651 
       
  1652 
       
  1653 TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1654     {
       
  1655     // we don't know the length of the string, so we have to allocate memory dynamically
       
  1656     TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
       
  1657     if (strlen > KUsbStringDescStringMaxSize)
       
  1658         {
       
  1659         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: config $ descriptor too long - will be truncated"));
       
  1660         strlen = KUsbStringDescStringMaxSize;
       
  1661         }
       
  1662     HBuf8* const strbuf = HBuf8::New(strlen);
       
  1663     if (!strbuf)
       
  1664         {
       
  1665         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for config $ desc string failed (1)"));
       
  1666         return KErrNoMemory;
       
  1667         }
       
  1668     strbuf->SetMax();
       
  1669     // the aString points to data that lives in user memory, so we have to copy it:
       
  1670     const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
       
  1671     if (r != KErrNone)
       
  1672         {
       
  1673         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
       
  1674         delete strbuf;
       
  1675         return r;
       
  1676         }
       
  1677     TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
       
  1678     if (!sd)
       
  1679         {
       
  1680         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for config $ desc failed (2)"));
       
  1681         delete strbuf;
       
  1682         return KErrNoMemory;
       
  1683         }
       
  1684     // Delete old string, put in new one
       
  1685     ExchangeStringDescriptor(KStringPosition_Config, sd);
       
  1686     // Update Config descriptor string index field
       
  1687     iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, KStringPosition_Config);
       
  1688     // Update Other_Speed_Config descriptor string index field as well, if applicable
       
  1689     if (iDescriptors[KDescPosition_OtherSpeedConfig])
       
  1690         iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config,
       
  1691                                                               KStringPosition_Config);
       
  1692     delete strbuf;
       
  1693     return KErrNone;
       
  1694     }
       
  1695 
       
  1696 
       
  1697 TInt TUsbcDescriptorPool::RemoveConfigurationStringDescriptor()
       
  1698     {
       
  1699     if (iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config) == 0)
       
  1700         {
       
  1701         __KTRACE_OPT(KUSB, Kern::Printf("  RemoveConfigurationStringDescriptor: no $ desc @ index %d",
       
  1702                                         KUsbDescStringIndex_Config));
       
  1703         return KErrNotFound;
       
  1704         }
       
  1705     // Delete old string, put in NULL pointer
       
  1706     ExchangeStringDescriptor(KStringPosition_Config, NULL);
       
  1707     // Update Config descriptor string index field
       
  1708     iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, 0);
       
  1709     // Update Other_Speed_Config descriptor string index field as well, if applicable
       
  1710     if (iDescriptors[KDescPosition_OtherSpeedConfig])
       
  1711         iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config, 0);
       
  1712     return KErrNone;
       
  1713     }
       
  1714 
       
  1715 
       
  1716 TInt TUsbcDescriptorPool::GetStringDescriptorTC(DThread* aThread, TInt aIndex, TDes8& aString) const
       
  1717     {
       
  1718     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptorTC()"));
       
  1719     if (!StringDescriptorExists(aIndex))
       
  1720         {
       
  1721         return KErrNotFound;
       
  1722         }
       
  1723     __KTRACE_OPT(KUSB, Kern::Printf("  String @ pos %d: \"%S\"",
       
  1724                                     aIndex, &iStrings[aIndex]->StringData()));
       
  1725     return Kern::ThreadDesWrite(aThread, &aString, iStrings[aIndex]->StringData(), 0);
       
  1726     }
       
  1727 
       
  1728 
       
  1729 TInt TUsbcDescriptorPool::SetStringDescriptorTC(DThread* aThread, TInt aIndex, const TDes8& aString)
       
  1730     {
       
  1731     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetStringDescriptorTC()"));
       
  1732     // we don't know the length of the string, so we have to allocate memory dynamically
       
  1733     TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
       
  1734     if (strlen > KUsbStringDescStringMaxSize)
       
  1735         {
       
  1736         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: $ descriptor too long - will be truncated"));
       
  1737         strlen = KUsbStringDescStringMaxSize;
       
  1738         }
       
  1739     HBuf8* strbuf = HBuf8::New(strlen);
       
  1740     if (!strbuf)
       
  1741         {
       
  1742         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Mem alloc for $ desc string failed (1)"));
       
  1743         return KErrNoMemory;
       
  1744         }
       
  1745     strbuf->SetMax();
       
  1746     // the aString points to data that lives in user memory, so we have to copy it over:
       
  1747     const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
       
  1748     if (r != KErrNone)
       
  1749         {
       
  1750         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
       
  1751         delete strbuf;
       
  1752         return r;
       
  1753         }
       
  1754     TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf);
       
  1755     if (!sd)
       
  1756         {
       
  1757         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Mem alloc for $ desc failed (2)"));
       
  1758         delete strbuf;
       
  1759         return KErrNoMemory;
       
  1760         }
       
  1761     if (aIndex < iStrings.Count())
       
  1762         {
       
  1763         ExchangeStringDescriptor(aIndex, sd);
       
  1764         }
       
  1765     else // if (aIndex >= iStrings.Count())
       
  1766         {
       
  1767         while (aIndex > iStrings.Count())
       
  1768             {
       
  1769             iStrings.Append(NULL);
       
  1770             }
       
  1771         iStrings.Append(sd);
       
  1772         }
       
  1773     delete strbuf;
       
  1774     return KErrNone;
       
  1775     }
       
  1776 
       
  1777 
       
  1778 TInt TUsbcDescriptorPool::RemoveStringDescriptor(TInt aIndex)
       
  1779     {
       
  1780     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveStringDescriptor()"));
       
  1781     if (!StringDescriptorExists(aIndex))
       
  1782         {
       
  1783         return KErrNotFound;
       
  1784         }
       
  1785     __KTRACE_OPT(KUSB, Kern::Printf("  Removing string @ pos %d: \"%S\"",
       
  1786                                     aIndex, &iStrings[aIndex]->StringData()));
       
  1787     ExchangeStringDescriptor(aIndex, NULL);
       
  1788 
       
  1789     // Make sure there's no $ after aIndex.
       
  1790     const TInt n = iStrings.Count();
       
  1791     for (TInt i = aIndex; i < n; i++)
       
  1792         {
       
  1793         if (iStrings[i] != NULL)
       
  1794             {
       
  1795             __KTRACE_OPT(KUSB, Kern::Printf("  Found $ @ idx %d - not compressing", i));
       
  1796             return KErrNone;
       
  1797             }
       
  1798         }
       
  1799 
       
  1800     __KTRACE_OPT(KUSB, Kern::Printf("  No $ found after idx %d - compressing array", aIndex));
       
  1801     // Move aIndex back just before the first !NULL element.
       
  1802     while (iStrings[--aIndex] == NULL)
       
  1803         ;
       
  1804     // Let aIndex point to first NULL.
       
  1805     aIndex++;
       
  1806     __KTRACE_OPT(KUSB, Kern::Printf("  Starting at index %d", aIndex));
       
  1807     // Now remove NULL pointers until (Count() == aIndex).
       
  1808     __KTRACE_OPT(KUSB, Kern::Printf("  iStrings.Count() before: %d", iStrings.Count()));
       
  1809     do
       
  1810         {
       
  1811         iStrings.Remove(aIndex);
       
  1812         __KTRACE_OPT(KUSB, Kern::Printf("  Removing $"));
       
  1813         }
       
  1814     while (iStrings.Count() > aIndex);
       
  1815     __KTRACE_OPT(KUSB, Kern::Printf("  iStrings.Count() after: %d", iStrings.Count()));
       
  1816 
       
  1817     // Regain some memory.
       
  1818     iStrings.Compress();
       
  1819 
       
  1820     return KErrNone;
       
  1821     }
       
  1822 
       
  1823 
       
  1824 // ===================================================================
       
  1825 // --- private ---
       
  1826 // ===================================================================
       
  1827 
       
  1828 //
       
  1829 // Insert an Interface descriptor into the descriptor array at the appropriate index.
       
  1830 //
       
  1831 void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc)
       
  1832     {
       
  1833     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertIfcDesc()"));
       
  1834 
       
  1835     const TInt count = iDescriptors.Count();
       
  1836     TBool ifc_exists = EFalse;                                // set to 'true' if we're adding an alternate
       
  1837                                                             // setting to an already existing interface
       
  1838     TInt i = KDescPosition_FirstAvailable;
       
  1839     while (i < count)
       
  1840         {
       
  1841         __KTRACE_OPT(KUSB, Kern::Printf("  already descriptors there (%d)...", count));
       
  1842         if (iDescriptors[i]->Type() == KUsbDescType_Interface)
       
  1843             {
       
  1844             if (iDescriptors[i]->Byte(2) > aDesc->Byte(2))
       
  1845                 {
       
  1846                 // our interface number is less than the one's just found => insert before it (= here)
       
  1847                 break;
       
  1848                 }
       
  1849             else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2))
       
  1850                 {
       
  1851                 ifc_exists = ETrue;
       
  1852                 // same interface number => look at settings number
       
  1853                 if (iDescriptors[i]->Byte(3) > aDesc->Byte(3))
       
  1854                     {
       
  1855                     // our setting number is less than the one's found => insert before (= here)
       
  1856                     break;
       
  1857                     }
       
  1858                 else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3))
       
  1859                     {
       
  1860                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: first delete old desc "
       
  1861                                                       "(TUsbcDescriptorPool::InsertIfcDesc)"));
       
  1862                     return;
       
  1863                     }
       
  1864                 }
       
  1865             }
       
  1866         ++i;
       
  1867         }
       
  1868     // In any case: put the new descriptor at position i.
       
  1869     __KTRACE_OPT(KUSB, Kern::Printf("  inserting descriptor at position %d", i));
       
  1870     iDescriptors.Insert(aDesc, i);
       
  1871 
       
  1872     // Update the config descriptor's wTotalLength field.
       
  1873     UpdateConfigDescriptorLength(KUsbDescSize_Interface);
       
  1874 
       
  1875     if (!ifc_exists)
       
  1876         {
       
  1877         // If this is the first setting for the interface, increment bNumInterfaces.
       
  1878         UpdateConfigDescriptorNumIfcs(1);
       
  1879         }
       
  1880 
       
  1881     iIfcIdx = i;
       
  1882     }
       
  1883 
       
  1884 
       
  1885 //
       
  1886 // Insert an Endpoint descriptor into the descriptor array at the appropriate index.
       
  1887 //
       
  1888 void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc)
       
  1889     {
       
  1890     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertEpDesc()"));
       
  1891     if (iIfcIdx == 0)
       
  1892         {
       
  1893         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: only after interface "
       
  1894                                           "(TUsbcDescriptorPool::InsertEpDesc)"));
       
  1895         return;
       
  1896         }
       
  1897     const TInt count = iDescriptors.Count();
       
  1898     TInt i = iIfcIdx + 1;
       
  1899     while (i < count)
       
  1900         {
       
  1901         if (iDescriptors[i]->Type() != KUsbDescType_Endpoint)
       
  1902             break;
       
  1903         ++i;
       
  1904         }
       
  1905     // put the new descriptor at position i
       
  1906     iDescriptors.Insert(aDesc, i);
       
  1907     // update the config descriptor's wTotalLength field
       
  1908     UpdateConfigDescriptorLength(aDesc->Size());
       
  1909     }
       
  1910 
       
  1911 
       
  1912 //
       
  1913 // Find the index of the Interface descriptor for a given interface setting.
       
  1914 //
       
  1915 TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const
       
  1916     {
       
  1917     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)",
       
  1918                                     aIfcNumber, aIfcSetting));
       
  1919     const TInt count = iDescriptors.Count();
       
  1920     for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
       
  1921         {
       
  1922         if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
       
  1923             (iDescriptors[i]->Byte(2) == aIfcNumber) &&
       
  1924             (iDescriptors[i]->Byte(3) == aIfcSetting))
       
  1925             {
       
  1926             return i;
       
  1927             }
       
  1928         }
       
  1929     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1930     return -1;
       
  1931     }
       
  1932 
       
  1933 
       
  1934 //
       
  1935 // Find the index of the Endpoint descriptor for a given endpoint on a given interface setting.
       
  1936 //
       
  1937 TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const
       
  1938     {
       
  1939     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)",
       
  1940                                     aIfcNumber, aIfcSetting, aEpAddress));
       
  1941     // first find the interface
       
  1942     const TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting);
       
  1943     if (ifc < 0)
       
  1944         {
       
  1945         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
       
  1946         return ifc;
       
  1947         }
       
  1948     const TInt count = iDescriptors.Count();
       
  1949     // then, before the next interface, try to locate the endpoint
       
  1950     for (TInt i = ifc + 1; i < count; i++)
       
  1951         {
       
  1952         if (iDescriptors[i]->Type() == KUsbDescType_Interface)
       
  1953             {
       
  1954             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint before next interface"));
       
  1955             return -1;
       
  1956             }
       
  1957         else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) &&
       
  1958                  (iDescriptors[i]->Byte(2) == aEpAddress))
       
  1959             {
       
  1960             // found
       
  1961             return i;
       
  1962             }
       
  1963         }
       
  1964     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
       
  1965     return -1;
       
  1966     }
       
  1967 
       
  1968 
       
  1969 //
       
  1970 // Delete n descriptors starting from aIndex and remove their pointers from the array.
       
  1971 //
       
  1972 void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount)
       
  1973     {
       
  1974     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteDescriptors()"));
       
  1975     if (aIndex < KDescPosition_FirstAvailable)
       
  1976         {
       
  1977         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aIndex < KDescPosition_FirstAvailable"));
       
  1978         return;
       
  1979         }
       
  1980     if (aCount <= 0)
       
  1981         {
       
  1982         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aCount <= 0"));
       
  1983         return;
       
  1984         }
       
  1985     __KTRACE_OPT(KUSB, Kern::Printf("  Removing descriptors at index %d:", aIndex));
       
  1986     // Try to update wTotalLength field in Config descriptor
       
  1987     while (aCount--)
       
  1988         {
       
  1989         // In this loop we don't decrement aIndex, because after deleting an element
       
  1990         // aIndex is already indexing the next one.
       
  1991         TUsbcDescriptorBase* const ptr = iDescriptors[aIndex];
       
  1992         switch (ptr->Type())
       
  1993             {
       
  1994         case KUsbDescType_Interface:
       
  1995             __KTRACE_OPT(KUSB, Kern::Printf("  - an interface descriptor"));
       
  1996             UpdateConfigDescriptorLength(-KUsbDescSize_Interface);
       
  1997             break;
       
  1998         case KUsbDescType_Endpoint:
       
  1999             __KTRACE_OPT(KUSB, Kern::Printf("  - an endpoint descriptor"));
       
  2000             UpdateConfigDescriptorLength(-ptr->Size());
       
  2001             break;
       
  2002         case KUsbDescType_CS_Interface:
       
  2003             /* fall through */
       
  2004         case KUsbDescType_CS_Endpoint:
       
  2005             __KTRACE_OPT(KUSB, Kern::Printf("  - a class specific descriptor"));
       
  2006             UpdateConfigDescriptorLength(-ptr->Size());
       
  2007             break;
       
  2008         default:
       
  2009             __KTRACE_OPT(KUSB, Kern::Printf("  - an unknown descriptor"));
       
  2010             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: unknown descriptor type"));
       
  2011             }
       
  2012         iDescriptors.Remove(aIndex);
       
  2013         delete ptr;
       
  2014         }
       
  2015     }
       
  2016 
       
  2017 
       
  2018 //
       
  2019 // Update the wTotalLength field in the Configuration descriptor (aLength can be negative).
       
  2020 //
       
  2021 void TUsbcDescriptorPool::UpdateConfigDescriptorLength(TInt aLength)
       
  2022     {
       
  2023     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorLength(%d)", aLength));
       
  2024     TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config];
       
  2025     __KTRACE_OPT(KUSB, Kern::Printf("  wTotalLength old: %d", cnf->Word(2)));
       
  2026     // Update Config descriptor
       
  2027     cnf->SetWord(2, cnf->Word(2) + aLength);
       
  2028     __KTRACE_OPT(KUSB, Kern::Printf("  wTotalLength new: %d", cnf->Word(2)));
       
  2029     // Update Other_Speed_Config descriptor as well, if applicable
       
  2030     if (iDescriptors[KDescPosition_OtherSpeedConfig])
       
  2031         iDescriptors[KDescPosition_OtherSpeedConfig]->SetWord(2, cnf->Word(2));
       
  2032     }
       
  2033 
       
  2034 
       
  2035 //
       
  2036 // Update the bNumInterfaces field in the Configuration descriptor (aNumber can be negative).
       
  2037 //
       
  2038 void TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(TInt aNumber)
       
  2039     {
       
  2040     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(%d)", aNumber));
       
  2041     TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config];
       
  2042     __KTRACE_OPT(KUSB, Kern::Printf("  bNumInterfaces old: %d", cnf->Byte(4)));
       
  2043     const TInt n = cnf->Byte(4) + aNumber;
       
  2044     if (n < 0)
       
  2045         {
       
  2046         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: bNumInterfaces + aNumber < 0"));
       
  2047         return;
       
  2048         }
       
  2049     // Update Config descriptor
       
  2050     cnf->SetByte(4, n);
       
  2051     __KTRACE_OPT(KUSB, Kern::Printf("  bNumInterfaces new: %d", cnf->Byte(4)));
       
  2052     // Update Other_Speed_Config descriptor as well, if applicable
       
  2053     if (iDescriptors[KDescPosition_OtherSpeedConfig])
       
  2054         iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(4, n);
       
  2055     }
       
  2056 
       
  2057 
       
  2058 //
       
  2059 // Update the bNumInterfaces field in the Configuration descriptor if necessary.
       
  2060 //
       
  2061 void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber)
       
  2062     {
       
  2063     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateIfcNumbers(%d)", aNumber));
       
  2064     const TInt count = iDescriptors.Count();
       
  2065     for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
       
  2066         {
       
  2067         if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
       
  2068             (iDescriptors[i]->Byte(2) == aNumber))
       
  2069             {
       
  2070             // there's still an interface with 'number' so we don't need to update anything
       
  2071             return;
       
  2072             }
       
  2073         }
       
  2074     // if we haven't returned yet, we decrement bNumInterfaces
       
  2075     UpdateConfigDescriptorNumIfcs(-1);
       
  2076     }
       
  2077 
       
  2078 
       
  2079 //
       
  2080 // Put the current Device or Device_Qualifier descriptor in the Ep0 Tx buffer.
       
  2081 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
       
  2082 //
       
  2083 TInt TUsbcDescriptorPool::GetDeviceDescriptor(TInt aIndex) const
       
  2084     {
       
  2085     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptor()"));
       
  2086     __ASSERT_DEBUG((aIndex == KDescPosition_Device) || (aIndex == KDescPosition_DeviceQualifier),
       
  2087                    Kern::Printf("  Error: invalid descriptor index: %d", aIndex));
       
  2088     if (iDescriptors[aIndex] == NULL)
       
  2089         {
       
  2090         // This doesn't have to be an error - we might get asked here for the Device_Qualifier descriptor
       
  2091         // on a FS-only device.
       
  2092         __KTRACE_OPT(KUSB, Kern::Printf("  Descriptor #%d requested but not available", aIndex));
       
  2093         return 0;
       
  2094         }
       
  2095     return iDescriptors[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
       
  2096     }
       
  2097 
       
  2098 
       
  2099 //
       
  2100 // Put the current Configuration or Other_Speed_Configuration descriptor + all the following
       
  2101 // descriptors in the Ep0 Tx buffer.
       
  2102 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
       
  2103 //
       
  2104 TInt TUsbcDescriptorPool::GetConfigurationDescriptor(TInt aIndex) const
       
  2105     {
       
  2106     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigDescriptor(%d)", aIndex));
       
  2107     __ASSERT_DEBUG((aIndex == KDescPosition_Config) || (aIndex == KDescPosition_OtherSpeedConfig),
       
  2108                    Kern::Printf("  Error: invalid descriptor index: %d", aIndex));
       
  2109     if (iDescriptors[aIndex] == NULL)
       
  2110         {
       
  2111         // This is always an error: We should always have a Configuration descriptor and we should never
       
  2112         // get asked for the Other_Speed_Configuration descriptor if we don't have one (9.6.2).
       
  2113         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Descriptor %d requested but not available", aIndex));
       
  2114         return 0;
       
  2115         }
       
  2116     const TInt count = iDescriptors.Count();
       
  2117     TInt copied = 0;
       
  2118     TUint8* buf = iEp0_TxBuf;
       
  2119     for (TInt i = aIndex; i < count; i++)
       
  2120         {
       
  2121         TUsbcDescriptorBase* const ptr = iDescriptors[i];
       
  2122         if ((aIndex == KDescPosition_OtherSpeedConfig) && (i == KDescPosition_Config))
       
  2123             {
       
  2124             // Skip Config descriptor when returning Other_Speed_Config
       
  2125             continue;
       
  2126             }
       
  2127         if ((i == KDescPosition_Otg) && (iDescriptors[i] == NULL))
       
  2128             {
       
  2129             __KTRACE_OPT(KUSB, Kern::Printf("  no OTG descriptor -> next"));
       
  2130             continue;
       
  2131             }
       
  2132         // We need to edit endpoint descriptors on the fly because we have only one copy
       
  2133         // of each and that copy has to contain different information, depending on the
       
  2134         // current speed and the type of descriptor requested.
       
  2135         if (ptr->Type() == KUsbDescType_Endpoint)
       
  2136             {
       
  2137             if ((iHighSpeed && (aIndex == KDescPosition_Config)) ||
       
  2138                 (!iHighSpeed && (aIndex == KDescPosition_OtherSpeedConfig)))
       
  2139                 {
       
  2140                 ptr->UpdateHs();
       
  2141                 }
       
  2142             else
       
  2143                 {
       
  2144                 ptr->UpdateFs();
       
  2145                 }
       
  2146             }
       
  2147         __KTRACE_OPT(KUSB, Kern::Printf("  desc[%02d]: type = 0x%02x size = %d ",
       
  2148                                         i, ptr->Type(), ptr->Size()));
       
  2149         const TInt size = ptr->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied);
       
  2150         if (size == 0)
       
  2151             {
       
  2152             __KTRACE_OPT(KPANIC,
       
  2153                          Kern::Printf("  Error: No Tx buffer space to copy this descriptor -> exiting"));
       
  2154             break;
       
  2155             }
       
  2156         copied += size;
       
  2157         if (copied >= KUsbcBufSz_Ep0Tx)
       
  2158             {
       
  2159             __KTRACE_OPT(KPANIC,
       
  2160                          Kern::Printf("  Error: No Tx buffer space left -> stopping here"));
       
  2161             break;
       
  2162             }
       
  2163         buf += size;
       
  2164         }
       
  2165     __KTRACE_OPT(KUSB, Kern::Printf("  copied %d bytes", copied));
       
  2166     return copied;
       
  2167     }
       
  2168 
       
  2169 
       
  2170 //
       
  2171 // Put the current OTG descriptor in the Ep0 Tx buffer.
       
  2172 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
       
  2173 //
       
  2174 TInt TUsbcDescriptorPool::GetOtgDescriptor() const
       
  2175     {
       
  2176     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtgDescriptor()"));
       
  2177     if (iDescriptors[KDescPosition_Otg] == NULL)
       
  2178         {
       
  2179         __KTRACE_OPT(KUSB, Kern::Printf("  OTG Descriptor not set"));
       
  2180         return 0;
       
  2181         }
       
  2182     return iDescriptors[KDescPosition_Otg]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
       
  2183     }
       
  2184 
       
  2185 
       
  2186 //
       
  2187 // Put a specific String descriptor in the Ep0 Tx buffer.
       
  2188 // Only used for Ep0 standard requests, so target buffer can be hard-wired.
       
  2189 //
       
  2190 TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const
       
  2191     {
       
  2192     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptor(%d)", aIndex));
       
  2193     // I really would have liked to display the descriptor contents here, but without trailing zero
       
  2194     // we got a problem: how can we tell printf where the string ends? We would have to
       
  2195     // dynamically allocate memory (since we don't know the size in advance), copy the descriptor
       
  2196     // contents there, append a zero, and give this to printf. That's a bit too much effort...
       
  2197     if (!StringDescriptorExists(aIndex))
       
  2198         {
       
  2199         return 0;
       
  2200         }
       
  2201     return iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
       
  2202     }
       
  2203 
       
  2204 
       
  2205 //
       
  2206 // Write a String descriptor pointed to by the Device descriptor to the user side
       
  2207 // (one of Manufacturer, Product, SerialNumber).
       
  2208 //
       
  2209 TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString,
       
  2210                                                       TInt aIndex, TInt aPosition) const
       
  2211     {
       
  2212     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceStringDescriptorTC()"));
       
  2213     const TInt str_idx = iDescriptors[KDescPosition_Device]->Byte(aIndex);
       
  2214     if (str_idx)
       
  2215         {
       
  2216         __ASSERT_ALWAYS((str_idx == aPosition), Kern::Fault(KUsbPanicCat, __LINE__));
       
  2217         __KTRACE_OPT(KUSB, Kern::Printf("  String @ pos %d (device $): \"%S\"",
       
  2218                                         str_idx, &iStrings[str_idx]->StringData()));
       
  2219         return Kern::ThreadDesWrite(aThread, &aString,
       
  2220                                     iStrings[str_idx]->StringData(), 0);
       
  2221         }
       
  2222     else
       
  2223         {
       
  2224         __KTRACE_OPT(KUSB, Kern::Printf("  No string descriptor @ pos %d", aIndex));
       
  2225         return KErrNotFound;
       
  2226         }
       
  2227     }
       
  2228 
       
  2229 
       
  2230 //
       
  2231 // Read a Device String descriptor from the user side and put in the descriptor arrays
       
  2232 // (one of Manufacturer, Product, SerialNumber).
       
  2233 //
       
  2234 TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString,
       
  2235                                                       TInt aIndex, TInt aPosition)
       
  2236     {
       
  2237     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceStringDescriptorTC()"));
       
  2238     // we don't know the length of the string, so we have to allocate memory dynamically
       
  2239     TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
       
  2240     if (strlen > KUsbStringDescStringMaxSize)
       
  2241         {
       
  2242         __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: $ descriptor too long - will be truncated"));
       
  2243         strlen = KUsbStringDescStringMaxSize;
       
  2244         }
       
  2245     HBuf8* const strbuf = HBuf8::New(strlen);
       
  2246     if (!strbuf)
       
  2247         {
       
  2248         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for dev $ desc string failed (1)"));
       
  2249         return KErrNoMemory;
       
  2250         }
       
  2251     strbuf->SetMax();
       
  2252     // the aString points to data that lives in user memory, so we have to copy it:
       
  2253     const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
       
  2254     if (r != KErrNone)
       
  2255         {
       
  2256         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
       
  2257         delete strbuf;
       
  2258         return r;
       
  2259         }
       
  2260     TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf);
       
  2261     if (!sd)
       
  2262         {
       
  2263         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for dev $ desc failed (2)"));
       
  2264         delete strbuf;
       
  2265         return KErrNoMemory;
       
  2266         }
       
  2267     ExchangeStringDescriptor(aPosition, sd);
       
  2268     iDescriptors[KDescPosition_Device]->SetByte(aIndex, aPosition);
       
  2269     delete strbuf;
       
  2270     return r;
       
  2271     }
       
  2272 
       
  2273 
       
  2274 //
       
  2275 // Remove a Device String descriptor from the descriptor arrays
       
  2276 // (one of Manufacturer, Product, SerialNumber).
       
  2277 //
       
  2278 TInt TUsbcDescriptorPool::RemoveDeviceStringDescriptor(TInt aIndex, TInt aPosition)
       
  2279     {
       
  2280     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveDeviceStringDescriptor()"));
       
  2281     if (iDescriptors[KDescPosition_Device]->Byte(aIndex) == 0)
       
  2282         {
       
  2283         __KTRACE_OPT(KUSB, Kern::Printf("  RemoveDeviceStringDescriptor: no $ desc @ index %d", aIndex));
       
  2284         return KErrNotFound;
       
  2285         }
       
  2286     ExchangeStringDescriptor(aPosition, NULL);
       
  2287     iDescriptors[KDescPosition_Device]->SetByte(aIndex, 0);
       
  2288     return KErrNone;
       
  2289     }
       
  2290 
       
  2291 
       
  2292 //
       
  2293 // Puts aDesc at postion aIndex in the string descriptor array, after deleting what was (possibly) there.
       
  2294 //
       
  2295 void TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc)
       
  2296     {
       
  2297     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::ExchangeStringDescriptor()"));
       
  2298     TUsbcStringDescriptorBase* const ptr = iStrings[aIndex];
       
  2299     __KTRACE_OPT(KUSB, Kern::Printf("  Deleting string descriptor at index %d: 0x%x", aIndex, ptr));
       
  2300     iStrings.Remove(aIndex);
       
  2301     delete ptr;
       
  2302     __KTRACE_OPT(KUSB, Kern::Printf("  Inserting string descriptor at index %d: 0x%x", aIndex, aDesc));
       
  2303     iStrings.Insert(aDesc, aIndex);
       
  2304     }
       
  2305 
       
  2306 
       
  2307 //
       
  2308 // Checks whether there are any string descriptors in the array (apart from LangID).
       
  2309 //
       
  2310 TBool TUsbcDescriptorPool::AnyStringDescriptors() const
       
  2311     {
       
  2312     const TInt n = iStrings.Count();
       
  2313     for (TInt i = 1; i < n; i++)
       
  2314         {
       
  2315         if (iStrings[i] != NULL)
       
  2316             return ETrue;
       
  2317         }
       
  2318     return EFalse;
       
  2319     }
       
  2320 
       
  2321 
       
  2322 //
       
  2323 // Returns true if aIndex exists and what is at that positition is not a NULL pointer.
       
  2324 //
       
  2325 TBool TUsbcDescriptorPool::StringDescriptorExists(TInt aIndex) const
       
  2326     {
       
  2327     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::StringDescriptorExists()"));
       
  2328     if (aIndex >= iStrings.Count())
       
  2329         {
       
  2330         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad string index: %d", aIndex));
       
  2331         return EFalse;
       
  2332         }
       
  2333     else if (iStrings[aIndex] == NULL)
       
  2334         {
       
  2335         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: No $ descriptor @ pos %d", aIndex));
       
  2336         return EFalse;
       
  2337         }
       
  2338     return ETrue;
       
  2339     }
       
  2340 
       
  2341 
       
  2342 //
       
  2343 //
       
  2344 //
       
  2345 TInt TUsbcDescriptorPool::FindAvailableStringPos() const
       
  2346     {
       
  2347     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindAvailableStringPos()"));
       
  2348     const TInt n = iStrings.Count();
       
  2349     // We don't start from 0 because the first few locations are 'reserved'.
       
  2350     for (TInt i = KStringPosition_FirstAvailable; i < n; i++)
       
  2351         {
       
  2352         if (iStrings[i] == NULL)
       
  2353             {
       
  2354             __KTRACE_OPT(KUSB, Kern::Printf(" Found available NULL position: %d", i));
       
  2355             return i;
       
  2356             }
       
  2357         }
       
  2358     return -1;
       
  2359     }
       
  2360 
       
  2361 
       
  2362 // -eof-