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-