kernel/eka/include/d32usbdi.inl
changeset 0 a41df078684a
child 87 2f92ad2dc5db
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  
       
    18  The driver's name
       
    19  
       
    20  @return The name of the driver
       
    21  
       
    22  @internalComponent
       
    23 */
       
    24 const TDesC& RUsbInterface::Name()
       
    25 	{
       
    26 	_LIT(KDriverName,"USBDI");
       
    27 	return KDriverName;
       
    28 	}
       
    29 
       
    30 /**
       
    31 The driver's version
       
    32 
       
    33 @return The version number of the driver
       
    34 
       
    35 @internalComponent
       
    36 */
       
    37 TVersion RUsbInterface::VersionRequired()
       
    38 	{
       
    39 	const TInt KMajorVersionNumber=1;
       
    40 	const TInt KMinorVersionNumber=0;
       
    41 	const TInt KBuildVersionNumber=KE32BuildVersionNumber;
       
    42 	return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
       
    43 	}
       
    44 
       
    45 
       
    46 
       
    47 #ifndef __KERNEL_MODE__
       
    48 RUsbInterface::RUsbInterface()
       
    49 	: iHeadInterfaceDescriptor(NULL)
       
    50 	, iInterfaceDescriptorData(NULL)
       
    51 	, iTransferStrategy(NULL)
       
    52 	, iAlternateSetting(0)
       
    53 	{
       
    54 	}
       
    55 
       
    56 /**
       
    57 Signals to the hub driver that this interface is idle and may be suspended.
       
    58 As suspend operates at the device level, this will only trigger a removal of bus activity if all interfaces
       
    59 associated with the device are marked as suspended.
       
    60 
       
    61 @param [in] aResumeSignal The TRequestStatus that will be completed when the interface is resumed.
       
    62 */
       
    63 void RUsbInterface::PermitSuspendAndWaitForResume(TRequestStatus& aResumeSignal)
       
    64 	{
       
    65 	DoRequest(ESuspend, aResumeSignal);
       
    66 	}
       
    67 
       
    68 /**
       
    69 Cancel the outstanding permission to suspend.
       
    70 */
       
    71 void RUsbInterface::CancelPermitSuspend()
       
    72 	{
       
    73 	DoCancel(ECancelSuspend);
       
    74 	}
       
    75 
       
    76 /**
       
    77 Cancel the outstanding PermitSuspendAndWaitForResume request with KErrCancel
       
    78 */
       
    79 void RUsbInterface::CancelWaitForResume()
       
    80 	{
       
    81 	DoCancel(ECancelWaitForResume);
       
    82 	}
       
    83 
       
    84 /**
       
    85 Request or clear the interface's remote wakeup flag.  If any interface on the device
       
    86 has this flag set, suspending the device will cause it to have remote wakeup capability
       
    87 enabled.  This function may only be called when the interface is active -- the device will
       
    88 not be woken to change the status if it is currently suspended.
       
    89 Note that clearing this flag will not prevent a device from using remote wakeup -- this
       
    90 will happen only if all interfaces on the device do not require it.
       
    91 By default the device will not have remote wakeup enabled.
       
    92 
       
    93 @param aAllowed ETrue if remote wakeup should be permitted, EFalse if this interface does
       
    94 not require it.
       
    95 
       
    96 @return KErrNotReady if two calls have been made in succession with the same parameter.
       
    97 KErrUsbDeviceSuspended if the interface is currently marked as suspended.
       
    98 */
       
    99 TInt RUsbInterface::PermitRemoteWakeup(TBool aAllowed)
       
   100 	{
       
   101 	return DoControl(EPermitRemoteWakeup, (TAny*)aAllowed);
       
   102 	}
       
   103 
       
   104 
       
   105 /**
       
   106 Select the specified alternate interface.
       
   107 
       
   108 Asserts that all open pipes have been closed.
       
   109 
       
   110 @param [in] aAlternateInterface The alternate interface to select.
       
   111 
       
   112 @return KErrArgument if the specified alternate interface does not exist.
       
   113 @return KErrOverflow if selecting this alternate interface would overcommit the bus' bandwidth.
       
   114 */
       
   115 TInt RUsbInterface::SelectAlternateInterface(TInt aAlternateInterface)
       
   116 	{
       
   117 	TInt err = DoControl(ESelectAlternateInterface, (TAny*)aAlternateInterface);
       
   118 	if(err == KErrNone)
       
   119 		{
       
   120 		iAlternateSetting = aAlternateInterface;
       
   121 		}
       
   122 	return err;
       
   123 	}
       
   124 
       
   125 TInt RUsbInterface::GetStringDescriptor(TDes8& aStringDescriptor, TUint8 aIndex, TUint16 aLangId)
       
   126 	{
       
   127 	TUint32 params;
       
   128 	params = aIndex | (aLangId << 16);
       
   129 	return DoControl(EGetStringDescriptor, &aStringDescriptor, &params);
       
   130 	}
       
   131 
       
   132 
       
   133 /**  
       
   134 Performs an Endpoint 0 transfer.
       
   135 */
       
   136 void RUsbInterface::Ep0Transfer(TUsbTransferRequestDetails& aDetails, const TDesC8& aSend, TDes8& aRecv, TRequestStatus& aRequest)
       
   137 	{
       
   138 	aDetails.iSend         = &aSend;
       
   139 	aDetails.iRecv         = &aRecv;
       
   140 	DoRequest(EEp0Transfer, aRequest, (TAny*)&aDetails);
       
   141 	}
       
   142 
       
   143 /**  
       
   144 Cancel an Endpoint 0 transfer.
       
   145 */
       
   146 void RUsbInterface::CancelEP0Transfer()
       
   147 	{
       
   148 	DoCancel(ECancelEp0Transfer);
       
   149 	}
       
   150 
       
   151 /**
       
   152 Establish a pipe between host and device.  The RUsbPipe object returned is ready for use.
       
   153 
       
   154 @param aPipe The pipe to connect to the remote endpoint. [out]
       
   155 @param aEndpoint The endpoint on the remote device to connect to. [in]
       
   156 @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]
       
   157 
       
   158 @return KErrArgument if the specified endpoint does not exist.
       
   159 @see SelectAlternateInterface
       
   160 */
       
   161 TInt RUsbInterface::OpenPipeForEndpoint(RUsbPipe& aPipe, TInt aEndpoint, TBool /*aUseDMA*/)
       
   162 	{
       
   163 	if(aPipe.iHandle)
       
   164 		{
       
   165 		return KErrInUse;
       
   166 		}
       
   167 
       
   168 	TInt err = GetEndpointDescriptor(iAlternateSetting, aEndpoint, aPipe.iHeadEndpointDescriptor);
       
   169 	// Allow KErrNotFound as audio endpoint descriptors are not valid endpoint descriptors
       
   170 	if ((err == KErrNone) || (err == KErrNotFound))
       
   171 		{
       
   172 		TUint32 pipeHandle;
       
   173 		err = DoControl(EOpenPipe, &pipeHandle, reinterpret_cast<TAny*>(aEndpoint));
       
   174 		if (err == KErrNone)
       
   175 			{
       
   176 			aPipe.iHandle = pipeHandle;
       
   177 			aPipe.iInterface = this;
       
   178 			}
       
   179 		}
       
   180 
       
   181 	return err;
       
   182 	}
       
   183 
       
   184 /**
       
   185 @internalComponent
       
   186 */
       
   187 TInt RUsbInterface::AllocateSharedChunk(RChunk& aChunk, TInt aSize, TInt& aOffset)
       
   188 	{
       
   189 	TInt chunkHandle = 0;
       
   190 	RUsbInterface::TChunkRequestDetails details;
       
   191 	details.iRequestSize = aSize;
       
   192 	details.iChunkHandle = &chunkHandle;
       
   193 	details.iOffset = &aOffset;
       
   194 	TInt err = DoControl(EAllocChunk, &details);
       
   195 	if(err == KErrNone)
       
   196 		{
       
   197 		aChunk.SetHandle(chunkHandle);
       
   198 		}
       
   199 	return err;
       
   200 	}
       
   201 
       
   202 /**
       
   203 Return the section of the USB Configuration Descriptor under this interface, including any alternate
       
   204 interfaces.
       
   205 
       
   206 Note: the supplied TUsbInterfaceDescriptor is owned by the caller, but any descriptor objects linked to it
       
   207 remain the property of the RUsbInterface object.  Memory leaks will result if the head pointer is not
       
   208 cleaned up, but the pointed to objects should not be destroyed.
       
   209 
       
   210 @param [out] aDescriptor The supplied TUsbInterfaceDescriptor object will be populated from the data retrieved from
       
   211 the	device.  Note that the caller owns the head of the list, but not any children or peers.
       
   212 
       
   213 @return System wide error code.
       
   214 */
       
   215 TInt RUsbInterface::GetInterfaceDescriptor(TUsbInterfaceDescriptor& aDescriptor)
       
   216 	{
       
   217 	if (!iHeadInterfaceDescriptor)
       
   218 		{
       
   219 		return KErrNotReady;
       
   220 		}
       
   221 
       
   222 	aDescriptor = *iHeadInterfaceDescriptor;
       
   223 	return KErrNone;
       
   224 	}
       
   225 
       
   226 /**
       
   227 Find and return the section of the USB Configuration Descriptor under the supplied alternate interface.
       
   228 
       
   229 Note: the supplied TUsbInterfaceDescriptor is owned by the caller, but any descriptor objects linked to it
       
   230 remain the property of the RUsbInterface object.  Memory leaks will result if the head pointer is not
       
   231 cleaned up, but the pointed to objects should not be destroyed.
       
   232 
       
   233 @param aAlternateInterface The alternate interface number to return the descriptor for. [in]
       
   234 @param aDescriptor The supplied TUsbInterfaceDescriptor object will be populated from the data retrieved from
       
   235 the	device.  Note that the caller owns the head of the list, but not any children or peers. [out]
       
   236 
       
   237 @return KErrArgument if the specified alternate interface does not exist.
       
   238 */
       
   239 TInt RUsbInterface::GetAlternateInterfaceDescriptor(TInt aAlternateInterface, TUsbInterfaceDescriptor& aDescriptor)
       
   240 	{
       
   241 	if (!iHeadInterfaceDescriptor)
       
   242 		{
       
   243 		return KErrNotReady;
       
   244 		}
       
   245 
       
   246 	TUsbGenericDescriptor* descriptor = iHeadInterfaceDescriptor;
       
   247 	while (descriptor)
       
   248 		{
       
   249 		TUsbInterfaceDescriptor* interface = TUsbInterfaceDescriptor::Cast(descriptor);
       
   250 		if (interface)
       
   251 			{
       
   252 			if (interface->AlternateSetting() == aAlternateInterface)
       
   253 				{
       
   254 				aDescriptor = *interface;
       
   255 				return KErrNone;
       
   256 				}
       
   257 			}
       
   258         // we must check any Interface Association Descriptors for
       
   259         // Alternate Interface settings.  The spec is abiguous on how these may be organised so we
       
   260         // presume the worst and do a full search
       
   261 		TUsbInterfaceAssociationDescriptor* iad = TUsbInterfaceAssociationDescriptor::Cast(descriptor);
       
   262 		if (iad)
       
   263 			{
       
   264 			TUsbGenericDescriptor* assocDes = iad->iFirstChild;
       
   265 			while (assocDes)
       
   266 				{
       
   267 				interface = TUsbInterfaceDescriptor::Cast(assocDes);
       
   268 				if (interface)
       
   269 					{
       
   270 					if (interface->AlternateSetting() == aAlternateInterface)
       
   271 						{
       
   272 						aDescriptor = *interface;
       
   273 						return KErrNone;
       
   274 						}
       
   275 					}
       
   276 				assocDes = assocDes->iNextPeer;
       
   277 				}
       
   278 			}
       
   279 		descriptor = descriptor->iNextPeer;
       
   280 		}
       
   281 
       
   282 	return KErrArgument;
       
   283 	}
       
   284 
       
   285 /**
       
   286 Find and return the section of the USB Configuration Descriptor under the supplied endpoint.
       
   287 
       
   288 Note: the supplied TUsbEndpointDescriptor is owned by the caller, but any descriptor objects linked to it
       
   289 remain the property of the RUsbInterface object.  Memory leaks will result if the head pointer is not
       
   290 cleaned up, but the pointed to objects should not be destroyed.
       
   291 
       
   292 @param aAlternateInterface The alternate interface number to return the descriptor for. [in]
       
   293 @param aEndpoint The endpoint number to return the descriptor for. [in]
       
   294 @param aDescriptor The supplied TUsbEndpointDescriptor object will be populated from the data retrieved from
       
   295 the	device.  Note that the caller owns the head of the list, but not any children or peers. [out]
       
   296 
       
   297 @return KErrArgument if the specified alternate interface does not exist, or KErrNotFound if the specified
       
   298 endpoint cannot be found on the alternate interface.
       
   299 */
       
   300 TInt RUsbInterface::GetEndpointDescriptor(TInt aAlternateInterface, TInt aEndpoint, TUsbEndpointDescriptor& aDescriptor)
       
   301 	{
       
   302 	TUsbEndpointDescriptor* descriptor = &aDescriptor;
       
   303 	TInt err = GetEndpointDescriptor(aAlternateInterface, aEndpoint, descriptor);
       
   304     if ((err == KErrNone) && descriptor)
       
   305 		{
       
   306 		aDescriptor = *descriptor;
       
   307 		}
       
   308 	return err;
       
   309 	}
       
   310 
       
   311 TInt RUsbInterface::GetEndpointDescriptor(TInt aAlternateInterface, TInt aEndpoint, TUsbEndpointDescriptor*& aDescriptor)
       
   312 	{
       
   313 	aDescriptor = NULL;
       
   314 
       
   315 	TUsbInterfaceDescriptor alternate;
       
   316 	TInt err = GetAlternateInterfaceDescriptor(aAlternateInterface, alternate);
       
   317 	if (err != KErrNone)
       
   318 		{
       
   319 		return err;
       
   320 		}
       
   321 
       
   322 	TUsbGenericDescriptor* descriptor = alternate.iFirstChild;
       
   323 	while (descriptor)
       
   324 		{
       
   325 		TUsbEndpointDescriptor* endpoint = TUsbEndpointDescriptor::Cast(descriptor);
       
   326 		if (endpoint && (endpoint->EndpointAddress() == aEndpoint))
       
   327 			{
       
   328 			aDescriptor = endpoint;
       
   329 			return KErrNone;
       
   330 			}
       
   331 
       
   332 		descriptor = descriptor->iNextPeer;
       
   333 		}
       
   334 
       
   335 	return KErrNotFound;
       
   336 	}
       
   337 
       
   338 /**
       
   339 @return Number of alternate interface options on this interface.
       
   340 */
       
   341 TInt RUsbInterface::GetAlternateInterfaceCount()
       
   342 	{
       
   343 	if (!iHeadInterfaceDescriptor)
       
   344 		{
       
   345 		return KErrNotReady;
       
   346 		}
       
   347 
       
   348 	TInt count = 0;
       
   349 
       
   350 	// Don't need to look for children of the interface -- all the alternates
       
   351     // must be peers.
       
   352 	TUsbGenericDescriptor* descriptor = iHeadInterfaceDescriptor;
       
   353 	while (descriptor)
       
   354 		{
       
   355 		TUsbInterfaceDescriptor* interface = TUsbInterfaceDescriptor::Cast(descriptor);
       
   356 		if (interface)
       
   357 			{
       
   358 			++count;
       
   359 			}
       
   360 		else
       
   361             {
       
   362             // we must check any Interface Association Descriptors for
       
   363             // Alternate Interface settings.  The spec is abiguous on how these may be organised so we
       
   364             // presume the worst and do a full search
       
   365             TUsbInterfaceAssociationDescriptor* iad = TUsbInterfaceAssociationDescriptor::Cast(descriptor);
       
   366             if (iad)
       
   367                 {
       
   368                 TUsbGenericDescriptor* assocDes = iad->iFirstChild;
       
   369                 while (assocDes)
       
   370                     {
       
   371                     interface = TUsbInterfaceDescriptor::Cast(assocDes);
       
   372                     if (interface)
       
   373                         {
       
   374                         ++count;
       
   375                         }
       
   376                     assocDes = assocDes->iNextPeer;
       
   377                     }
       
   378                 }
       
   379             }
       
   380 		descriptor = descriptor->iNextPeer;
       
   381 		}
       
   382 
       
   383 	return count;
       
   384 	}
       
   385 
       
   386 /**
       
   387 Count the endpoints on an alternate interface.
       
   388 
       
   389 @param [in] aAlternateInterface The alternate interface to count endpoints on.
       
   390 @return Number of endpoionts on the requested alternate interface or an error code.
       
   391 */
       
   392 TInt RUsbInterface::EnumerateEndpointsOnInterface(TInt aAlternateInterface)
       
   393 	{
       
   394 	TUsbInterfaceDescriptor alternate;
       
   395 	TInt err = GetAlternateInterfaceDescriptor(aAlternateInterface, alternate);
       
   396 	if (err != KErrNone)
       
   397 		{
       
   398 		return err;
       
   399 		}
       
   400 
       
   401 	return alternate.NumEndpoints();
       
   402 	}
       
   403 	
       
   404 /**
       
   405 Returns an identifier that is unique for the bus that the device that provides this interface is on.
       
   406 @param aBusId On success provides an identifier that is unique for the bus this interface is on.
       
   407 @return KErrNone on success, otherwise a system-wide error code.
       
   408 */
       
   409 TInt RUsbInterface::GetBusId(TUsbBusId& aBusId)
       
   410 	{
       
   411 	return DoControl(EGetBusId, &aBusId);
       
   412 	}
       
   413 
       
   414 /**
       
   415 Returns the size of pages used by the HCD.
       
   416 @internalComponent
       
   417 @return The HCD's page size.
       
   418 */
       
   419 TInt RUsbInterface::HcdPageSize()
       
   420 	{
       
   421 	return DoControl(EHcdPageSize);
       
   422 	}
       
   423 
       
   424 /**
       
   425 Returns the speed the remote device is connected at.
       
   426 @param aDeviceSpeed On sucess an enumeration value describing the current speed of the remote device.
       
   427 @return KErrNone on success, otherwise a system-wide error code.
       
   428 */
       
   429 TInt RUsbInterface::GetDeviceSpeed(RUsbInterface::TDeviceSpeed& aDeviceSpeed)
       
   430 	{
       
   431 	return DoControl(EGetDeviceSpeed, &aDeviceSpeed);
       
   432 	}
       
   433 
       
   434 
       
   435 
       
   436 
       
   437 
       
   438 RUsbPipe::RUsbPipe()
       
   439 	: iHandle(0)
       
   440 	, iInterface(NULL)
       
   441 	{
       
   442 	}
       
   443 
       
   444 TUint32 RUsbPipe::Handle() const
       
   445 	{
       
   446 	return iHandle;
       
   447 	}
       
   448 
       
   449 /**
       
   450 Close a pipe to a remote device.
       
   451 */
       
   452 void RUsbPipe::Close()
       
   453 	{
       
   454 	if (iInterface)
       
   455 		{
       
   456 		static_cast<void>(iInterface->DoControl(EClose, (TAny*)iHandle));
       
   457 		}
       
   458 	iHeadEndpointDescriptor = NULL;
       
   459 	iInterface = NULL;
       
   460 	iHandle = 0;
       
   461 	}
       
   462 
       
   463 /**
       
   464 Clear a stall on the remote endpoint.
       
   465 
       
   466 @return System-wide error code.
       
   467 */
       
   468 TInt RUsbPipe::ClearRemoteStall()
       
   469 	{
       
   470 	__ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
       
   471 	__ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
       
   472 	return iInterface->DoControl(EClearRemoteStall, (TAny*)iHandle);
       
   473 	}
       
   474 
       
   475 /**
       
   476 Cancel all queued transfers
       
   477 */
       
   478 void RUsbPipe::CancelAllTransfers()
       
   479 	{
       
   480 	__ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
       
   481 	__ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
       
   482 	static_cast<void>(iInterface->DoControl(EAbort, (TAny*)iHandle));
       
   483 	}
       
   484 
       
   485 /**
       
   486 Issues a transfer.
       
   487 @internalComponent
       
   488 */
       
   489 void RUsbPipe::IssueTransfer(TInt aTransferHandle, TRequestStatus& aRequest)
       
   490 	{
       
   491 	__ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
       
   492 	__ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
       
   493 	iInterface->DoRequest(EIssueTransfer, aRequest, (TAny*)iHandle, (TAny*)aTransferHandle);
       
   494 	}
       
   495 
       
   496 /**
       
   497 Get endpoint ID
       
   498 */
       
   499 TInt RUsbPipe::GetEndpointId(TUsbEndpointId& aEndpointId)
       
   500 	{
       
   501 	__ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
       
   502 	__ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
       
   503 	return iInterface->DoControl(EGetEndpointId, reinterpret_cast<TAny*>(iHandle), &aEndpointId);
       
   504 	}
       
   505 
       
   506 /**
       
   507 Get Bus ID
       
   508 */
       
   509 TInt RUsbPipe::GetBusId(TUsbBusId& aBusId)
       
   510 	{
       
   511 	__ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
       
   512 	__ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
       
   513 	return iInterface->GetBusId(aBusId);
       
   514 	}
       
   515 
       
   516 /**
       
   517 Return the section of the USB Configuration Descriptor under the supplied endpoint.
       
   518 
       
   519 @param [out] aDescriptor The descriptor tree for this endpoint.
       
   520 @return System-wide error code.
       
   521 */
       
   522 TInt RUsbPipe::GetEndpointDescriptor(TUsbEndpointDescriptor& aDescriptor)
       
   523 	{
       
   524     __ASSERT_ALWAYS(iHandle, User::Panic(UsbdiPanics::KUsbdiPanicCat, UsbdiPanics::EPipeRequestMadeWhileClosed));
       
   525     __ASSERT_DEBUG(iInterface, User::Panic(UsbdiFaults::KUsbdiFaultCat, UsbdiFaults::EUsbPipeHasHandleButNoInterface));
       
   526 
       
   527 	if (iHeadEndpointDescriptor)
       
   528 		{
       
   529 		aDescriptor = *iHeadEndpointDescriptor;
       
   530 		return KErrNone;
       
   531 		}
       
   532 	else
       
   533 		{
       
   534 		return KErrNotFound;
       
   535 		}
       
   536 	}
       
   537 
       
   538 #endif