os/kernelhwsrv/kernel/eka/drivers/usbcc/descriptors.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/usbcc/descriptors.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2361 @@
     1.4 +// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32/drivers/usbcc/descriptors.cpp
    1.18 +// Platform independent layer (PIL) of the USB Device controller driver:
    1.19 +// USB descriptor handling and management.
    1.20 +// 
    1.21 +//
    1.22 +
    1.23 +/**
    1.24 + @file descriptors.cpp
    1.25 + @internalTechnology
    1.26 +*/
    1.27 +
    1.28 +#include <kernel/kern_priv.h>
    1.29 +#include <drivers/usbc.h>
    1.30 +
    1.31 +
    1.32 +// Debug Support
    1.33 +static const char KUsbPanicCat[] = "USB PIL";
    1.34 +
    1.35 +
    1.36 +// --- TUsbcDescriptorBase
    1.37 +
    1.38 +TUsbcDescriptorBase::TUsbcDescriptorBase()
    1.39 +	:
    1.40 +#ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
    1.41 +	iIndex(0),
    1.42 +#endif
    1.43 +	iBufPtr(NULL, 0)
    1.44 +	{
    1.45 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::TUsbcDescriptorBase()"));
    1.46 +	}
    1.47 +
    1.48 +
    1.49 +TUsbcDescriptorBase::~TUsbcDescriptorBase()
    1.50 +	{
    1.51 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::~TUsbcDescriptorBase()"));
    1.52 +	}
    1.53 +
    1.54 +
    1.55 +void TUsbcDescriptorBase::SetByte(TInt aPosition, TUint8 aValue)
    1.56 +	{
    1.57 +	iBufPtr[aPosition] = aValue;
    1.58 +	}
    1.59 +
    1.60 +
    1.61 +void TUsbcDescriptorBase::SetWord(TInt aPosition, TUint16 aValue)
    1.62 +	{
    1.63 +	*reinterpret_cast<TUint16*>(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue);
    1.64 +	}
    1.65 +
    1.66 +
    1.67 +TUint8 TUsbcDescriptorBase::Byte(TInt aPosition) const
    1.68 +	{
    1.69 +	return iBufPtr[aPosition];
    1.70 +	}
    1.71 +
    1.72 +
    1.73 +TUint16 TUsbcDescriptorBase::Word(TInt aPosition) const
    1.74 +	{
    1.75 +	return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition]));
    1.76 +	}
    1.77 +
    1.78 +
    1.79 +void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const
    1.80 +	{
    1.81 +	aBuffer = iBufPtr;
    1.82 +	}
    1.83 +
    1.84 +
    1.85 +TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
    1.86 +	{
    1.87 +	memcpy(aBuffer, iBufPtr.Ptr(), Size());
    1.88 +	return Size();
    1.89 +	}
    1.90 +
    1.91 +
    1.92 +TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const
    1.93 +	{
    1.94 +	if (aMaxSize < Size())
    1.95 +		{
    1.96 +		// No use to copy only half a descriptor
    1.97 +		return 0;
    1.98 +		}
    1.99 +	return GetDescriptorData(aBuffer);
   1.100 +	}
   1.101 +
   1.102 +
   1.103 +const TDes8& TUsbcDescriptorBase::DescriptorData() const
   1.104 +	{
   1.105 +	return iBufPtr;
   1.106 +	}
   1.107 +
   1.108 +
   1.109 +TDes8& TUsbcDescriptorBase::DescriptorData()
   1.110 +	{
   1.111 +	return iBufPtr;
   1.112 +	}
   1.113 +
   1.114 +
   1.115 +TUint TUsbcDescriptorBase::Size() const
   1.116 +	{
   1.117 +	return iBufPtr.Size();
   1.118 +	}
   1.119 +
   1.120 +
   1.121 +TUint8 TUsbcDescriptorBase::Type() const
   1.122 +	{
   1.123 +	return iBufPtr[1];
   1.124 +	}
   1.125 +
   1.126 +
   1.127 +void TUsbcDescriptorBase::UpdateFs()
   1.128 +	{
   1.129 +	// virtual function can be overridden in derived classes.
   1.130 +	return;
   1.131 +	}
   1.132 +
   1.133 +
   1.134 +void TUsbcDescriptorBase::UpdateHs()
   1.135 +	{
   1.136 +	// virtual function can be overridden in derived classes.
   1.137 +	return;
   1.138 +	}
   1.139 +
   1.140 +
   1.141 +void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes)
   1.142 +	{
   1.143 +	iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
   1.144 +	}
   1.145 +
   1.146 +
   1.147 +// --- TUsbcDeviceDescriptor
   1.148 +
   1.149 +TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()
   1.150 +	: iBuf()
   1.151 +	{
   1.152 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()"));
   1.153 +	}
   1.154 +
   1.155 +
   1.156 +TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
   1.157 +												  TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
   1.158 +												  TUint16 aVendorId, TUint16 aProductId,
   1.159 +												  TUint16 aDeviceRelease, TUint8 aNumConfigurations)
   1.160 +	{
   1.161 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::New()"));
   1.162 +	TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor();
   1.163 +	if (self)
   1.164 +		{
   1.165 +		if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId,
   1.166 +							aProductId, aDeviceRelease, aNumConfigurations) != KErrNone)
   1.167 +			{
   1.168 +			delete self;
   1.169 +			return NULL;
   1.170 +			}
   1.171 +		}
   1.172 +	return self;
   1.173 +	}
   1.174 +
   1.175 +
   1.176 +TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
   1.177 +									  TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
   1.178 +									  TUint16 aDeviceRelease, TUint8 aNumConfigurations)
   1.179 +	{
   1.180 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::Construct()"));
   1.181 +	iBuf.SetMax();
   1.182 +	SetBufferPointer(iBuf);
   1.183 +	iBuf[0] = iBuf.Size();									// bLength
   1.184 +	iBuf[1] = KUsbDescType_Device;							// bDescriptorType
   1.185 +	SetWord(2, KUsbcUsbVersion);							// bcdUSB
   1.186 +	iBuf[4] = aDeviceClass;									// bDeviceClass
   1.187 +	iBuf[5] = aDeviceSubClass;								// bDeviceSubClass
   1.188 +	iBuf[6] = aDeviceProtocol;								// bDeviceProtocol
   1.189 +	iBuf[7] = aMaxPacketSize0;								// bMaxPacketSize0
   1.190 +	SetWord(8, aVendorId);									// idVendor
   1.191 +	SetWord(10, aProductId);								// idProduct
   1.192 +	SetWord(12, aDeviceRelease);							// bcdDevice
   1.193 +	iBuf[14] = 0;											// iManufacturer
   1.194 +	iBuf[15] = 0;											// iProduct
   1.195 +	iBuf[16] = 0;											// iSerialNumber
   1.196 +	iBuf[17] = aNumConfigurations;							// bNumConfigurations
   1.197 +	iEp0Size_Fs = aMaxPacketSize0;
   1.198 +	return KErrNone;
   1.199 +	}
   1.200 +
   1.201 +
   1.202 +void TUsbcDeviceDescriptor::UpdateFs()
   1.203 +	{
   1.204 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateFs()"));
   1.205 +	SetByte(7, iEp0Size_Fs);								// bMaxPacketSize0
   1.206 +	}
   1.207 +
   1.208 +
   1.209 +void TUsbcDeviceDescriptor::UpdateHs()
   1.210 +	{
   1.211 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateHs()"));
   1.212 +	SetByte(7, 64);											// bMaxPacketSize0
   1.213 +	}
   1.214 +
   1.215 +
   1.216 +// --- TUsbcDeviceQualifierDescriptor
   1.217 +
   1.218 +TUsbcDeviceQualifierDescriptor::TUsbcDeviceQualifierDescriptor()
   1.219 +	: iBuf()
   1.220 +	{
   1.221 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceQualifierDescriptor()"));
   1.222 +	}
   1.223 +
   1.224 +
   1.225 +TUsbcDeviceQualifierDescriptor* TUsbcDeviceQualifierDescriptor::New(TUint8 aDeviceClass,
   1.226 +																	TUint8 aDeviceSubClass,
   1.227 +																	TUint8 aDeviceProtocol,
   1.228 +																	TUint8 aMaxPacketSize0,
   1.229 +																	TUint8 aNumConfigurations,
   1.230 +																	TUint8 aReserved)
   1.231 +	{
   1.232 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::New()"));
   1.233 +	TUsbcDeviceQualifierDescriptor* self = new TUsbcDeviceQualifierDescriptor();
   1.234 +	if (self)
   1.235 +		{
   1.236 +		if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0,
   1.237 +							aNumConfigurations, aReserved) != KErrNone)
   1.238 +			{
   1.239 +			delete self;
   1.240 +			return NULL;
   1.241 +			}
   1.242 +		}
   1.243 +	return self;
   1.244 +	}
   1.245 +
   1.246 +
   1.247 +TInt TUsbcDeviceQualifierDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
   1.248 +											   TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
   1.249 +											   TUint8 aNumConfigurations, TUint8 aReserved)
   1.250 +	{
   1.251 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::Construct()"));
   1.252 +	iBuf.SetMax();
   1.253 +	SetBufferPointer(iBuf);
   1.254 +	iBuf[0] = iBuf.Size();									// bLength
   1.255 +	iBuf[1] = KUsbDescType_DeviceQualifier;					// bDescriptorType
   1.256 +	SetWord(2, KUsbcUsbVersion);							// bcdUSB
   1.257 +	iBuf[4] = aDeviceClass;									// bDeviceClass
   1.258 +	iBuf[5] = aDeviceSubClass;								// bDeviceSubClass
   1.259 +	iBuf[6] = aDeviceProtocol;								// bDeviceProtocol
   1.260 +	iBuf[7] = aMaxPacketSize0;								// bMaxPacketSize0
   1.261 +	iBuf[8] = aNumConfigurations;							// bNumConfigurations
   1.262 +	if (aReserved) aReserved = 0;
   1.263 +	iBuf[9] = aReserved;									// Reserved for future use, must be zero
   1.264 +	iEp0Size_Fs = aMaxPacketSize0;
   1.265 +	return KErrNone;
   1.266 +	}
   1.267 +
   1.268 +
   1.269 +void TUsbcDeviceQualifierDescriptor::UpdateFs()
   1.270 +	{
   1.271 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateFs()"));
   1.272 +	// Here we do exactly the opposite of what's done in the Device descriptor (as this one's
   1.273 +	// documenting the 'other than the current speed').
   1.274 +	SetByte(7, 64);											// bMaxPacketSize0
   1.275 +	}
   1.276 +
   1.277 +
   1.278 +void TUsbcDeviceQualifierDescriptor::UpdateHs()
   1.279 +	{
   1.280 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateHs()"));
   1.281 +	// Here we do exactly the opposite of what's done in the Device descriptor (as this one's
   1.282 +	// documenting the 'other than the current speed').
   1.283 +	SetByte(7, iEp0Size_Fs);								// bMaxPacketSize0
   1.284 +	}
   1.285 +
   1.286 +
   1.287 +// --- TUsbcConfigDescriptor
   1.288 +
   1.289 +TUsbcConfigDescriptor::TUsbcConfigDescriptor()
   1.290 +	: iBuf()
   1.291 +	{
   1.292 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::TUsbcConfigDescriptor()"));
   1.293 +	}
   1.294 +
   1.295 +
   1.296 +TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered,
   1.297 +												  TBool aRemoteWakeup, TUint16 aMaxPower)
   1.298 +	{
   1.299 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::New()"));
   1.300 +	TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor();
   1.301 +	if (self)
   1.302 +		{
   1.303 +		if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone)
   1.304 +			{
   1.305 +			delete self;
   1.306 +			return NULL;
   1.307 +			}
   1.308 +		}
   1.309 +	return self;
   1.310 +	}
   1.311 +
   1.312 +
   1.313 +TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered,
   1.314 +									   TBool aRemoteWakeup, TUint16 aMaxPower)
   1.315 +	{
   1.316 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::Construct()"));
   1.317 +	iBuf.SetMax();
   1.318 +	SetBufferPointer(iBuf);
   1.319 +	iBuf[0] = iBuf.Size();									// bLength
   1.320 +	iBuf[1] = KUsbDescType_Config;							// bDescriptorType
   1.321 +	SetWord(2, KUsbDescSize_Config);						// wTotalLength
   1.322 +	iBuf[4] = 0;											// bNumInterfaces
   1.323 +	iBuf[5] = aConfigurationValue;							// bConfigurationValue
   1.324 +	iBuf[6] = 0;											// iConfiguration
   1.325 +	iBuf[7] = 0x80 |
   1.326 +		(aSelfPowered ? KUsbDevAttr_SelfPowered : 0) |
   1.327 +		(aRemoteWakeup ? KUsbDevAttr_RemoteWakeup : 0);		// bmAttributes (bit 7 always 1)
   1.328 +	if (aMaxPower > 510)
   1.329 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid value for bMaxPower: %d", aMaxPower));
   1.330 +	iBuf[8] = aMaxPower / 2;								// bMaxPower (2mA units!)
   1.331 +	return KErrNone;
   1.332 +	}
   1.333 +
   1.334 +
   1.335 +// --- TUsbcInterfaceDescriptor
   1.336 +
   1.337 +TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()
   1.338 +	: iBuf()
   1.339 +	{
   1.340 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()"));
   1.341 +	}
   1.342 +
   1.343 +
   1.344 +TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
   1.345 +														TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
   1.346 +	{
   1.347 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::New()"));
   1.348 +	TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor();
   1.349 +	if (self)
   1.350 +		{
   1.351 +		if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone)
   1.352 +			{
   1.353 +			delete self;
   1.354 +			return NULL;
   1.355 +			}
   1.356 +		}
   1.357 +	return self;
   1.358 +	}
   1.359 +
   1.360 +
   1.361 +TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
   1.362 +										 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
   1.363 +	{
   1.364 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::Construct()"));
   1.365 +	iBuf.SetMax();
   1.366 +	SetBufferPointer(iBuf);
   1.367 +	iBuf[0] = iBuf.Size();									// bLength
   1.368 +	iBuf[1] = KUsbDescType_Interface;						// bDescriptorType
   1.369 +	iBuf[2] = aInterfaceNumber;								// bInterfaceNumber
   1.370 +	iBuf[3] = aAlternateSetting;							// bAlternateSetting
   1.371 +	iBuf[4] = aNumEndpoints;								// bNumEndpoints
   1.372 +	iBuf[5] = aClassInfo.iClassNum;							// bInterfaceClass
   1.373 +	iBuf[6] = aClassInfo.iSubClassNum;						// bInterfaceSubClass
   1.374 +	iBuf[7] = aClassInfo.iProtocolNum;						// bInterfaceProtocol
   1.375 +	iBuf[8] = 0;											// iInterface
   1.376 +	return KErrNone;
   1.377 +	}
   1.378 +
   1.379 +
   1.380 +// --- TUsbcEndpointDescriptorBase
   1.381 +
   1.382 +TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()
   1.383 +	{
   1.384 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()"));
   1.385 +	}
   1.386 +
   1.387 +
   1.388 +TInt TUsbcEndpointDescriptorBase::Construct(const TUsbcEndpointInfo& aEpInfo)
   1.389 +	{
   1.390 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::Construct()"));
   1.391 +	//  Adjust FS/HS endpoint sizes
   1.392 +	if (aEpInfo.AdjustEpSizes(iEpSize_Fs, iEpSize_Hs) != KErrNone)
   1.393 +		{
   1.394 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown endpoint type: %d", aEpInfo.iType));
   1.395 +		}
   1.396 +	__KTRACE_OPT(KUSB, Kern::Printf("  Now set: iEpSize_Fs=%d iEpSize_Hs=%d (aEpInfo.iSize=%d)",
   1.397 +									iEpSize_Fs, iEpSize_Hs, aEpInfo.iSize));
   1.398 +
   1.399 +	//  Adjust HS endpoint size for additional transactions
   1.400 +	if ((aEpInfo.iType == KUsbEpTypeIsochronous) || (aEpInfo.iType == KUsbEpTypeInterrupt))
   1.401 +		{
   1.402 +		if ((aEpInfo.iTransactions > 0) && (aEpInfo.iTransactions < 3))
   1.403 +			{
   1.404 +			// Bits 12..11 specify the number of additional transactions per microframe
   1.405 +			iEpSize_Hs |= (aEpInfo.iTransactions << 12);
   1.406 +			__KTRACE_OPT(KUSB, Kern::Printf("  Adjusted for add. transact.: iEpSize_Hs=0x%02x "
   1.407 +											"(aEpInfo.iTransactions=%d)",
   1.408 +											iEpSize_Hs, aEpInfo.iTransactions));
   1.409 +			}
   1.410 +		else if (aEpInfo.iTransactions != 0)
   1.411 +			{
   1.412 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Invalid iTransactions value: %d (ignored)",
   1.413 +											  aEpInfo.iTransactions));
   1.414 +			}
   1.415 +		}
   1.416 +
   1.417 +	//  Adjust HS polling interval
   1.418 +	TUsbcEndpointInfo info(aEpInfo);						// create local writeable copy
   1.419 +	if (info.AdjustPollInterval() != KErrNone)
   1.420 +		{
   1.421 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown ep type (%d) or invalid interval value (%d)",
   1.422 +										  info.iType, info.iInterval));
   1.423 +		}
   1.424 +	iInterval_Fs = info.iInterval;
   1.425 +	iInterval_Hs = info.iInterval_Hs;
   1.426 +	__KTRACE_OPT(KUSB, Kern::Printf("  Now set: iInterval_Fs=%d iInterval_Hs=%d",
   1.427 +									iInterval_Fs, iInterval_Hs));
   1.428 +	return KErrNone;
   1.429 +	}
   1.430 +
   1.431 +
   1.432 +void TUsbcEndpointDescriptorBase::UpdateFs()
   1.433 +	{
   1.434 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateFs()"));
   1.435 +	// (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values got
   1.436 +	//  adjusted in its Construct() method.)
   1.437 +	SetWord(4, iEpSize_Fs);									// wMaxPacketSize
   1.438 +	SetByte(6, iInterval_Fs);								// bInterval
   1.439 +	}
   1.440 +
   1.441 +
   1.442 +void TUsbcEndpointDescriptorBase::UpdateHs()
   1.443 +	{
   1.444 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateHs()"));
   1.445 +	// (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values get
   1.446 +	//  adjusted in its Construct() method.)
   1.447 +	SetWord(4, iEpSize_Hs);									// wMaxPacketSize
   1.448 +	SetByte(6, iInterval_Hs);								// bInterval
   1.449 +	}
   1.450 +
   1.451 +
   1.452 +// --- TUsbcEndpointDescriptor
   1.453 +
   1.454 +TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()
   1.455 +	: iBuf()
   1.456 +	{
   1.457 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()"));
   1.458 +	}
   1.459 +
   1.460 +
   1.461 +TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress,
   1.462 +													  const TUsbcEndpointInfo& aEpInfo)
   1.463 +	{
   1.464 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::New()"));
   1.465 +	TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor();
   1.466 +	if (self)
   1.467 +		{
   1.468 +		if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
   1.469 +			{
   1.470 +			delete self;
   1.471 +			return NULL;
   1.472 +			}
   1.473 +		}
   1.474 +	return self;
   1.475 +	}
   1.476 +
   1.477 +
   1.478 +TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
   1.479 +	{
   1.480 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::Construct()"));
   1.481 +	(void) TUsbcEndpointDescriptorBase::Construct(aEpInfo);	// Init Base class
   1.482 +	iBuf.SetMax();
   1.483 +	SetBufferPointer(iBuf);
   1.484 +	iBuf[0] = iBuf.Size();									// bLength
   1.485 +	iBuf[1] = KUsbDescType_Endpoint;						// bDescriptorType
   1.486 +	iBuf[2] = aEndpointAddress;								// bEndpointAddress
   1.487 +	iBuf[3] = EpTypeMask2Value(aEpInfo.iType);				// bmAttributes
   1.488 +	SetWord(4, iEpSize_Fs);									// wMaxPacketSize (default is FS)
   1.489 +	iBuf[6] = iInterval_Fs;									// bInterval (default is FS)
   1.490 +	return KErrNone;
   1.491 +	}
   1.492 +
   1.493 +
   1.494 +// --- TUsbcAudioEndpointDescriptor
   1.495 +
   1.496 +TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()
   1.497 +	: iBuf()
   1.498 +	{
   1.499 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()"));
   1.500 +	}
   1.501 +
   1.502 +
   1.503 +TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress,
   1.504 +																const TUsbcEndpointInfo& aEpInfo)
   1.505 +	{
   1.506 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::New()"));
   1.507 +	TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor();
   1.508 +	if (self)
   1.509 +		{
   1.510 +		if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
   1.511 +			{
   1.512 +			delete self;
   1.513 +			return NULL;
   1.514 +			}
   1.515 +		}
   1.516 +	return self;
   1.517 +	}
   1.518 +
   1.519 +
   1.520 +TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
   1.521 +	{
   1.522 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::Construct()"));
   1.523 +	(void) TUsbcEndpointDescriptorBase::Construct(aEpInfo);	// Init Base class
   1.524 +	iBuf.SetMax();
   1.525 +	SetBufferPointer(iBuf);
   1.526 +	iBuf[0] = iBuf.Size();									// bLength
   1.527 +	iBuf[1] = KUsbDescType_Endpoint;						// bDescriptorType
   1.528 +	iBuf[2] = aEndpointAddress;								// bEndpointAddress
   1.529 +	iBuf[3] = EpTypeMask2Value(aEpInfo.iType);				// bmAttributes
   1.530 +	SetWord(4, iEpSize_Fs);									// wMaxPacketSize (default is FS)
   1.531 +	iBuf[6] = iInterval_Fs;									// bInterval (default is FS)
   1.532 +	iBuf[7] = 0;
   1.533 +	iBuf[8] = 0;
   1.534 +	return KErrNone;
   1.535 +	}
   1.536 +
   1.537 +
   1.538 +// --- TUsbcOtgDescriptor
   1.539 +
   1.540 +TUsbcOtgDescriptor* TUsbcOtgDescriptor::New(TBool aHnpSupport, TBool aSrpSupport)
   1.541 +	{
   1.542 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::New()"));
   1.543 +	TUsbcOtgDescriptor* self = new TUsbcOtgDescriptor();
   1.544 +	if (self && (self->Construct(aHnpSupport, aSrpSupport) != KErrNone))
   1.545 +		{
   1.546 +		delete self;
   1.547 +		return NULL;
   1.548 +		}
   1.549 +	return self;
   1.550 +	}
   1.551 +
   1.552 +
   1.553 +TUsbcOtgDescriptor::TUsbcOtgDescriptor()
   1.554 +	: iBuf()
   1.555 +	{
   1.556 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::TUsbcOtgDescriptor()"));
   1.557 +	}
   1.558 +
   1.559 +
   1.560 +TInt TUsbcOtgDescriptor::Construct(TBool aHnpSupport, TBool aSrpSupport)
   1.561 +	{
   1.562 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::Construct()"));
   1.563 +	iBuf.SetMax();
   1.564 +	SetBufferPointer(iBuf);
   1.565 +	iBuf[0] = iBuf.Size();									// bLength
   1.566 +	iBuf[1] = KUsbDescType_Otg;								// bDescriptorType
   1.567 +	iBuf[2] = (aHnpSupport ? KUsbOtgAttr_HnpSupp : 0) |
   1.568 +		(aSrpSupport ? KUsbOtgAttr_SrpSupp : 0);			// bmAttributes
   1.569 +	return KErrNone;
   1.570 +    }
   1.571 +
   1.572 +
   1.573 +// --- TUsbcClassSpecificDescriptor
   1.574 +
   1.575 +TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()
   1.576 +	: iBuf(NULL)
   1.577 +	{
   1.578 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()"));
   1.579 +	}
   1.580 +
   1.581 +
   1.582 +TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()
   1.583 +	{
   1.584 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()"));
   1.585 +	delete iBuf;
   1.586 +	}
   1.587 +
   1.588 +
   1.589 +TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize)
   1.590 +	{
   1.591 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::New()"));
   1.592 +	TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor();
   1.593 +	if (self)
   1.594 +		{
   1.595 +		if (self->Construct(aType, aSize) != KErrNone)
   1.596 +			{
   1.597 +			delete self;
   1.598 +			return NULL;
   1.599 +			}
   1.600 +		}
   1.601 +	return self;
   1.602 +	}
   1.603 +
   1.604 +
   1.605 +TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize)
   1.606 +	{
   1.607 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::Construct()"));
   1.608 +	iBuf = HBuf8::New(aSize);
   1.609 +	if (!iBuf)
   1.610 +		{
   1.611 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Allocation of CS desc buffer failed"));
   1.612 +		return KErrNoMemory;
   1.613 +		}
   1.614 +	iBuf->SetMax();
   1.615 +	SetBufferPointer(*iBuf);
   1.616 +	SetByte(1, aType);										// bDescriptorType
   1.617 +	return KErrNone;
   1.618 +	}
   1.619 +
   1.620 +
   1.621 +// --- TUsbcStringDescriptorBase
   1.622 +
   1.623 +TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()
   1.624 +	: /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0)
   1.625 +	{
   1.626 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()"));
   1.627 +	}
   1.628 +
   1.629 +
   1.630 +TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()
   1.631 +	{
   1.632 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()"));
   1.633 +	}
   1.634 +
   1.635 +
   1.636 +TUint16 TUsbcStringDescriptorBase::Word(TInt aPosition) const
   1.637 +	{
   1.638 +	if (aPosition <= 1)
   1.639 +		{
   1.640 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Word(%d) in string descriptor "
   1.641 +										  "(TUsbcStringDescriptorBase::Word)", aPosition));
   1.642 +		return 0;
   1.643 +		}
   1.644 +	else
   1.645 +		{
   1.646 +		// since iBufPtr[0] is actually string descriptor byte index 2,
   1.647 +		// we have to subtract 2 from the absolute position.
   1.648 +		return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition - 2]));
   1.649 +		}
   1.650 +	}
   1.651 +
   1.652 +
   1.653 +void TUsbcStringDescriptorBase::SetWord(TInt aPosition, TUint16 aValue)
   1.654 +	{
   1.655 +	if (aPosition <= 1)
   1.656 +		{
   1.657 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: SetWord(%d) in string descriptor "
   1.658 +										  "(TUsbcStringDescriptorBase::SetWord)", aPosition));
   1.659 +		return;
   1.660 +		}
   1.661 +	else
   1.662 +		{
   1.663 +		// since iBufPtr[0] is actually string descriptor byte index 2,
   1.664 +		// we have to subtract 2 from the absolute position.
   1.665 +		*reinterpret_cast<TUint16*>(&iBufPtr[aPosition - 2]) = SWAP_BYTES_16(aValue);
   1.666 +		}
   1.667 +	}
   1.668 +
   1.669 +
   1.670 +TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
   1.671 +	{
   1.672 +	aBuffer[0] = iSBuf[0];
   1.673 +	aBuffer[1] = iSBuf[1];
   1.674 +	memcpy(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size());
   1.675 +	return Size();
   1.676 +	}
   1.677 +
   1.678 +
   1.679 +TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const
   1.680 +	{
   1.681 +	if (aMaxSize < Size())
   1.682 +		{
   1.683 +		// No use to copy only half a string
   1.684 +		return 0;
   1.685 +		}
   1.686 +	return GetDescriptorData(aBuffer);
   1.687 +	}
   1.688 +
   1.689 +
   1.690 +const TDes8& TUsbcStringDescriptorBase::StringData() const
   1.691 +	{
   1.692 +	return iBufPtr;
   1.693 +	}
   1.694 +
   1.695 +
   1.696 +TDes8& TUsbcStringDescriptorBase::StringData()
   1.697 +	{
   1.698 +	return iBufPtr;
   1.699 +	}
   1.700 +
   1.701 +
   1.702 +TUint TUsbcStringDescriptorBase::Size() const
   1.703 +	{
   1.704 +	return iSBuf[0];
   1.705 +	}
   1.706 +
   1.707 +
   1.708 +void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes)
   1.709 +	{
   1.710 +	iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
   1.711 +	}
   1.712 +
   1.713 +
   1.714 +// --- TUsbcStringDescriptor
   1.715 +
   1.716 +TUsbcStringDescriptor::TUsbcStringDescriptor()
   1.717 +	: iBuf(NULL)
   1.718 +	{
   1.719 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::TUsbcStringDescriptor()"));
   1.720 +	}
   1.721 +
   1.722 +
   1.723 +TUsbcStringDescriptor::~TUsbcStringDescriptor()
   1.724 +	{
   1.725 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::~TUsbcStringDescriptor()"));
   1.726 +	delete iBuf;
   1.727 +	}
   1.728 +
   1.729 +
   1.730 +TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString)
   1.731 +	{
   1.732 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::New"));
   1.733 +	TUsbcStringDescriptor* self = new TUsbcStringDescriptor();
   1.734 +	if (self)
   1.735 +		{
   1.736 +		if (self->Construct(aString) != KErrNone)
   1.737 +			{
   1.738 +			delete self;
   1.739 +			return NULL;
   1.740 +			}
   1.741 +		}
   1.742 +	return self;
   1.743 +	}
   1.744 +
   1.745 +
   1.746 +TInt TUsbcStringDescriptor::Construct(const TDesC8& aString)
   1.747 +	{
   1.748 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::Construct"));
   1.749 +	iBuf = HBuf8::New(aString.Size());						// bytes, not UNICODE chars
   1.750 +	if (!iBuf)
   1.751 +		{
   1.752 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Allocation of string buffer failed"));
   1.753 +		return KErrNoMemory;
   1.754 +		}
   1.755 +	iBuf->SetMax();
   1.756 +	SetBufferPointer(*iBuf);
   1.757 +	iBufPtr.Copy(aString);
   1.758 +	iSBuf.SetMax();
   1.759 +	iSBuf[0] = iBuf->Size() + 2;							// Bytes
   1.760 +	iSBuf[1] = KUsbDescType_String;
   1.761 +	return KErrNone;
   1.762 +	}
   1.763 +
   1.764 +
   1.765 +// --- TUsbcLangIdDescriptor
   1.766 +
   1.767 +TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()
   1.768 +	: iBuf(NULL)
   1.769 +	{
   1.770 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()"));
   1.771 +	}
   1.772 +
   1.773 +
   1.774 +TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()
   1.775 +	{
   1.776 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()"));
   1.777 +	}
   1.778 +
   1.779 +
   1.780 +TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId)
   1.781 +	{
   1.782 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::New"));
   1.783 +	TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor();
   1.784 +	if (self)
   1.785 +		{
   1.786 +		if (self->Construct(aLangId) != KErrNone)
   1.787 +			{
   1.788 +			delete self;
   1.789 +			return NULL;
   1.790 +			}
   1.791 +		}
   1.792 +	return self;
   1.793 +	}
   1.794 +
   1.795 +
   1.796 +TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId)
   1.797 +	{
   1.798 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::Construct"));
   1.799 +	iBuf.SetMax();
   1.800 +	SetBufferPointer(iBuf);
   1.801 +	iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId));			// Language ID value
   1.802 +	iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId));
   1.803 +	iSBuf.SetMax();
   1.804 +	iSBuf[0] = iBuf.Size() + 2;								// Bytes
   1.805 +	iSBuf[1] = KUsbDescType_String;
   1.806 +	return KErrNone;
   1.807 +	}
   1.808 +
   1.809 +
   1.810 +// --- TUsbcDescriptorPool
   1.811 +
   1.812 +TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf)
   1.813 +//
   1.814 +//	The constructor for this class.
   1.815 +//
   1.816 +	: iDescriptors(), iStrings(), iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf), iHighSpeed(EFalse)
   1.817 +	{
   1.818 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::TUsbcDescriptorPool()"));
   1.819 +	}
   1.820 +
   1.821 +
   1.822 +TUsbcDescriptorPool::~TUsbcDescriptorPool()
   1.823 +	{
   1.824 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::~TUsbcDescriptorPool()"));
   1.825 +	// The destructor of each <class T> object is called before the objects themselves are destroyed.
   1.826 +	__KTRACE_OPT(KUSB, Kern::Printf("  iDescriptors.Count(): %d", iDescriptors.Count()));
   1.827 +	iDescriptors.ResetAndDestroy();
   1.828 +	__KTRACE_OPT(KUSB, Kern::Printf("  iStrings.Count(): %d", iStrings.Count()));
   1.829 +	iStrings.ResetAndDestroy();
   1.830 +	}
   1.831 +
   1.832 +
   1.833 +TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
   1.834 +							   TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
   1.835 +							   TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
   1.836 +							   TUsbcStringDescriptor* aConfig, TUsbcOtgDescriptor* aOtgDesc)
   1.837 +	{
   1.838 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::Init()"));
   1.839 +	if (!aDeviceDesc || !aConfigDesc)
   1.840 +		{
   1.841 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: No Device or Config descriptor specified"));
   1.842 +		return KErrArgument;
   1.843 +		}
   1.844 +	for (TInt n = 0; n < KDescPosition_FirstAvailable; n++)
   1.845 +		{
   1.846 +		iDescriptors.Append(NULL);
   1.847 +		}
   1.848 +	__ASSERT_DEBUG((iDescriptors.Count() == KDescPosition_FirstAvailable),
   1.849 +				   Kern::Printf("  Error: iDescriptors.Count() (%d) != KDescPosition_FirstAvailable (%d)",
   1.850 +								iDescriptors.Count(), KDescPosition_FirstAvailable));
   1.851 +	iDescriptors[KDescPosition_Device] = aDeviceDesc;
   1.852 +	iDescriptors[KDescPosition_Config] = aConfigDesc;
   1.853 +	if (aOtgDesc)
   1.854 +		{
   1.855 +		iDescriptors[KDescPosition_Otg] = aOtgDesc;
   1.856 +		// Update the config descriptor's wTotalLength field
   1.857 +		UpdateConfigDescriptorLength(KUsbDescSize_Otg);
   1.858 +		}
   1.859 +	if (!aLangId)
   1.860 +		{
   1.861 +		// USB spec 9.6.7 says: "String index zero for all languages returns a string descriptor
   1.862 +		// that contains an array of two-byte LANGID codes supported by the device. ...
   1.863 +		// USB devices that omit all string descriptors must not return an array of LANGID codes."
   1.864 +		// So if we have at least one string descriptor, we must also have a LANGID descriptor.
   1.865 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: No LANGID string descriptor specified"));
   1.866 +		return KErrArgument;
   1.867 +		}
   1.868 +	iStrings.Insert(aLangId, KStringPosition_Langid);
   1.869 +	iStrings.Insert(aManufacturer, KStringPosition_Manufact);
   1.870 +	iStrings.Insert(aProduct, KStringPosition_Product);
   1.871 +	iStrings.Insert(aSerialNum, KStringPosition_Serial);
   1.872 +	iStrings.Insert(aConfig, KStringPosition_Config);
   1.873 +	__ASSERT_DEBUG((iStrings.Count() == 5),
   1.874 +				   Kern::Printf("  Error: iStrings.Count() != 5 (%d)", iStrings.Count()));
   1.875 +#ifdef _DEBUG
   1.876 +	for (TInt i = KStringPosition_Langid; i <= KStringPosition_Config; i++)
   1.877 +		{
   1.878 +		__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool.iStrings[%d] = 0x%x", i, iStrings[i]));
   1.879 +		}
   1.880 +#endif
   1.881 +	// Set string indices
   1.882 +	if (aManufacturer)
   1.883 +		iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Manufact,
   1.884 +													KStringPosition_Manufact);
   1.885 +	if (aProduct)
   1.886 +		iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Product,
   1.887 +													KStringPosition_Product);
   1.888 +	if (aSerialNum)
   1.889 +		iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Serial,
   1.890 +													KStringPosition_Serial);
   1.891 +	if (aConfig)
   1.892 +		iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config,
   1.893 +													KStringPosition_Config);
   1.894 +	return KErrNone;
   1.895 +	}
   1.896 +
   1.897 +
   1.898 +TInt TUsbcDescriptorPool::InitHs()
   1.899 +	{
   1.900 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InitHs()"));
   1.901 +	__ASSERT_DEBUG((iDescriptors.Count() >= KDescPosition_FirstAvailable),
   1.902 +				   Kern::Printf("  Error: Call Init() first)"));
   1.903 +
   1.904 +	TUsbcDeviceQualifierDescriptor* const dq_desc = TUsbcDeviceQualifierDescriptor::New(
   1.905 +		iDescriptors[KDescPosition_Device]->Byte(4),		// aDeviceClass
   1.906 +		iDescriptors[KDescPosition_Device]->Byte(5),		// aDeviceSubClass
   1.907 +		iDescriptors[KDescPosition_Device]->Byte(6),		// aDeviceProtocol
   1.908 +		iDescriptors[KDescPosition_Device]->Byte(7),		// aMaxPacketSize0
   1.909 +		iDescriptors[KDescPosition_Device]->Byte(17));		// aNumConfigurations
   1.910 +	if (!dq_desc)
   1.911 +		{
   1.912 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for dev qualif desc failed."));
   1.913 +		return KErrGeneral;
   1.914 +		}
   1.915 +	iDescriptors[KDescPosition_DeviceQualifier] = dq_desc;
   1.916 +
   1.917 +	TUsbcOtherSpeedConfigDescriptor* const osc_desc = TUsbcOtherSpeedConfigDescriptor::New(
   1.918 +		iDescriptors[KDescPosition_Config]->Byte(5),		// aConfigurationValue
   1.919 +		iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_SelfPowered, // aSelfPowered
   1.920 +		iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_RemoteWakeup,	// aRemoteWakeup
   1.921 +		iDescriptors[KDescPosition_Config]->Byte(8) * 2);	// aMaxPower (mA)
   1.922 +	if (!osc_desc)
   1.923 +		{
   1.924 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for other speed conf desc failed."));
   1.925 +		return KErrGeneral;
   1.926 +		}
   1.927 +
   1.928 +	// We need to set the bDescriptorType field manually, as that's the only one
   1.929 +	// that differs from a Configuration descriptor.
   1.930 +	osc_desc->SetByte(1, KUsbDescType_OtherSpeedConfig);
   1.931 +
   1.932 +	// Also, initially we set the iConfiguration string index to the same value as
   1.933 +	// in the Configuration descriptor.
   1.934 +	osc_desc->SetByte(KUsbDescStringIndex_Config,
   1.935 +					  iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config));
   1.936 +
   1.937 +	iDescriptors[KDescPosition_OtherSpeedConfig] = osc_desc;
   1.938 +
   1.939 +	return KErrNone;
   1.940 +	}
   1.941 +
   1.942 +
   1.943 +TInt TUsbcDescriptorPool::UpdateDescriptorsFs()
   1.944 +	{
   1.945 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsFs()"));
   1.946 +	const TInt count = iDescriptors.Count();
   1.947 +	for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
   1.948 +		{
   1.949 +		TUsbcDescriptorBase* const ptr = iDescriptors[i];
   1.950 +		ptr->UpdateFs();
   1.951 +		}
   1.952 +	iHighSpeed = EFalse;
   1.953 +	return KErrNone;
   1.954 +	}
   1.955 +
   1.956 +
   1.957 +TInt TUsbcDescriptorPool::UpdateDescriptorsHs()
   1.958 +	{
   1.959 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsHs()"));
   1.960 +	const TInt count = iDescriptors.Count();
   1.961 +	for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
   1.962 +		{
   1.963 +		TUsbcDescriptorBase* const ptr = iDescriptors[i];
   1.964 +		ptr->UpdateHs();
   1.965 +		}
   1.966 +	iHighSpeed = ETrue;
   1.967 +	return KErrNone;
   1.968 +	}
   1.969 +
   1.970 +
   1.971 +//
   1.972 +// An error can be indicated by either a return value != KErrNone or by a descriptor size == 0.
   1.973 +//
   1.974 +TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const
   1.975 +	{
   1.976 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindDescriptor()"));
   1.977 +	TInt result = KErrGeneral;
   1.978 +	switch (aType)
   1.979 +		{
   1.980 +	case KUsbDescType_Device:
   1.981 +		if (aLangid != 0)
   1.982 +			{
   1.983 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
   1.984 +			}
   1.985 +		else if (aIndex > 0)
   1.986 +			{
   1.987 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad device index: %d", aIndex));
   1.988 +			}
   1.989 +		else
   1.990 +			{
   1.991 +			aSize = GetDeviceDescriptor(KDescPosition_Device);
   1.992 +			result = KErrNone;
   1.993 +			}
   1.994 +		break;
   1.995 +	case KUsbDescType_Config:
   1.996 +		if (aLangid != 0)
   1.997 +			{
   1.998 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
   1.999 +			}
  1.1000 +		else if (aIndex > 0)
  1.1001 +			{
  1.1002 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad config index: %d", aIndex));
  1.1003 +			}
  1.1004 +		else
  1.1005 +			{
  1.1006 +			aSize = GetConfigurationDescriptor(KDescPosition_Config);
  1.1007 +			result = KErrNone;
  1.1008 +			}
  1.1009 +		break;
  1.1010 +	case KUsbDescType_DeviceQualifier:
  1.1011 +		if (aLangid != 0)
  1.1012 +			{
  1.1013 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
  1.1014 +			}
  1.1015 +		else if (aIndex > 0)
  1.1016 +			{
  1.1017 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad device index: %d", aIndex));
  1.1018 +			}
  1.1019 +		else
  1.1020 +			{
  1.1021 +			aSize = GetDeviceDescriptor(KDescPosition_DeviceQualifier);
  1.1022 +			result = KErrNone;
  1.1023 +			}
  1.1024 +		break;
  1.1025 +	case KUsbDescType_OtherSpeedConfig:
  1.1026 +		if (aLangid != 0)
  1.1027 +			{
  1.1028 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad langid: 0x%04x", aLangid));
  1.1029 +			}
  1.1030 +		else if (aIndex > 0)
  1.1031 +			{
  1.1032 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bad config index: %d", aIndex));
  1.1033 +			}
  1.1034 +		else
  1.1035 +			{
  1.1036 +			aSize = GetConfigurationDescriptor(KDescPosition_OtherSpeedConfig);
  1.1037 +			result = KErrNone;
  1.1038 +			}
  1.1039 +		break;
  1.1040 +	case KUsbDescType_Otg:
  1.1041 +		aSize = GetOtgDescriptor();
  1.1042 +		result = KErrNone;
  1.1043 +		break;
  1.1044 +	case KUsbDescType_String:
  1.1045 +		if (aIndex == 0)									// 0 addresses the LangId array
  1.1046 +			{
  1.1047 +			if (AnyStringDescriptors())
  1.1048 +				{
  1.1049 +				aSize = GetStringDescriptor(aIndex);
  1.1050 +				result = KErrNone;
  1.1051 +				}
  1.1052 +			else
  1.1053 +				{
  1.1054 +				__KTRACE_OPT(KUSB, Kern::Printf("  No string descriptors: not returning LANGID array"));
  1.1055 +				}
  1.1056 +			}
  1.1057 +		else
  1.1058 +			{
  1.1059 +   			if (!aLangid)
  1.1060 +   				{
  1.1061 +   				__KTRACE_OPT(KUSB,
  1.1062 + 							 Kern::Printf("  Strange: LANGID=0 for a $ descriptor (ignoring LANGID)"));
  1.1063 +				// The USB spec doesn't really say what to do in this case, but as there are host apps
  1.1064 +				// that fail if we return an error here, we choose to ignore the issue.
  1.1065 +   				}
  1.1066 +			else if (aLangid != iStrings[KStringPosition_Langid]->Word(2))
  1.1067 +				{
  1.1068 +				// We have only one (this) language
  1.1069 +				__KTRACE_OPT(KUSB,
  1.1070 +							 Kern::Printf("  Bad LANGID: 0x%04X requested, 0x%04X supported (ignoring LANGID)",
  1.1071 +										  aLangid, iStrings[KStringPosition_Langid]->Word(2)));
  1.1072 +				// We could return an error here, but rather choose to ignore the discrepancy
  1.1073 +				// (the USB spec is not very clear what to do in such a case anyway).
  1.1074 +				}
  1.1075 +			aSize = GetStringDescriptor(aIndex);
  1.1076 +			result = KErrNone;
  1.1077 +			}
  1.1078 +		break;
  1.1079 +	case KUsbDescType_CS_Interface:
  1.1080 +		/* fall through */
  1.1081 +	case KUsbDescType_CS_Endpoint:
  1.1082 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: finding of class specific descriptors not supported"));
  1.1083 +		break;
  1.1084 +	default:
  1.1085 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: unknown descriptor type requested: %d", aType));
  1.1086 +		break;
  1.1087 +		}
  1.1088 +	return result;
  1.1089 +	}
  1.1090 +
  1.1091 +
  1.1092 +void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc)
  1.1093 +	{
  1.1094 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertDescriptor()"));
  1.1095 +	switch (aDesc->Type())
  1.1096 +		{
  1.1097 +	case KUsbDescType_Interface:
  1.1098 +		InsertIfcDesc(aDesc);
  1.1099 +		break;
  1.1100 +	case KUsbDescType_Endpoint:
  1.1101 +		InsertEpDesc(aDesc);
  1.1102 +		break;
  1.1103 +	default:
  1.1104 +		__KTRACE_OPT(KUSB, Kern::Printf("  Error: unsupported descriptor type"));
  1.1105 +		}
  1.1106 +	}
  1.1107 +
  1.1108 +
  1.1109 +void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting)
  1.1110 +	{
  1.1111 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetIfcDescriptor(%d, %d)", aNumber, aSetting));
  1.1112 +	const TInt i = FindIfcDescriptor(aNumber, aSetting);
  1.1113 +	if (i < 0)
  1.1114 +		{
  1.1115 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ifc descriptor not found (%d, %d)",
  1.1116 +										  aNumber, aSetting));
  1.1117 +		return;
  1.1118 +		}
  1.1119 +	// Try to find available NULL postition
  1.1120 +	TInt str_idx = FindAvailableStringPos();
  1.1121 +	if (str_idx >= 0)
  1.1122 +		{
  1.1123 +		// Insert string descriptor for specified interface
  1.1124 +		ExchangeStringDescriptor(str_idx, aDesc);
  1.1125 +		}
  1.1126 +	else
  1.1127 +		{
  1.1128 +		// No NULL found - expand array
  1.1129 +		str_idx = iStrings.Count();
  1.1130 +		if (str_idx > 0xff)
  1.1131 +			{
  1.1132 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: $ descriptor array full (idx=%d)", str_idx));
  1.1133 +			return;
  1.1134 +			}
  1.1135 +		while (str_idx < KStringPosition_FirstAvailable)
  1.1136 +			{
  1.1137 +			iStrings.Append(NULL);
  1.1138 +			str_idx = iStrings.Count();
  1.1139 +			}
  1.1140 +		// Append string descriptor for specified interface
  1.1141 +		iStrings.Append(aDesc);
  1.1142 +		}
  1.1143 +	// Update this ifc descriptor's string index field
  1.1144 +	iDescriptors[i]->SetByte(8, str_idx);
  1.1145 +	__KTRACE_OPT(KUSB, Kern::Printf("  String for ifc %d/%d (@ pos %d): \"%S\"", aNumber, aSetting, str_idx,
  1.1146 +									&iStrings[str_idx]->StringData()));
  1.1147 +	}
  1.1148 +
  1.1149 +
  1.1150 +void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting)
  1.1151 +	{
  1.1152 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)", aNumber, aSetting));
  1.1153 +	const TInt i = FindIfcDescriptor(aNumber, aSetting);
  1.1154 +	if (i < 0)
  1.1155 +		{
  1.1156 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: DeleteIfcDescriptor - descriptor not found (%d, %d)",
  1.1157 +										  aNumber, aSetting));
  1.1158 +		return;
  1.1159 +		}
  1.1160 +	// Delete (if necessary) specified interface's string descriptor
  1.1161 +	const TInt si = iDescriptors[i]->Byte(8);
  1.1162 +	if (si != 0)
  1.1163 +		{
  1.1164 +		ExchangeStringDescriptor(si, NULL);
  1.1165 +		}
  1.1166 +	// Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors:
  1.1167 +	// find position of the next interface descriptor: we need to delete everything in between
  1.1168 +	const TInt count = iDescriptors.Count();
  1.1169 +	TInt j = i, n = 1;
  1.1170 +	while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface)
  1.1171 +		++n;
  1.1172 +	DeleteDescriptors(i, n);
  1.1173 +	// Update all the following interfaces' bInterfaceNumber field if required
  1.1174 +	// (because those descriptors might have moved down by one position)
  1.1175 +	UpdateIfcNumbers(aNumber);
  1.1176 +	iIfcIdx = 0;											// ifc index no longer valid
  1.1177 +	}
  1.1178 +
  1.1179 +
  1.1180 +// The TC in many of the following functions stands for 'ThreadCopy',
  1.1181 +// because that's what's happening there.
  1.1182 +
  1.1183 +TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const
  1.1184 +	{
  1.1185 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptorTC()"));
  1.1186 +	return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Device]->DescriptorData(), 0);
  1.1187 +	}
  1.1188 +
  1.1189 +
  1.1190 +TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer)
  1.1191 +	{
  1.1192 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceDescriptorTC()"));
  1.1193 +	TBuf8<KUsbDescSize_Device> device;
  1.1194 +	const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0);
  1.1195 +	if (r != KErrNone)
  1.1196 +		{
  1.1197 +		return r;
  1.1198 +		}
  1.1199 +	iDescriptors[KDescPosition_Device]->SetByte(2, device[2]); // bcdUSB
  1.1200 +	iDescriptors[KDescPosition_Device]->SetByte(3, device[3]); // bcdUSB (part II)
  1.1201 +	iDescriptors[KDescPosition_Device]->SetByte(4, device[4]); // bDeviceClass
  1.1202 +	iDescriptors[KDescPosition_Device]->SetByte(5, device[5]); // bDeviceSubClass
  1.1203 +	iDescriptors[KDescPosition_Device]->SetByte(6, device[6]); // bDeviceProtocol
  1.1204 +	iDescriptors[KDescPosition_Device]->SetByte(8, device[8]); // idVendor
  1.1205 +	iDescriptors[KDescPosition_Device]->SetByte(9, device[9]); // idVendor (part II)
  1.1206 +	iDescriptors[KDescPosition_Device]->SetByte(10, device[10]); // idProduct
  1.1207 +	iDescriptors[KDescPosition_Device]->SetByte(11, device[11]); // idProduct (part II)
  1.1208 +	iDescriptors[KDescPosition_Device]->SetByte(12, device[12]); // bcdDevice
  1.1209 +	iDescriptors[KDescPosition_Device]->SetByte(13, device[13]); // bcdDevice (part II)
  1.1210 +	return KErrNone;
  1.1211 +	}
  1.1212 +
  1.1213 +
  1.1214 +TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
  1.1215 +	{
  1.1216 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigurationDescriptorTC()"));
  1.1217 +	return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Config]->DescriptorData(), 0);
  1.1218 +	}
  1.1219 +
  1.1220 +
  1.1221 +TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
  1.1222 +	{
  1.1223 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetConfigurationDescriptorTC()"));
  1.1224 +	TBuf8<KUsbDescSize_Config> config;
  1.1225 +	const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0);
  1.1226 +	if (r != KErrNone)
  1.1227 +		{
  1.1228 +		return r;
  1.1229 +		}
  1.1230 +	iDescriptors[KDescPosition_Config]->SetByte(7, config[7]); // bmAttributes
  1.1231 +	iDescriptors[KDescPosition_Config]->SetByte(8, config[8]); // bMaxPower
  1.1232 +	return KErrNone;
  1.1233 +	}
  1.1234 +
  1.1235 +
  1.1236 +TInt TUsbcDescriptorPool::GetOtgDescriptorTC(DThread* aThread, TDes8& aBuffer) const
  1.1237 +	{
  1.1238 +	return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Otg]->DescriptorData(), 0);
  1.1239 +	}
  1.1240 +
  1.1241 +
  1.1242 +TInt TUsbcDescriptorPool::SetOtgDescriptor(const TDesC8& aBuffer)
  1.1243 +	{
  1.1244 +	iDescriptors[KDescPosition_Otg]->SetByte(2, aBuffer[2]); // bmAttributes
  1.1245 +	return KErrNone;
  1.1246 +	}
  1.1247 +
  1.1248 +
  1.1249 +TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
  1.1250 +												   TInt aInterface, TInt aSetting) const
  1.1251 +	{
  1.1252 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetInterfaceDescriptorTC()"));
  1.1253 +	const TInt i = FindIfcDescriptor(aInterface, aSetting);
  1.1254 +	if (i < 0)
  1.1255 +		{
  1.1256 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1257 +		return KErrNotFound;
  1.1258 +		}
  1.1259 +	return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
  1.1260 +	}
  1.1261 +
  1.1262 +
  1.1263 +TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting)
  1.1264 +	{
  1.1265 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetInterfaceDescriptor()"));
  1.1266 +	const TInt i = FindIfcDescriptor(aInterface, aSetting);
  1.1267 +	if (i < 0)
  1.1268 +		{
  1.1269 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1270 +		return KErrNotFound;
  1.1271 +		}
  1.1272 +	iDescriptors[i]->SetByte(2, aBuffer[2]);				// bInterfaceNumber
  1.1273 +	iDescriptors[i]->SetByte(5, aBuffer[5]);				// bInterfaceClass
  1.1274 +	iDescriptors[i]->SetByte(6, aBuffer[6]);				// bInterfaceSubClass
  1.1275 +	iDescriptors[i]->SetByte(7, aBuffer[7]);				// bInterfaceProtocol
  1.1276 +	return KErrNone;
  1.1277 +	}
  1.1278 +
  1.1279 +
  1.1280 +TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer,
  1.1281 +												  TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const
  1.1282 +	{
  1.1283 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorTC()"));
  1.1284 +	const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1.1285 +	if (i < 0)
  1.1286 +		{
  1.1287 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1288 +		return KErrNotFound;
  1.1289 +		}
  1.1290 +	return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
  1.1291 +	}
  1.1292 +
  1.1293 +
  1.1294 +TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer,
  1.1295 +												  TInt aInterface, TInt aSetting, TUint8 aEndpointAddress)
  1.1296 +	{
  1.1297 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetEndpointDescriptorTC()"));
  1.1298 +	const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1.1299 +	if (i < 0)
  1.1300 +		{
  1.1301 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1302 +		return KErrNotFound;
  1.1303 +		}
  1.1304 +	TBuf8<KUsbDescSize_AudioEndpoint> ep;					// it could be an audio endpoint
  1.1305 +	const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, ep, 0);
  1.1306 +	if (r != KErrNone)
  1.1307 +		{
  1.1308 +		return r;
  1.1309 +		}
  1.1310 +	iDescriptors[i]->SetByte(3, ep[3]);						// bmAttributes
  1.1311 +	iDescriptors[i]->SetByte(6, ep[6]);						// bInterval
  1.1312 +	if (iDescriptors[i]->Size() == KUsbDescSize_AudioEndpoint)
  1.1313 +		{
  1.1314 +		iDescriptors[i]->SetByte(7, ep[7]);					// bRefresh
  1.1315 +		iDescriptors[i]->SetByte(8, ep[8]);					// bSynchAddress
  1.1316 +		}
  1.1317 +	return KErrNone;
  1.1318 +	}
  1.1319 +
  1.1320 +
  1.1321 +TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress,
  1.1322 +													TInt& aSize) const
  1.1323 +	{
  1.1324 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorSize()"));
  1.1325 +	const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1.1326 +	if (i < 0)
  1.1327 +		{
  1.1328 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1329 +		return KErrNotFound;
  1.1330 +		}
  1.1331 +	aSize = iDescriptors[i]->Size();
  1.1332 +	return KErrNone;
  1.1333 +	}
  1.1334 +
  1.1335 +
  1.1336 +TInt TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC(DThread* aThread, TDes8& aBuffer) const
  1.1337 +	{
  1.1338 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC()"));
  1.1339 +	if (iDescriptors[KDescPosition_DeviceQualifier] == NULL)
  1.1340 +		{
  1.1341 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Device_Qualifier descriptor not supported"));
  1.1342 +		return KErrNotSupported;
  1.1343 +		}
  1.1344 +	return Kern::ThreadDesWrite(aThread, &aBuffer,
  1.1345 +								iDescriptors[KDescPosition_DeviceQualifier]->DescriptorData(), 0);
  1.1346 +	}
  1.1347 +
  1.1348 +
  1.1349 +TInt TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC(DThread* aThread, const TDes8& aBuffer)
  1.1350 +	{
  1.1351 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC()"));
  1.1352 +	if (iDescriptors[KDescPosition_DeviceQualifier] == NULL)
  1.1353 +		{
  1.1354 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Device_Qualifier descriptor not supported"));
  1.1355 +		return KErrNotSupported;
  1.1356 +		}
  1.1357 +	TBuf8<KUsbDescSize_DeviceQualifier> device;
  1.1358 +	const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0);
  1.1359 +	if (r != KErrNone)
  1.1360 +		{
  1.1361 +		return r;
  1.1362 +		}
  1.1363 +	iDescriptors[KDescPosition_DeviceQualifier]->SetByte(2, device[2]); // bcdUSB
  1.1364 +	iDescriptors[KDescPosition_DeviceQualifier]->SetByte(3, device[3]); // bcdUSB (part II)
  1.1365 +	iDescriptors[KDescPosition_DeviceQualifier]->SetByte(4, device[4]); // bDeviceClass
  1.1366 +	iDescriptors[KDescPosition_DeviceQualifier]->SetByte(5, device[5]); // bDeviceSubClass
  1.1367 +	iDescriptors[KDescPosition_DeviceQualifier]->SetByte(6, device[6]); // bDeviceProtocol
  1.1368 +	return KErrNone;
  1.1369 +	}
  1.1370 +
  1.1371 +
  1.1372 +TInt TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
  1.1373 +	{
  1.1374 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC()"));
  1.1375 +	if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL)
  1.1376 +		{
  1.1377 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Other_Speed_Configuration descriptor not supported"));
  1.1378 +		return KErrNotSupported;
  1.1379 +		}
  1.1380 +	return Kern::ThreadDesWrite(aThread, &aBuffer,
  1.1381 +								iDescriptors[KDescPosition_OtherSpeedConfig]->DescriptorData(), 0);
  1.1382 +	}
  1.1383 +
  1.1384 +
  1.1385 +TInt TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
  1.1386 +	{
  1.1387 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC()"));
  1.1388 +	if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL)
  1.1389 +		{
  1.1390 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Other_Speed_Configuration descriptor not supported"));
  1.1391 +		return KErrNotSupported;
  1.1392 +		}
  1.1393 +	TBuf8<KUsbDescSize_OtherSpeedConfig> config;
  1.1394 +	const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0);
  1.1395 +	if (r != KErrNone)
  1.1396 +		{
  1.1397 +		return r;
  1.1398 +		}
  1.1399 +	iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(7, config[7]); // bmAttributes
  1.1400 +	iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(8, config[8]); // bMaxPower
  1.1401 +	return KErrNone;
  1.1402 +	}
  1.1403 +
  1.1404 +
  1.1405 +TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
  1.1406 +													 TInt aInterface, TInt aSetting) const
  1.1407 +	{
  1.1408 +	// first find the interface
  1.1409 +	TInt i = FindIfcDescriptor(aInterface, aSetting);
  1.1410 +	if (i < 0)
  1.1411 +		{
  1.1412 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1413 +		return KErrNotFound;
  1.1414 +		}
  1.1415 +	TInt r = KErrNotFound;
  1.1416 +	TInt offset = 0;
  1.1417 +	const TInt count = iDescriptors.Count();
  1.1418 +	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
  1.1419 +		{
  1.1420 +		r = Kern::ThreadDesWrite(aThread, &aBuffer,
  1.1421 +								 iDescriptors[i]->DescriptorData(), offset);
  1.1422 +		if (r != KErrNone)
  1.1423 +			break;
  1.1424 +		offset += iDescriptors[i]->Size();
  1.1425 +		}
  1.1426 +	return r;
  1.1427 +	}
  1.1428 +
  1.1429 +
  1.1430 +TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer,
  1.1431 +													 TInt aInterface, TInt aSetting, TInt aSize)
  1.1432 +	{
  1.1433 +	// First find the interface
  1.1434 +	TInt i = FindIfcDescriptor(aInterface, aSetting);
  1.1435 +	if (i < 0)
  1.1436 +		{
  1.1437 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1438 +		return KErrNotFound;
  1.1439 +		}
  1.1440 +	// Find a position where to insert the new class specific interface descriptor(s)
  1.1441 +	const TInt count = iDescriptors.Count();
  1.1442 +	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
  1.1443 +		;
  1.1444 +	// Create a new cs descriptor
  1.1445 +	TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize);
  1.1446 +	if (!desc)
  1.1447 +		{
  1.1448 +		return KErrNoMemory;
  1.1449 +		}
  1.1450 +	__KTRACE_OPT(KUSB, Kern::Printf("  inserting descriptor at position %d", i));
  1.1451 +	iDescriptors.Insert(desc, i);
  1.1452 +
  1.1453 +	// Update the config descriptor's wTotalLength field
  1.1454 +	UpdateConfigDescriptorLength(aSize);
  1.1455 +
  1.1456 +	// Copy contents from the user side
  1.1457 +	return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
  1.1458 +	}
  1.1459 +
  1.1460 +
  1.1461 +TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const
  1.1462 +	{
  1.1463 +	// first find the interface
  1.1464 +	TInt i = FindIfcDescriptor(aInterface, aSetting);
  1.1465 +	if (i < 0)
  1.1466 +		{
  1.1467 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1468 +		return KErrNotFound;
  1.1469 +		}
  1.1470 +	TInt r = KErrNotFound;
  1.1471 +	TInt size = 0;
  1.1472 +	const TInt count = iDescriptors.Count();
  1.1473 +	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
  1.1474 +		{
  1.1475 +		size += iDescriptors[i]->Size();
  1.1476 +		r = KErrNone;
  1.1477 +		}
  1.1478 +	if (r == KErrNone)
  1.1479 +		aSize = size;
  1.1480 +	return r;
  1.1481 +	}
  1.1482 +
  1.1483 +
  1.1484 +TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface,
  1.1485 +													TInt aSetting, TUint8 aEndpointAddress) const
  1.1486 +	{
  1.1487 +	// first find the endpoint
  1.1488 +	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1.1489 +	if (i < 0)
  1.1490 +		{
  1.1491 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1492 +		return KErrNotFound;
  1.1493 +		}
  1.1494 +	TInt r = KErrNotFound;
  1.1495 +	TInt offset = 0;
  1.1496 +	const TInt count = iDescriptors.Count();
  1.1497 +	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
  1.1498 +		{
  1.1499 +		r = Kern::ThreadDesWrite(aThread, &aBuffer,
  1.1500 +								 iDescriptors[i]->DescriptorData(), offset);
  1.1501 +		if (r != KErrNone)
  1.1502 +			break;
  1.1503 +		offset += iDescriptors[i]->Size();
  1.1504 +		}
  1.1505 +	return r;
  1.1506 +	}
  1.1507 +
  1.1508 +
  1.1509 +TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface,
  1.1510 +													TInt aSetting, TUint8 aEndpointAddress, TInt aSize)
  1.1511 +	{
  1.1512 +	// first find the endpoint
  1.1513 +	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1.1514 +	if (i < 0)
  1.1515 +		{
  1.1516 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1517 +		return KErrNotFound;
  1.1518 +		}
  1.1519 +	// find a position where to insert the new class specific endpoint descriptor(s)
  1.1520 +	const TInt count = iDescriptors.Count();
  1.1521 +	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
  1.1522 +		;
  1.1523 +	// create a new cs descriptor
  1.1524 +	TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize);
  1.1525 +	if (!desc)
  1.1526 +		{
  1.1527 +		return KErrNoMemory;
  1.1528 +		}
  1.1529 +	iDescriptors.Insert(desc, i);
  1.1530 +	// update the config descriptor's wTotalLength field
  1.1531 +	UpdateConfigDescriptorLength(aSize);
  1.1532 +	// copy contents from user side
  1.1533 +	return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0);
  1.1534 +	}
  1.1535 +
  1.1536 +
  1.1537 +TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting,
  1.1538 +													  TUint8 aEndpointAddress, TInt& aSize) const
  1.1539 +	{
  1.1540 +	// first find the endpoint
  1.1541 +	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
  1.1542 +	if (i < 0)
  1.1543 +		{
  1.1544 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1545 +		return KErrNotFound;
  1.1546 +		}
  1.1547 +	TInt r = KErrNotFound;
  1.1548 +	TInt size = 0;
  1.1549 +	const TInt count = iDescriptors.Count();
  1.1550 +	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
  1.1551 +		{
  1.1552 +		size += iDescriptors[i]->Size();
  1.1553 +		r = KErrNone;
  1.1554 +		}
  1.1555 +	if (r == KErrNone)
  1.1556 +		aSize = size;
  1.1557 +	return r;
  1.1558 +	}
  1.1559 +
  1.1560 +
  1.1561 +TInt TUsbcDescriptorPool::GetStringDescriptorLangIdTC(DThread* aThread, TDes8& aLangId) const
  1.1562 +	{
  1.1563 +	const TUint16 id = iStrings[KStringPosition_Langid]->Word(2);
  1.1564 +	const TPtrC8 id_des(reinterpret_cast<const TUint8*>(&id), sizeof(id));
  1.1565 +	return Kern::ThreadDesWrite(aThread, &aLangId, id_des, 0);
  1.1566 +	}
  1.1567 +
  1.1568 +
  1.1569 +TInt TUsbcDescriptorPool::SetStringDescriptorLangId(TUint16 aLangId)
  1.1570 +	{
  1.1571 +	iStrings[KStringPosition_Langid]->SetWord(2, aLangId);
  1.1572 +	return KErrNone;
  1.1573 +	}
  1.1574 +
  1.1575 +
  1.1576 +TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1.1577 +	{
  1.1578 +	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact,
  1.1579 +									   KStringPosition_Manufact);
  1.1580 +	}
  1.1581 +
  1.1582 +
  1.1583 +TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1.1584 +	{
  1.1585 +	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact,
  1.1586 +									   KStringPosition_Manufact);
  1.1587 +	}
  1.1588 +
  1.1589 +
  1.1590 +TInt TUsbcDescriptorPool::RemoveManufacturerStringDescriptor()
  1.1591 +	{
  1.1592 +	return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Manufact, KStringPosition_Manufact);
  1.1593 +	}
  1.1594 +
  1.1595 +
  1.1596 +TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1.1597 +	{
  1.1598 +	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product,
  1.1599 +									   KStringPosition_Product);
  1.1600 +	}
  1.1601 +
  1.1602 +
  1.1603 +TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1.1604 +	{
  1.1605 +	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product,
  1.1606 +									   KStringPosition_Product);
  1.1607 +	}
  1.1608 +
  1.1609 +
  1.1610 +TInt TUsbcDescriptorPool::RemoveProductStringDescriptor()
  1.1611 +	{
  1.1612 +	return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Product, KStringPosition_Product);
  1.1613 +	}
  1.1614 +
  1.1615 +
  1.1616 +TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1.1617 +	{
  1.1618 +	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial,
  1.1619 +									   KStringPosition_Serial);
  1.1620 +	}
  1.1621 +
  1.1622 +
  1.1623 +TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1.1624 +	{
  1.1625 +	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial,
  1.1626 +									   KStringPosition_Serial);
  1.1627 +	}
  1.1628 +
  1.1629 +
  1.1630 +TInt TUsbcDescriptorPool::RemoveSerialNumberStringDescriptor()
  1.1631 +	{
  1.1632 +	return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Serial, KStringPosition_Serial);
  1.1633 +	}
  1.1634 +
  1.1635 +
  1.1636 +TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const
  1.1637 +	{
  1.1638 +	const TInt str_idx = iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config);
  1.1639 +	if (str_idx)
  1.1640 +		{
  1.1641 +		__ASSERT_ALWAYS((str_idx == KStringPosition_Config), Kern::Fault(KUsbPanicCat, __LINE__));
  1.1642 +		__KTRACE_OPT(KUSB, Kern::Printf("  String @ pos %d (conf $): \"%S\"",
  1.1643 +										str_idx, &iStrings[str_idx]->StringData()));
  1.1644 +		return Kern::ThreadDesWrite(aThread, &aString,
  1.1645 +									iStrings[str_idx]->StringData(), 0);
  1.1646 +		}
  1.1647 +	else
  1.1648 +		{
  1.1649 +		__KTRACE_OPT(KUSB, Kern::Printf("  No config string descriptor @ pos %d", str_idx));
  1.1650 +		return KErrNotFound;
  1.1651 +		}
  1.1652 +	}
  1.1653 +
  1.1654 +
  1.1655 +TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString)
  1.1656 +	{
  1.1657 +	// we don't know the length of the string, so we have to allocate memory dynamically
  1.1658 +	TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
  1.1659 +	if (strlen > KUsbStringDescStringMaxSize)
  1.1660 +		{
  1.1661 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: config $ descriptor too long - will be truncated"));
  1.1662 +		strlen = KUsbStringDescStringMaxSize;
  1.1663 +		}
  1.1664 +	HBuf8* const strbuf = HBuf8::New(strlen);
  1.1665 +	if (!strbuf)
  1.1666 +		{
  1.1667 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for config $ desc string failed (1)"));
  1.1668 +		return KErrNoMemory;
  1.1669 +		}
  1.1670 +	strbuf->SetMax();
  1.1671 +	// the aString points to data that lives in user memory, so we have to copy it:
  1.1672 +	const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
  1.1673 +	if (r != KErrNone)
  1.1674 +		{
  1.1675 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
  1.1676 +		delete strbuf;
  1.1677 +		return r;
  1.1678 +		}
  1.1679 +	TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
  1.1680 +	if (!sd)
  1.1681 +		{
  1.1682 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for config $ desc failed (2)"));
  1.1683 +		delete strbuf;
  1.1684 +		return KErrNoMemory;
  1.1685 +		}
  1.1686 +	// Delete old string, put in new one
  1.1687 +	ExchangeStringDescriptor(KStringPosition_Config, sd);
  1.1688 +	// Update Config descriptor string index field
  1.1689 +	iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, KStringPosition_Config);
  1.1690 +	// Update Other_Speed_Config descriptor string index field as well, if applicable
  1.1691 +	if (iDescriptors[KDescPosition_OtherSpeedConfig])
  1.1692 +		iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config,
  1.1693 +															  KStringPosition_Config);
  1.1694 +	delete strbuf;
  1.1695 +	return KErrNone;
  1.1696 +	}
  1.1697 +
  1.1698 +
  1.1699 +TInt TUsbcDescriptorPool::RemoveConfigurationStringDescriptor()
  1.1700 +	{
  1.1701 +	if (iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config) == 0)
  1.1702 +		{
  1.1703 +		__KTRACE_OPT(KUSB, Kern::Printf("  RemoveConfigurationStringDescriptor: no $ desc @ index %d",
  1.1704 +										KUsbDescStringIndex_Config));
  1.1705 +		return KErrNotFound;
  1.1706 +		}
  1.1707 +	// Delete old string, put in NULL pointer
  1.1708 +	ExchangeStringDescriptor(KStringPosition_Config, NULL);
  1.1709 +	// Update Config descriptor string index field
  1.1710 +	iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, 0);
  1.1711 +	// Update Other_Speed_Config descriptor string index field as well, if applicable
  1.1712 +	if (iDescriptors[KDescPosition_OtherSpeedConfig])
  1.1713 +		iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config, 0);
  1.1714 +	return KErrNone;
  1.1715 +	}
  1.1716 +
  1.1717 +
  1.1718 +TInt TUsbcDescriptorPool::GetStringDescriptorTC(DThread* aThread, TInt aIndex, TDes8& aString) const
  1.1719 +	{
  1.1720 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptorTC()"));
  1.1721 +	if (!StringDescriptorExists(aIndex))
  1.1722 +		{
  1.1723 +		return KErrNotFound;
  1.1724 +		}
  1.1725 +	__KTRACE_OPT(KUSB, Kern::Printf("  String @ pos %d: \"%S\"",
  1.1726 +									aIndex, &iStrings[aIndex]->StringData()));
  1.1727 +	return Kern::ThreadDesWrite(aThread, &aString, iStrings[aIndex]->StringData(), 0);
  1.1728 +	}
  1.1729 +
  1.1730 +
  1.1731 +TInt TUsbcDescriptorPool::SetStringDescriptorTC(DThread* aThread, TInt aIndex, const TDes8& aString)
  1.1732 +	{
  1.1733 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetStringDescriptorTC()"));
  1.1734 +	// we don't know the length of the string, so we have to allocate memory dynamically
  1.1735 +	TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
  1.1736 +	if (strlen > KUsbStringDescStringMaxSize)
  1.1737 +		{
  1.1738 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: $ descriptor too long - will be truncated"));
  1.1739 +		strlen = KUsbStringDescStringMaxSize;
  1.1740 +		}
  1.1741 +	HBuf8* strbuf = HBuf8::New(strlen);
  1.1742 +	if (!strbuf)
  1.1743 +		{
  1.1744 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Mem alloc for $ desc string failed (1)"));
  1.1745 +		return KErrNoMemory;
  1.1746 +		}
  1.1747 +	strbuf->SetMax();
  1.1748 +	// the aString points to data that lives in user memory, so we have to copy it over:
  1.1749 +	const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
  1.1750 +	if (r != KErrNone)
  1.1751 +		{
  1.1752 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
  1.1753 +		delete strbuf;
  1.1754 +		return r;
  1.1755 +		}
  1.1756 +	TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf);
  1.1757 +	if (!sd)
  1.1758 +		{
  1.1759 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Mem alloc for $ desc failed (2)"));
  1.1760 +		delete strbuf;
  1.1761 +		return KErrNoMemory;
  1.1762 +		}
  1.1763 +	if (aIndex < iStrings.Count())
  1.1764 +		{
  1.1765 +		ExchangeStringDescriptor(aIndex, sd);
  1.1766 +		}
  1.1767 +	else // if (aIndex >= iStrings.Count())
  1.1768 +		{
  1.1769 +		while (aIndex > iStrings.Count())
  1.1770 +			{
  1.1771 +			iStrings.Append(NULL);
  1.1772 +			}
  1.1773 +		iStrings.Append(sd);
  1.1774 +		}
  1.1775 +	delete strbuf;
  1.1776 +	return KErrNone;
  1.1777 +	}
  1.1778 +
  1.1779 +
  1.1780 +TInt TUsbcDescriptorPool::RemoveStringDescriptor(TInt aIndex)
  1.1781 +	{
  1.1782 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveStringDescriptor()"));
  1.1783 +	if (!StringDescriptorExists(aIndex))
  1.1784 +		{
  1.1785 +		return KErrNotFound;
  1.1786 +		}
  1.1787 +	__KTRACE_OPT(KUSB, Kern::Printf("  Removing string @ pos %d: \"%S\"",
  1.1788 +									aIndex, &iStrings[aIndex]->StringData()));
  1.1789 +	ExchangeStringDescriptor(aIndex, NULL);
  1.1790 +
  1.1791 +	// Make sure there's no $ after aIndex.
  1.1792 +	const TInt n = iStrings.Count();
  1.1793 +	for (TInt i = aIndex; i < n; i++)
  1.1794 +		{
  1.1795 +		if (iStrings[i] != NULL)
  1.1796 +			{
  1.1797 +			__KTRACE_OPT(KUSB, Kern::Printf("  Found $ @ idx %d - not compressing", i));
  1.1798 +			return KErrNone;
  1.1799 +			}
  1.1800 +		}
  1.1801 +
  1.1802 +	__KTRACE_OPT(KUSB, Kern::Printf("  No $ found after idx %d - compressing array", aIndex));
  1.1803 +	// Move aIndex back just before the first !NULL element.
  1.1804 +	while (iStrings[--aIndex] == NULL)
  1.1805 +		;
  1.1806 +	// Let aIndex point to first NULL.
  1.1807 +	aIndex++;
  1.1808 +	__KTRACE_OPT(KUSB, Kern::Printf("  Starting at index %d", aIndex));
  1.1809 +	// Now remove NULL pointers until (Count() == aIndex).
  1.1810 +	__KTRACE_OPT(KUSB, Kern::Printf("  iStrings.Count() before: %d", iStrings.Count()));
  1.1811 +	do
  1.1812 +		{
  1.1813 +		iStrings.Remove(aIndex);
  1.1814 +		__KTRACE_OPT(KUSB, Kern::Printf("  Removing $"));
  1.1815 +		}
  1.1816 +	while (iStrings.Count() > aIndex);
  1.1817 +	__KTRACE_OPT(KUSB, Kern::Printf("  iStrings.Count() after: %d", iStrings.Count()));
  1.1818 +
  1.1819 +	// Regain some memory.
  1.1820 +	iStrings.Compress();
  1.1821 +
  1.1822 +	return KErrNone;
  1.1823 +	}
  1.1824 +
  1.1825 +
  1.1826 +// ===================================================================
  1.1827 +// --- private ---
  1.1828 +// ===================================================================
  1.1829 +
  1.1830 +//
  1.1831 +// Insert an Interface descriptor into the descriptor array at the appropriate index.
  1.1832 +//
  1.1833 +void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc)
  1.1834 +	{
  1.1835 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertIfcDesc()"));
  1.1836 +
  1.1837 +	const TInt count = iDescriptors.Count();
  1.1838 +	TBool ifc_exists = EFalse;								// set to 'true' if we're adding an alternate
  1.1839 +															// setting to an already existing interface
  1.1840 +	TInt i = KDescPosition_FirstAvailable;
  1.1841 +	while (i < count)
  1.1842 +		{
  1.1843 +		__KTRACE_OPT(KUSB, Kern::Printf("  already descriptors there (%d)...", count));
  1.1844 +		if (iDescriptors[i]->Type() == KUsbDescType_Interface)
  1.1845 +			{
  1.1846 +			if (iDescriptors[i]->Byte(2) > aDesc->Byte(2))
  1.1847 +				{
  1.1848 +				// our interface number is less than the one's just found => insert before it (= here)
  1.1849 +				break;
  1.1850 +				}
  1.1851 +			else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2))
  1.1852 +				{
  1.1853 +				ifc_exists = ETrue;
  1.1854 +				// same interface number => look at settings number
  1.1855 +				if (iDescriptors[i]->Byte(3) > aDesc->Byte(3))
  1.1856 +					{
  1.1857 +					// our setting number is less than the one's found => insert before (= here)
  1.1858 +					break;
  1.1859 +					}
  1.1860 +				else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3))
  1.1861 +					{
  1.1862 +					__KTRACE_OPT(KPANIC, Kern::Printf("  Error: first delete old desc "
  1.1863 +													  "(TUsbcDescriptorPool::InsertIfcDesc)"));
  1.1864 +					return;
  1.1865 +					}
  1.1866 +				}
  1.1867 +			}
  1.1868 +		++i;
  1.1869 +		}
  1.1870 +	// In any case: put the new descriptor at position i.
  1.1871 +	__KTRACE_OPT(KUSB, Kern::Printf("  inserting descriptor at position %d", i));
  1.1872 +	iDescriptors.Insert(aDesc, i);
  1.1873 +
  1.1874 +	// Update the config descriptor's wTotalLength field.
  1.1875 +	UpdateConfigDescriptorLength(KUsbDescSize_Interface);
  1.1876 +
  1.1877 +	if (!ifc_exists)
  1.1878 +		{
  1.1879 +		// If this is the first setting for the interface, increment bNumInterfaces.
  1.1880 +		UpdateConfigDescriptorNumIfcs(1);
  1.1881 +		}
  1.1882 +
  1.1883 +	iIfcIdx = i;
  1.1884 +	}
  1.1885 +
  1.1886 +
  1.1887 +//
  1.1888 +// Insert an Endpoint descriptor into the descriptor array at the appropriate index.
  1.1889 +//
  1.1890 +void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc)
  1.1891 +	{
  1.1892 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertEpDesc()"));
  1.1893 +	if (iIfcIdx == 0)
  1.1894 +		{
  1.1895 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: only after interface "
  1.1896 +										  "(TUsbcDescriptorPool::InsertEpDesc)"));
  1.1897 +		return;
  1.1898 +		}
  1.1899 +	const TInt count = iDescriptors.Count();
  1.1900 +	TInt i = iIfcIdx + 1;
  1.1901 +	while (i < count)
  1.1902 +		{
  1.1903 +		if (iDescriptors[i]->Type() != KUsbDescType_Endpoint)
  1.1904 +			break;
  1.1905 +		++i;
  1.1906 +		}
  1.1907 +	// put the new descriptor at position i
  1.1908 +	iDescriptors.Insert(aDesc, i);
  1.1909 +	// update the config descriptor's wTotalLength field
  1.1910 +	UpdateConfigDescriptorLength(aDesc->Size());
  1.1911 +	}
  1.1912 +
  1.1913 +
  1.1914 +//
  1.1915 +// Find the index of the Interface descriptor for a given interface setting.
  1.1916 +//
  1.1917 +TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const
  1.1918 +	{
  1.1919 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)",
  1.1920 +									aIfcNumber, aIfcSetting));
  1.1921 +	const TInt count = iDescriptors.Count();
  1.1922 +	for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
  1.1923 +		{
  1.1924 +		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
  1.1925 +			(iDescriptors[i]->Byte(2) == aIfcNumber) &&
  1.1926 +			(iDescriptors[i]->Byte(3) == aIfcSetting))
  1.1927 +			{
  1.1928 +			return i;
  1.1929 +			}
  1.1930 +		}
  1.1931 +	__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1932 +	return -1;
  1.1933 +	}
  1.1934 +
  1.1935 +
  1.1936 +//
  1.1937 +// Find the index of the Endpoint descriptor for a given endpoint on a given interface setting.
  1.1938 +//
  1.1939 +TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const
  1.1940 +	{
  1.1941 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)",
  1.1942 +									aIfcNumber, aIfcSetting, aEpAddress));
  1.1943 +	// first find the interface
  1.1944 +	const TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting);
  1.1945 +	if (ifc < 0)
  1.1946 +		{
  1.1947 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such interface"));
  1.1948 +		return ifc;
  1.1949 +		}
  1.1950 +	const TInt count = iDescriptors.Count();
  1.1951 +	// then, before the next interface, try to locate the endpoint
  1.1952 +	for (TInt i = ifc + 1; i < count; i++)
  1.1953 +		{
  1.1954 +		if (iDescriptors[i]->Type() == KUsbDescType_Interface)
  1.1955 +			{
  1.1956 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint before next interface"));
  1.1957 +			return -1;
  1.1958 +			}
  1.1959 +		else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) &&
  1.1960 +				 (iDescriptors[i]->Byte(2) == aEpAddress))
  1.1961 +			{
  1.1962 +			// found
  1.1963 +			return i;
  1.1964 +			}
  1.1965 +		}
  1.1966 +	__KTRACE_OPT(KPANIC, Kern::Printf("  Error: no such endpoint"));
  1.1967 +	return -1;
  1.1968 +	}
  1.1969 +
  1.1970 +
  1.1971 +//
  1.1972 +// Delete n descriptors starting from aIndex and remove their pointers from the array.
  1.1973 +//
  1.1974 +void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount)
  1.1975 +	{
  1.1976 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteDescriptors()"));
  1.1977 +	if (aIndex < KDescPosition_FirstAvailable)
  1.1978 +		{
  1.1979 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: aIndex < KDescPosition_FirstAvailable"));
  1.1980 +		return;
  1.1981 +		}
  1.1982 +	if (aCount <= 0)
  1.1983 +		{
  1.1984 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: aCount <= 0"));
  1.1985 +		return;
  1.1986 +		}
  1.1987 +	__KTRACE_OPT(KUSB, Kern::Printf("  Removing descriptors at index %d:", aIndex));
  1.1988 +	// Try to update wTotalLength field in Config descriptor
  1.1989 +	while (aCount--)
  1.1990 +		{
  1.1991 +		// In this loop we don't decrement aIndex, because after deleting an element
  1.1992 +		// aIndex is already indexing the next one.
  1.1993 +		TUsbcDescriptorBase* const ptr = iDescriptors[aIndex];
  1.1994 +		switch (ptr->Type())
  1.1995 +			{
  1.1996 +		case KUsbDescType_Interface:
  1.1997 +			__KTRACE_OPT(KUSB, Kern::Printf("  - an interface descriptor"));
  1.1998 +			UpdateConfigDescriptorLength(-KUsbDescSize_Interface);
  1.1999 +			break;
  1.2000 +		case KUsbDescType_Endpoint:
  1.2001 +			__KTRACE_OPT(KUSB, Kern::Printf("  - an endpoint descriptor"));
  1.2002 +			UpdateConfigDescriptorLength(-ptr->Size());
  1.2003 +			break;
  1.2004 +		case KUsbDescType_CS_Interface:
  1.2005 +			/* fall through */
  1.2006 +		case KUsbDescType_CS_Endpoint:
  1.2007 +			__KTRACE_OPT(KUSB, Kern::Printf("  - a class specific descriptor"));
  1.2008 +			UpdateConfigDescriptorLength(-ptr->Size());
  1.2009 +			break;
  1.2010 +		default:
  1.2011 +			__KTRACE_OPT(KUSB, Kern::Printf("  - an unknown descriptor"));
  1.2012 +			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: unknown descriptor type"));
  1.2013 +			}
  1.2014 +		iDescriptors.Remove(aIndex);
  1.2015 +		delete ptr;
  1.2016 +		}
  1.2017 +	}
  1.2018 +
  1.2019 +
  1.2020 +//
  1.2021 +// Update the wTotalLength field in the Configuration descriptor (aLength can be negative).
  1.2022 +//
  1.2023 +void TUsbcDescriptorPool::UpdateConfigDescriptorLength(TInt aLength)
  1.2024 +	{
  1.2025 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorLength(%d)", aLength));
  1.2026 +	TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config];
  1.2027 +	__KTRACE_OPT(KUSB, Kern::Printf("  wTotalLength old: %d", cnf->Word(2)));
  1.2028 +	// Update Config descriptor
  1.2029 +	cnf->SetWord(2, cnf->Word(2) + aLength);
  1.2030 +	__KTRACE_OPT(KUSB, Kern::Printf("  wTotalLength new: %d", cnf->Word(2)));
  1.2031 +	// Update Other_Speed_Config descriptor as well, if applicable
  1.2032 +	if (iDescriptors[KDescPosition_OtherSpeedConfig])
  1.2033 +		iDescriptors[KDescPosition_OtherSpeedConfig]->SetWord(2, cnf->Word(2));
  1.2034 +	}
  1.2035 +
  1.2036 +
  1.2037 +//
  1.2038 +// Update the bNumInterfaces field in the Configuration descriptor (aNumber can be negative).
  1.2039 +//
  1.2040 +void TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(TInt aNumber)
  1.2041 +	{
  1.2042 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(%d)", aNumber));
  1.2043 +	TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config];
  1.2044 +	__KTRACE_OPT(KUSB, Kern::Printf("  bNumInterfaces old: %d", cnf->Byte(4)));
  1.2045 +	const TInt n = cnf->Byte(4) + aNumber;
  1.2046 +	if (n < 0)
  1.2047 +		{
  1.2048 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bNumInterfaces + aNumber < 0"));
  1.2049 +		return;
  1.2050 +		}
  1.2051 +	// Update Config descriptor
  1.2052 +	cnf->SetByte(4, n);
  1.2053 +	__KTRACE_OPT(KUSB, Kern::Printf("  bNumInterfaces new: %d", cnf->Byte(4)));
  1.2054 +	// Update Other_Speed_Config descriptor as well, if applicable
  1.2055 +	if (iDescriptors[KDescPosition_OtherSpeedConfig])
  1.2056 +		iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(4, n);
  1.2057 +	}
  1.2058 +
  1.2059 +
  1.2060 +//
  1.2061 +// Update the bNumInterfaces field in the Configuration descriptor if necessary.
  1.2062 +//
  1.2063 +void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber)
  1.2064 +	{
  1.2065 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateIfcNumbers(%d)", aNumber));
  1.2066 +	const TInt count = iDescriptors.Count();
  1.2067 +	for (TInt i = KDescPosition_FirstAvailable; i < count; i++)
  1.2068 +		{
  1.2069 +		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
  1.2070 +			(iDescriptors[i]->Byte(2) == aNumber))
  1.2071 +			{
  1.2072 +			// there's still an interface with 'number' so we don't need to update anything
  1.2073 +			return;
  1.2074 +			}
  1.2075 +		}
  1.2076 +	// if we haven't returned yet, we decrement bNumInterfaces
  1.2077 +	UpdateConfigDescriptorNumIfcs(-1);
  1.2078 +	}
  1.2079 +
  1.2080 +
  1.2081 +//
  1.2082 +// Put the current Device or Device_Qualifier descriptor in the Ep0 Tx buffer.
  1.2083 +// Only used for Ep0 standard requests, so target buffer can be hard-wired.
  1.2084 +//
  1.2085 +TInt TUsbcDescriptorPool::GetDeviceDescriptor(TInt aIndex) const
  1.2086 +	{
  1.2087 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptor()"));
  1.2088 +	__ASSERT_DEBUG((aIndex == KDescPosition_Device) || (aIndex == KDescPosition_DeviceQualifier),
  1.2089 +				   Kern::Printf("  Error: invalid descriptor index: %d", aIndex));
  1.2090 +	if (iDescriptors[aIndex] == NULL)
  1.2091 +		{
  1.2092 +		// This doesn't have to be an error - we might get asked here for the Device_Qualifier descriptor
  1.2093 +		// on a FS-only device.
  1.2094 +		__KTRACE_OPT(KUSB, Kern::Printf("  Descriptor #%d requested but not available", aIndex));
  1.2095 +		return 0;
  1.2096 +		}
  1.2097 +	return iDescriptors[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
  1.2098 +	}
  1.2099 +
  1.2100 +
  1.2101 +//
  1.2102 +// Put the current Configuration or Other_Speed_Configuration descriptor + all the following
  1.2103 +// descriptors in the Ep0 Tx buffer.
  1.2104 +// Only used for Ep0 standard requests, so target buffer can be hard-wired.
  1.2105 +//
  1.2106 +TInt TUsbcDescriptorPool::GetConfigurationDescriptor(TInt aIndex) const
  1.2107 +	{
  1.2108 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigDescriptor(%d)", aIndex));
  1.2109 +	__ASSERT_DEBUG((aIndex == KDescPosition_Config) || (aIndex == KDescPosition_OtherSpeedConfig),
  1.2110 +				   Kern::Printf("  Error: invalid descriptor index: %d", aIndex));
  1.2111 +	if (iDescriptors[aIndex] == NULL)
  1.2112 +		{
  1.2113 +		// This is always an error: We should always have a Configuration descriptor and we should never
  1.2114 +		// get asked for the Other_Speed_Configuration descriptor if we don't have one (9.6.2).
  1.2115 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Descriptor %d requested but not available", aIndex));
  1.2116 +		return 0;
  1.2117 +		}
  1.2118 +	const TInt count = iDescriptors.Count();
  1.2119 +	TInt copied = 0;
  1.2120 +	TUint8* buf = iEp0_TxBuf;
  1.2121 +	for (TInt i = aIndex; i < count; i++)
  1.2122 +		{
  1.2123 +		TUsbcDescriptorBase* const ptr = iDescriptors[i];
  1.2124 +		if ((aIndex == KDescPosition_OtherSpeedConfig) && (i == KDescPosition_Config))
  1.2125 +			{
  1.2126 +			// Skip Config descriptor when returning Other_Speed_Config
  1.2127 +			continue;
  1.2128 +			}
  1.2129 +		if ((i == KDescPosition_Otg) && (iDescriptors[i] == NULL))
  1.2130 +			{
  1.2131 +			__KTRACE_OPT(KUSB, Kern::Printf("  no OTG descriptor -> next"));
  1.2132 +			continue;
  1.2133 +			}
  1.2134 +		// We need to edit endpoint descriptors on the fly because we have only one copy
  1.2135 +		// of each and that copy has to contain different information, depending on the
  1.2136 +		// current speed and the type of descriptor requested.
  1.2137 +		if (ptr->Type() == KUsbDescType_Endpoint)
  1.2138 +			{
  1.2139 +			if ((iHighSpeed && (aIndex == KDescPosition_Config)) ||
  1.2140 +				(!iHighSpeed && (aIndex == KDescPosition_OtherSpeedConfig)))
  1.2141 +				{
  1.2142 +				ptr->UpdateHs();
  1.2143 +				}
  1.2144 +			else
  1.2145 +				{
  1.2146 +				ptr->UpdateFs();
  1.2147 +				}
  1.2148 +			}
  1.2149 +		__KTRACE_OPT(KUSB, Kern::Printf("  desc[%02d]: type = 0x%02x size = %d ",
  1.2150 +										i, ptr->Type(), ptr->Size()));
  1.2151 +		const TInt size = ptr->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied);
  1.2152 +		if (size == 0)
  1.2153 +			{
  1.2154 +			__KTRACE_OPT(KPANIC,
  1.2155 +						 Kern::Printf("  Error: No Tx buffer space to copy this descriptor -> exiting"));
  1.2156 +			break;
  1.2157 +			}
  1.2158 +		copied += size;
  1.2159 +		if (copied >= KUsbcBufSz_Ep0Tx)
  1.2160 +			{
  1.2161 +			__KTRACE_OPT(KPANIC,
  1.2162 +						 Kern::Printf("  Error: No Tx buffer space left -> stopping here"));
  1.2163 +			break;
  1.2164 +			}
  1.2165 +		buf += size;
  1.2166 +		}
  1.2167 +	__KTRACE_OPT(KUSB, Kern::Printf("  copied %d bytes", copied));
  1.2168 +	return copied;
  1.2169 +	}
  1.2170 +
  1.2171 +
  1.2172 +//
  1.2173 +// Put the current OTG descriptor in the Ep0 Tx buffer.
  1.2174 +// Only used for Ep0 standard requests, so target buffer can be hard-wired.
  1.2175 +//
  1.2176 +TInt TUsbcDescriptorPool::GetOtgDescriptor() const
  1.2177 +	{
  1.2178 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtgDescriptor()"));
  1.2179 +	if (iDescriptors[KDescPosition_Otg] == NULL)
  1.2180 +		{
  1.2181 +		__KTRACE_OPT(KUSB, Kern::Printf("  OTG Descriptor not set"));
  1.2182 +		return 0;
  1.2183 +		}
  1.2184 +	return iDescriptors[KDescPosition_Otg]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
  1.2185 +	}
  1.2186 +
  1.2187 +
  1.2188 +//
  1.2189 +// Put a specific String descriptor in the Ep0 Tx buffer.
  1.2190 +// Only used for Ep0 standard requests, so target buffer can be hard-wired.
  1.2191 +//
  1.2192 +TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const
  1.2193 +	{
  1.2194 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptor(%d)", aIndex));
  1.2195 +	// I really would have liked to display the descriptor contents here, but without trailing zero
  1.2196 +	// we got a problem: how can we tell printf where the string ends? We would have to
  1.2197 +	// dynamically allocate memory (since we don't know the size in advance), copy the descriptor
  1.2198 +	// contents there, append a zero, and give this to printf. That's a bit too much effort...
  1.2199 +	if (!StringDescriptorExists(aIndex))
  1.2200 +		{
  1.2201 +		return 0;
  1.2202 +		}
  1.2203 +	return iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
  1.2204 +	}
  1.2205 +
  1.2206 +
  1.2207 +//
  1.2208 +// Write a String descriptor pointed to by the Device descriptor to the user side
  1.2209 +// (one of Manufacturer, Product, SerialNumber).
  1.2210 +//
  1.2211 +TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString,
  1.2212 +													  TInt aIndex, TInt aPosition) const
  1.2213 +	{
  1.2214 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceStringDescriptorTC()"));
  1.2215 +	const TInt str_idx = iDescriptors[KDescPosition_Device]->Byte(aIndex);
  1.2216 +	if (str_idx)
  1.2217 +		{
  1.2218 +		__ASSERT_ALWAYS((str_idx == aPosition), Kern::Fault(KUsbPanicCat, __LINE__));
  1.2219 +		__KTRACE_OPT(KUSB, Kern::Printf("  String @ pos %d (device $): \"%S\"",
  1.2220 +										str_idx, &iStrings[str_idx]->StringData()));
  1.2221 +		return Kern::ThreadDesWrite(aThread, &aString,
  1.2222 +									iStrings[str_idx]->StringData(), 0);
  1.2223 +		}
  1.2224 +	else
  1.2225 +		{
  1.2226 +		__KTRACE_OPT(KUSB, Kern::Printf("  No string descriptor @ pos %d", aIndex));
  1.2227 +		return KErrNotFound;
  1.2228 +		}
  1.2229 +	}
  1.2230 +
  1.2231 +
  1.2232 +//
  1.2233 +// Read a Device String descriptor from the user side and put in the descriptor arrays
  1.2234 +// (one of Manufacturer, Product, SerialNumber).
  1.2235 +//
  1.2236 +TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString,
  1.2237 +													  TInt aIndex, TInt aPosition)
  1.2238 +	{
  1.2239 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceStringDescriptorTC()"));
  1.2240 +	// we don't know the length of the string, so we have to allocate memory dynamically
  1.2241 +	TUint strlen = Kern::ThreadGetDesLength(aThread, &aString);
  1.2242 +	if (strlen > KUsbStringDescStringMaxSize)
  1.2243 +		{
  1.2244 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Warning: $ descriptor too long - will be truncated"));
  1.2245 +		strlen = KUsbStringDescStringMaxSize;
  1.2246 +		}
  1.2247 +	HBuf8* const strbuf = HBuf8::New(strlen);
  1.2248 +	if (!strbuf)
  1.2249 +		{
  1.2250 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for dev $ desc string failed (1)"));
  1.2251 +		return KErrNoMemory;
  1.2252 +		}
  1.2253 +	strbuf->SetMax();
  1.2254 +	// the aString points to data that lives in user memory, so we have to copy it:
  1.2255 +	const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0);
  1.2256 +	if (r != KErrNone)
  1.2257 +		{
  1.2258 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
  1.2259 +		delete strbuf;
  1.2260 +		return r;
  1.2261 +		}
  1.2262 +	TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf);
  1.2263 +	if (!sd)
  1.2264 +		{
  1.2265 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for dev $ desc failed (2)"));
  1.2266 +		delete strbuf;
  1.2267 +		return KErrNoMemory;
  1.2268 +		}
  1.2269 +	ExchangeStringDescriptor(aPosition, sd);
  1.2270 +	iDescriptors[KDescPosition_Device]->SetByte(aIndex, aPosition);
  1.2271 +	delete strbuf;
  1.2272 +	return r;
  1.2273 +	}
  1.2274 +
  1.2275 +
  1.2276 +//
  1.2277 +// Remove a Device String descriptor from the descriptor arrays
  1.2278 +// (one of Manufacturer, Product, SerialNumber).
  1.2279 +//
  1.2280 +TInt TUsbcDescriptorPool::RemoveDeviceStringDescriptor(TInt aIndex, TInt aPosition)
  1.2281 +	{
  1.2282 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveDeviceStringDescriptor()"));
  1.2283 +	if (iDescriptors[KDescPosition_Device]->Byte(aIndex) == 0)
  1.2284 +		{
  1.2285 +		__KTRACE_OPT(KUSB, Kern::Printf("  RemoveDeviceStringDescriptor: no $ desc @ index %d", aIndex));
  1.2286 +		return KErrNotFound;
  1.2287 +		}
  1.2288 +	ExchangeStringDescriptor(aPosition, NULL);
  1.2289 +	iDescriptors[KDescPosition_Device]->SetByte(aIndex, 0);
  1.2290 +	return KErrNone;
  1.2291 +	}
  1.2292 +
  1.2293 +
  1.2294 +//
  1.2295 +// Puts aDesc at postion aIndex in the string descriptor array, after deleting what was (possibly) there.
  1.2296 +//
  1.2297 +void TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc)
  1.2298 +	{
  1.2299 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::ExchangeStringDescriptor()"));
  1.2300 +	TUsbcStringDescriptorBase* const ptr = iStrings[aIndex];
  1.2301 +	__KTRACE_OPT(KUSB, Kern::Printf("  Deleting string descriptor at index %d: 0x%x", aIndex, ptr));
  1.2302 +	iStrings.Remove(aIndex);
  1.2303 +	delete ptr;
  1.2304 +	__KTRACE_OPT(KUSB, Kern::Printf("  Inserting string descriptor at index %d: 0x%x", aIndex, aDesc));
  1.2305 +	iStrings.Insert(aDesc, aIndex);
  1.2306 +	}
  1.2307 +
  1.2308 +
  1.2309 +//
  1.2310 +// Checks whether there are any string descriptors in the array (apart from LangID).
  1.2311 +//
  1.2312 +TBool TUsbcDescriptorPool::AnyStringDescriptors() const
  1.2313 +	{
  1.2314 +	const TInt n = iStrings.Count();
  1.2315 +	for (TInt i = 1; i < n; i++)
  1.2316 +		{
  1.2317 +		if (iStrings[i] != NULL)
  1.2318 +			return ETrue;
  1.2319 +		}
  1.2320 +	return EFalse;
  1.2321 +	}
  1.2322 +
  1.2323 +
  1.2324 +//
  1.2325 +// Returns true if aIndex exists and what is at that positition is not a NULL pointer.
  1.2326 +//
  1.2327 +TBool TUsbcDescriptorPool::StringDescriptorExists(TInt aIndex) const
  1.2328 +	{
  1.2329 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::StringDescriptorExists()"));
  1.2330 +	if (aIndex >= iStrings.Count())
  1.2331 +		{
  1.2332 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad string index: %d", aIndex));
  1.2333 +		return EFalse;
  1.2334 +		}
  1.2335 +	else if (iStrings[aIndex] == NULL)
  1.2336 +		{
  1.2337 +		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: No $ descriptor @ pos %d", aIndex));
  1.2338 +		return EFalse;
  1.2339 +		}
  1.2340 +	return ETrue;
  1.2341 +	}
  1.2342 +
  1.2343 +
  1.2344 +//
  1.2345 +//
  1.2346 +//
  1.2347 +TInt TUsbcDescriptorPool::FindAvailableStringPos() const
  1.2348 +	{
  1.2349 +	__KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindAvailableStringPos()"));
  1.2350 +	const TInt n = iStrings.Count();
  1.2351 +	// We don't start from 0 because the first few locations are 'reserved'.
  1.2352 +	for (TInt i = KStringPosition_FirstAvailable; i < n; i++)
  1.2353 +		{
  1.2354 +		if (iStrings[i] == NULL)
  1.2355 +			{
  1.2356 +			__KTRACE_OPT(KUSB, Kern::Printf(" Found available NULL position: %d", i));
  1.2357 +			return i;
  1.2358 +			}
  1.2359 +		}
  1.2360 +	return -1;
  1.2361 +	}
  1.2362 +
  1.2363 +
  1.2364 +// -eof-