diff -r f92a4f87e424 -r 012cc2ee6408 usbdrv/peripheral/pdd/pil/src/descriptors.cpp --- a/usbdrv/peripheral/pdd/pil/src/descriptors.cpp Tue Aug 31 17:01:47 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2362 +0,0 @@ -// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// e32/drivers/usbcc/descriptors.cpp -// Platform independent layer (PIL) of the USB Device controller driver: -// USB descriptor handling and management. -// -// - -/** - @file descriptors.cpp - @internalTechnology -*/ - -#include -// #include -#include - - -// Debug Support -static const char KUsbPanicCat[] = "USB PIL"; - - -// --- TUsbcDescriptorBase - -TUsbcDescriptorBase::TUsbcDescriptorBase() - : -#ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST - iIndex(0), -#endif - iBufPtr(NULL, 0) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::TUsbcDescriptorBase()")); - } - - -TUsbcDescriptorBase::~TUsbcDescriptorBase() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorBase::~TUsbcDescriptorBase()")); - } - - -void TUsbcDescriptorBase::SetByte(TInt aPosition, TUint8 aValue) - { - iBufPtr[aPosition] = aValue; - } - - -void TUsbcDescriptorBase::SetWord(TInt aPosition, TUint16 aValue) - { - *reinterpret_cast(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue); - } - - -TUint8 TUsbcDescriptorBase::Byte(TInt aPosition) const - { - return iBufPtr[aPosition]; - } - - -TUint16 TUsbcDescriptorBase::Word(TInt aPosition) const - { - return SWAP_BYTES_16(*reinterpret_cast(&iBufPtr[aPosition])); - } - - -void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const - { - aBuffer = iBufPtr; - } - - -TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const - { - memcpy(aBuffer, iBufPtr.Ptr(), Size()); - return Size(); - } - - -TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const - { - if (aMaxSize < Size()) - { - // No use to copy only half a descriptor - return 0; - } - return GetDescriptorData(aBuffer); - } - - -const TDes8& TUsbcDescriptorBase::DescriptorData() const - { - return iBufPtr; - } - - -TDes8& TUsbcDescriptorBase::DescriptorData() - { - return iBufPtr; - } - - -TUint TUsbcDescriptorBase::Size() const - { - return iBufPtr.Size(); - } - - -TUint8 TUsbcDescriptorBase::Type() const - { - return iBufPtr[1]; - } - - -void TUsbcDescriptorBase::UpdateFs() - { - // virtual function can be overridden in derived classes. - return; - } - - -void TUsbcDescriptorBase::UpdateHs() - { - // virtual function can be overridden in derived classes. - return; - } - - -void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes) - { - iBufPtr.Set(const_cast(aDes.Ptr()), aDes.Size(), aDes.Size()); - } - - -// --- TUsbcDeviceDescriptor - -TUsbcDeviceDescriptor::TUsbcDeviceDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()")); - } - - -TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass, - TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0, - TUint16 aVendorId, TUint16 aProductId, - TUint16 aDeviceRelease, TUint8 aNumConfigurations) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::New()")); - TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor(); - if (self) - { - if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId, - aProductId, aDeviceRelease, aNumConfigurations) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol, - TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId, - TUint16 aDeviceRelease, TUint8 aNumConfigurations) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::Construct()")); - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_Device; // bDescriptorType - SetWord(2, KUsbcUsbVersion); // bcdUSB - iBuf[4] = aDeviceClass; // bDeviceClass - iBuf[5] = aDeviceSubClass; // bDeviceSubClass - iBuf[6] = aDeviceProtocol; // bDeviceProtocol - iBuf[7] = aMaxPacketSize0; // bMaxPacketSize0 - SetWord(8, aVendorId); // idVendor - SetWord(10, aProductId); // idProduct - SetWord(12, aDeviceRelease); // bcdDevice - iBuf[14] = 0; // iManufacturer - iBuf[15] = 0; // iProduct - iBuf[16] = 0; // iSerialNumber - iBuf[17] = aNumConfigurations; // bNumConfigurations - iEp0Size_Fs = aMaxPacketSize0; - return KErrNone; - } - - -void TUsbcDeviceDescriptor::UpdateFs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateFs()")); - SetByte(7, iEp0Size_Fs); // bMaxPacketSize0 - } - - -void TUsbcDeviceDescriptor::UpdateHs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::UpdateHs()")); - SetByte(7, 64); // bMaxPacketSize0 - } - - -// --- TUsbcDeviceQualifierDescriptor - -TUsbcDeviceQualifierDescriptor::TUsbcDeviceQualifierDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceDescriptor::TUsbcDeviceQualifierDescriptor()")); - } - - -TUsbcDeviceQualifierDescriptor* TUsbcDeviceQualifierDescriptor::New(TUint8 aDeviceClass, - TUint8 aDeviceSubClass, - TUint8 aDeviceProtocol, - TUint8 aMaxPacketSize0, - TUint8 aNumConfigurations, - TUint8 aReserved) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::New()")); - TUsbcDeviceQualifierDescriptor* self = new TUsbcDeviceQualifierDescriptor(); - if (self) - { - if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, - aNumConfigurations, aReserved) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcDeviceQualifierDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, - TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0, - TUint8 aNumConfigurations, TUint8 aReserved) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::Construct()")); - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_DeviceQualifier; // bDescriptorType - SetWord(2, KUsbcUsbVersion); // bcdUSB - iBuf[4] = aDeviceClass; // bDeviceClass - iBuf[5] = aDeviceSubClass; // bDeviceSubClass - iBuf[6] = aDeviceProtocol; // bDeviceProtocol - iBuf[7] = aMaxPacketSize0; // bMaxPacketSize0 - iBuf[8] = aNumConfigurations; // bNumConfigurations - if (aReserved) aReserved = 0; - iBuf[9] = aReserved; // Reserved for future use, must be zero - iEp0Size_Fs = aMaxPacketSize0; - return KErrNone; - } - - -void TUsbcDeviceQualifierDescriptor::UpdateFs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateFs()")); - // Here we do exactly the opposite of what's done in the Device descriptor (as this one's - // documenting the 'other than the current speed'). - SetByte(7, 64); // bMaxPacketSize0 - } - - -void TUsbcDeviceQualifierDescriptor::UpdateHs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDeviceQualifierDescriptor::UpdateHs()")); - // Here we do exactly the opposite of what's done in the Device descriptor (as this one's - // documenting the 'other than the current speed'). - SetByte(7, iEp0Size_Fs); // bMaxPacketSize0 - } - - -// --- TUsbcConfigDescriptor - -TUsbcConfigDescriptor::TUsbcConfigDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::TUsbcConfigDescriptor()")); - } - - -TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered, - TBool aRemoteWakeup, TUint16 aMaxPower) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::New()")); - TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor(); - if (self) - { - if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered, - TBool aRemoteWakeup, TUint16 aMaxPower) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfigDescriptor::Construct()")); - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_Config; // bDescriptorType - SetWord(2, KUsbDescSize_Config); // wTotalLength - iBuf[4] = 0; // bNumInterfaces - iBuf[5] = aConfigurationValue; // bConfigurationValue - iBuf[6] = 0; // iConfiguration - iBuf[7] = 0x80 | - (aSelfPowered ? KUsbDevAttr_SelfPowered : 0) | - (aRemoteWakeup ? KUsbDevAttr_RemoteWakeup : 0); // bmAttributes (bit 7 always 1) - if (aMaxPower > 510) - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Invalid value for bMaxPower: %d", aMaxPower)); - iBuf[8] = aMaxPower / 2; // bMaxPower (2mA units!) - return KErrNone; - } - - -// --- TUsbcInterfaceDescriptor - -TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()")); - } - - -TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting, - TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::New()")); - TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor(); - if (self) - { - if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting, - TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceDescriptor::Construct()")); - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_Interface; // bDescriptorType - iBuf[2] = aInterfaceNumber; // bInterfaceNumber - iBuf[3] = aAlternateSetting; // bAlternateSetting - iBuf[4] = aNumEndpoints; // bNumEndpoints - iBuf[5] = aClassInfo.iClassNum; // bInterfaceClass - iBuf[6] = aClassInfo.iSubClassNum; // bInterfaceSubClass - iBuf[7] = aClassInfo.iProtocolNum; // bInterfaceProtocol - iBuf[8] = 0; // iInterface - return KErrNone; - } - - -// --- TUsbcEndpointDescriptorBase - -TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::TUsbcEndpointDescriptorBase()")); - } - - -TInt TUsbcEndpointDescriptorBase::Construct(const TUsbcEndpointInfo& aEpInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::Construct()")); - // Adjust FS/HS endpoint sizes - if (aEpInfo.AdjustEpSizes(iEpSize_Fs, iEpSize_Hs) != KErrNone) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Unknown endpoint type: %d", aEpInfo.iType)); - } - __KTRACE_OPT(KUSB, Kern::Printf(" Now set: iEpSize_Fs=%d iEpSize_Hs=%d (aEpInfo.iSize=%d)", - iEpSize_Fs, iEpSize_Hs, aEpInfo.iSize)); - - // Adjust HS endpoint size for additional transactions - if ((aEpInfo.iType == UsbShai::KUsbEpTypeIsochronous) || (aEpInfo.iType == UsbShai::KUsbEpTypeInterrupt)) - { - if ((aEpInfo.iTransactions > 0) && (aEpInfo.iTransactions < 3)) - { - // Bits 12..11 specify the number of additional transactions per microframe - iEpSize_Hs |= (aEpInfo.iTransactions << 12); - __KTRACE_OPT(KUSB, Kern::Printf(" Adjusted for add. transact.: iEpSize_Hs=0x%02x " - "(aEpInfo.iTransactions=%d)", - iEpSize_Hs, aEpInfo.iTransactions)); - } - else if (aEpInfo.iTransactions != 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Invalid iTransactions value: %d (ignored)", - aEpInfo.iTransactions)); - } - } - - // Adjust HS polling interval - TUsbcEndpointInfo info(aEpInfo); // create local writeable copy - if (info.AdjustPollInterval() != KErrNone) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Unknown ep type (%d) or invalid interval value (%d)", - info.iType, info.iInterval)); - } - iInterval_Fs = info.iInterval; - iInterval_Hs = info.iInterval_Hs; - __KTRACE_OPT(KUSB, Kern::Printf(" Now set: iInterval_Fs=%d iInterval_Hs=%d", - iInterval_Fs, iInterval_Hs)); - return KErrNone; - } - - -void TUsbcEndpointDescriptorBase::UpdateFs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateFs()")); - // (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values got - // adjusted in its Construct() method.) - SetWord(4, iEpSize_Fs); // wMaxPacketSize - SetByte(6, iInterval_Fs); // bInterval - } - - -void TUsbcEndpointDescriptorBase::UpdateHs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptorBase::UpdateHs()")); - // (TUsbcEndpointDescriptorBase's FS/HS endpoint sizes and interval values get - // adjusted in its Construct() method.) - SetWord(4, iEpSize_Hs); // wMaxPacketSize - SetByte(6, iInterval_Hs); // bInterval - } - - -// --- TUsbcEndpointDescriptor - -TUsbcEndpointDescriptor::TUsbcEndpointDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()")); - } - - -TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress, - const TUsbcEndpointInfo& aEpInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::New()")); - TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor(); - if (self) - { - if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpointDescriptor::Construct()")); - (void) TUsbcEndpointDescriptorBase::Construct(aEpInfo); // Init Base class - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType - iBuf[2] = aEndpointAddress; // bEndpointAddress - iBuf[3] = EpTypeMask2Value(aEpInfo.iType); // bmAttributes - SetWord(4, iEpSize_Fs); // wMaxPacketSize (default is FS) - iBuf[6] = iInterval_Fs; // bInterval (default is FS) - return KErrNone; - } - - -// --- TUsbcAudioEndpointDescriptor - -TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()")); - } - - -TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress, - const TUsbcEndpointInfo& aEpInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::New()")); - TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor(); - if (self) - { - if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAudioEndpointDescriptor::Construct()")); - (void) TUsbcEndpointDescriptorBase::Construct(aEpInfo); // Init Base class - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType - iBuf[2] = aEndpointAddress; // bEndpointAddress - iBuf[3] = EpTypeMask2Value(aEpInfo.iType); // bmAttributes - SetWord(4, iEpSize_Fs); // wMaxPacketSize (default is FS) - iBuf[6] = iInterval_Fs; // bInterval (default is FS) - iBuf[7] = 0; - iBuf[8] = 0; - return KErrNone; - } - - -// --- TUsbcOtgDescriptor - -TUsbcOtgDescriptor* TUsbcOtgDescriptor::New(TBool aHnpSupport, TBool aSrpSupport) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::New()")); - TUsbcOtgDescriptor* self = new TUsbcOtgDescriptor(); - if (self && (self->Construct(aHnpSupport, aSrpSupport) != KErrNone)) - { - delete self; - return NULL; - } - return self; - } - - -TUsbcOtgDescriptor::TUsbcOtgDescriptor() - : iBuf() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::TUsbcOtgDescriptor()")); - } - - -TInt TUsbcOtgDescriptor::Construct(TBool aHnpSupport, TBool aSrpSupport) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcOtgDescriptor::Construct()")); - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBuf[0] = iBuf.Size(); // bLength - iBuf[1] = KUsbDescType_Otg; // bDescriptorType - iBuf[2] = (aHnpSupport ? KUsbOtgAttr_HnpSupp : 0) | - (aSrpSupport ? KUsbOtgAttr_SrpSupp : 0); // bmAttributes - return KErrNone; - } - - -// --- TUsbcClassSpecificDescriptor - -TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor() - : iBuf(NULL) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()")); - } - - -TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()")); - delete iBuf; - } - - -TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::New()")); - TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor(); - if (self) - { - if (self->Construct(aType, aSize) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcClassSpecificDescriptor::Construct()")); - iBuf = HBuf8::New(aSize); - if (!iBuf) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Allocation of CS desc buffer failed")); - return KErrNoMemory; - } - iBuf->SetMax(); - SetBufferPointer(*iBuf); - SetByte(1, aType); // bDescriptorType - return KErrNone; - } - - -// --- TUsbcStringDescriptorBase - -TUsbcStringDescriptorBase::TUsbcStringDescriptorBase() - : /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()")); - } - - -TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()")); - } - - -TUint16 TUsbcStringDescriptorBase::Word(TInt aPosition) const - { - if (aPosition <= 1) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Word(%d) in string descriptor " - "(TUsbcStringDescriptorBase::Word)", aPosition)); - return 0; - } - else - { - // since iBufPtr[0] is actually string descriptor byte index 2, - // we have to subtract 2 from the absolute position. - return SWAP_BYTES_16(*reinterpret_cast(&iBufPtr[aPosition - 2])); - } - } - - -void TUsbcStringDescriptorBase::SetWord(TInt aPosition, TUint16 aValue) - { - if (aPosition <= 1) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetWord(%d) in string descriptor " - "(TUsbcStringDescriptorBase::SetWord)", aPosition)); - return; - } - else - { - // since iBufPtr[0] is actually string descriptor byte index 2, - // we have to subtract 2 from the absolute position. - *reinterpret_cast(&iBufPtr[aPosition - 2]) = SWAP_BYTES_16(aValue); - } - } - - -TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const - { - aBuffer[0] = iSBuf[0]; - aBuffer[1] = iSBuf[1]; - memcpy(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size()); - return Size(); - } - - -TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const - { - if (aMaxSize < Size()) - { - // No use to copy only half a string - return 0; - } - return GetDescriptorData(aBuffer); - } - - -const TDes8& TUsbcStringDescriptorBase::StringData() const - { - return iBufPtr; - } - - -TDes8& TUsbcStringDescriptorBase::StringData() - { - return iBufPtr; - } - - -TUint TUsbcStringDescriptorBase::Size() const - { - return iSBuf[0]; - } - - -void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes) - { - iBufPtr.Set(const_cast(aDes.Ptr()), aDes.Size(), aDes.Size()); - } - - -// --- TUsbcStringDescriptor - -TUsbcStringDescriptor::TUsbcStringDescriptor() - : iBuf(NULL) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::TUsbcStringDescriptor()")); - } - - -TUsbcStringDescriptor::~TUsbcStringDescriptor() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::~TUsbcStringDescriptor()")); - delete iBuf; - } - - -TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::New")); - TUsbcStringDescriptor* self = new TUsbcStringDescriptor(); - if (self) - { - if (self->Construct(aString) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcStringDescriptor::Construct(const TDesC8& aString) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcStringDescriptor::Construct")); - iBuf = HBuf8::New(aString.Size()); // bytes, not UNICODE chars - if (!iBuf) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Allocation of string buffer failed")); - return KErrNoMemory; - } - iBuf->SetMax(); - SetBufferPointer(*iBuf); - iBufPtr.Copy(aString); - iSBuf.SetMax(); - iSBuf[0] = iBuf->Size() + 2; // Bytes - iSBuf[1] = KUsbDescType_String; - return KErrNone; - } - - -// --- TUsbcLangIdDescriptor - -TUsbcLangIdDescriptor::TUsbcLangIdDescriptor() - : iBuf(NULL) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()")); - } - - -TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()")); - } - - -TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::New")); - TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor(); - if (self) - { - if (self->Construct(aLangId) != KErrNone) - { - delete self; - return NULL; - } - } - return self; - } - - -TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLangIdDescriptor::Construct")); - iBuf.SetMax(); - SetBufferPointer(iBuf); - iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId)); // Language ID value - iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId)); - iSBuf.SetMax(); - iSBuf[0] = iBuf.Size() + 2; // Bytes - iSBuf[1] = KUsbDescType_String; - return KErrNone; - } - - -// --- TUsbcDescriptorPool - -TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf) -// -// The constructor for this class. -// - : iDescriptors(), iStrings(), iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf), iHighSpeed(EFalse) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::TUsbcDescriptorPool()")); - } - - -TUsbcDescriptorPool::~TUsbcDescriptorPool() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::~TUsbcDescriptorPool()")); - // The destructor of each object is called before the objects themselves are destroyed. - __KTRACE_OPT(KUSB, Kern::Printf(" iDescriptors.Count(): %d", iDescriptors.Count())); - iDescriptors.ResetAndDestroy(); - __KTRACE_OPT(KUSB, Kern::Printf(" iStrings.Count(): %d", iStrings.Count())); - iStrings.ResetAndDestroy(); - } - - -TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc, - TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer, - TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum, - TUsbcStringDescriptor* aConfig, TUsbcOtgDescriptor* aOtgDesc) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::Init()")); - if (!aDeviceDesc || !aConfigDesc) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Device or Config descriptor specified")); - return KErrArgument; - } - for (TInt n = 0; n < KDescPosition_FirstAvailable; n++) - { - iDescriptors.Append(NULL); - } - __ASSERT_DEBUG((iDescriptors.Count() == KDescPosition_FirstAvailable), - Kern::Printf(" Error: iDescriptors.Count() (%d) != KDescPosition_FirstAvailable (%d)", - iDescriptors.Count(), KDescPosition_FirstAvailable)); - iDescriptors[KDescPosition_Device] = aDeviceDesc; - iDescriptors[KDescPosition_Config] = aConfigDesc; - if (aOtgDesc) - { - iDescriptors[KDescPosition_Otg] = aOtgDesc; - // Update the config descriptor's wTotalLength field - UpdateConfigDescriptorLength(KUsbDescSize_Otg); - } - if (!aLangId) - { - // USB spec 9.6.7 says: "String index zero for all languages returns a string descriptor - // that contains an array of two-byte LANGID codes supported by the device. ... - // USB devices that omit all string descriptors must not return an array of LANGID codes." - // So if we have at least one string descriptor, we must also have a LANGID descriptor. - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No LANGID string descriptor specified")); - return KErrArgument; - } - iStrings.Insert(aLangId, KStringPosition_Langid); - iStrings.Insert(aManufacturer, KStringPosition_Manufact); - iStrings.Insert(aProduct, KStringPosition_Product); - iStrings.Insert(aSerialNum, KStringPosition_Serial); - iStrings.Insert(aConfig, KStringPosition_Config); - __ASSERT_DEBUG((iStrings.Count() == 5), - Kern::Printf(" Error: iStrings.Count() != 5 (%d)", iStrings.Count())); -#ifdef _DEBUG - for (TInt i = KStringPosition_Langid; i <= KStringPosition_Config; i++) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool.iStrings[%d] = 0x%x", i, iStrings[i])); - } -#endif - // Set string indices - if (aManufacturer) - iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Manufact, - KStringPosition_Manufact); - if (aProduct) - iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Product, - KStringPosition_Product); - if (aSerialNum) - iDescriptors[KDescPosition_Device]->SetByte(KUsbDescStringIndex_Serial, - KStringPosition_Serial); - if (aConfig) - iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, - KStringPosition_Config); - return KErrNone; - } - - -TInt TUsbcDescriptorPool::InitHs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InitHs()")); - __ASSERT_DEBUG((iDescriptors.Count() >= KDescPosition_FirstAvailable), - Kern::Printf(" Error: Call Init() first)")); - - TUsbcDeviceQualifierDescriptor* const dq_desc = TUsbcDeviceQualifierDescriptor::New( - iDescriptors[KDescPosition_Device]->Byte(4), // aDeviceClass - iDescriptors[KDescPosition_Device]->Byte(5), // aDeviceSubClass - iDescriptors[KDescPosition_Device]->Byte(6), // aDeviceProtocol - iDescriptors[KDescPosition_Device]->Byte(7), // aMaxPacketSize0 - iDescriptors[KDescPosition_Device]->Byte(17)); // aNumConfigurations - if (!dq_desc) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev qualif desc failed.")); - return KErrGeneral; - } - iDescriptors[KDescPosition_DeviceQualifier] = dq_desc; - - TUsbcOtherSpeedConfigDescriptor* const osc_desc = TUsbcOtherSpeedConfigDescriptor::New( - iDescriptors[KDescPosition_Config]->Byte(5), // aConfigurationValue - iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_SelfPowered, // aSelfPowered - iDescriptors[KDescPosition_Config]->Byte(7) & KUsbDevAttr_RemoteWakeup, // aRemoteWakeup - iDescriptors[KDescPosition_Config]->Byte(8) * 2); // aMaxPower (mA) - if (!osc_desc) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for other speed conf desc failed.")); - return KErrGeneral; - } - - // We need to set the bDescriptorType field manually, as that's the only one - // that differs from a Configuration descriptor. - osc_desc->SetByte(1, KUsbDescType_OtherSpeedConfig); - - // Also, initially we set the iConfiguration string index to the same value as - // in the Configuration descriptor. - osc_desc->SetByte(KUsbDescStringIndex_Config, - iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config)); - - iDescriptors[KDescPosition_OtherSpeedConfig] = osc_desc; - - return KErrNone; - } - - -TInt TUsbcDescriptorPool::UpdateDescriptorsFs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsFs()")); - const TInt count = iDescriptors.Count(); - for (TInt i = KDescPosition_FirstAvailable; i < count; i++) - { - TUsbcDescriptorBase* const ptr = iDescriptors[i]; - ptr->UpdateFs(); - } - iHighSpeed = EFalse; - return KErrNone; - } - - -TInt TUsbcDescriptorPool::UpdateDescriptorsHs() - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateDescriptorsHs()")); - const TInt count = iDescriptors.Count(); - for (TInt i = KDescPosition_FirstAvailable; i < count; i++) - { - TUsbcDescriptorBase* const ptr = iDescriptors[i]; - ptr->UpdateHs(); - } - iHighSpeed = ETrue; - return KErrNone; - } - - -// -// An error can be indicated by either a return value != KErrNone or by a descriptor size == 0. -// -TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindDescriptor()")); - TInt result = KErrGeneral; - switch (aType) - { - case KUsbDescType_Device: - if (aLangid != 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid)); - } - else if (aIndex > 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad device index: %d", aIndex)); - } - else - { - aSize = GetDeviceDescriptor(KDescPosition_Device); - result = KErrNone; - } - break; - case KUsbDescType_Config: - if (aLangid != 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid)); - } - else if (aIndex > 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad config index: %d", aIndex)); - } - else - { - aSize = GetConfigurationDescriptor(KDescPosition_Config); - result = KErrNone; - } - break; - case KUsbDescType_DeviceQualifier: - if (aLangid != 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid)); - } - else if (aIndex > 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad device index: %d", aIndex)); - } - else - { - aSize = GetDeviceDescriptor(KDescPosition_DeviceQualifier); - result = KErrNone; - } - break; - case KUsbDescType_OtherSpeedConfig: - if (aLangid != 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad langid: 0x%04x", aLangid)); - } - else if (aIndex > 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bad config index: %d", aIndex)); - } - else - { - aSize = GetConfigurationDescriptor(KDescPosition_OtherSpeedConfig); - result = KErrNone; - } - break; - case KUsbDescType_Otg: - aSize = GetOtgDescriptor(); - result = KErrNone; - break; - case KUsbDescType_String: - if (aIndex == 0) // 0 addresses the LangId array - { - if (AnyStringDescriptors()) - { - aSize = GetStringDescriptor(aIndex); - result = KErrNone; - } - else - { - __KTRACE_OPT(KUSB, Kern::Printf(" No string descriptors: not returning LANGID array")); - } - } - else - { - if (!aLangid) - { - __KTRACE_OPT(KUSB, - Kern::Printf(" Strange: LANGID=0 for a $ descriptor (ignoring LANGID)")); - // The USB spec doesn't really say what to do in this case, but as there are host apps - // that fail if we return an error here, we choose to ignore the issue. - } - else if (aLangid != iStrings[KStringPosition_Langid]->Word(2)) - { - // We have only one (this) language - __KTRACE_OPT(KUSB, - Kern::Printf(" Bad LANGID: 0x%04X requested, 0x%04X supported (ignoring LANGID)", - aLangid, iStrings[KStringPosition_Langid]->Word(2))); - // We could return an error here, but rather choose to ignore the discrepancy - // (the USB spec is not very clear what to do in such a case anyway). - } - aSize = GetStringDescriptor(aIndex); - result = KErrNone; - } - break; - case KUsbDescType_CS_Interface: - /* fall through */ - case KUsbDescType_CS_Endpoint: - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: finding of class specific descriptors not supported")); - break; - default: - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: unknown descriptor type requested: %d", aType)); - break; - } - return result; - } - - -void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertDescriptor()")); - switch (aDesc->Type()) - { - case KUsbDescType_Interface: - InsertIfcDesc(aDesc); - break; - case KUsbDescType_Endpoint: - InsertEpDesc(aDesc); - break; - default: - __KTRACE_OPT(KUSB, Kern::Printf(" Error: unsupported descriptor type")); - } - } - - -void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetIfcDescriptor(%d, %d)", aNumber, aSetting)); - const TInt i = FindIfcDescriptor(aNumber, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Ifc descriptor not found (%d, %d)", - aNumber, aSetting)); - return; - } - // Try to find available NULL postition - TInt str_idx = FindAvailableStringPos(); - if (str_idx >= 0) - { - // Insert string descriptor for specified interface - ExchangeStringDescriptor(str_idx, aDesc); - } - else - { - // No NULL found - expand array - str_idx = iStrings.Count(); - if (str_idx > 0xff) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: $ descriptor array full (idx=%d)", str_idx)); - return; - } - while (str_idx < KStringPosition_FirstAvailable) - { - iStrings.Append(NULL); - str_idx = iStrings.Count(); - } - // Append string descriptor for specified interface - iStrings.Append(aDesc); - } - // Update this ifc descriptor's string index field - iDescriptors[i]->SetByte(8, str_idx); - __KTRACE_OPT(KUSB, Kern::Printf(" String for ifc %d/%d (@ pos %d): \"%S\"", aNumber, aSetting, str_idx, - &iStrings[str_idx]->StringData())); - } - - -void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)", aNumber, aSetting)); - const TInt i = FindIfcDescriptor(aNumber, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DeleteIfcDescriptor - descriptor not found (%d, %d)", - aNumber, aSetting)); - return; - } - // Delete (if necessary) specified interface's string descriptor - const TInt si = iDescriptors[i]->Byte(8); - if (si != 0) - { - ExchangeStringDescriptor(si, NULL); - } - // Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors: - // find position of the next interface descriptor: we need to delete everything in between - const TInt count = iDescriptors.Count(); - TInt j = i, n = 1; - while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface) - ++n; - DeleteDescriptors(i, n); - // Update all the following interfaces' bInterfaceNumber field if required - // (because those descriptors might have moved down by one position) - UpdateIfcNumbers(aNumber); - iIfcIdx = 0; // ifc index no longer valid - } - - -// The TC in many of the following functions stands for 'ThreadCopy', -// because that's what's happening there. - -TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptorTC()")); - return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Device]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceDescriptorTC()")); - TBuf8 device; - const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0); - if (r != KErrNone) - { - return r; - } - iDescriptors[KDescPosition_Device]->SetByte(2, device[2]); // bcdUSB - iDescriptors[KDescPosition_Device]->SetByte(3, device[3]); // bcdUSB (part II) - iDescriptors[KDescPosition_Device]->SetByte(4, device[4]); // bDeviceClass - iDescriptors[KDescPosition_Device]->SetByte(5, device[5]); // bDeviceSubClass - iDescriptors[KDescPosition_Device]->SetByte(6, device[6]); // bDeviceProtocol - iDescriptors[KDescPosition_Device]->SetByte(8, device[8]); // idVendor - iDescriptors[KDescPosition_Device]->SetByte(9, device[9]); // idVendor (part II) - iDescriptors[KDescPosition_Device]->SetByte(10, device[10]); // idProduct - iDescriptors[KDescPosition_Device]->SetByte(11, device[11]); // idProduct (part II) - iDescriptors[KDescPosition_Device]->SetByte(12, device[12]); // bcdDevice - iDescriptors[KDescPosition_Device]->SetByte(13, device[13]); // bcdDevice (part II) - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigurationDescriptorTC()")); - return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Config]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetConfigurationDescriptorTC()")); - TBuf8 config; - const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0); - if (r != KErrNone) - { - return r; - } - iDescriptors[KDescPosition_Config]->SetByte(7, config[7]); // bmAttributes - iDescriptors[KDescPosition_Config]->SetByte(8, config[8]); // bMaxPower - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetOtgDescriptorTC(DThread* aThread, TDes8& aBuffer) const - { - return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[KDescPosition_Otg]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetOtgDescriptor(const TDesC8& aBuffer) - { - iDescriptors[KDescPosition_Otg]->SetByte(2, aBuffer[2]); // bmAttributes - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer, - TInt aInterface, TInt aSetting) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetInterfaceDescriptorTC()")); - const TInt i = FindIfcDescriptor(aInterface, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return KErrNotFound; - } - return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetInterfaceDescriptor()")); - const TInt i = FindIfcDescriptor(aInterface, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return KErrNotFound; - } - iDescriptors[i]->SetByte(2, aBuffer[2]); // bInterfaceNumber - iDescriptors[i]->SetByte(5, aBuffer[5]); // bInterfaceClass - iDescriptors[i]->SetByte(6, aBuffer[6]); // bInterfaceSubClass - iDescriptors[i]->SetByte(7, aBuffer[7]); // bInterfaceProtocol - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, - TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorTC()")); - const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return KErrNotFound; - } - return Kern::ThreadDesWrite(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, - TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetEndpointDescriptorTC()")); - const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return KErrNotFound; - } - TBuf8 ep; // it could be an audio endpoint - const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, ep, 0); - if (r != KErrNone) - { - return r; - } - iDescriptors[i]->SetByte(3, ep[3]); // bmAttributes - iDescriptors[i]->SetByte(6, ep[6]); // bInterval - if (iDescriptors[i]->Size() == KUsbDescSize_AudioEndpoint) - { - iDescriptors[i]->SetByte(7, ep[7]); // bRefresh - iDescriptors[i]->SetByte(8, ep[8]); // bSynchAddress - } - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress, - TInt& aSize) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetEndpointDescriptorSize()")); - const TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return KErrNotFound; - } - aSize = iDescriptors[i]->Size(); - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC(DThread* aThread, TDes8& aBuffer) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceQualifierDescriptorTC()")); - if (iDescriptors[KDescPosition_DeviceQualifier] == NULL) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Device_Qualifier descriptor not supported")); - return KErrNotSupported; - } - return Kern::ThreadDesWrite(aThread, &aBuffer, - iDescriptors[KDescPosition_DeviceQualifier]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC(DThread* aThread, const TDes8& aBuffer) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceQualifierDescriptorTC()")); - if (iDescriptors[KDescPosition_DeviceQualifier] == NULL) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Device_Qualifier descriptor not supported")); - return KErrNotSupported; - } - TBuf8 device; - const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, device, 0); - if (r != KErrNone) - { - return r; - } - iDescriptors[KDescPosition_DeviceQualifier]->SetByte(2, device[2]); // bcdUSB - iDescriptors[KDescPosition_DeviceQualifier]->SetByte(3, device[3]); // bcdUSB (part II) - iDescriptors[KDescPosition_DeviceQualifier]->SetByte(4, device[4]); // bDeviceClass - iDescriptors[KDescPosition_DeviceQualifier]->SetByte(5, device[5]); // bDeviceSubClass - iDescriptors[KDescPosition_DeviceQualifier]->SetByte(6, device[6]); // bDeviceProtocol - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtherSpeedConfigurationDescriptorTC()")); - if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Other_Speed_Configuration descriptor not supported")); - return KErrNotSupported; - } - return Kern::ThreadDesWrite(aThread, &aBuffer, - iDescriptors[KDescPosition_OtherSpeedConfig]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetOtherSpeedConfigurationDescriptorTC()")); - if (iDescriptors[KDescPosition_OtherSpeedConfig] == NULL) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Other_Speed_Configuration descriptor not supported")); - return KErrNotSupported; - } - TBuf8 config; - const TInt r = Kern::ThreadDesRead(aThread, &aBuffer, config, 0); - if (r != KErrNone) - { - return r; - } - iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(7, config[7]); // bmAttributes - iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(8, config[8]); // bMaxPower - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer, - TInt aInterface, TInt aSetting) const - { - // first find the interface - TInt i = FindIfcDescriptor(aInterface, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return KErrNotFound; - } - TInt r = KErrNotFound; - TInt offset = 0; - const TInt count = iDescriptors.Count(); - while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface) - { - r = Kern::ThreadDesWrite(aThread, &aBuffer, - iDescriptors[i]->DescriptorData(), offset); - if (r != KErrNone) - break; - offset += iDescriptors[i]->Size(); - } - return r; - } - - -TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer, - TInt aInterface, TInt aSetting, TInt aSize) - { - // First find the interface - TInt i = FindIfcDescriptor(aInterface, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return KErrNotFound; - } - // Find a position where to insert the new class specific interface descriptor(s) - const TInt count = iDescriptors.Count(); - while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface) - ; - // Create a new cs descriptor - TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize); - if (!desc) - { - return KErrNoMemory; - } - __KTRACE_OPT(KUSB, Kern::Printf(" inserting descriptor at position %d", i)); - iDescriptors.Insert(desc, i); - - // Update the config descriptor's wTotalLength field - UpdateConfigDescriptorLength(aSize); - - // Copy contents from the user side - return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const - { - // first find the interface - TInt i = FindIfcDescriptor(aInterface, aSetting); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return KErrNotFound; - } - TInt r = KErrNotFound; - TInt size = 0; - const TInt count = iDescriptors.Count(); - while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface) - { - size += iDescriptors[i]->Size(); - r = KErrNone; - } - if (r == KErrNone) - aSize = size; - return r; - } - - -TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface, - TInt aSetting, TUint8 aEndpointAddress) const - { - // first find the endpoint - TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return KErrNotFound; - } - TInt r = KErrNotFound; - TInt offset = 0; - const TInt count = iDescriptors.Count(); - while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint) - { - r = Kern::ThreadDesWrite(aThread, &aBuffer, - iDescriptors[i]->DescriptorData(), offset); - if (r != KErrNone) - break; - offset += iDescriptors[i]->Size(); - } - return r; - } - - -TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface, - TInt aSetting, TUint8 aEndpointAddress, TInt aSize) - { - // first find the endpoint - TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return KErrNotFound; - } - // find a position where to insert the new class specific endpoint descriptor(s) - const TInt count = iDescriptors.Count(); - while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint) - ; - // create a new cs descriptor - TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize); - if (!desc) - { - return KErrNoMemory; - } - iDescriptors.Insert(desc, i); - // update the config descriptor's wTotalLength field - UpdateConfigDescriptorLength(aSize); - // copy contents from user side - return Kern::ThreadDesRead(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), 0); - } - - -TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting, - TUint8 aEndpointAddress, TInt& aSize) const - { - // first find the endpoint - TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); - if (i < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return KErrNotFound; - } - TInt r = KErrNotFound; - TInt size = 0; - const TInt count = iDescriptors.Count(); - while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint) - { - size += iDescriptors[i]->Size(); - r = KErrNone; - } - if (r == KErrNone) - aSize = size; - return r; - } - - -TInt TUsbcDescriptorPool::GetStringDescriptorLangIdTC(DThread* aThread, TDes8& aLangId) const - { - const TUint16 id = iStrings[KStringPosition_Langid]->Word(2); - const TPtrC8 id_des(reinterpret_cast(&id), sizeof(id)); - return Kern::ThreadDesWrite(aThread, &aLangId, id_des, 0); - } - - -TInt TUsbcDescriptorPool::SetStringDescriptorLangId(TUint16 aLangId) - { - iStrings[KStringPosition_Langid]->SetWord(2, aLangId); - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const - { - return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact, - KStringPosition_Manufact); - } - - -TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString) - { - return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact, - KStringPosition_Manufact); - } - - -TInt TUsbcDescriptorPool::RemoveManufacturerStringDescriptor() - { - return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Manufact, KStringPosition_Manufact); - } - - -TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const - { - return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product, - KStringPosition_Product); - } - - -TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString) - { - return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product, - KStringPosition_Product); - } - - -TInt TUsbcDescriptorPool::RemoveProductStringDescriptor() - { - return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Product, KStringPosition_Product); - } - - -TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const - { - return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial, - KStringPosition_Serial); - } - - -TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString) - { - return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial, - KStringPosition_Serial); - } - - -TInt TUsbcDescriptorPool::RemoveSerialNumberStringDescriptor() - { - return RemoveDeviceStringDescriptor(KUsbDescStringIndex_Serial, KStringPosition_Serial); - } - - -TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const - { - const TInt str_idx = iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config); - if (str_idx) - { - __ASSERT_ALWAYS((str_idx == KStringPosition_Config), Kern::Fault(KUsbPanicCat, __LINE__)); - __KTRACE_OPT(KUSB, Kern::Printf(" String @ pos %d (conf $): \"%S\"", - str_idx, &iStrings[str_idx]->StringData())); - return Kern::ThreadDesWrite(aThread, &aString, - iStrings[str_idx]->StringData(), 0); - } - else - { - __KTRACE_OPT(KUSB, Kern::Printf(" No config string descriptor @ pos %d", str_idx)); - return KErrNotFound; - } - } - - -TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString) - { - // we don't know the length of the string, so we have to allocate memory dynamically - TUint strlen = Kern::ThreadGetDesLength(aThread, &aString); - if (strlen > KUsbStringDescStringMaxSize) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: config $ descriptor too long - will be truncated")); - strlen = KUsbStringDescStringMaxSize; - } - HBuf8* const strbuf = HBuf8::New(strlen); - if (!strbuf) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config $ desc string failed (1)")); - return KErrNoMemory; - } - strbuf->SetMax(); - // the aString points to data that lives in user memory, so we have to copy it: - const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0); - if (r != KErrNone) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Thread read error")); - delete strbuf; - return r; - } - TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf); - if (!sd) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config $ desc failed (2)")); - delete strbuf; - return KErrNoMemory; - } - // Delete old string, put in new one - ExchangeStringDescriptor(KStringPosition_Config, sd); - // Update Config descriptor string index field - iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, KStringPosition_Config); - // Update Other_Speed_Config descriptor string index field as well, if applicable - if (iDescriptors[KDescPosition_OtherSpeedConfig]) - iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config, - KStringPosition_Config); - delete strbuf; - return KErrNone; - } - - -TInt TUsbcDescriptorPool::RemoveConfigurationStringDescriptor() - { - if (iDescriptors[KDescPosition_Config]->Byte(KUsbDescStringIndex_Config) == 0) - { - __KTRACE_OPT(KUSB, Kern::Printf(" RemoveConfigurationStringDescriptor: no $ desc @ index %d", - KUsbDescStringIndex_Config)); - return KErrNotFound; - } - // Delete old string, put in NULL pointer - ExchangeStringDescriptor(KStringPosition_Config, NULL); - // Update Config descriptor string index field - iDescriptors[KDescPosition_Config]->SetByte(KUsbDescStringIndex_Config, 0); - // Update Other_Speed_Config descriptor string index field as well, if applicable - if (iDescriptors[KDescPosition_OtherSpeedConfig]) - iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(KUsbDescStringIndex_Config, 0); - return KErrNone; - } - - -TInt TUsbcDescriptorPool::GetStringDescriptorTC(DThread* aThread, TInt aIndex, TDes8& aString) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptorTC()")); - if (!StringDescriptorExists(aIndex)) - { - return KErrNotFound; - } - __KTRACE_OPT(KUSB, Kern::Printf(" String @ pos %d: \"%S\"", - aIndex, &iStrings[aIndex]->StringData())); - return Kern::ThreadDesWrite(aThread, &aString, iStrings[aIndex]->StringData(), 0); - } - - -TInt TUsbcDescriptorPool::SetStringDescriptorTC(DThread* aThread, TInt aIndex, const TDes8& aString) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetStringDescriptorTC()")); - // we don't know the length of the string, so we have to allocate memory dynamically - TUint strlen = Kern::ThreadGetDesLength(aThread, &aString); - if (strlen > KUsbStringDescStringMaxSize) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: $ descriptor too long - will be truncated")); - strlen = KUsbStringDescStringMaxSize; - } - HBuf8* strbuf = HBuf8::New(strlen); - if (!strbuf) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Mem alloc for $ desc string failed (1)")); - return KErrNoMemory; - } - strbuf->SetMax(); - // the aString points to data that lives in user memory, so we have to copy it over: - const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0); - if (r != KErrNone) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Thread read error")); - delete strbuf; - return r; - } - TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf); - if (!sd) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Mem alloc for $ desc failed (2)")); - delete strbuf; - return KErrNoMemory; - } - if (aIndex < iStrings.Count()) - { - ExchangeStringDescriptor(aIndex, sd); - } - else // if (aIndex >= iStrings.Count()) - { - while (aIndex > iStrings.Count()) - { - iStrings.Append(NULL); - } - iStrings.Append(sd); - } - delete strbuf; - return KErrNone; - } - - -TInt TUsbcDescriptorPool::RemoveStringDescriptor(TInt aIndex) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveStringDescriptor()")); - if (!StringDescriptorExists(aIndex)) - { - return KErrNotFound; - } - __KTRACE_OPT(KUSB, Kern::Printf(" Removing string @ pos %d: \"%S\"", - aIndex, &iStrings[aIndex]->StringData())); - ExchangeStringDescriptor(aIndex, NULL); - - // Make sure there's no $ after aIndex. - const TInt n = iStrings.Count(); - for (TInt i = aIndex; i < n; i++) - { - if (iStrings[i] != NULL) - { - __KTRACE_OPT(KUSB, Kern::Printf(" Found $ @ idx %d - not compressing", i)); - return KErrNone; - } - } - - __KTRACE_OPT(KUSB, Kern::Printf(" No $ found after idx %d - compressing array", aIndex)); - // Move aIndex back just before the first !NULL element. - while (iStrings[--aIndex] == NULL) - ; - // Let aIndex point to first NULL. - aIndex++; - __KTRACE_OPT(KUSB, Kern::Printf(" Starting at index %d", aIndex)); - // Now remove NULL pointers until (Count() == aIndex). - __KTRACE_OPT(KUSB, Kern::Printf(" iStrings.Count() before: %d", iStrings.Count())); - do - { - iStrings.Remove(aIndex); - __KTRACE_OPT(KUSB, Kern::Printf(" Removing $")); - } - while (iStrings.Count() > aIndex); - __KTRACE_OPT(KUSB, Kern::Printf(" iStrings.Count() after: %d", iStrings.Count())); - - // Regain some memory. - iStrings.Compress(); - - return KErrNone; - } - - -// =================================================================== -// --- private --- -// =================================================================== - -// -// Insert an Interface descriptor into the descriptor array at the appropriate index. -// -void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertIfcDesc()")); - - const TInt count = iDescriptors.Count(); - TBool ifc_exists = EFalse; // set to 'true' if we're adding an alternate - // setting to an already existing interface - TInt i = KDescPosition_FirstAvailable; - while (i < count) - { - __KTRACE_OPT(KUSB, Kern::Printf(" already descriptors there (%d)...", count)); - if (iDescriptors[i]->Type() == KUsbDescType_Interface) - { - if (iDescriptors[i]->Byte(2) > aDesc->Byte(2)) - { - // our interface number is less than the one's just found => insert before it (= here) - break; - } - else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2)) - { - ifc_exists = ETrue; - // same interface number => look at settings number - if (iDescriptors[i]->Byte(3) > aDesc->Byte(3)) - { - // our setting number is less than the one's found => insert before (= here) - break; - } - else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3)) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: first delete old desc " - "(TUsbcDescriptorPool::InsertIfcDesc)")); - return; - } - } - } - ++i; - } - // In any case: put the new descriptor at position i. - __KTRACE_OPT(KUSB, Kern::Printf(" inserting descriptor at position %d", i)); - iDescriptors.Insert(aDesc, i); - - // Update the config descriptor's wTotalLength field. - UpdateConfigDescriptorLength(KUsbDescSize_Interface); - - if (!ifc_exists) - { - // If this is the first setting for the interface, increment bNumInterfaces. - UpdateConfigDescriptorNumIfcs(1); - } - - iIfcIdx = i; - } - - -// -// Insert an Endpoint descriptor into the descriptor array at the appropriate index. -// -void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::InsertEpDesc()")); - if (iIfcIdx == 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: only after interface " - "(TUsbcDescriptorPool::InsertEpDesc)")); - return; - } - const TInt count = iDescriptors.Count(); - TInt i = iIfcIdx + 1; - while (i < count) - { - if (iDescriptors[i]->Type() != KUsbDescType_Endpoint) - break; - ++i; - } - // put the new descriptor at position i - iDescriptors.Insert(aDesc, i); - // update the config descriptor's wTotalLength field - UpdateConfigDescriptorLength(aDesc->Size()); - } - - -// -// Find the index of the Interface descriptor for a given interface setting. -// -TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)", - aIfcNumber, aIfcSetting)); - const TInt count = iDescriptors.Count(); - for (TInt i = KDescPosition_FirstAvailable; i < count; i++) - { - if ((iDescriptors[i]->Type() == KUsbDescType_Interface) && - (iDescriptors[i]->Byte(2) == aIfcNumber) && - (iDescriptors[i]->Byte(3) == aIfcSetting)) - { - return i; - } - } - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return -1; - } - - -// -// Find the index of the Endpoint descriptor for a given endpoint on a given interface setting. -// -TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)", - aIfcNumber, aIfcSetting, aEpAddress)); - // first find the interface - const TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting); - if (ifc < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such interface")); - return ifc; - } - const TInt count = iDescriptors.Count(); - // then, before the next interface, try to locate the endpoint - for (TInt i = ifc + 1; i < count; i++) - { - if (iDescriptors[i]->Type() == KUsbDescType_Interface) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint before next interface")); - return -1; - } - else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) && - (iDescriptors[i]->Byte(2) == aEpAddress)) - { - // found - return i; - } - } - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no such endpoint")); - return -1; - } - - -// -// Delete n descriptors starting from aIndex and remove their pointers from the array. -// -void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::DeleteDescriptors()")); - if (aIndex < KDescPosition_FirstAvailable) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: aIndex < KDescPosition_FirstAvailable")); - return; - } - if (aCount <= 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: aCount <= 0")); - return; - } - __KTRACE_OPT(KUSB, Kern::Printf(" Removing descriptors at index %d:", aIndex)); - // Try to update wTotalLength field in Config descriptor - while (aCount--) - { - // In this loop we don't decrement aIndex, because after deleting an element - // aIndex is already indexing the next one. - TUsbcDescriptorBase* const ptr = iDescriptors[aIndex]; - switch (ptr->Type()) - { - case KUsbDescType_Interface: - __KTRACE_OPT(KUSB, Kern::Printf(" - an interface descriptor")); - UpdateConfigDescriptorLength(-KUsbDescSize_Interface); - break; - case KUsbDescType_Endpoint: - __KTRACE_OPT(KUSB, Kern::Printf(" - an endpoint descriptor")); - UpdateConfigDescriptorLength(-ptr->Size()); - break; - case KUsbDescType_CS_Interface: - /* fall through */ - case KUsbDescType_CS_Endpoint: - __KTRACE_OPT(KUSB, Kern::Printf(" - a class specific descriptor")); - UpdateConfigDescriptorLength(-ptr->Size()); - break; - default: - __KTRACE_OPT(KUSB, Kern::Printf(" - an unknown descriptor")); - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: unknown descriptor type")); - } - iDescriptors.Remove(aIndex); - delete ptr; - } - } - - -// -// Update the wTotalLength field in the Configuration descriptor (aLength can be negative). -// -void TUsbcDescriptorPool::UpdateConfigDescriptorLength(TInt aLength) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorLength(%d)", aLength)); - TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config]; - __KTRACE_OPT(KUSB, Kern::Printf(" wTotalLength old: %d", cnf->Word(2))); - // Update Config descriptor - cnf->SetWord(2, cnf->Word(2) + aLength); - __KTRACE_OPT(KUSB, Kern::Printf(" wTotalLength new: %d", cnf->Word(2))); - // Update Other_Speed_Config descriptor as well, if applicable - if (iDescriptors[KDescPosition_OtherSpeedConfig]) - iDescriptors[KDescPosition_OtherSpeedConfig]->SetWord(2, cnf->Word(2)); - } - - -// -// Update the bNumInterfaces field in the Configuration descriptor (aNumber can be negative). -// -void TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(TInt aNumber) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateConfigDescriptorNumIfcs(%d)", aNumber)); - TUsbcDescriptorBase* const cnf = iDescriptors[KDescPosition_Config]; - __KTRACE_OPT(KUSB, Kern::Printf(" bNumInterfaces old: %d", cnf->Byte(4))); - const TInt n = cnf->Byte(4) + aNumber; - if (n < 0) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: bNumInterfaces + aNumber < 0")); - return; - } - // Update Config descriptor - cnf->SetByte(4, n); - __KTRACE_OPT(KUSB, Kern::Printf(" bNumInterfaces new: %d", cnf->Byte(4))); - // Update Other_Speed_Config descriptor as well, if applicable - if (iDescriptors[KDescPosition_OtherSpeedConfig]) - iDescriptors[KDescPosition_OtherSpeedConfig]->SetByte(4, n); - } - - -// -// Update the bNumInterfaces field in the Configuration descriptor if necessary. -// -void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::UpdateIfcNumbers(%d)", aNumber)); - const TInt count = iDescriptors.Count(); - for (TInt i = KDescPosition_FirstAvailable; i < count; i++) - { - if ((iDescriptors[i]->Type() == KUsbDescType_Interface) && - (iDescriptors[i]->Byte(2) == aNumber)) - { - // there's still an interface with 'number' so we don't need to update anything - return; - } - } - // if we haven't returned yet, we decrement bNumInterfaces - UpdateConfigDescriptorNumIfcs(-1); - } - - -// -// Put the current Device or Device_Qualifier descriptor in the Ep0 Tx buffer. -// Only used for Ep0 standard requests, so target buffer can be hard-wired. -// -TInt TUsbcDescriptorPool::GetDeviceDescriptor(TInt aIndex) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceDescriptor()")); - __ASSERT_DEBUG((aIndex == KDescPosition_Device) || (aIndex == KDescPosition_DeviceQualifier), - Kern::Printf(" Error: invalid descriptor index: %d", aIndex)); - if (iDescriptors[aIndex] == NULL) - { - // This doesn't have to be an error - we might get asked here for the Device_Qualifier descriptor - // on a FS-only device. - __KTRACE_OPT(KUSB, Kern::Printf(" Descriptor #%d requested but not available", aIndex)); - return 0; - } - return iDescriptors[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx); - } - - -// -// Put the current Configuration or Other_Speed_Configuration descriptor + all the following -// descriptors in the Ep0 Tx buffer. -// Only used for Ep0 standard requests, so target buffer can be hard-wired. -// -TInt TUsbcDescriptorPool::GetConfigurationDescriptor(TInt aIndex) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetConfigDescriptor(%d)", aIndex)); - __ASSERT_DEBUG((aIndex == KDescPosition_Config) || (aIndex == KDescPosition_OtherSpeedConfig), - Kern::Printf(" Error: invalid descriptor index: %d", aIndex)); - if (iDescriptors[aIndex] == NULL) - { - // This is always an error: We should always have a Configuration descriptor and we should never - // get asked for the Other_Speed_Configuration descriptor if we don't have one (9.6.2). - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: Descriptor %d requested but not available", aIndex)); - return 0; - } - const TInt count = iDescriptors.Count(); - TInt copied = 0; - TUint8* buf = iEp0_TxBuf; - for (TInt i = aIndex; i < count; i++) - { - TUsbcDescriptorBase* const ptr = iDescriptors[i]; - if ((aIndex == KDescPosition_OtherSpeedConfig) && (i == KDescPosition_Config)) - { - // Skip Config descriptor when returning Other_Speed_Config - continue; - } - if ((i == KDescPosition_Otg) && (iDescriptors[i] == NULL)) - { - __KTRACE_OPT(KUSB, Kern::Printf(" no OTG descriptor -> next")); - continue; - } - // We need to edit endpoint descriptors on the fly because we have only one copy - // of each and that copy has to contain different information, depending on the - // current speed and the type of descriptor requested. - if (ptr->Type() == KUsbDescType_Endpoint) - { - if ((iHighSpeed && (aIndex == KDescPosition_Config)) || - (!iHighSpeed && (aIndex == KDescPosition_OtherSpeedConfig))) - { - ptr->UpdateHs(); - } - else - { - ptr->UpdateFs(); - } - } - __KTRACE_OPT(KUSB, Kern::Printf(" desc[%02d]: type = 0x%02x size = %d ", - i, ptr->Type(), ptr->Size())); - const TInt size = ptr->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied); - if (size == 0) - { - __KTRACE_OPT(KPANIC, - Kern::Printf(" Error: No Tx buffer space to copy this descriptor -> exiting")); - break; - } - copied += size; - if (copied >= KUsbcBufSz_Ep0Tx) - { - __KTRACE_OPT(KPANIC, - Kern::Printf(" Error: No Tx buffer space left -> stopping here")); - break; - } - buf += size; - } - __KTRACE_OPT(KUSB, Kern::Printf(" copied %d bytes", copied)); - return copied; - } - - -// -// Put the current OTG descriptor in the Ep0 Tx buffer. -// Only used for Ep0 standard requests, so target buffer can be hard-wired. -// -TInt TUsbcDescriptorPool::GetOtgDescriptor() const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetOtgDescriptor()")); - if (iDescriptors[KDescPosition_Otg] == NULL) - { - __KTRACE_OPT(KUSB, Kern::Printf(" OTG Descriptor not set")); - return 0; - } - return iDescriptors[KDescPosition_Otg]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx); - } - - -// -// Put a specific String descriptor in the Ep0 Tx buffer. -// Only used for Ep0 standard requests, so target buffer can be hard-wired. -// -TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetStringDescriptor(%d)", aIndex)); - // I really would have liked to display the descriptor contents here, but without trailing zero - // we got a problem: how can we tell printf where the string ends? We would have to - // dynamically allocate memory (since we don't know the size in advance), copy the descriptor - // contents there, append a zero, and give this to printf. That's a bit too much effort... - if (!StringDescriptorExists(aIndex)) - { - return 0; - } - return iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx); - } - - -// -// Write a String descriptor pointed to by the Device descriptor to the user side -// (one of Manufacturer, Product, SerialNumber). -// -TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString, - TInt aIndex, TInt aPosition) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::GetDeviceStringDescriptorTC()")); - const TInt str_idx = iDescriptors[KDescPosition_Device]->Byte(aIndex); - if (str_idx) - { - __ASSERT_ALWAYS((str_idx == aPosition), Kern::Fault(KUsbPanicCat, __LINE__)); - __KTRACE_OPT(KUSB, Kern::Printf(" String @ pos %d (device $): \"%S\"", - str_idx, &iStrings[str_idx]->StringData())); - return Kern::ThreadDesWrite(aThread, &aString, - iStrings[str_idx]->StringData(), 0); - } - else - { - __KTRACE_OPT(KUSB, Kern::Printf(" No string descriptor @ pos %d", aIndex)); - return KErrNotFound; - } - } - - -// -// Read a Device String descriptor from the user side and put in the descriptor arrays -// (one of Manufacturer, Product, SerialNumber). -// -TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString, - TInt aIndex, TInt aPosition) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::SetDeviceStringDescriptorTC()")); - // we don't know the length of the string, so we have to allocate memory dynamically - TUint strlen = Kern::ThreadGetDesLength(aThread, &aString); - if (strlen > KUsbStringDescStringMaxSize) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Warning: $ descriptor too long - will be truncated")); - strlen = KUsbStringDescStringMaxSize; - } - HBuf8* const strbuf = HBuf8::New(strlen); - if (!strbuf) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev $ desc string failed (1)")); - return KErrNoMemory; - } - strbuf->SetMax(); - // the aString points to data that lives in user memory, so we have to copy it: - const TInt r = Kern::ThreadDesRead(aThread, &aString, *strbuf, 0); - if (r != KErrNone) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Thread read error")); - delete strbuf; - return r; - } - TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*strbuf); - if (!sd) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev $ desc failed (2)")); - delete strbuf; - return KErrNoMemory; - } - ExchangeStringDescriptor(aPosition, sd); - iDescriptors[KDescPosition_Device]->SetByte(aIndex, aPosition); - delete strbuf; - return r; - } - - -// -// Remove a Device String descriptor from the descriptor arrays -// (one of Manufacturer, Product, SerialNumber). -// -TInt TUsbcDescriptorPool::RemoveDeviceStringDescriptor(TInt aIndex, TInt aPosition) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::RemoveDeviceStringDescriptor()")); - if (iDescriptors[KDescPosition_Device]->Byte(aIndex) == 0) - { - __KTRACE_OPT(KUSB, Kern::Printf(" RemoveDeviceStringDescriptor: no $ desc @ index %d", aIndex)); - return KErrNotFound; - } - ExchangeStringDescriptor(aPosition, NULL); - iDescriptors[KDescPosition_Device]->SetByte(aIndex, 0); - return KErrNone; - } - - -// -// Puts aDesc at postion aIndex in the string descriptor array, after deleting what was (possibly) there. -// -void TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc) - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::ExchangeStringDescriptor()")); - TUsbcStringDescriptorBase* const ptr = iStrings[aIndex]; - __KTRACE_OPT(KUSB, Kern::Printf(" Deleting string descriptor at index %d: 0x%x", aIndex, ptr)); - iStrings.Remove(aIndex); - delete ptr; - __KTRACE_OPT(KUSB, Kern::Printf(" Inserting string descriptor at index %d: 0x%x", aIndex, aDesc)); - iStrings.Insert(aDesc, aIndex); - } - - -// -// Checks whether there are any string descriptors in the array (apart from LangID). -// -TBool TUsbcDescriptorPool::AnyStringDescriptors() const - { - const TInt n = iStrings.Count(); - for (TInt i = 1; i < n; i++) - { - if (iStrings[i] != NULL) - return ETrue; - } - return EFalse; - } - - -// -// Returns true if aIndex exists and what is at that positition is not a NULL pointer. -// -TBool TUsbcDescriptorPool::StringDescriptorExists(TInt aIndex) const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::StringDescriptorExists()")); - if (aIndex >= iStrings.Count()) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Bad string index: %d", aIndex)); - return EFalse; - } - else if (iStrings[aIndex] == NULL) - { - __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No $ descriptor @ pos %d", aIndex)); - return EFalse; - } - return ETrue; - } - - -// -// -// -TInt TUsbcDescriptorPool::FindAvailableStringPos() const - { - __KTRACE_OPT(KUSB, Kern::Printf("TUsbcDescriptorPool::FindAvailableStringPos()")); - const TInt n = iStrings.Count(); - // We don't start from 0 because the first few locations are 'reserved'. - for (TInt i = KStringPosition_FirstAvailable; i < n; i++) - { - if (iStrings[i] == NULL) - { - __KTRACE_OPT(KUSB, Kern::Printf(" Found available NULL position: %d", i)); - return i; - } - } - return -1; - } - - -// -eof-