1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/d32usbdi.inl Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,538 @@
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 +
1.21 + The driver's name
1.22 +
1.23 + @return The name of the driver
1.24 +
1.25 + @internalComponent
1.26 +*/
1.27 +const TDesC& RUsbInterface::Name()
1.28 + {
1.29 + _LIT(KDriverName,"USBDI");
1.30 + return KDriverName;
1.31 + }
1.32 +
1.33 +/**
1.34 +The driver's version
1.35 +
1.36 +@return The version number of the driver
1.37 +
1.38 +@internalComponent
1.39 +*/
1.40 +TVersion RUsbInterface::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 +
1.50 +#ifndef __KERNEL_MODE__
1.51 +RUsbInterface::RUsbInterface()
1.52 + : iHeadInterfaceDescriptor(NULL)
1.53 + , iInterfaceDescriptorData(NULL)
1.54 + , iTransferStrategy(NULL)
1.55 + , iAlternateSetting(0)
1.56 + {
1.57 + }
1.58 +
1.59 +/**
1.60 +Signals to the hub driver that this interface is idle and may be suspended.
1.61 +As suspend operates at the device level, this will only trigger a removal of bus activity if all interfaces
1.62 +associated with the device are marked as suspended.
1.63 +
1.64 +@param [in] aResumeSignal The TRequestStatus that will be completed when the interface is resumed.
1.65 +*/
1.66 +void RUsbInterface::PermitSuspendAndWaitForResume(TRequestStatus& aResumeSignal)
1.67 + {
1.68 + DoRequest(ESuspend, aResumeSignal);
1.69 + }
1.70 +
1.71 +/**
1.72 +Cancel the outstanding permission to suspend.
1.73 +*/
1.74 +void RUsbInterface::CancelPermitSuspend()
1.75 + {
1.76 + DoCancel(ECancelSuspend);
1.77 + }
1.78 +
1.79 +/**
1.80 +Cancel the outstanding PermitSuspendAndWaitForResume request with KErrCancel
1.81 +*/
1.82 +void RUsbInterface::CancelWaitForResume()
1.83 + {
1.84 + DoCancel(ECancelWaitForResume);
1.85 + }
1.86 +
1.87 +/**
1.88 +Request or clear the interface's remote wakeup flag. If any interface on the device
1.89 +has this flag set, suspending the device will cause it to have remote wakeup capability
1.90 +enabled. This function may only be called when the interface is active -- the device will
1.91 +not be woken to change the status if it is currently suspended.
1.92 +Note that clearing this flag will not prevent a device from using remote wakeup -- this
1.93 +will happen only if all interfaces on the device do not require it.
1.94 +By default the device will not have remote wakeup enabled.
1.95 +
1.96 +@param aAllowed ETrue if remote wakeup should be permitted, EFalse if this interface does
1.97 +not require it.
1.98 +
1.99 +@return KErrNotReady if two calls have been made in succession with the same parameter.
1.100 +KErrUsbDeviceSuspended if the interface is currently marked as suspended.
1.101 +*/
1.102 +TInt RUsbInterface::PermitRemoteWakeup(TBool aAllowed)
1.103 + {
1.104 + return DoControl(EPermitRemoteWakeup, (TAny*)aAllowed);
1.105 + }
1.106 +
1.107 +
1.108 +/**
1.109 +Select the specified alternate interface.
1.110 +
1.111 +Asserts that all open pipes have been closed.
1.112 +
1.113 +@param [in] aAlternateInterface The alternate interface to select.
1.114 +
1.115 +@return KErrArgument if the specified alternate interface does not exist.
1.116 +@return KErrOverflow if selecting this alternate interface would overcommit the bus' bandwidth.
1.117 +*/
1.118 +TInt RUsbInterface::SelectAlternateInterface(TInt aAlternateInterface)
1.119 + {
1.120 + TInt err = DoControl(ESelectAlternateInterface, (TAny*)aAlternateInterface);
1.121 + if(err == KErrNone)
1.122 + {
1.123 + iAlternateSetting = aAlternateInterface;
1.124 + }
1.125 + return err;
1.126 + }
1.127 +
1.128 +TInt RUsbInterface::GetStringDescriptor(TDes8& aStringDescriptor, TUint8 aIndex, TUint16 aLangId)
1.129 + {
1.130 + TUint32 params;
1.131 + params = aIndex | (aLangId << 16);
1.132 + return DoControl(EGetStringDescriptor, &aStringDescriptor, ¶ms);
1.133 + }
1.134 +
1.135 +
1.136 +/**
1.137 +Performs an Endpoint 0 transfer.
1.138 +*/
1.139 +void RUsbInterface::Ep0Transfer(TUsbTransferRequestDetails& aDetails, const TDesC8& aSend, TDes8& aRecv, TRequestStatus& aRequest)
1.140 + {
1.141 + aDetails.iSend = &aSend;
1.142 + aDetails.iRecv = &aRecv;
1.143 + DoRequest(EEp0Transfer, aRequest, (TAny*)&aDetails);
1.144 + }
1.145 +
1.146 +/**
1.147 +Cancel an Endpoint 0 transfer.
1.148 +*/
1.149 +void RUsbInterface::CancelEP0Transfer()
1.150 + {
1.151 + DoCancel(ECancelEp0Transfer);
1.152 + }
1.153 +
1.154 +/**
1.155 +Establish a pipe between host and device. The RUsbPipe object returned is ready for use.
1.156 +
1.157 +@param aPipe The pipe to connect to the remote endpoint. [out]
1.158 +@param aEndpoint The endpoint on the remote device to connect to. [in]
1.159 +@param aUseDMA In future implementations where DMA is supported this flag indicates DMA must be used. The Open attempt will fail if DMA cannot be offered on the pipe. [in]
1.160 +
1.161 +@return KErrArgument if the specified endpoint does not exist.
1.162 +@see SelectAlternateInterface
1.163 +*/
1.164 +TInt RUsbInterface::OpenPipeForEndpoint(RUsbPipe& aPipe, TInt aEndpoint, TBool /*aUseDMA*/)
1.165 + {
1.166 + if(aPipe.iHandle)
1.167 + {
1.168 + return KErrInUse;
1.169 + }
1.170 +
1.171 + TInt err = GetEndpointDescriptor(iAlternateSetting, aEndpoint, aPipe.iHeadEndpointDescriptor);
1.172 + // Allow KErrNotFound as audio endpoint descriptors are not valid endpoint descriptors
1.173 + if ((err == KErrNone) || (err == KErrNotFound))
1.174 + {
1.175 + TUint32 pipeHandle;
1.176 + err = DoControl(EOpenPipe, &pipeHandle, reinterpret_cast<TAny*>(aEndpoint));
1.177 + if (err == KErrNone)
1.178 + {
1.179 + aPipe.iHandle = pipeHandle;
1.180 + aPipe.iInterface = this;
1.181 + }
1.182 + }
1.183 +
1.184 + return err;
1.185 + }
1.186 +
1.187 +/**
1.188 +@internalComponent
1.189 +*/
1.190 +TInt RUsbInterface::AllocateSharedChunk(RChunk& aChunk, TInt aSize, TInt& aOffset)
1.191 + {
1.192 + TInt chunkHandle = 0;
1.193 + RUsbInterface::TChunkRequestDetails details;
1.194 + details.iRequestSize = aSize;
1.195 + details.iChunkHandle = &chunkHandle;
1.196 + details.iOffset = &aOffset;
1.197 + TInt err = DoControl(EAllocChunk, &details);
1.198 + if(err == KErrNone)
1.199 + {
1.200 + aChunk.SetHandle(chunkHandle);
1.201 + }
1.202 + return err;
1.203 + }
1.204 +
1.205 +/**
1.206 +Return the section of the USB Configuration Descriptor under this interface, including any alternate
1.207 +interfaces.
1.208 +
1.209 +Note: the supplied TUsbInterfaceDescriptor is owned by the caller, but any descriptor objects linked to it
1.210 +remain the property of the RUsbInterface object. Memory leaks will result if the head pointer is not
1.211 +cleaned up, but the pointed to objects should not be destroyed.
1.212 +
1.213 +@param [out] aDescriptor The supplied TUsbInterfaceDescriptor object will be populated from the data retrieved from
1.214 +the device. Note that the caller owns the head of the list, but not any children or peers.
1.215 +
1.216 +@return System wide error code.
1.217 +*/
1.218 +TInt RUsbInterface::GetInterfaceDescriptor(TUsbInterfaceDescriptor& aDescriptor)
1.219 + {
1.220 + if (!iHeadInterfaceDescriptor)
1.221 + {
1.222 + return KErrNotReady;
1.223 + }
1.224 +
1.225 + aDescriptor = *iHeadInterfaceDescriptor;
1.226 + return KErrNone;
1.227 + }
1.228 +
1.229 +/**
1.230 +Find and return the section of the USB Configuration Descriptor under the supplied alternate interface.
1.231 +
1.232 +Note: the supplied TUsbInterfaceDescriptor is owned by the caller, but any descriptor objects linked to it
1.233 +remain the property of the RUsbInterface object. Memory leaks will result if the head pointer is not
1.234 +cleaned up, but the pointed to objects should not be destroyed.
1.235 +
1.236 +@param aAlternateInterface The alternate interface number to return the descriptor for. [in]
1.237 +@param aDescriptor The supplied TUsbInterfaceDescriptor object will be populated from the data retrieved from
1.238 +the device. Note that the caller owns the head of the list, but not any children or peers. [out]
1.239 +
1.240 +@return KErrArgument if the specified alternate interface does not exist.
1.241 +*/
1.242 +TInt RUsbInterface::GetAlternateInterfaceDescriptor(TInt aAlternateInterface, TUsbInterfaceDescriptor& aDescriptor)
1.243 + {
1.244 + if (!iHeadInterfaceDescriptor)
1.245 + {
1.246 + return KErrNotReady;
1.247 + }
1.248 +
1.249 + TUsbGenericDescriptor* descriptor = iHeadInterfaceDescriptor;
1.250 + while (descriptor)
1.251 + {
1.252 + TUsbInterfaceDescriptor* interface = TUsbInterfaceDescriptor::Cast(descriptor);
1.253 + if (interface)
1.254 + {
1.255 + if (interface->AlternateSetting() == aAlternateInterface)
1.256 + {
1.257 + aDescriptor = *interface;
1.258 + return KErrNone;
1.259 + }
1.260 + }
1.261 + // we must check any Interface Association Descriptors for
1.262 + // Alternate Interface settings. The spec is abiguous on how these may be organised so we
1.263 + // presume the worst and do a full search
1.264 + TUsbInterfaceAssociationDescriptor* iad = TUsbInterfaceAssociationDescriptor::Cast(descriptor);
1.265 + if (iad)
1.266 + {
1.267 + TUsbGenericDescriptor* assocDes = iad->iFirstChild;
1.268 + while (assocDes)
1.269 + {
1.270 + interface = TUsbInterfaceDescriptor::Cast(assocDes);
1.271 + if (interface)
1.272 + {
1.273 + if (interface->AlternateSetting() == aAlternateInterface)
1.274 + {
1.275 + aDescriptor = *interface;
1.276 + return KErrNone;
1.277 + }
1.278 + }
1.279 + assocDes = assocDes->iNextPeer;
1.280 + }
1.281 + }
1.282 + descriptor = descriptor->iNextPeer;
1.283 + }
1.284 +
1.285 + return KErrArgument;
1.286 + }
1.287 +
1.288 +/**
1.289 +Find and return the section of the USB Configuration Descriptor under the supplied endpoint.
1.290 +
1.291 +Note: the supplied TUsbEndpointDescriptor is owned by the caller, but any descriptor objects linked to it
1.292 +remain the property of the RUsbInterface object. Memory leaks will result if the head pointer is not
1.293 +cleaned up, but the pointed to objects should not be destroyed.
1.294 +
1.295 +@param aAlternateInterface The alternate interface number to return the descriptor for. [in]
1.296 +@param aEndpoint The endpoint number to return the descriptor for. [in]
1.297 +@param aDescriptor The supplied TUsbEndpointDescriptor object will be populated from the data retrieved from
1.298 +the device. Note that the caller owns the head of the list, but not any children or peers. [out]
1.299 +
1.300 +@return KErrArgument if the specified alternate interface does not exist, or KErrNotFound if the specified
1.301 +endpoint cannot be found on the alternate interface.
1.302 +*/
1.303 +TInt RUsbInterface::GetEndpointDescriptor(TInt aAlternateInterface, TInt aEndpoint, TUsbEndpointDescriptor& aDescriptor)
1.304 + {
1.305 + TUsbEndpointDescriptor* descriptor = &aDescriptor;
1.306 + TInt err = GetEndpointDescriptor(aAlternateInterface, aEndpoint, descriptor);
1.307 + if ((err == KErrNone) && descriptor)
1.308 + {
1.309 + aDescriptor = *descriptor;
1.310 + }
1.311 + return err;
1.312 + }
1.313 +
1.314 +TInt RUsbInterface::GetEndpointDescriptor(TInt aAlternateInterface, TInt aEndpoint, TUsbEndpointDescriptor*& aDescriptor)
1.315 + {
1.316 + aDescriptor = NULL;
1.317 +
1.318 + TUsbInterfaceDescriptor alternate;
1.319 + TInt err = GetAlternateInterfaceDescriptor(aAlternateInterface, alternate);
1.320 + if (err != KErrNone)
1.321 + {
1.322 + return err;
1.323 + }
1.324 +
1.325 + TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
1.326 + while (descriptor)
1.327 + {
1.328 + TUsbEndpointDescriptor* endpoint = TUsbEndpointDescriptor::Cast(descriptor);
1.329 + if (endpoint && (endpoint->EndpointAddress() == aEndpoint))
1.330 + {
1.331 + aDescriptor = endpoint;
1.332 + return KErrNone;
1.333 + }
1.334 +
1.335 + descriptor = descriptor->iNextPeer;
1.336 + }
1.337 +
1.338 + return KErrNotFound;
1.339 + }
1.340 +
1.341 +/**
1.342 +@return Number of alternate interface options on this interface.
1.343 +*/
1.344 +TInt RUsbInterface::GetAlternateInterfaceCount()
1.345 + {
1.346 + if (!iHeadInterfaceDescriptor)
1.347 + {
1.348 + return KErrNotReady;
1.349 + }
1.350 +
1.351 + TInt count = 0;
1.352 +
1.353 + // Don't need to look for children of the interface -- all the alternates
1.354 + // must be peers.
1.355 + TUsbGenericDescriptor* descriptor = iHeadInterfaceDescriptor;
1.356 + while (descriptor)
1.357 + {
1.358 + TUsbInterfaceDescriptor* interface = TUsbInterfaceDescriptor::Cast(descriptor);
1.359 + if (interface)
1.360 + {
1.361 + ++count;
1.362 + }
1.363 + else
1.364 + {
1.365 + // we must check any Interface Association Descriptors for
1.366 + // Alternate Interface settings. The spec is abiguous on how these may be organised so we
1.367 + // presume the worst and do a full search
1.368 + TUsbInterfaceAssociationDescriptor* iad = TUsbInterfaceAssociationDescriptor::Cast(descriptor);
1.369 + if (iad)
1.370 + {
1.371 + TUsbGenericDescriptor* assocDes = iad->iFirstChild;
1.372 + while (assocDes)
1.373 + {
1.374 + interface = TUsbInterfaceDescriptor::Cast(assocDes);
1.375 + if (interface)
1.376 + {
1.377 + ++count;
1.378 + }
1.379 + assocDes = assocDes->iNextPeer;
1.380 + }
1.381 + }
1.382 + }
1.383 + descriptor = descriptor->iNextPeer;
1.384 + }
1.385 +
1.386 + return count;
1.387 + }
1.388 +
1.389 +/**
1.390 +Count the endpoints on an alternate interface.
1.391 +
1.392 +@param [in] aAlternateInterface The alternate interface to count endpoints on.
1.393 +@return Number of endpoionts on the requested alternate interface or an error code.
1.394 +*/
1.395 +TInt RUsbInterface::EnumerateEndpointsOnInterface(TInt aAlternateInterface)
1.396 + {
1.397 + TUsbInterfaceDescriptor alternate;
1.398 + TInt err = GetAlternateInterfaceDescriptor(aAlternateInterface, alternate);
1.399 + if (err != KErrNone)
1.400 + {
1.401 + return err;
1.402 + }
1.403 +
1.404 + return alternate.NumEndpoints();
1.405 + }
1.406 +
1.407 +/**
1.408 +Returns an identifier that is unique for the bus that the device that provides this interface is on.
1.409 +@param aBusId On success provides an identifier that is unique for the bus this interface is on.
1.410 +@return KErrNone on success, otherwise a system-wide error code.
1.411 +*/
1.412 +TInt RUsbInterface::GetBusId(TUsbBusId& aBusId)
1.413 + {
1.414 + return DoControl(EGetBusId, &aBusId);
1.415 + }
1.416 +
1.417 +/**
1.418 +Returns the size of pages used by the HCD.
1.419 +@internalComponent
1.420 +@return The HCD's page size.
1.421 +*/
1.422 +TInt RUsbInterface::HcdPageSize()
1.423 + {
1.424 + return DoControl(EHcdPageSize);
1.425 + }
1.426 +
1.427 +/**
1.428 +Returns the speed the remote device is connected at.
1.429 +@param aDeviceSpeed On sucess an enumeration value describing the current speed of the remote device.
1.430 +@return KErrNone on success, otherwise a system-wide error code.
1.431 +*/
1.432 +TInt RUsbInterface::GetDeviceSpeed(RUsbInterface::TDeviceSpeed& aDeviceSpeed)
1.433 + {
1.434 + return DoControl(EGetDeviceSpeed, &aDeviceSpeed);
1.435 + }
1.436 +
1.437 +
1.438 +
1.439 +
1.440 +
1.441 +RUsbPipe::RUsbPipe()
1.442 + : iHandle(0)
1.443 + , iInterface(NULL)
1.444 + {
1.445 + }
1.446 +
1.447 +TUint32 RUsbPipe::Handle() const
1.448 + {
1.449 + return iHandle;
1.450 + }
1.451 +
1.452 +/**
1.453 +Close a pipe to a remote device.
1.454 +*/
1.455 +void RUsbPipe::Close()
1.456 + {
1.457 + if (iInterface)
1.458 + {
1.459 + static_cast<void>(iInterface->DoControl(EClose, (TAny*)iHandle));
1.460 + }
1.461 + iHeadEndpointDescriptor = NULL;
1.462 + iInterface = NULL;
1.463 + iHandle = 0;
1.464 + }
1.465 +
1.466 +/**
1.467 +Clear a stall on the remote endpoint.
1.468 +
1.469 +@return System-wide error code.
1.470 +*/
1.471 +TInt RUsbPipe::ClearRemoteStall()
1.472 + {
1.473 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
1.474 + __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
1.475 + return iInterface->DoControl(EClearRemoteStall, (TAny*)iHandle);
1.476 + }
1.477 +
1.478 +/**
1.479 +Cancel all queued transfers
1.480 +*/
1.481 +void RUsbPipe::CancelAllTransfers()
1.482 + {
1.483 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
1.484 + __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
1.485 + static_cast<void>(iInterface->DoControl(EAbort, (TAny*)iHandle));
1.486 + }
1.487 +
1.488 +/**
1.489 +Issues a transfer.
1.490 +@internalComponent
1.491 +*/
1.492 +void RUsbPipe::IssueTransfer(TInt aTransferHandle, TRequestStatus& aRequest)
1.493 + {
1.494 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
1.495 + __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
1.496 + iInterface->DoRequest(EIssueTransfer, aRequest, (TAny*)iHandle, (TAny*)aTransferHandle);
1.497 + }
1.498 +
1.499 +/**
1.500 +Get endpoint ID
1.501 +*/
1.502 +TInt RUsbPipe::GetEndpointId(TUsbEndpointId& aEndpointId)
1.503 + {
1.504 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
1.505 + __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
1.506 + return iInterface->DoControl(EGetEndpointId, reinterpret_cast<TAny*>(iHandle), &aEndpointId);
1.507 + }
1.508 +
1.509 +/**
1.510 +Get Bus ID
1.511 +*/
1.512 +TInt RUsbPipe::GetBusId(TUsbBusId& aBusId)
1.513 + {
1.514 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
1.515 + __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
1.516 + return iInterface->GetBusId(aBusId);
1.517 + }
1.518 +
1.519 +/**
1.520 +Return the section of the USB Configuration Descriptor under the supplied endpoint.
1.521 +
1.522 +@param [out] aDescriptor The descriptor tree for this endpoint.
1.523 +@return System-wide error code.
1.524 +*/
1.525 +TInt RUsbPipe::GetEndpointDescriptor(TUsbEndpointDescriptor& aDescriptor)
1.526 + {
1.527 + __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
1.528 + __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
1.529 +
1.530 + if (iHeadEndpointDescriptor)
1.531 + {
1.532 + aDescriptor = *iHeadEndpointDescriptor;
1.533 + return KErrNone;
1.534 + }
1.535 + else
1.536 + {
1.537 + return KErrNotFound;
1.538 + }
1.539 + }
1.540 +
1.541 +#endif