1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/d32usbdi_hubdriver.inl Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,442 @@
1.4 +// Copyright (c) 2007-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 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @internalComponent
1.22 +
1.23 + The driver's name
1.24 +
1.25 + @return The name of the driver
1.26 +
1.27 + @internalComponent
1.28 +*/
1.29 +inline const TDesC& RUsbHubDriver::Name()
1.30 + {
1.31 + _LIT(KDriverName,"USBHUBDRIVER");
1.32 + return KDriverName;
1.33 + }
1.34 +
1.35 +/**
1.36 + The driver's version
1.37 +
1.38 + @return The version number of the driver
1.39 +*/
1.40 +inline TVersion RUsbHubDriver::VersionRequired()
1.41 + {
1.42 + const TInt KMajorVersionNumber=1;
1.43 + const TInt KMinorVersionNumber=0;
1.44 + const TInt KBuildVersionNumber=KE32BuildVersionNumber;
1.45 + return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.46 + }
1.47 +
1.48 +
1.49 +#ifndef __KERNEL_MODE__
1.50 +
1.51 +/**
1.52 +Open a handle to the host controller.
1.53 +@return System-wide error code giving status of connection attempt.
1.54 +*/
1.55 +TInt RUsbHubDriver::Open()
1.56 + {
1.57 + TInt rc = KErrNone;
1.58 +
1.59 + // Check to see if this object has already been opened - if it has,
1.60 + // there will be a handle set.
1.61 +
1.62 + if ( Handle() )
1.63 + {
1.64 + User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverAlreadyOpened);
1.65 + }
1.66 +
1.67 + rc = DoCreate(Name(),VersionRequired(),KNullUnit,NULL,NULL,EOwnerThread);
1.68 +
1.69 + if ( rc != KErrNone )
1.70 + {
1.71 + RDebug::Print(_L("********************************"));
1.72 + RDebug::Print(_L("* RUsbHubDriver::Open() Fault! *"));
1.73 + RDebug::Print(_L("********************************"));
1.74 + }
1.75 +
1.76 + return rc;
1.77 + }
1.78 +
1.79 +
1.80 +/**
1.81 +Start the host stack.
1.82 +*/
1.83 +TInt RUsbHubDriver::StartHost()
1.84 + {
1.85 + return DoControl(EStartHost);
1.86 + }
1.87 +
1.88 +
1.89 +/**
1.90 +Stop the host stack.
1.91 +*/
1.92 +void RUsbHubDriver::StopHost()
1.93 + {
1.94 + DoControl(EStopHost);
1.95 + }
1.96 +
1.97 +
1.98 +/**
1.99 +Wait for a bus event. These include device attachments and detachments.
1.100 +@see TBusEvent
1.101 +@param aEvent The details of the event that occured, filled in when the request completes.
1.102 +@param aStatus Completed when an event occurs
1.103 +*/
1.104 +void RUsbHubDriver::WaitForBusEvent(TBusEvent& aEvent, TRequestStatus& aStatus)
1.105 + {
1.106 + DoRequest(EWaitForBusEvent, aStatus, &aEvent);
1.107 + }
1.108 +
1.109 +
1.110 +/**
1.111 +Cancel a request to wait for bus events.
1.112 +*/
1.113 +void RUsbHubDriver::CancelWaitForBusEvent()
1.114 + {
1.115 + DoCancel(ECancelWaitForBusEvent);
1.116 + }
1.117 +
1.118 +
1.119 +RUsbDevice::RUsbDevice()
1.120 + : iHeadDeviceDescriptor(NULL)
1.121 + , iHeadConfDescriptor(NULL)
1.122 + , iConfigurationDescriptorData(NULL)
1.123 + , iHub(NULL)
1.124 + , iHandle(0)
1.125 + {
1.126 + }
1.127 +
1.128 +/**
1.129 +Open a handle to a device.
1.130 +*/
1.131 +TInt RUsbDevice::Open(RUsbHubDriver& aHub, TUint aHandle)
1.132 + {
1.133 + if(iHandle)
1.134 + {
1.135 + return KErrInUse;
1.136 + }
1.137 +
1.138 + TInt err;
1.139 + err = aHub.DoControl(EOpen, (TAny*)aHandle);
1.140 +
1.141 +
1.142 + if (err == KErrNone)
1.143 + {
1.144 + iHub = &aHub;
1.145 + iHandle = aHandle;
1.146 + }
1.147 + else
1.148 + {
1.149 + return err;
1.150 + }
1.151 +
1.152 + TRAP(err, GetLocalDescriptorsL());
1.153 + // GetLocalDescriptorsL should roll back iHandle etc on error.
1.154 + __ASSERT_DEBUG(err == KErrNone || !iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverNoRollBackAfterFailedDeviceOpen));
1.155 +
1.156 + return err;
1.157 + }
1.158 +
1.159 +void RUsbDevice::GetLocalDescriptorsL()
1.160 + {
1.161 + CleanupClosePushL(*this); // Ensure that we roll back to closed on error.
1.162 +
1.163 + // Get Device Descriptor Data.
1.164 + User::LeaveIfError(GetDeviceDescriptor(iDeviceDescriptorData));
1.165 +
1.166 + // Get Configuration Descriptor Data
1.167 + TInt configSize = 0;
1.168 + User::LeaveIfError(GetConfigurationDescriptorSize(configSize));
1.169 +
1.170 + iConfigurationDescriptorData = HBufC8::NewL(configSize);
1.171 + TPtr8 ptr = iConfigurationDescriptorData->Des();
1.172 + User::LeaveIfError(GetConfigurationDescriptor(ptr));
1.173 +
1.174 +
1.175 + TUsbGenericDescriptor* parsed = NULL;
1.176 +
1.177 + // Parse Device Descriptor
1.178 + User::LeaveIfError(UsbDescriptorParser::Parse(iDeviceDescriptorData, parsed));
1.179 + iHeadDeviceDescriptor = TUsbDeviceDescriptor::Cast(parsed);
1.180 + if(!iHeadDeviceDescriptor)
1.181 + {
1.182 + User::Leave(KErrCorrupt);
1.183 + }
1.184 +
1.185 + // Parse Configuration Descriptor
1.186 + User::LeaveIfError(UsbDescriptorParser::Parse(*iConfigurationDescriptorData, parsed));
1.187 + iHeadConfDescriptor = TUsbConfigurationDescriptor::Cast(parsed);
1.188 + if(!iHeadConfDescriptor)
1.189 + {
1.190 + User::Leave(KErrCorrupt);
1.191 + }
1.192 +
1.193 + CleanupStack::Pop(); // this
1.194 + }
1.195 +
1.196 +
1.197 +/**
1.198 +Close a handle to a device.
1.199 +*/
1.200 +void RUsbDevice::Close()
1.201 + {
1.202 + if(iHub)
1.203 + {
1.204 + iHub->DoControl(EClose, (TAny*)iHandle);
1.205 + }
1.206 +
1.207 + if(iHeadConfDescriptor)
1.208 + {
1.209 + iHeadConfDescriptor->DestroyTree();
1.210 + delete iHeadConfDescriptor;
1.211 + iHeadConfDescriptor = NULL;
1.212 + }
1.213 +
1.214 + if(iHeadDeviceDescriptor)
1.215 + {
1.216 + iHeadDeviceDescriptor->DestroyTree();
1.217 + delete iHeadDeviceDescriptor;
1.218 + iHeadDeviceDescriptor = NULL;
1.219 + }
1.220 +
1.221 + delete iConfigurationDescriptorData;
1.222 + iConfigurationDescriptorData = NULL;
1.223 +
1.224 + iHub = NULL;
1.225 + iHandle = 0;
1.226 + }
1.227 +
1.228 +
1.229 +/**
1.230 +Return the handle to a device
1.231 +*/
1.232 +TUint RUsbDevice::Handle() const
1.233 + {
1.234 + return iHandle;
1.235 + }
1.236 +
1.237 +
1.238 +/**
1.239 +Places the device into a suspended state.
1.240 +*/
1.241 +TInt RUsbDevice::Suspend()
1.242 + {
1.243 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.244 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.245 + return iHub->DoControl(ESuspend, (TAny*)iHandle);
1.246 + }
1.247 +
1.248 +
1.249 +/**
1.250 +Resumes the device from a suspended state.
1.251 +*/
1.252 +TInt RUsbDevice::Resume()
1.253 + {
1.254 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.255 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.256 + return iHub->DoControl(EResume, (TAny*)iHandle);
1.257 + }
1.258 +
1.259 +
1.260 +TInt RUsbDevice::GetStringDescriptor(TDes8& aStringDescriptor, TInt aIndex, TInt aLangId)
1.261 + {
1.262 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.263 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.264 + __ASSERT_ALWAYS(aStringDescriptor.MaxLength() >= 255,
1.265 + User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverInsufficientSizeToHoldStringDescriptor));
1.266 +
1.267 + aStringDescriptor.Zero();
1.268 +
1.269 + TStringDescParams stringDescParams;
1.270 + stringDescParams.iTarget = &aStringDescriptor;
1.271 + stringDescParams.iIndex = aIndex;
1.272 + stringDescParams.iLangId = aLangId;
1.273 +
1.274 + return iHub->DoControl(EGetStringDescriptor, (TAny*)iHandle, &stringDescParams);
1.275 + }
1.276 +
1.277 +
1.278 +/**
1.279 +Return a token which may be used to uniquely identify the supplied interface on this device. The returned
1.280 +token may then be passed to a function driver, to allow it to open the required interface.
1.281 +
1.282 +@param [in] aInterfaceNumber Interface to return a token for.
1.283 +@param [out] aToken The token assigned to the interface.
1.284 +@return System wide error code, for instance KErrNotFound if the supplied interface number is unknown.
1.285 +*/
1.286 +TInt RUsbDevice::GetTokenForInterface(TInt aInterfaceNumber, TUint32& aToken)
1.287 + {
1.288 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.289 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.290 +
1.291 + TInterfaceTokenParameters params;
1.292 + params.iInterfaceNumber = aInterfaceNumber;
1.293 + params.iToken = &aToken;
1.294 +
1.295 + return iHub->DoControl(EGetInterfaceToken, (TAny*)iHandle, ¶ms);
1.296 + }
1.297 +
1.298 +/**
1.299 +Queues an asynchronous request for changes in the state of the device represented by this handle.
1.300 +
1.301 +@param [out] aNewState The new state of the device
1.302 +@param [out] aRequest The request status completed when a state change has occured.
1.303 +*/
1.304 +void RUsbDevice::QueueDeviceStateChangeNotification(TDeviceState& aNewState, TRequestStatus& aRequest)
1.305 + {
1.306 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.307 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.308 + iHub->DoRequest(EDeviceStateChange, aRequest, (TAny*)iHandle, &aNewState);
1.309 + }
1.310 +
1.311 +
1.312 +/**
1.313 +Cancels an outstanding request for device state changes
1.314 +@see QueueDeviceStateChangeNotification
1.315 +*/
1.316 +void RUsbDevice::CancelDeviceStateChangeNotification()
1.317 + {
1.318 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.319 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.320 + iHub->DoControl(ECancelDeviceStateChange, (TAny*)iHandle);
1.321 + }
1.322 +
1.323 +
1.324 +/**
1.325 +Return the USB Device Descriptor for this device.
1.326 +
1.327 +Note: the supplied TUsbDeviceDescriptor is owned by the caller, but any descriptor objects linked to it
1.328 +remain the property of the RUsbDevice object. Memory leaks will result if the head pointer is not
1.329 +cleaned up, but the pointed to objects should not be destroyed.
1.330 +
1.331 +@param [out] aDescriptor The supplied TUsbDeviceDescriptor object will be populated from the data retrieved from the
1.332 +device.
1.333 +
1.334 +@return KErrNone on success, otherwise a system wide error code.
1.335 +*/
1.336 +TInt RUsbDevice::GetDeviceDescriptor(TUsbDeviceDescriptor& aDescriptor)
1.337 + {
1.338 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.339 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.340 + aDescriptor = *iHeadDeviceDescriptor;
1.341 + return KErrNone;
1.342 + }
1.343 +
1.344 +/**
1.345 +Return the USB Configuration Descriptor for this device.
1.346 +
1.347 +Note: the supplied TUsbConfigurationDescriptor is owned by the caller, but any descriptor objects linked to it
1.348 +remain the property of the RUsbDevice object. Memory leaks will result if the head pointer is not
1.349 +cleaned up, but the pointed to objects should not be destroyed.
1.350 +
1.351 +@param [out] aDescriptor The supplied TUsbConfigurationDescriptor object will be populated from the data retrieved from
1.352 +the device. Note that the caller owns the head of the list, but not any children or peers.
1.353 +
1.354 +@return KErrNone on success, otherwise a system wide error code.
1.355 +*/
1.356 +TInt RUsbDevice::GetConfigurationDescriptor(TUsbConfigurationDescriptor& aDescriptor)
1.357 + {
1.358 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.359 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.360 + aDescriptor = *iHeadConfDescriptor;
1.361 + return KErrNone;
1.362 + }
1.363 +
1.364 +TInt RUsbDevice::GetStringDescriptor(TUsbStringDescriptor*& aDescriptor, TDes8& aTarget, TInt aIndex)
1.365 + {
1.366 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.367 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.368 +
1.369 + aDescriptor = NULL;
1.370 + // aTarget will be Zero-ed in the GetStringDescriptor overload.
1.371 +
1.372 + TInt err = GetStringDescriptor(aTarget, aIndex);
1.373 + if(err != KErrNone)
1.374 + {
1.375 + return err;
1.376 + }
1.377 + return ParseStringDescriptor(aDescriptor, aTarget);
1.378 + }
1.379 +
1.380 +TInt RUsbDevice::GetStringDescriptor(TUsbStringDescriptor*& aDescriptor, TDes8& aTarget, TInt aIndex, TInt aLangId)
1.381 + {
1.382 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.383 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.384 +
1.385 + aDescriptor = NULL;
1.386 + // aTarget will be Zero-ed in the GetStringDescriptor overload.
1.387 +
1.388 + TInt err = GetStringDescriptor(aTarget, aIndex, aLangId);
1.389 + if(err != KErrNone)
1.390 + {
1.391 + return err;
1.392 + }
1.393 +
1.394 + return ParseStringDescriptor(aDescriptor, aTarget);
1.395 + }
1.396 +
1.397 +TInt RUsbDevice::ParseStringDescriptor(TUsbStringDescriptor*& aDescriptor, const TDesC8& aData)
1.398 + {
1.399 + TUsbGenericDescriptor* parsed = NULL;
1.400 + TInt err = UsbDescriptorParser::Parse(aData, parsed);
1.401 + if(err == KErrNone)
1.402 + {
1.403 + aDescriptor = TUsbStringDescriptor::Cast(parsed);
1.404 + if(aDescriptor)
1.405 + {
1.406 + return KErrNone;
1.407 + }
1.408 + }
1.409 + // If here then there has been an error when parsing the descriptor
1.410 + if(parsed)
1.411 + {
1.412 + parsed->DestroyTree();
1.413 + delete parsed;
1.414 + }
1.415 + return (err != KErrNone) ? err : KErrCorrupt;
1.416 + }
1.417 +
1.418 +
1.419 +
1.420 +
1.421 +TInt RUsbDevice::GetDeviceDescriptor(TDes8& aDeviceDesc)
1.422 + {
1.423 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.424 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.425 + return iHub->DoControl(EGetDeviceDescriptor, (TAny*)iHandle, &aDeviceDesc);
1.426 + }
1.427 +
1.428 +
1.429 +TInt RUsbDevice::GetConfigurationDescriptorSize(TInt& aSize)
1.430 + {
1.431 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.432 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.433 + return iHub->DoControl(EGetConfigurationDescriptorSize, (TAny*)iHandle, &aSize);
1.434 + }
1.435 +
1.436 +
1.437 +TInt RUsbDevice::GetConfigurationDescriptor(TDes8& aConfigDesc)
1.438 + {
1.439 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbHubDriverPanicCat, UsbdiPanics::EUsbHubDriverRequestMadeWhileClosed));
1.440 + __ASSERT_DEBUG(iHub, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbDeviceHasHandleButNoHubDriver));
1.441 + return iHub->DoControl(EGetConfigurationDescriptor, (TAny*)iHandle, &aConfigDesc);
1.442 + }
1.443 +
1.444 +
1.445 +#endif // !__KERNEL_MODE__