os/kernelhwsrv/kerneltest/e32utils/testusbcldd/src/descriptors.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2004-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 // f32test\testusbcldd\src\descriptors.cpp
    15 // Platform independent USB client controller layer (PIL):
    16 // USB descriptor handling and management.
    17 // 
    18 //
    19 
    20 #include "usbcdesc.h"
    21 #include "dtestusblogdev.h"
    22 
    23 // --- TUsbcDescriptorBase
    24 
    25 TUsbcDescriptorBase::TUsbcDescriptorBase()
    26 	:
    27 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
    28 	iIndex(0),
    29 #endif
    30 	iBufPtr(NULL, 0)
    31   	{
    32 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::TUsbcDescriptorBase()")));
    33 	}
    34 
    35 
    36 TUsbcDescriptorBase::~TUsbcDescriptorBase()
    37 	{
    38 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::~TUsbcDescriptorBase()")));
    39 	}
    40 
    41 
    42 void TUsbcDescriptorBase::SetByte(TUint aPosition, TUint8 aValue)
    43 	{
    44 	iBufPtr[aPosition] = aValue;
    45 	}
    46 
    47 
    48 void TUsbcDescriptorBase::SetWord(TUint aPosition, TUint16 aValue)
    49 	{
    50 	*reinterpret_cast<TUint16*>(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue);
    51 	}
    52 
    53 
    54 TUint8 TUsbcDescriptorBase::Byte(TUint aPosition) const
    55 	{
    56 	return iBufPtr[aPosition];
    57 	}
    58 
    59 
    60 TUint16 TUsbcDescriptorBase::Word(TUint aPosition) const
    61 	{
    62 	return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition]));
    63 	}
    64 
    65 
    66 void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const
    67 	{
    68 	aBuffer = iBufPtr;
    69 	}
    70 
    71 
    72 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
    73 	{
    74 	__MEMCPY(aBuffer, iBufPtr.Ptr(), Size());
    75 	return Size();
    76 	}
    77 
    78 
    79 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const
    80 	{
    81 	if (aMaxSize < Size())
    82 		{
    83 		// No use to copy only half a descriptor
    84 		return 0;
    85 		}
    86 	return GetDescriptorData(aBuffer);
    87 	}
    88 
    89 
    90 const TDes8& TUsbcDescriptorBase::DescriptorData() const
    91 	{
    92 	return iBufPtr;
    93 	}
    94 
    95 
    96 TDes8& TUsbcDescriptorBase::DescriptorData()
    97 	{
    98 	return iBufPtr;
    99 	}
   100 
   101 
   102 TInt TUsbcDescriptorBase::Size() const
   103 	{
   104 	return iBufPtr.Size();
   105 	}
   106 
   107 
   108 TUint8 TUsbcDescriptorBase::Type() const
   109 	{
   110 	return iBufPtr[1];
   111 	}
   112 
   113 
   114 void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes)
   115 	{
   116 	iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
   117 	}
   118 
   119 
   120 // --- TUsbcDeviceDescriptor
   121 
   122 TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()
   123 	: iBuf()
   124   	{
   125 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()")));
   126 	}
   127 
   128 
   129 TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
   130 												  TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
   131 												  TUint16 aVendorId, TUint16 aProductId,
   132 												  TUint16 aDeviceRelease, TUint8 aNumConfigurations)
   133 	{
   134 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::New()")));
   135 	TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor();
   136 	if (self)
   137 		{
   138 		if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId,
   139 							aProductId, aDeviceRelease, aNumConfigurations) != KErrNone)
   140 			{
   141 			delete self;
   142 			return NULL;
   143 			}
   144 		}
   145 	return self;
   146 	}
   147 
   148 
   149 TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
   150 									  TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
   151 									  TUint16 aDeviceRelease, TUint8 aNumConfigurations)
   152 	{
   153 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::Construct()")));
   154 	iBuf.SetMax();
   155 	SetBufferPointer(iBuf);
   156 	iBuf[0] = (TUint8)iBuf.Size();									// bLength
   157 	iBuf[1] = KUsbDescType_Device;							// bDescriptorType
   158  	SetWord(2, KUsbcUsbVersion);							// bcdUSB
   159 	iBuf[4] = aDeviceClass;									// bDeviceClass
   160 	iBuf[5] = aDeviceSubClass;								// bDeviceSubClass
   161 	iBuf[6] = aDeviceProtocol;								// bDeviceProtocol
   162 	iBuf[7] = aMaxPacketSize0;								// bMaxPacketSize0
   163 	SetWord(8, aVendorId);									// idVendor
   164 	SetWord(10, aProductId);								// idProduct
   165 	SetWord(12, aDeviceRelease);							// bcdDevice
   166 	iBuf[14] = 0;											// iManufacturer
   167 	iBuf[15] = 0;											// iProduct
   168 	iBuf[16] = 0;											// iSerialNumber
   169 	iBuf[17] = aNumConfigurations;							// bNumConfigurations
   170 	return KErrNone;
   171 	}
   172 
   173 // --- TUsbcConfigDescriptor
   174 
   175 TUsbcConfigDescriptor::TUsbcConfigDescriptor()
   176 	: iBuf()
   177   	{
   178 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::TUsbcConfigDescriptor()")));
   179 	}
   180 
   181 
   182 TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered,
   183 												  TBool aRemoteWakeup, TUint8 aMaxPower)
   184 	{
   185 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::New()")));
   186 	TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor();
   187 	if (self)
   188 		{
   189 		if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone)
   190 			{
   191 			delete self;
   192 			return NULL;
   193 			}
   194 		}
   195 	return self;
   196 	}
   197 
   198 
   199 TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered,
   200 									   TBool aRemoteWakeup, TUint8 aMaxPower)
   201 	{
   202 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::Construct()")));
   203 	iBuf.SetMax();
   204 	SetBufferPointer(iBuf);
   205 	iBuf[0] = (TUint8)iBuf.Size();									// bLength
   206 	iBuf[1] = KUsbDescType_Config;							// bDescriptorType
   207 	SetWord(2, KUsbDescSize_Config);						// wTotalLength
   208 	iBuf[4] = 0;											// bNumInterfaces
   209 	iBuf[5] = aConfigurationValue;							// bConfigurationValue
   210 	iBuf[6] = 0;											// iConfiguration
   211 	iBuf[7] = (TUint8)(0x80 | (aSelfPowered ? 0x40 : 0) | (aRemoteWakeup ? 0x20 : 0)); // bmAttributes (bit 7 always 1)
   212 	iBuf[8] = (TUint8)(aMaxPower / 2);								// MaxPower (2mA units!)
   213 	return KErrNone;
   214 	}
   215 
   216 
   217 // --- TUsbcInterfaceDescriptor
   218 
   219 TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()
   220 	: iBuf()
   221   	{
   222  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()")));
   223 	}
   224 
   225 
   226 TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
   227 														TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
   228 	{
   229 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::New()")));
   230 	TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor();
   231 	if (self)
   232 		{
   233 		if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone)
   234 			{
   235 			delete self;
   236 			return NULL;
   237 			}
   238 		}
   239 	return self;
   240 	}
   241 
   242 
   243 TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
   244 										 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
   245 	{
   246 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::Construct()")));
   247 	iBuf.SetMax();
   248 	SetBufferPointer(iBuf);
   249 	iBuf[0] = (TUint8)iBuf.Size();									// bLength
   250 	iBuf[1] = KUsbDescType_Interface;						// bDescriptorType
   251 	iBuf[2] = aInterfaceNumber;								// bInterfaceNumber
   252 	iBuf[3] = aAlternateSetting;							// bAlternateSetting
   253 	iBuf[4] = (TUint8)aNumEndpoints;								// bNumEndpoints
   254 	iBuf[5] = (TUint8)aClassInfo.iClassNum;							// bInterfaceClass
   255 	iBuf[6] = (TUint8)aClassInfo.iSubClassNum;						// bInterfaceSubClass
   256 	iBuf[7] = (TUint8)aClassInfo.iProtocolNum;						// bInterfaceProtocol
   257 	iBuf[8] = 0;											// iInterface
   258 	return KErrNone;
   259 	}
   260 
   261 
   262 // --- TUsbcEndpointDescriptor
   263 
   264 TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()
   265 	: iBuf()
   266   	{
   267  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()")));
   268 	}
   269 
   270 
   271 TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress,
   272 													  const TUsbcEndpointInfo& aEpInfo)
   273 	{
   274 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::New()")));
   275 	TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor();
   276 	if (self)
   277 		{
   278 		if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
   279 			{
   280 			delete self;
   281 			return NULL;
   282 			}
   283 		}
   284 	return self;
   285 	}
   286 
   287 
   288 TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
   289 	{
   290 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::Construct()")));
   291 	iBuf.SetMax();
   292 	SetBufferPointer(iBuf);
   293 	iBuf[0] = (TUint8)iBuf.Size();									// bLength
   294 	iBuf[1] = KUsbDescType_Endpoint;						// bDescriptorType
   295  	iBuf[2] = aEndpointAddress;								// bEndpointAddress
   296 	iBuf[3] = (TUint8)EpTypeMask2Value(aEpInfo.iType);				// bmAttributes
   297 	SetWord(4, (TUint8)aEpInfo.iSize);								// wMaxPacketSize
   298 	iBuf[6] = (TUint8)aEpInfo.iInterval;							// bInterval
   299 	return KErrNone;
   300 	}
   301 
   302 
   303 // --- TUsbcAudioEndpointDescriptor
   304 
   305 TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()
   306 	: iBuf()
   307   	{
   308  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()")));
   309 	}
   310 
   311 
   312 TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress,
   313 																const TUsbcEndpointInfo& aEpInfo)
   314 	{
   315 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::New()")));
   316 	TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor();
   317 	if (self)
   318 		{
   319 		if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
   320 			{
   321 			delete self;
   322 			return NULL;
   323 			}
   324 		}
   325 	return self;
   326 	}
   327 
   328 
   329 TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
   330 	{
   331 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::Construct()")));
   332 	iBuf.SetMax();
   333 	SetBufferPointer(iBuf);
   334 	iBuf[0] = (TUint8)iBuf.Size();									// bLength
   335 	iBuf[1] = KUsbDescType_Endpoint;						// bDescriptorType
   336  	iBuf[2] = aEndpointAddress;								// bEndpointAddress
   337 	iBuf[3] = (TUint8)EpTypeMask2Value(aEpInfo.iType);				// bmAttributes
   338 	SetWord(4, (TUint8)aEpInfo.iSize);								// wMaxPacketSize
   339 	iBuf[6] = (TUint8)aEpInfo.iInterval;							// bInterval
   340 	iBuf[7] = 0;
   341 	iBuf[8] = 0;
   342 	return KErrNone;
   343 	}
   344 
   345 
   346 // --- TUsbcClassSpecificDescriptor
   347 
   348 TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()
   349 	: iBuf(NULL)
   350   	{
   351  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()")));
   352 	}
   353 
   354 
   355 TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()
   356 	{
   357 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()")));
   358 	delete iBuf;
   359 	}
   360 
   361 
   362 TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize)
   363 	{
   364 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::New()")));
   365 	TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor();
   366 	if (self)
   367 		{
   368 		if (self->Construct(aType, aSize) != KErrNone)
   369 			{
   370 			delete self;
   371 			return NULL;
   372 			}
   373 		}
   374 	return self;
   375 	}
   376 
   377 
   378 TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize)
   379 	{
   380 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::Construct()")));
   381 	__NEWPLATBUF(iBuf, aSize);
   382 	if (!iBuf)
   383 		{
   384 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Allocation of CS desc buffer failed")));
   385 		return KErrNoMemory;
   386 		}
   387 	SetBufferPointer(*iBuf);
   388 	SetByte(1, aType);										// bDescriptorType
   389 	return KErrNone;
   390 	}
   391 
   392 
   393 // --- TUsbcStringDescriptorBase
   394 
   395 TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()
   396 	: /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0)
   397 	{
   398 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()")));
   399 	}
   400 
   401 
   402 TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()
   403 	{
   404 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()")));
   405 	}
   406 
   407 
   408 TUint16 TUsbcStringDescriptorBase::Word(TUint aPosition) const
   409 	{
   410 	if (aPosition <= 1)
   411 		{
   412 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::Word: Error: Word(%d) in string descriptor!"), aPosition));
   413 		return 0;
   414 		}
   415 	else
   416 		{
   417 		// since iBufPtr[0] is actually string descriptor byte index 2,
   418 		// we have to subtract 2 from the absolute position.
   419 		return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition - 2]));
   420 		}
   421 	}
   422 
   423 
   424 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
   425 	{
   426 	aBuffer[0] = iSBuf[0];
   427 	aBuffer[1] = iSBuf[1];
   428 	__MEMCPY(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size());
   429 	return Size();
   430 	}
   431 
   432 
   433 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const
   434 	{
   435 	if (aMaxSize < Size())
   436 		{
   437 		// No use to copy only half a string
   438 		return 0;
   439 		}
   440 	return GetDescriptorData(aBuffer);
   441 	}
   442 
   443 
   444 const TDes8& TUsbcStringDescriptorBase::StringData() const
   445 	{
   446 	return iBufPtr;
   447 	}
   448 
   449 
   450 TDes8& TUsbcStringDescriptorBase::StringData()
   451 	{
   452 	return iBufPtr;
   453 	}
   454 
   455 
   456 TInt TUsbcStringDescriptorBase::Size() const
   457 	{
   458 	return iSBuf[0];
   459 	}
   460 
   461 
   462 void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes)
   463 	{
   464 	iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
   465 	}
   466 
   467 
   468 // --- TUsbcStringDescriptor
   469 
   470 TUsbcStringDescriptor::TUsbcStringDescriptor()
   471 	: iBuf(NULL)
   472 	{
   473 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::TUsbcStringDescriptor()")));
   474 	}
   475 
   476 
   477 TUsbcStringDescriptor::~TUsbcStringDescriptor()
   478 	{
   479 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::~TUsbcStringDescriptor()")));
   480 	delete iBuf;
   481 	}
   482 
   483 
   484 TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString)
   485 	{
   486 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::New")));
   487 	TUsbcStringDescriptor* self = new TUsbcStringDescriptor();
   488 	if (self)
   489 		{
   490 		if (self->Construct(aString) != KErrNone)
   491 			{
   492 			delete self;
   493 			return NULL;
   494 			}
   495 		}
   496 	return self;
   497 	}
   498 
   499 
   500 TInt TUsbcStringDescriptor::Construct(const TDesC8& aString)
   501 	{
   502 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::Construct")));
   503 	__NEWPLATBUF(iBuf, aString.Size());
   504 	if (!iBuf)
   505 		{
   506 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Allocation of string buffer failed")));
   507 		return KErrNoMemory;
   508 		}
   509 	SetBufferPointer(*iBuf);
   510 	iBufPtr.Copy(aString);
   511 	iSBuf.SetMax();
   512 	iSBuf[0] = (TUint8)(iBuf->Size() + 2); // Bytes
   513 	iSBuf[1] = KUsbDescType_String;
   514 	return KErrNone;
   515 	}
   516 
   517 
   518 // --- TUsbcLangIdDescriptor
   519 
   520 TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()
   521 	: iBuf(NULL)
   522 	{
   523 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()")));
   524 	}
   525 
   526 
   527 TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()
   528 	{
   529 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()")));
   530 	}
   531 
   532 
   533 TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId)
   534 	{
   535 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::New")));
   536 	TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor();
   537 	if (self)
   538 		{
   539 		if (self->Construct(aLangId) != KErrNone)
   540 			{
   541 			delete self;
   542 			return NULL;
   543 			}
   544 		}
   545 	return self;
   546 	}
   547 
   548 
   549 TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId)
   550 	{
   551 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::Construct")));
   552 	iBuf.SetMax();
   553 	SetBufferPointer(iBuf);
   554 	iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId));			// Language ID value
   555 	iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId));
   556 	iSBuf.SetMax();
   557 	iSBuf[0] = (TUint8)(iBuf.Size() + 2);								// Bytes
   558 	iSBuf[1] = KUsbDescType_String;
   559 	return KErrNone;
   560 	}
   561 
   562 
   563 // --- TUsbcDescriptorPool
   564 
   565 TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf)
   566 //
   567 //  The constructor for this class.
   568 //
   569 	: iDescriptors(4), iStrings(4),	iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf) // 4 = granularity
   570 	{
   571 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::TUsbcDescriptorPool()")));
   572 	}
   573 
   574 
   575 TUsbcDescriptorPool::~TUsbcDescriptorPool()
   576 	{
   577 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::~TUsbcDescriptorPool()")));
   578 	// The destructor of each <class T> object is called before the objects themselves are destroyed.
   579 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  iDescriptors.Count(): %d"), iDescriptors.Count()));
   580 	iDescriptors.ResetAndDestroy();
   581 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  iStrings.Count(): %d"), iStrings.Count()));
   582 	iStrings.ResetAndDestroy();
   583 	}
   584 
   585 
   586 TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
   587 							   TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
   588 							   TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
   589 							   TUsbcStringDescriptor* aConfig)
   590 	{
   591 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::Init()")));
   592 	iDescriptors.Insert(aDeviceDesc, 0);
   593 	iDescriptors.Insert(aConfigDesc, 1);
   594 	if (!aLangId || !aManufacturer || !aProduct || !aSerialNum || !aConfig)
   595 		{
   596 		// USB spec p. 202 says: "A USB device may omit all string descriptors."
   597 		// So, either ALL string descriptors are supplied or none at all.
   598 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: No string descriptor(s)")));
   599 		return KErrArgument;
   600 		}
   601 	iStrings.Insert(aLangId, 0);
   602 	iStrings.Insert(aManufacturer, 1);
   603 	iStrings.Insert(aProduct, 2);
   604 	iStrings.Insert(aSerialNum, 3);
   605 	iStrings.Insert(aConfig, 4);
   606 	// set string indices
   607 	iDescriptors[0]->SetByte(14, 1);						// Device.iManufacturer
   608 	iDescriptors[0]->SetByte(15, 2);						// Device.iProduct
   609 	iDescriptors[0]->SetByte(16, 3);						// Device.iSerialNumber
   610 	iDescriptors[1]->SetByte( 6, 4);						// Config.iConfiguration
   611 	return KErrNone;
   612 	}
   613 
   614 
   615 TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const
   616 	{
   617 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindDescriptor()")));
   618 	TInt result = KErrGeneral;
   619 
   620 	switch(aType)
   621 		{
   622 	case KUsbDescType_Device:
   623 		if (aLangid != 0)
   624 			{
   625 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad langid: 0x%04x"), aLangid));
   626 			result = KErrGeneral;							// bad langid
   627 			}
   628 		else if (aIndex > 0)
   629 			{
   630 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad device index: %d"), aIndex));
   631 			result = KErrGeneral;							// we have only one device
   632 			}
   633 		else
   634 			{
   635 			aSize = GetDeviceDescriptor();
   636 			result = KErrNone;
   637 			}
   638 		break;
   639 	case KUsbDescType_Config:
   640 		if (aLangid != 0)
   641 			{
   642 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad langid: 0x%04x"), aLangid));
   643 			result = KErrGeneral;							// bad langid
   644 			}
   645 		else if (aIndex > 0)
   646 			{
   647 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad config index: %d"), aIndex));
   648 			result = KErrGeneral;							// we have only one configuration
   649 			}
   650 		else
   651 			{
   652 			aSize = GetConfigDescriptor();
   653 			result = KErrNone;
   654 			}
   655 		break;
   656 	case KUsbDescType_String:
   657 		if ((aLangid != 0) &&								// 0 addresses the LangId array
   658 			(aLangid != iStrings[0]->Word(2)))				// we have just one (this) language
   659 			{
   660 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad langid (0x%04x requested, 0x%04x supported)"),
   661 											  aLangid, iStrings[0]->Word(2)));
   662 			result = KErrGeneral;							// bad langid
   663 			}
   664 		else if (aIndex >= iStrings.Count())
   665 			{
   666 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad string index: %d"), aIndex));
   667 			result = KErrGeneral;
   668 			}
   669 		else
   670 			{
   671 			aSize = GetStringDescriptor(aIndex);
   672 			result = KErrNone;
   673 			}
   674 		break;
   675 	case KUsbDescType_CS_Interface:
   676 		/* fall through */
   677 	case KUsbDescType_CS_Endpoint:
   678 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: finding of class specific descriptors not supported")));
   679 		break;
   680 	default:
   681 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: unknown descriptor type requested: %d"), aType));
   682 		result = KErrGeneral;
   683 		break;
   684 		}
   685 
   686 	return result;
   687 	}
   688 
   689 
   690 void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc)
   691 	{
   692 	switch (aDesc->Type())
   693 		{
   694 	case KUsbDescType_Device:
   695 		InsertDevDesc(aDesc);
   696 		break;
   697 	case KUsbDescType_Config:
   698 		InsertConfigDesc(aDesc);
   699 		break;
   700 	case KUsbDescType_Interface:
   701 		InsertIfcDesc(aDesc);
   702 		break;
   703 	case KUsbDescType_Endpoint:
   704 		InsertEpDesc(aDesc);
   705 		break;
   706 	case KUsbDescType_CS_Interface:
   707 		/* fall through */
   708 	case KUsbDescType_CS_Endpoint:
   709 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: inserting class specific descriptors not supported")));
   710 		break;
   711 	default:
   712 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertDescriptor: Error: invalid type")));
   713 		break;
   714 		}
   715 	}
   716 
   717 
   718 void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting)
   719 	{
   720 	TInt i = FindIfcDescriptor(aNumber, aSetting);
   721 	if (i < 0)
   722 		{
   723 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::SetIfcStringDescriptor: error")));
   724 		return;
   725 		}
   726 	// Set (append) string descriptor for specified interface
   727 	iStrings.Append(aDesc);
   728 	// Update this ifc descriptors' string index field
   729 	const TInt str_idx = iStrings.Count() - 1;
   730 	iDescriptors[i]->SetByte(8, (TUint8)str_idx);
   731 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  String for ifc %d/%d (@ pos %d): \"%S\""), aNumber, aSetting, str_idx,
   732 									&iStrings[str_idx]->StringData()));
   733 	}
   734 
   735 
   736 void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting)
   737 	{
   738 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)"), aNumber, aSetting));
   739 	TInt i = FindIfcDescriptor(aNumber, aSetting);
   740 	if (i < 0)
   741 		{
   742 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: descriptor not found")));
   743 		return;
   744 		}
   745 	// Delete (if necessary) specified interface's string descriptor
   746 	TInt si = iDescriptors[i]->Byte(8);
   747 	if (si != 0)
   748 		{
   749 		DeleteString(si);
   750 		}
   751 	// Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors:
   752 	// find position of the next interface descriptor: we need to delete everything in between
   753 	const TInt count = iDescriptors.Count();
   754 	TInt j = i, n = 1;
   755 	while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface)
   756 		++n;
   757 	DeleteDescriptors(i, n);
   758 	// Update all the following interfaces' bInterfaceNumber field if required
   759 	// (because these descriptors might have moved down by one position)
   760 	UpdateIfcNumbers(aNumber);
   761 	// Update (if necessary) all interfaces' string index field
   762 	if (si != 0)
   763 		{
   764 		UpdateIfcStringIndexes(si);
   765 		}
   766 	iIfcIdx = 0;											// ifc index no longer valid
   767 	}
   768 
   769 
   770 // The TC in many of the following functions stands for 'ThreadCopy',
   771 // because that's what's happening there.
   772 
   773 TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const
   774 	{
   775 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[0]->DescriptorData());
   776 	}
   777 
   778 
   779 TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer)
   780 	{
   781 	TBuf8<KUsbDescSize_Device> device;
   782 	TInt r = __THREADREAD(aThread, &aBuffer, device);
   783 	if (r != KErrNone)
   784 		{
   785 		return r;
   786 		}
   787 	iDescriptors[0]->SetByte(2, device[2]);					// bcdUSB
   788 	iDescriptors[0]->SetByte(3, device[3]);					// bcdUSB (part II)
   789 	iDescriptors[0]->SetByte(4, device[4]);					// bDeviceClass
   790 	iDescriptors[0]->SetByte(5, device[5]);					// bDeviceSubClass
   791 	iDescriptors[0]->SetByte(6, device[6]);					// bDeviceProtocol
   792 	iDescriptors[0]->SetByte(8, device[8]);					// idVendor
   793 	iDescriptors[0]->SetByte(9, device[9]);					// idVendor (part II)
   794 	iDescriptors[0]->SetByte(10, device[10]);				// idProduct
   795 	iDescriptors[0]->SetByte(11, device[11]);				// idProduct (part II)
   796 	iDescriptors[0]->SetByte(12, device[12]);				// bcdDevice
   797 	iDescriptors[0]->SetByte(13, device[13]);				// bcdDevice (part II)
   798 	return KErrNone;
   799 	}
   800 
   801 
   802 TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
   803 	{
   804 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[1]->DescriptorData());
   805 	}
   806 
   807 
   808 TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
   809 	{
   810 	TBuf8<KUsbDescSize_Config> config;
   811 	TInt r = __THREADREAD(aThread, &aBuffer, config);
   812 	if (r != KErrNone)
   813 		{
   814 		return r;
   815 		}
   816 	iDescriptors[1]->SetByte(7, config[7]);					// bmAttributes
   817 	iDescriptors[1]->SetByte(8, config[8]);					// bMaxPower
   818 	return KErrNone;
   819 	}
   820 
   821 
   822 TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
   823 												   TInt aInterface, TInt aSetting) const
   824 	{
   825 	TInt i = FindIfcDescriptor(aInterface, aSetting);
   826 	if (i < 0)
   827 		{
   828 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
   829 		return KErrNotFound;
   830 		}
   831 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
   832 	}
   833 
   834 
   835 TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting)
   836 	{
   837 	TInt i = FindIfcDescriptor(aInterface, aSetting);
   838 	if (i < 0)
   839 		{
   840 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
   841 		return KErrNotFound;
   842 		}
   843 	iDescriptors[i]->SetByte(2, aBuffer[2]);				// bInterfaceNumber
   844 	iDescriptors[i]->SetByte(5, aBuffer[5]);				// bInterfaceClass
   845 	iDescriptors[i]->SetByte(6, aBuffer[6]);				// bInterfaceSubClass
   846 	iDescriptors[i]->SetByte(7, aBuffer[7]);				// bInterfaceProtocol
   847 	return KErrNone;
   848 	}
   849 
   850 
   851 TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer,
   852 												  TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const
   853 	{
   854 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
   855 	if (i < 0)
   856 		{
   857 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
   858 		return KErrNotFound;
   859 		}
   860 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
   861 	}
   862 
   863 
   864 TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer,
   865 												  TInt aInterface, TInt aSetting, TUint8 aEndpointAddress)
   866 	{
   867 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
   868 	if (i < 0)
   869 		{
   870 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
   871 		return KErrNotFound;
   872 		}
   873 	TBuf8<KUsbDescSize_AudioEndpoint> ep;					// it could be an audio endpoint
   874 	TInt r = __THREADREAD(aThread, &aBuffer, ep);
   875 	if (r != KErrNone)
   876 		{
   877 		return r;
   878 		}
   879 	iDescriptors[i]->SetByte(3, ep[3]);						// bmAttributes
   880 	iDescriptors[i]->SetByte(6, ep[6]);						// bInterval
   881 	if (static_cast<TUint>(iDescriptors[i]->Size()) == KUsbDescSize_AudioEndpoint)
   882 		{
   883 		iDescriptors[i]->SetByte(7, ep[7]);					// bRefresh
   884 		iDescriptors[i]->SetByte(8, ep[8]);					// bSynchAddress
   885 		}
   886 	return KErrNone;
   887 	}
   888 
   889 
   890 TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress,
   891 													TInt& aSize) const
   892 	{
   893 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
   894 	if (i < 0)
   895 		{
   896 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
   897 		return KErrNotFound;
   898 		}
   899 	aSize = iDescriptors[i]->Size();
   900 	return KErrNone;
   901 	}
   902 
   903 
   904 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
   905 													 TInt aInterface, TInt aSetting) const
   906 	{
   907 	// first find the interface
   908 	TInt i = FindIfcDescriptor(aInterface, aSetting);
   909 	if (i < 0)
   910 		{
   911 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
   912 		return KErrNotFound;
   913 		}
   914 	TInt r = KErrNotFound;
   915 	TInt offset = 0;
   916 	const TInt count = iDescriptors.Count();
   917 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
   918 		{
   919 		r = __THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset);
   920 		if (r != KErrNone)
   921 			break;
   922 		offset += iDescriptors[i]->Size();
   923 		}
   924 	return r;
   925 	}
   926 
   927 
   928 TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer,
   929 													 TInt aInterface, TInt aSetting, TInt aSize)
   930 	{
   931 	// first find the interface
   932 	TInt i = FindIfcDescriptor(aInterface, aSetting);
   933 	if (i < 0)
   934 		{
   935 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
   936 		return KErrNotFound;
   937 		}
   938 	// find a position where to insert the new class specific interface descriptor(s)
   939 	const TInt count = iDescriptors.Count();
   940 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
   941 		;
   942 	// create a new cs descriptor
   943 	TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize);
   944 	if (!desc)
   945 		{
   946 		return KErrNoMemory;
   947 		}
   948 	iDescriptors.Insert(desc, i);
   949 	if (iDescriptors[1])
   950 		{
   951 		// if there's a config descriptor (and not a NULL pointer), we update its wTotalLength field
   952 		iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aSize));
   953 		}
   954 	// copy contents from user side
   955 	return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
   956 	}
   957 
   958 
   959 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const
   960 	{
   961 	// first find the interface
   962 	TInt i = FindIfcDescriptor(aInterface, aSetting);
   963 	if (i < 0)
   964 		{
   965 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
   966 		return KErrNotFound;
   967 		}
   968 	TInt r = KErrNotFound;
   969 	TInt size = 0;
   970 	const TInt count = iDescriptors.Count();
   971 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
   972 		{
   973 		size += iDescriptors[i]->Size();
   974 		r = KErrNone;
   975 		}
   976 	if (r == KErrNone)
   977 		aSize = size;
   978 	return r;
   979 	}
   980 
   981 
   982 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface,
   983 													TInt aSetting, TUint8 aEndpointAddress) const
   984 	{
   985 	// first find the endpoint
   986 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
   987 	if (i < 0)
   988 		{
   989 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
   990 		return KErrNotFound;
   991 		}
   992 	TInt r = KErrNotFound;
   993 	TInt offset = 0;
   994 	const TInt count = iDescriptors.Count();
   995 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
   996 		{
   997 		__THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset);
   998 		if (r != KErrNone)
   999 			break;
  1000 		offset += iDescriptors[i]->Size();
  1001 		}
  1002 	return r;
  1003 	}
  1004 
  1005 
  1006 TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface,
  1007 													TInt aSetting, TUint8 aEndpointAddress, TInt aSize)
  1008 	{
  1009 	// first find the endpoint
  1010 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1011 	if (i < 0)
  1012 		{
  1013 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
  1014 		return KErrNotFound;
  1015 		}
  1016 	// find a position where to insert the new class specific endpoint descriptor(s)
  1017 	const TInt count = iDescriptors.Count();
  1018 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
  1019 		;
  1020 	// create a new cs descriptor
  1021 	TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize);
  1022 	if (!desc)
  1023 		{
  1024 		return KErrNoMemory;
  1025 		}
  1026 	iDescriptors.Insert(desc, i);
  1027 	if (iDescriptors[1])
  1028 		{
  1029 		// if there's a config descriptor (and not a NULL pointer), we update its wTotalLength field
  1030 		iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aSize));
  1031 		}
  1032 	// copy contents from user side
  1033 	return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
  1034 	}
  1035 
  1036 
  1037 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting,
  1038 													  TUint8 aEndpointAddress, TInt& aSize) const
  1039 	{
  1040 	// first find the endpoint
  1041 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1042 	if (i < 0)
  1043 		{
  1044 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
  1045 		return KErrNotFound;
  1046 		}
  1047 	TInt r = KErrNotFound;
  1048 	TInt size = 0;
  1049 	const TInt count = iDescriptors.Count();
  1050 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
  1051 		{
  1052 		size += iDescriptors[i]->Size();
  1053 		r = KErrNone;
  1054 		}
  1055 	if (r == KErrNone)
  1056 		aSize = size;
  1057 	return r;
  1058 	}
  1059 
  1060 
  1061 TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1062 	{
  1063 	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact);
  1064 	}
  1065 
  1066 
  1067 TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1068 	{
  1069 	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact);
  1070 	}
  1071 
  1072 
  1073 TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1074 	{
  1075 	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product);
  1076 	}
  1077 
  1078 
  1079 TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1080 	{
  1081 	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product);
  1082 	}
  1083 
  1084 
  1085 TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1086 	{
  1087 	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial);
  1088 	}
  1089 
  1090 
  1091 TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1092 	{
  1093 	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial);
  1094 	}
  1095 
  1096 
  1097 TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1098 	{
  1099 	TBuf8<KUsbDescSize_Config> config_desc;
  1100 	iDescriptors[1]->GetDescriptorData(config_desc);
  1101 	const TInt str_idx = config_desc[KUsbDescStringIndex_Config];
  1102 	if ((str_idx > 0) && iStrings[str_idx])
  1103 		{
  1104 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  String @ pos %d (conf $): \"%S\""),
  1105 										str_idx, &iStrings[str_idx]->StringData()));
  1106 		return __THREADWRITE(aThread, &aString, iStrings[str_idx]->StringData());
  1107 		}
  1108 	else
  1109 		{
  1110 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no string descriptor @ pos %d!"), str_idx));
  1111 		return KErrNotFound;
  1112 		}
  1113 	}
  1114 
  1115 
  1116 TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1117 	{
  1118 	// we don't know the length of the string, so we have to allocate memory dynamically
  1119 	TUint strlen = __THREADDESLEN(aThread, &aString);
  1120 	if (strlen > KUsbStringDescStringMaxSize)
  1121 		{
  1122 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: $ descriptor too long - string will be truncated")));
  1123 		strlen = KUsbStringDescStringMaxSize;
  1124 		}
  1125 
  1126 	HBuf8Plat* strbuf = NULL;
  1127 	__NEWPLATBUF(strbuf, strlen);
  1128 	if (!strbuf)
  1129 		{
  1130 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for config $ desc string failed (1)")));
  1131 		return KErrNoMemory;
  1132 		}
  1133 
  1134 	TInt r;	
  1135 	__THREADREADPLATBUF(aThread, &aString, strbuf, r);
  1136 	if (r != KErrNone)
  1137 		{
  1138 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Thread read error")));
  1139 		delete strbuf;
  1140 		return r;
  1141 		}
  1142 	TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
  1143 	if (!sd)
  1144 		{
  1145 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for config $ desc failed (2)")));
  1146 		delete strbuf;
  1147 		return KErrNoMemory;
  1148 		}
  1149 	TBuf8<KUsbDescSize_Config> config_desc;
  1150 	config_desc.FillZ(config_desc.MaxLength());
  1151 	iDescriptors[1]->GetDescriptorData(config_desc);
  1152 	ExchangeStringDescriptor(config_desc[KUsbDescStringIndex_Config], sd);
  1153 	delete strbuf;
  1154 	return r;
  1155 	}
  1156 
  1157 
  1158 // --- private ---
  1159 
  1160 void TUsbcDescriptorPool::InsertDevDesc(TUsbcDescriptorBase* aDesc)
  1161 	{
  1162 	TInt count = iDescriptors.Count();
  1163 	if (count > 0)
  1164 		{
  1165 		DeleteDescriptors(0);								// if there's already something at pos. 0, delete it
  1166 		}
  1167 	iDescriptors.Insert(aDesc, 0);							// in any case: put the new descriptor at position 0
  1168 	}
  1169 
  1170 
  1171 void TUsbcDescriptorPool::InsertConfigDesc(TUsbcDescriptorBase* aDesc)
  1172 	{
  1173 	TInt count = iDescriptors.Count();
  1174 	if (count == 0)
  1175 		{
  1176 		TUsbcDescriptorBase* const iNullDesc = NULL;
  1177 		iDescriptors.Append(iNullDesc);						// if array's empty, put a dummy in position 0
  1178 		}
  1179 	else if (count > 1)
  1180 		{
  1181 		DeleteDescriptors(1);								// if there's already something at pos. 1, delete it
  1182 		}
  1183 	iDescriptors.Insert(aDesc, 1);							// in any case: put the new descriptor at position 1
  1184 	// Currently this code assumes, that the config descriptor is inserted _before_ any interface
  1185 	// or endpoint descriptors!
  1186 	if (iDescriptors.Count() != 2)
  1187 		{
  1188 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertConfigDesc: config descriptor will be invalid!")));
  1189 		}
  1190 	}
  1191 
  1192 
  1193 void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc)
  1194 	{
  1195 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc()")));
  1196 	TInt count = iDescriptors.Count();
  1197 	if (count < 2)
  1198 		{
  1199 		TUsbcDescriptorBase* const iNullDesc = NULL;
  1200 		iDescriptors.Append(iNullDesc);						// if array's too small, put some dummies in
  1201 		iDescriptors.Append(iNullDesc);
  1202 		}
  1203 	TBool interface_exists = EFalse;						// set to 'true' if we're adding an alternate
  1204 															// setting to an already existing interface
  1205 	TInt i = 2;
  1206 	while (i < count)
  1207 		{
  1208 		if (iDescriptors[i]->Type() == KUsbDescType_Interface)
  1209 			{
  1210 			if (iDescriptors[i]->Byte(2) > aDesc->Byte(2))
  1211 				{
  1212 				// our interface number is less than the one's just found => insert before it (= here)
  1213 				break;
  1214 				}
  1215 			else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2))
  1216 				{
  1217 				interface_exists = ETrue;
  1218 				// same interface number => look at settings number
  1219 				if (iDescriptors[i]->Byte(3) > aDesc->Byte(3))
  1220 					{
  1221 					// our setting number is less than the one's found => insert before (= here)
  1222 					break;
  1223 					}
  1224 				else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3))
  1225 					{
  1226 					__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc: error: first delete old one!")));
  1227 					return;
  1228 					}
  1229 				}
  1230 			}
  1231 		++i;
  1232 		}
  1233 	iDescriptors.Insert(aDesc, i);							// in any case: put the new descriptor at position i
  1234 	if (iDescriptors[1])
  1235 		{
  1236 		// if there's a config descriptor (and not a NULL pointer), update its wTotalLength field...
  1237 		iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + KUsbDescSize_Interface));
  1238 		//  and increment bNumInterfaces if this is the first setting for the interface
  1239 		if (!interface_exists)
  1240 			iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) + 1));
  1241 		}
  1242 	iIfcIdx = i;
  1243 	}
  1244 
  1245 
  1246 void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc)
  1247 	{
  1248 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc()")));
  1249 	if (iIfcIdx == 0)
  1250 		{
  1251 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc: error: only after interface")));
  1252 		return;
  1253 		}
  1254 	TInt count = iDescriptors.Count();
  1255 	TInt i = iIfcIdx + 1;
  1256 	while (i < count)
  1257 		{
  1258 		if (iDescriptors[i]->Type() != KUsbDescType_Endpoint)
  1259 			break;
  1260 		++i;
  1261 		}
  1262 	iDescriptors.Insert(aDesc, i);							// put the new descriptor at position i
  1263 	if (iDescriptors[1])
  1264 		{
  1265 		// if there's a config descriptor (and not a NULL pointer), update its wTotalLength field
  1266 		iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aDesc->Size()));
  1267 		}
  1268 	}
  1269 
  1270 
  1271 TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const
  1272 	{
  1273 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)"),
  1274 									aIfcNumber, aIfcSetting));
  1275 	TInt count = iDescriptors.Count();
  1276 	for (TInt i = 2; i < count; ++i)
  1277 		{
  1278 		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
  1279 			(iDescriptors[i]->Byte(2) == aIfcNumber) &&
  1280 			(iDescriptors[i]->Byte(3) == aIfcSetting))
  1281 			{
  1282 			return i;
  1283 			}
  1284 		}
  1285 	__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
  1286 	return -1;
  1287 	}
  1288 
  1289 
  1290 TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const
  1291 	{
  1292 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)"),
  1293 									aIfcNumber, aIfcSetting, aEpAddress));
  1294 	// first find the interface
  1295 	TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting);
  1296 	if (ifc < 0)
  1297 		{
  1298 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
  1299 		return ifc;
  1300 		}
  1301 	TInt count = iDescriptors.Count();
  1302 	// then, before the next interface, try to locate the endpoint
  1303 	for (TInt i = ifc + 1; i < count; ++i)
  1304 		{
  1305 		if (iDescriptors[i]->Type() == KUsbDescType_Interface)
  1306 			{
  1307 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint before next interface")));
  1308 			return -1;
  1309 			}
  1310 		else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) &&
  1311 				 (iDescriptors[i]->Byte(2) == aEpAddress))
  1312 			{
  1313 			return i;										// found
  1314 			}
  1315 		}
  1316 	__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
  1317 	return -1;
  1318 	}
  1319 
  1320 
  1321 void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount)
  1322 	{
  1323 	if (aCount <= 0)
  1324 		{
  1325 		return;
  1326 		}
  1327 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  Removing descriptors at index %d:"), aIndex));
  1328 	while (aCount--)
  1329 		{
  1330 		// in this loop we don't decrement aIndex, because after deleting an element
  1331 		// aIndex is already indexing the next one!
  1332 		TUsbcDescriptorBase* ptr = iDescriptors[aIndex];
  1333 		if (iDescriptors[1])
  1334 			{
  1335 			// if there's a config descriptor (and not a NULL pointer),
  1336 			if (ptr->Type() == KUsbDescType_Interface)
  1337 				{
  1338 				__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  - an interface descriptor")));
  1339 				// if it's an interface descriptor:
  1340 				// we update its wTotalLength field...
  1341 				iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - KUsbDescSize_Interface));
  1342 				}
  1343 			else if (ptr->Type() == KUsbDescType_Endpoint)
  1344 				{
  1345 				__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  - an endpoint descriptor")));
  1346 				// if it's an endpoint descriptor:
  1347 				// we only update its wTotalLength field
  1348 				iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - ptr->Size()));
  1349 				}
  1350 			else if (ptr->Type() == KUsbDescType_CS_Interface || ptr->Type() == KUsbDescType_CS_Endpoint)
  1351 				{
  1352 				__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  - a class specific descriptor")));
  1353 				// if it's an class specific descriptor:
  1354 				// we only update its wTotalLength field
  1355 				iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - ptr->Size()));
  1356 				}
  1357 			}
  1358 		iDescriptors.Remove(aIndex);
  1359 		delete ptr;
  1360 		}
  1361 	}
  1362 
  1363 
  1364 void TUsbcDescriptorPool::DeleteString(TInt aIndex)
  1365 	{
  1366 	TUsbcStringDescriptorBase* ptr = iStrings[aIndex];
  1367 	iStrings.Remove(aIndex);
  1368 	delete ptr;
  1369 	}
  1370 
  1371 
  1372 void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber)
  1373 	{
  1374 	const TInt count = iDescriptors.Count();
  1375 	for (TInt i = 2; i < count; ++i)
  1376 		{
  1377 		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
  1378 			(iDescriptors[i]->Byte(2) == aNumber))
  1379 			{
  1380 			// there's still an interface with 'number' so we don't need to update anything
  1381 			return;
  1382 			}
  1383 		}
  1384 	// if we haven't returned yet, we decrement bNumInterfaces
  1385 	iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) - 1));
  1386 	}
  1387 
  1388 
  1389 void TUsbcDescriptorPool::UpdateIfcStringIndexes(TInt aStringIndex)
  1390 	{
  1391 	// aStringIndex is the index value of the string descriptor that has just been removed.
  1392 	// We update all ifc descriptors with a string index value that is greater than aStringIndex,
  1393 	// because those strings moved all down by one position.
  1394 	//
  1395 	TInt count = iDescriptors.Count();
  1396 	for (TInt i = 2; i < count; ++i)
  1397 		{
  1398 		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
  1399 			(iDescriptors[i]->Byte(8) > aStringIndex))
  1400 			{
  1401 			iDescriptors[i]->SetByte(8, (TUint8)(iDescriptors[i]->Byte(8) - 1));
  1402 			}
  1403 		}
  1404 	}
  1405 
  1406 
  1407 //
  1408 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
  1409 //
  1410 TInt TUsbcDescriptorPool::GetDeviceDescriptor() const
  1411 	{
  1412 	return iDescriptors[0]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
  1413 	}
  1414 
  1415 
  1416 //
  1417 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
  1418 //
  1419 TInt TUsbcDescriptorPool::GetConfigDescriptor() const
  1420 	{
  1421 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetConfigDescriptor()")));
  1422 	TInt copied = 0;
  1423 	TInt count = iDescriptors.Count();
  1424 	TUint8* buf = iEp0_TxBuf;
  1425 	for (TInt i = 1; i < count; ++i)
  1426 		{
  1427 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" > desc[%02d]: type = 0x%02x size = %d "),
  1428 										i, iDescriptors[i]->Type(), iDescriptors[i]->Size()));
  1429 		const TInt size = iDescriptors[i]->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied);
  1430 		if (size == 0)
  1431 			{
  1432 			// There was no buffer space to copy the descriptor -> no use to proceed
  1433 			break;
  1434 			}
  1435 		copied += size;
  1436 		if (copied >= KUsbcBufSz_Ep0Tx)
  1437 			{
  1438 			// There's no buffer space left -> we need to stop copying here
  1439 			break;
  1440 			}
  1441 		buf += size;
  1442 		}
  1443 	return copied;
  1444 	}
  1445 
  1446 
  1447 //
  1448 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
  1449 //
  1450 TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const
  1451 	{
  1452 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetStringDescriptor()")));
  1453 	// I really would have liked to display here the descriptor contents, but without trailing zero
  1454 	// we got a problem: how could we tell printf where the string ends? We would have to
  1455 	// dynamically allocate memory (since we don't know the size in advance), copy the descriptor
  1456 	// contents there, append a zero, and give this to printf. That's a bit too much effort...
  1457 	if (iStrings[aIndex])
  1458 		{
  1459 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  String @ pos %d"), aIndex));
  1460 		TInt size = iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
  1461 		return size;
  1462 		}
  1463 	else
  1464 		{
  1465 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no descriptor @ pos %d!"), aIndex));
  1466 		return 0;
  1467 		}
  1468 	}
  1469 
  1470 
  1471 TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString, TInt aIndex) const
  1472 	{
  1473 	TBuf8<KUsbDescSize_Device> dev_desc;
  1474 	iDescriptors[0]->GetDescriptorData(dev_desc);
  1475 	const TInt str_idx = dev_desc[aIndex];
  1476 	if ((str_idx > 0) && iStrings[str_idx])
  1477 		{
  1478 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  String @ pos %d (device $): \"%S\""),
  1479 										str_idx, &iStrings[str_idx]->StringData()));
  1480 		return __THREADWRITE(aThread, &aString, iStrings[str_idx]->StringData());
  1481 		}
  1482 	else
  1483 		{
  1484 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no string descriptor @ pos %d!"), str_idx));
  1485 		return KErrNotFound;
  1486 		}
  1487 	}
  1488 
  1489 
  1490 TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString, TInt aIndex)
  1491 	{
  1492 	// we don't know the length of the string, so we have to allocate memory dynamically
  1493 	TUint strlen = __THREADDESLEN(aThread, &aString);
  1494 	if (strlen > KUsbStringDescStringMaxSize)
  1495 		{
  1496 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: $ descriptor too long - string will be truncated")));
  1497 		strlen = KUsbStringDescStringMaxSize;
  1498 		}
  1499 	
  1500 	HBuf8Plat* strbuf = NULL;
  1501 	__NEWPLATBUF(strbuf, strlen);
  1502 	if (!strbuf)
  1503 		{
  1504 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for dev $ desc string failed (1)")));
  1505 		return KErrNoMemory;
  1506 		}
  1507 
  1508 	TInt r;	
  1509 	__THREADREADPLATBUF(aThread, &aString, strbuf, r);
  1510 	if (r != KErrNone)
  1511 		{
  1512 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Thread read error")));
  1513 		delete strbuf;
  1514 		return r;
  1515 		}
  1516 	TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
  1517 	if (!sd)
  1518 		{
  1519 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for dev $ desc failed (2)")));
  1520 		delete strbuf;
  1521 		return KErrNoMemory;
  1522 		}
  1523 	TBuf8<KUsbDescSize_Device> dev_desc;
  1524 	dev_desc.FillZ(dev_desc.MaxLength());
  1525 	iDescriptors[0]->GetDescriptorData(dev_desc);
  1526 	ExchangeStringDescriptor(dev_desc[aIndex], sd);
  1527 	delete strbuf;
  1528 	return r;
  1529 	}
  1530 
  1531 
  1532 TInt TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc)
  1533 	{
  1534 	if (aIndex <= 0)
  1535 		{
  1536 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: invalid string descriptor index: %d!"), aIndex));
  1537 		return KErrArgument;
  1538 		}
  1539 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  Exchanging string descriptor @ index %d"), aIndex));
  1540 	DeleteString(aIndex);
  1541 	iStrings.Insert(aDesc, aIndex);
  1542 	return KErrNone;
  1543 	}
  1544 
  1545 
  1546 // -eof-