os/kernelhwsrv/kernel/eka/drivers/usbcc/chapter9.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2000-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 // e32/drivers/usbcc/chapter9.cpp
    15 // Platform independent layer (PIL) of the USB Device controller driver:
    16 // Processing of USB spec chapter 9 standard requests.
    17 // 
    18 //
    19 
    20 /**
    21  @file chapter9.cpp
    22  @internalTechnology
    23 */
    24 
    25 #include <drivers/usbc.h>
    26 
    27 
    28 //#define ENABLE_EXCESSIVE_DEBUG_OUTPUT
    29 
    30 //
    31 // The way functions are called after an request has been completed by the PSL:
    32 //
    33 //                                         Ep0RequestComplete
    34 //                                                 |
    35 //                                        ------------------------------------------------
    36 //                                       |                                                |
    37 //                              ProcessEp0ReceiveDone                            ProcessEp0TransmitDone
    38 //                                       |                                                |
    39 //                   ---------------------------------------                              |
    40 //                  |                                       |                             |
    41 //        ProcessEp0SetupReceived                 ProcessEp0DataReceived        ProcessDataTransferDone
    42 //                  |                                       |
    43 //         ---------------------                      ---------------
    44 //        |                     |                    |               |
    45 //   ProcessXXX       ProcessDataTransferDone   ProceedXXX  ProcessDataTransferDone
    46 //
    47 //   XXX = Specific_Request
    48 //
    49 
    50 //
    51 // === USB Controller member function implementation - PSL API (protected) ========================
    52 //
    53 
    54 /** Used to synchronize the Ep0 state machine between the PSL and PIL.
    55 	Accepts a SETUP packet and returns the next Ep0 state.
    56 
    57 	@param aSetupBuf The SETUP packet just received by the PSL.
    58 	@return The next Ep0 state.
    59 
    60 	@publishedPartner @released
    61 */
    62 TUsbcEp0State DUsbClientController::EnquireEp0NextState(const TUint8* aSetupBuf) const
    63 	{
    64 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EnquireEp0NextState()"));
    65 
    66 	// This function may be called by the PSL from within an ISR -- so we have
    67 	// to take care what we do here (and also in all functions that get called
    68 	// from here).
    69 
    70 	if (SWAP_BYTES_16((reinterpret_cast<const TUint16*>(aSetupBuf)[3])) == 0) // iLength
    71 		{
    72 		__KTRACE_OPT(KUSB, Kern::Printf("  --> EEp0StateStatusIn"));
    73 		return EEp0StateStatusIn;							// No-data Control => Status_IN
    74 		}
    75 	else if ((aSetupBuf[0] & KUsbRequestType_DirMask) == KUsbRequestType_DirToDev)
    76 		{
    77 		__KTRACE_OPT(KUSB, Kern::Printf("  --> EEp0StateDataOut"));
    78 		return EEp0StateDataOut;							// Control Write => Data_OUT
    79 		}
    80 	else
    81 		{
    82 		__KTRACE_OPT(KUSB, Kern::Printf("  --> EEp0StateDataIn"));
    83 		return EEp0StateDataIn;								// Control Read => Data_IN
    84 		}
    85 	}
    86 
    87 
    88 TInt DUsbClientController::ProcessEp0ReceiveDone(TInt aCount)
    89 	{
    90 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessEp0ReceiveDone()"));
    91 	TInt r;
    92 	if (iEp0DataReceiving == EFalse)
    93 		{
    94 		// It's obviously a Setup packet, so...
    95 		r = ProcessEp0SetupReceived(aCount);
    96 		}
    97 	else
    98 		{
    99 		// If it isn't a Setup, it must be data...
   100 		// (This is actually not quite true, as it could also be - in theory - a new Setup packet
   101 		//  when the host has abandoned, for whatever reason, the previous one which was still
   102 		//  in progress. However no such case is known to have occurred with this driver, or at
   103 		//  least it didn't lead to problems.
   104 		//  Some UDCs have a dedicated interrupt for Setup packets, but so far this driver hasn't
   105 		//  made use of such a feature (as it would require a PSL/PIL API change).)
   106 		r = ProcessEp0DataReceived(aCount);
   107 		}
   108 	return r;
   109 	}
   110 
   111 
   112 TInt DUsbClientController::ProcessEp0TransmitDone(TInt aCount, TInt aError)
   113 	{
   114 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessEp0TransmitDone()"));
   115 	// In any case: there's now no longer a write pending
   116 	iEp0WritePending = EFalse;
   117 	// If it was a client who set up this transmission, we report to that client
   118 	if (iEp0ClientDataTransmitting)
   119 		{
   120 		iEp0ClientDataTransmitting = EFalse;
   121 		TUsbcRequestCallback* const p = iRequestCallbacks[KEp0_Tx];
   122 		if (p)
   123 			{
   124 			__ASSERT_DEBUG((p->iTransferDir == EControllerWrite), Kern::Fault(KUsbPILPanicCat, __LINE__));
   125 			p->iError = aError;
   126 			p->iTxBytes = aCount;
   127 			ProcessDataTransferDone(*p);
   128 			return KErrNone;
   129 			}
   130 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: DUsbClientController::ProcessEpTransmitDone: Stalling Ep0"));
   131 		StallEndpoint(KEp0_In);								// request not found
   132 		return KErrNotFound;
   133 		}
   134 	// If _we_ sent the data, we simply do nothing here...
   135 	return KErrNone;
   136 	}
   137 
   138 
   139 #define USB_PROCESS_REQUEST(request) \
   140 	if (Process ## request(packet) != KErrNone) \
   141 		{ \
   142 		__KTRACE_OPT(KUSB, \
   143 					 Kern::Printf("  ProcessEp0SetupReceived: Stalling Ep0")); \
   144 		StallEndpoint(KEp0_In); \
   145 		}
   146 
   147 TInt DUsbClientController::ProcessEp0SetupReceived(TInt aCount)
   148 	{
   149 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessEp0SetupReceived()"));
   150 
   151 	if (aCount > iEp0MaxPacketSize)
   152 		{
   153 		// Fatal error: too much data!
   154 		aCount = iEp0MaxPacketSize;
   155 		}
   156 
   157 	// first we split the data into meaningful units:
   158 	TUsbcSetup packet;
   159 	Buffer2Setup(iEp0_RxBuf, packet);
   160 
   161 #if defined(_DEBUG) && defined(ENABLE_EXCESSIVE_DEBUG_OUTPUT)
   162 	// let's see what we've got:
   163 	__KTRACE_OPT(KUSB, Kern::Printf("  bmRequestType = 0x%02x", packet.iRequestType));
   164 	if ((packet.iRequestType & KUsbRequestType_TypeMask) == KUsbRequestType_TypeStd)
   165 		{
   166 		switch (packet.iRequest)
   167 			{
   168 		case KUsbRequest_GetStatus:
   169 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (GET_STATUS)",
   170 											KUsbRequest_GetStatus));
   171 			break;
   172 		case KUsbRequest_ClearFeature:
   173 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (CLEAR_FEATURE)",
   174 											KUsbRequest_ClearFeature));
   175 			break;
   176 		case KUsbRequest_SetFeature:
   177 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (SET_FEATURE)",
   178 											KUsbRequest_SetFeature));
   179 			break;
   180 		case KUsbRequest_SetAddress:
   181 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (SET_ADDRESS)",
   182 											KUsbRequest_SetAddress));
   183 			break;
   184 		case KUsbRequest_GetDescriptor:
   185 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (GET_DESCRIPTOR)",
   186 											KUsbRequest_GetDescriptor));
   187 			break;
   188 		case KUsbRequest_SetDescriptor:
   189 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (SET_DESCRIPTOR)",
   190 											KUsbRequest_SetDescriptor));
   191 			break;
   192 		case KUsbRequest_GetConfig:
   193 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (GET_CONFIGURATION)",
   194 											KUsbRequest_GetConfig));
   195 			break;
   196 		case KUsbRequest_SetConfig:
   197 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (SET_CONFIGURATION)",
   198 											KUsbRequest_SetConfig));
   199 			break;
   200 		case KUsbRequest_GetInterface:
   201 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (GET_INTERFACE)",
   202 											KUsbRequest_GetInterface));
   203 			break;
   204 		case KUsbRequest_SetInterface:
   205 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (SET_INTERFACE)",
   206 											KUsbRequest_SetInterface));
   207 			break;
   208 		case KUsbRequest_SynchFrame:
   209 			__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (SYNCH_FRAME)",
   210 											KUsbRequest_SynchFrame));
   211 			break;
   212 		default:
   213 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: bRequest = 0x%02x (UNKNWON STANDARD REQUEST)",
   214 											  packet.iRequest));
   215 			break;
   216 			}
   217 		}
   218 	else
   219 		{
   220 		__KTRACE_OPT(KUSB, Kern::Printf("  bRequest      = 0x%02x (NON-STANDARD REQUEST)",
   221 										packet.iRequest));
   222 		}
   223 	__KTRACE_OPT(KUSB, Kern::Printf("  wValue        = 0x%04x", packet.iValue));
   224 	__KTRACE_OPT(KUSB, Kern::Printf("  wIndex        = 0x%04x", packet.iIndex));
   225 	__KTRACE_OPT(KUSB, Kern::Printf("  wLength       = 0x%04x", packet.iLength));
   226 #endif // defined(_DEBUG) && defined(ENABLE_EXCESSIVE_DEBUG_OUTPUT)
   227 
   228 	// now the actual analysis
   229 	if ((packet.iRequestType & KUsbRequestType_TypeMask) == KUsbRequestType_TypeStd)
   230 		{
   231 		iEp0ReceivedNonStdRequest = EFalse;
   232 		switch (packet.iRequest)
   233 			{
   234 		case KUsbRequest_GetStatus:
   235 			switch (packet.iRequestType & KUsbRequestType_DestMask)
   236 				{ // Recipient
   237 			case KUsbRequestType_DestDevice:
   238 				USB_PROCESS_REQUEST(GetDeviceStatus);
   239 				break;
   240 			case KUsbRequestType_DestIfc:
   241 				USB_PROCESS_REQUEST(GetInterfaceStatus);
   242 				break;
   243 			case KUsbRequestType_DestEp:
   244 				USB_PROCESS_REQUEST(GetEndpointStatus);
   245 				break;
   246 			default:
   247 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: GET STATUS - Other or Unknown recipient"));
   248 				__KTRACE_OPT(KPANIC, Kern::Printf("  -> DUsbClientController::ProcessEp0SetupReceived: "
   249 												  "Stalling Ep0"));
   250 				StallEndpoint(KEp0_In);
   251 				break;
   252 				}
   253 			break;
   254 		case KUsbRequest_ClearFeature:
   255 		case KUsbRequest_SetFeature:
   256 			switch (packet.iRequestType & KUsbRequestType_DestMask)
   257 				{ // Recipient
   258 			case KUsbRequestType_DestDevice:
   259 				USB_PROCESS_REQUEST(SetClearDevFeature);
   260 				break;
   261 			case KUsbRequestType_DestIfc:
   262 				USB_PROCESS_REQUEST(SetClearIfcFeature);
   263 				break;
   264 			case KUsbRequestType_DestEp:
   265 				USB_PROCESS_REQUEST(SetClearEpFeature);
   266 				break;
   267 			default:
   268 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: SET/CLEAR FEATURE - "
   269 												  "Other or Unknown recipient"));
   270 				__KTRACE_OPT(KPANIC, Kern::Printf("  -> Stalling Ep0"));
   271 				StallEndpoint(KEp0_In);
   272 				break;
   273 				}
   274 			break;
   275 		case KUsbRequest_SetAddress:
   276 			USB_PROCESS_REQUEST(SetAddress);
   277 			break;
   278 		case KUsbRequest_GetDescriptor:
   279 			USB_PROCESS_REQUEST(GetDescriptor);
   280 			break;
   281 		case KUsbRequest_SetDescriptor:
   282 			USB_PROCESS_REQUEST(SetDescriptor);
   283 			break;
   284 		case KUsbRequest_GetConfig:
   285 			USB_PROCESS_REQUEST(GetConfiguration);
   286 			break;
   287 		case KUsbRequest_SetConfig:
   288 			USB_PROCESS_REQUEST(SetConfiguration);
   289 			break;
   290 		case KUsbRequest_GetInterface:
   291 			USB_PROCESS_REQUEST(GetInterface);
   292 			break;
   293 		case KUsbRequest_SetInterface:
   294 			USB_PROCESS_REQUEST(SetInterface);
   295 			break;
   296 		case KUsbRequest_SynchFrame:
   297 			USB_PROCESS_REQUEST(SynchFrame);
   298 			break;
   299 		default:
   300 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown/unsupported Std Setup Request"));
   301 			__KTRACE_OPT(KPANIC, Kern::Printf("  -> Stalling Ep0"));
   302 			StallEndpoint(KEp0_In);
   303 			break;
   304 			}
   305 		}
   306 	else
   307 		{
   308 		// Type mask != KUsbRequestType_TypeStd => class- or vendor-specific request
   309 		iEp0ReceivedNonStdRequest = ETrue;
   310 		const DBase* client = NULL;
   311 		switch (packet.iRequestType & KUsbRequestType_DestMask)
   312 			{ // Recipient
   313 		case KUsbRequestType_DestDevice:
   314 			client = iEp0DeviceControl;
   315 			break;
   316 		case KUsbRequestType_DestIfc:
   317 			if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   318 				{
   319 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   320 				}
   321 			else
   322 				{
   323 				const TUsbcInterfaceSet* const ifcset_ptr =
   324 					InterfaceNumber2InterfacePointer(packet.iIndex);
   325 				if (ifcset_ptr)
   326 					{
   327 					if (ifcset_ptr->CurrentInterface()->iNoEp0Requests)
   328 						{
   329 						__KTRACE_OPT(KUSB, Kern::Printf("  Recipient says: NoEp0RequestsPlease"));
   330 						}
   331 					else
   332 						{
   333 						client = ifcset_ptr->iClientId;
   334 						}
   335 					}
   336 				else
   337 					{
   338 					__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface 0x%02x does not exist",
   339 													  packet.iIndex));
   340 					}
   341 				}
   342 			break;
   343 		case KUsbRequestType_DestEp:
   344 			if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   345 				{
   346 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   347 				}
   348 			else if (EndpointExists(packet.iIndex) == EFalse)
   349 				{
   350 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint 0x%02x does not exist",
   351 												  packet.iIndex));
   352 				}
   353 			else
   354 				{
   355 				const TInt idx = EpAddr2Idx(packet.iIndex);
   356 				const TUsbcInterfaceSet* const ifcset_ptr =
   357 					iRealEndpoints[idx].iLEndpoint->iInterface->iInterfaceSet;
   358 				if (ifcset_ptr->CurrentInterface()->iNoEp0Requests)
   359 					{
   360 					__KTRACE_OPT(KUSB, Kern::Printf("  Recipient says: NoEp0RequestsPlease"));
   361 					}
   362 				else
   363 					{
   364 					client = ifcset_ptr->iClientId;
   365 					}
   366 				}
   367 			break;
   368 		default:
   369 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Other or Unknown recipient"));
   370 			break;
   371 			}
   372 		if (client != NULL)
   373 			{
   374 			// Try to relay packet to the appropriate recipient
   375 			TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
   376 			TUsbcRequestCallback* p;
   377 			while ((p = iter++) != NULL)
   378 				{
   379 				if (p->Owner() == client)
   380 					{
   381 					__ASSERT_DEBUG((p->iEndpointNum == 0), Kern::Fault(KUsbPILPanicCat, __LINE__));
   382 					__ASSERT_DEBUG((p->iTransferDir == EControllerRead), Kern::Fault(KUsbPILPanicCat, __LINE__));
   383 					__KTRACE_OPT(KUSB, Kern::Printf("  Found Ep0 read request"));
   384 					if (packet.iLength != 0)
   385 						{
   386 						if ((packet.iRequestType & KUsbRequestType_DirMask) == KUsbRequestType_DirToDev)
   387 							{
   388 							// Data transfer & direction OUT => there'll be a DATA_OUT stage
   389 							__KTRACE_OPT(KUSB, Kern::Printf("  Next is DATA_OUT: setting up DataOutVars"));
   390 							SetEp0DataOutVars(packet, client);
   391 							}
   392 						else if ((packet.iRequestType & KUsbRequestType_DirMask) == KUsbRequestType_DirToHost)
   393 							{
   394 							// For possible later use (ZLP).
   395 							iEp0_TxNonStdCount = packet.iLength;
   396 							}
   397 						}
   398 					memcpy(p->iBufferStart, iEp0_RxBuf, aCount);
   399 					p->iError = KErrNone;					// if it wasn't 'KErrNone' we wouldn't be here
   400 					*(p->iPacketSize) = aCount;
   401 					p->iRxPackets = 1;
   402 					*(p->iPacketIndex) = 0;
   403 					ProcessDataTransferDone(*p);
   404 					return KErrNone;
   405 					}
   406 				}
   407 			__KTRACE_OPT(KUSB, Kern::Printf("  Ep0 read request not found: setting RxExtra vars (Setup)"));
   408 			iEp0_RxExtraCount = aCount;
   409 			iEp0_RxExtraData = ETrue;
   410 			return KErrNotFound;
   411 			}
   412 		else // if (client == NULL)
   413 			{
   414 			__KTRACE_OPT(KPANIC, Kern::Printf("  Ep0 request error: Stalling Ep0"));
   415 			StallEndpoint(KEp0_In);
   416 			return KErrGeneral;
   417 			}
   418 		}
   419 	return KErrNone;
   420 	}
   421 
   422 #undef USB_PROCESS_REQUEST
   423 
   424 
   425 TInt DUsbClientController::ProcessEp0DataReceived(TInt aCount)
   426 	{
   427 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessEp0DataReceived()"));
   428 
   429 	__KTRACE_OPT(KUSB, Kern::Printf("  : %d bytes", aCount));
   430 
   431 	if (aCount > iEp0MaxPacketSize)
   432 		{
   433 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Too much data"));
   434 		aCount = iEp0MaxPacketSize;
   435 		}
   436 	iEp0DataReceived += aCount;
   437 	if (iEp0ClientId == NULL)
   438 		{
   439 		// it is us (not an app), who owns this transaction
   440 		switch (iSetup.iRequest)
   441 			{
   442 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
   443 		case KUsbRequest_SetDescriptor:
   444 			memcpy(iEp0_RxCollectionBuf + iEp0DataReceived, iEp0_RxBuf, aCount);
   445 			ProceedSetDescriptor();
   446 			break;
   447 #endif
   448 		default:
   449 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid request in iSetup"));
   450 			__KTRACE_OPT(KPANIC, Kern::Printf("  -> DUsbClientController::ProcessEp0DataReceived: Stalling Ep0"));
   451 			StallEndpoint(KEp0_In);
   452 			ResetEp0DataOutVars();
   453 			break;
   454 			}
   455 		}
   456 	else
   457 		{
   458 		// pass the data on to a client
   459 		TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
   460 		TUsbcRequestCallback* p;
   461 		while ((p = iter++) != NULL)
   462 			{
   463 			if (p->Owner() == iEp0ClientId)
   464 				{
   465 				__ASSERT_DEBUG((p->iEndpointNum == 0), Kern::Fault(KUsbPILPanicCat, __LINE__));
   466 				__ASSERT_DEBUG((p->iTransferDir == EControllerRead), Kern::Fault(KUsbPILPanicCat, __LINE__));
   467 				__KTRACE_OPT(KUSB, Kern::Printf("  Found Ep0 read request"));
   468 				memcpy(p->iBufferStart, iEp0_RxBuf, aCount);
   469 				p->iError = KErrNone;						// if it wasn't 'KErrNone' we wouldn't be here
   470 				*(p->iPacketSize) = aCount;
   471 				p->iRxPackets = 1;
   472 				*(p->iPacketIndex) = 0;
   473 				ProcessDataTransferDone(*p);
   474 				goto found;
   475 				}
   476 			}
   477 		__KTRACE_OPT(KUSB, Kern::Printf("  Ep0 read request not found: setting RxExtra vars (Data)"));
   478 		iEp0_RxExtraCount = aCount;
   479 		iEp0_RxExtraData = ETrue;
   480 		iEp0DataReceived -= aCount;
   481 		return KErrNotFound;
   482 		}
   483  found:
   484 	if (iEp0DataReceived >= iSetup.iLength)
   485 		{
   486 		// all data seems now to be here
   487 		ResetEp0DataOutVars();
   488 		}
   489 	return KErrNone;
   490 	}
   491 
   492 
   493 // --- The USB Spec Chapter 9 Standard Endpoint Zero Device Requests ---
   494 
   495 TInt DUsbClientController::ProcessGetDeviceStatus(const TUsbcSetup& aPacket)
   496 	{
   497 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetDeviceStatus()"));
   498 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateAddress)
   499 		{
   500 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   501 		return KErrGeneral;
   502 		}
   503 	const TUint16 status = ((DeviceSelfPowered() ? KUsbDevStat_SelfPowered : 0) |
   504 					  (iRmWakeupStatus_Enabled ? KUsbDevStat_RemoteWakeup : 0));
   505 	__KTRACE_OPT(KUSB, Kern::Printf("  Reporting device status: 0x%02x", status));
   506 	*reinterpret_cast<TUint16*>(iEp0_TxBuf) = SWAP_BYTES_16(status);
   507 	if (SetupEndpointZeroWrite(iEp0_TxBuf, sizeof(status)) == KErrNone)
   508 		{
   509 		iEp0WritePending = ETrue;
   510 		}
   511 	return KErrNone;
   512 	}
   513 
   514 
   515 TInt DUsbClientController::ProcessGetInterfaceStatus(const TUsbcSetup& aPacket)
   516 	{
   517 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetInterfaceStatus()"));
   518 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   519 		{
   520 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   521 		return KErrGeneral;
   522 		}
   523 	if (InterfaceExists(aPacket.iIndex) == EFalse)
   524 		{
   525 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface does not exist"));
   526 		return KErrGeneral;
   527 		}
   528 	const TUint16 status = 0x0000;							// as of USB Spec 2.0
   529 	__KTRACE_OPT(KUSB, Kern::Printf("  Reporting interface status: 0x%02x", status));
   530 	*reinterpret_cast<TUint16*>(iEp0_TxBuf) = SWAP_BYTES_16(status);
   531 	if (SetupEndpointZeroWrite(iEp0_TxBuf, sizeof(status)) == KErrNone)
   532 		{
   533 		iEp0WritePending = ETrue;
   534 		}
   535 	return KErrNone;
   536 	}
   537 
   538 
   539 TInt DUsbClientController::ProcessGetEndpointStatus(const TUsbcSetup& aPacket)
   540 	{
   541 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetEndpointStatus()"));
   542 	if (iTrackDeviceState &&
   543 		((iDeviceState < EUsbcDeviceStateAddress) ||
   544 		 (iDeviceState == EUsbcDeviceStateAddress && (aPacket.iIndex & KUsbEpAddress_Portmask) != 0)))
   545 		{
   546 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   547 		return KErrGeneral;
   548 		}
   549 	if (EndpointExists(aPacket.iIndex) == EFalse)
   550 		{
   551 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint does not exist"));
   552 		return KErrGeneral;
   553 		}
   554 	const TInt ep = EpAddr2Idx(aPacket.iIndex);
   555 	const TUint16 status = (iRealEndpoints[ep].iHalt) ?	 KUsbEpStat_Halt : 0;
   556 	__KTRACE_OPT(KUSB, Kern::Printf("  Reporting endpoint status 0x%02x for real endpoint %d",
   557 									status, ep));
   558 	*reinterpret_cast<TUint16*>(iEp0_TxBuf) = SWAP_BYTES_16(status);
   559 	if (SetupEndpointZeroWrite(iEp0_TxBuf, 2) == KErrNone)
   560 		{
   561 		iEp0WritePending = ETrue;
   562 		}
   563 	return KErrNone;
   564 	}
   565 
   566 
   567 TInt DUsbClientController::ProcessSetClearDevFeature(const TUsbcSetup& aPacket)
   568 	{
   569 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetClearDevFeature()"));
   570 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateDefault)
   571 		{
   572 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   573 		return KErrGeneral;
   574 		}
   575 
   576 	TUint test_sel = 0;
   577 
   578 	if (aPacket.iRequest == KUsbRequest_SetFeature)
   579 		{
   580 		switch (aPacket.iValue)
   581 			{
   582 		case KUsbFeature_RemoteWakeup:
   583 			if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateAddress)
   584 				{
   585 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   586 				return KErrGeneral;
   587 				}
   588 			iRmWakeupStatus_Enabled = ETrue;
   589 			break;
   590 		case KUsbFeature_TestMode:
   591 			if (!iHighSpeed)
   592 				{
   593 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported in High-Speed mode"));
   594 				return KErrGeneral;
   595 				}
   596 			if (LowByte(aPacket.iIndex) != 0)
   597 				{
   598 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Lower byte of wIndex must be zero"));
   599 				return KErrGeneral;
   600 				}
   601 			test_sel = HighByte(aPacket.iIndex);
   602 			if ((test_sel < KUsbTestSelector_Test_J) || (test_sel > KUsbTestSelector_Test_Force_Enable))
   603 				{
   604 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid test selector: %d", test_sel));
   605 				return KErrGeneral;
   606 				}
   607 			break;
   608 		case KUsbFeature_B_HnpEnable:
   609 			if (!iOtgSupport)
   610 				{
   611 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
   612 				return KErrGeneral;
   613 				}
   614 			if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
   615 				{
   616 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
   617 				return KErrGeneral;
   618 				}
   619 			iOtgFuncMap |= KUsbOtgAttr_B_HnpEnable;
   620 			OtgFeaturesNotify();
   621 			break;
   622 		case KUsbFeature_A_HnpSupport:
   623 			if (!iOtgSupport)
   624 				{
   625 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
   626 				return KErrGeneral;
   627 				}
   628 			if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
   629 				{
   630 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
   631 				return KErrGeneral;
   632 				}
   633 			iOtgFuncMap |= KUsbOtgAttr_A_HnpSupport;
   634 			OtgFeaturesNotify();
   635 			break;
   636 		case KUsbFeature_A_AltHnpSupport:
   637 			if (!iOtgSupport)
   638 				{
   639 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
   640 				return KErrGeneral;
   641 				}
   642 			if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
   643 				{
   644 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
   645 				return KErrGeneral;
   646 				}
   647 			iOtgFuncMap |= KUsbOtgAttr_A_AltHnpSupport;
   648 			OtgFeaturesNotify();
   649 			break;
   650 		default:
   651 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown feature requested"));
   652 			return KErrGeneral;
   653 			}
   654 		}
   655 	else // KUsbRequest_ClearFeature
   656 		{
   657 		switch (aPacket.iValue)
   658 			{
   659 		case KUsbFeature_RemoteWakeup:
   660 			if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateAddress)
   661 				{
   662 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   663 				return KErrGeneral;
   664 				}
   665 			iRmWakeupStatus_Enabled = EFalse;
   666 			break;
   667 		default:
   668 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown feature requested"));
   669 			return KErrGeneral;
   670 			}
   671 		}
   672 
   673 	SendEp0ZeroByteStatusPacket();							// success: zero bytes data during status stage
   674 
   675 	// 9.4.9: "The transition to test mode of an upstream facing port must not happen until
   676 	// after the status stage of the request."
   677 	if (test_sel)
   678 		{
   679 		__KTRACE_OPT(KPANIC, Kern::Printf("  Entering HS Test Mode %d", test_sel));
   680 		EnterTestMode(test_sel);
   681 		}
   682 
   683 	return KErrNone;
   684 	}
   685 
   686 
   687 TInt DUsbClientController::ProcessSetClearIfcFeature(const TUsbcSetup& aPacket)
   688 	{
   689 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetClearIfcFeature()"));
   690 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   691 		{
   692 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   693 		return KErrGeneral;
   694 		}
   695 	// No interface features defined in USB spec, thus
   696 	return KErrGeneral;
   697 	}
   698 
   699 
   700 TInt DUsbClientController::ProcessSetClearEpFeature(const TUsbcSetup& aPacket)
   701 	{
   702 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetClearEpFeature()"));
   703 	if (iTrackDeviceState &&
   704 		((iDeviceState < EUsbcDeviceStateAddress) ||
   705 		 (iDeviceState == EUsbcDeviceStateAddress && (aPacket.iIndex & KUsbEpAddress_Portmask) != 0)))
   706 		{
   707 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   708 		return KErrGeneral;
   709 		}
   710 	if (aPacket.iValue != KUsbFeature_EndpointHalt)
   711 		{
   712 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown feature requested"));
   713 		return KErrGeneral;
   714 		}
   715 	if (EndpointExists(aPacket.iIndex) == EFalse)
   716 		{
   717 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint does not exist"));
   718 		return KErrGeneral;
   719 		}
   720 	const TInt ep = EpAddr2Idx(aPacket.iIndex);
   721 	if (iRealEndpoints[ep].iLEndpoint->iInfo.iType == KUsbEpTypeControl ||
   722 		iRealEndpoints[ep].iLEndpoint->iInfo.iType == KUsbEpTypeIsochronous)
   723 		{
   724 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint is Control or Isochronous"));
   725 		return KErrGeneral;
   726 		}
   727 	SetClearHaltFeature(ep, aPacket.iRequest);
   728 	SendEp0ZeroByteStatusPacket();							// success: zero bytes data during status stage
   729 	return KErrNone;
   730 	}
   731 
   732 
   733 TInt DUsbClientController::ProcessSetAddress(const TUsbcSetup& aPacket)
   734 	{
   735 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetAddress()"));
   736 	if (iTrackDeviceState && iDeviceState > EUsbcDeviceStateAddress)
   737 		{
   738 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   739 		return KErrGeneral;
   740 		}
   741 	const TUint16 addr = aPacket.iValue;
   742 	if (addr > 127)
   743 		{
   744 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad address value: %d (>127)", addr));
   745 		return KErrGeneral;
   746 		}
   747 	if (addr == 0)
   748 		{
   749 		// Enter Default state (from Default or Address)
   750 		NextDeviceState(EUsbcDeviceStateDefault);
   751 		}
   752 	__KTRACE_OPT(KUSB, Kern::Printf("  USB address: %d", addr));
   753 	// The spec says, under section 9.4.6:
   754 	// "Stages after the initial Setup packet assume the same device address as the Setup packet. The USB
   755 	// device does not change its device address until after the Status stage of this request is completed
   756 	// successfully. Note that this is a difference between this request and all other requests. For all other
   757 	// requests, the operation indicated must be completed before the Status stage."
   758 	// Therefore, here we first send the status packet and only then actually execute the request.
   759 	SendEp0ZeroByteStatusPacket();
   760 	SetDeviceAddress(addr);
   761 	return KErrNone;
   762 	}
   763 
   764 
   765 TInt DUsbClientController::ProcessGetDescriptor(const TUsbcSetup& aPacket)
   766 	{
   767 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetDescriptor()"));
   768 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateDefault)
   769 		{
   770 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   771 		return KErrGeneral;
   772 		}
   773 
   774 	// Make sure we assume the correct speed
   775 	__ASSERT_DEBUG((iHighSpeed == CurrentlyUsingHighSpeed()), Kern::Fault(KUsbPILPanicCat, __LINE__));
   776 
   777 	TInt size = 0;
   778 	const TInt result = iDescriptors.FindDescriptor(HighByte(aPacket.iValue), // Type
   779 													LowByte(aPacket.iValue), // Index
   780 													aPacket.iIndex, // Language ID
   781 													size);
   782 
   783 	if ((result != KErrNone) || (size == 0))
   784 		{
   785 		// This doesn't have to be an error - protocol-wise it's OK.
   786 		__KTRACE_OPT(KUSB, Kern::Printf("  Couldn't retrieve descriptor"));
   787 		return KErrGeneral;
   788 		}
   789 
   790 	__KTRACE_OPT(KUSB, Kern::Printf("  Descriptor found, size: %d (requested: %d)",
   791 									size, aPacket.iLength));
   792 	if (size > KUsbcBufSz_Ep0Tx)
   793 		{
   794 		// This should actually not be possible (i.e. we should never get here).
   795 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ep0_Tx buffer too small"));
   796 		}
   797 	if (size > aPacket.iLength)
   798 		{
   799 		// Send only as much data as requested by the host
   800 		size = aPacket.iLength;
   801 		}
   802 
   803 #ifdef ENABLE_EXCESSIVE_DEBUG_OUTPUT
   804 	__KTRACE_OPT(KUSB,
   805 				 Kern::Printf("  Data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x ...",
   806 							  iEp0_TxBuf[0], iEp0_TxBuf[1], iEp0_TxBuf[2], iEp0_TxBuf[3],
   807 							  iEp0_TxBuf[4], iEp0_TxBuf[5], iEp0_TxBuf[6], iEp0_TxBuf[7]));
   808 #endif
   809 	// If we're about to send less bytes than expected by the host AND our number is a
   810 	// multiple of the packet size, in order to indicate the end of the control transfer,
   811 	// we must finally send a zero length data packet (ZLP):
   812 	const TBool zlp = ((size < aPacket.iLength) && (size % iEp0MaxPacketSize == 0));
   813 	if (SetupEndpointZeroWrite(iEp0_TxBuf, size, zlp) == KErrNone)
   814 		{
   815 		iEp0WritePending = ETrue;
   816 		}
   817 
   818 	return KErrNone;
   819 	}
   820 
   821 
   822 TInt DUsbClientController::ProcessSetDescriptor(const TUsbcSetup& aPacket)
   823 	{
   824 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetDescriptor()"));
   825 #ifndef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
   826 	return KErrGeneral;
   827 #else
   828 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateAddress)
   829 		{
   830 		// Error: Invalid device state!
   831 		return KErrGeneral;
   832 		}
   833 	if (aPacket.iLength > KUsbcBufSz_Ep0Rx)
   834 		{
   835 		// Error: Our Rx buffer is too small! (Raise a defect to make it larger)
   836 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ep0_Rx buffer too small"));
   837 		return KErrGeneral;
   838 		}
   839 	SetEp0DataOutVars(aPacket);
   840 	SetupEndpointZeroRead();
   841 	return KErrNone;
   842 #endif
   843 	}
   844 
   845 
   846 TInt DUsbClientController::ProcessGetConfiguration(const TUsbcSetup& aPacket)
   847 	{
   848 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetConfiguration()"));
   849 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateAddress)
   850 		{
   851 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   852 		return KErrGeneral;
   853 		}
   854 	if (iTrackDeviceState && iDeviceState == EUsbcDeviceStateAddress && iCurrentConfig != 0)
   855 		{
   856 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: DeviceState Address && Config != 0"));
   857 		return KErrGeneral;
   858 		}
   859 	if (iTrackDeviceState && iDeviceState == EUsbcDeviceStateConfigured && iCurrentConfig == 0)
   860 		{
   861 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: DeviceState Configured && Config == 0"));
   862 		return KErrGeneral;
   863 		}
   864 	if (aPacket.iLength != 1)								// "unspecified behavior"
   865 		{
   866 		__KTRACE_OPT(KUSB, Kern::Printf("  Warning: wLength != 1 (= %d)", aPacket.iLength));
   867 		}
   868 	__KTRACE_OPT(KUSB, Kern::Printf("  Reporting configuration value %d", iCurrentConfig));
   869 	if (SetupEndpointZeroWrite(&iCurrentConfig, sizeof(iCurrentConfig)) == KErrNone)
   870 		{
   871 		iEp0WritePending = ETrue;
   872 		}
   873 	return KErrNone;
   874 	}
   875 
   876 
   877 /** Changes the device's configuration value, including interface setup and/or
   878 	teardown and state change notification of higher-layer clients.
   879 	May also be called by the PSL in special cases - therefore publishedPartner.
   880 
   881 	@param aPacket The received Ep0 SET_CONFIGURATION setup request packet.
   882 	@return KErrGeneral in case of a protocol error, KErrNone otherwise.
   883 
   884 	@publishedPartner @released
   885 */
   886 TInt DUsbClientController::ProcessSetConfiguration(const TUsbcSetup& aPacket)
   887 	{
   888 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetConfiguration()"));
   889 
   890 	// This function may be called by the PSL from within an ISR -- so we have
   891 	// to take care what we do here (and also in all functions that get called
   892 	// from here).
   893 
   894 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateAddress)
   895 		{
   896 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   897 		return KErrGeneral;
   898 		}
   899 	const TUint16 value = aPacket.iValue;
   900 	if (value > 1)											// we support only one configuration
   901 		{
   902 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Configuration value too large: %d", value));
   903 		return KErrGeneral;
   904 		}
   905 
   906 	__KTRACE_OPT(KUSB, Kern::Printf("  Configuration value: %d", value));
   907 	ChangeConfiguration(value);
   908 
   909 	// In 9.4.5 under GET_STATUS we read, that after SET_CONFIGURATION the HALT feature
   910 	// for all endpoints is reset to zero.
   911 	TInt num = 0;
   912 	(TAny) DoForEveryEndpointInUse(&DUsbClientController::ClearHaltFeature, num);
   913 	__KTRACE_OPT(KUSB, Kern::Printf("  Called ClearHaltFeature() for %d endpoints", num));
   914 	SendEp0ZeroByteStatusPacket();							// success: zero bytes data during status stage
   915 	return KErrNone;
   916 	}
   917 
   918 
   919 TInt DUsbClientController::ProcessGetInterface(const TUsbcSetup& aPacket)
   920 	{
   921 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetInterface()"));
   922 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   923 		{
   924 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   925 		return KErrGeneral;
   926 		}
   927 	if (iCurrentConfig == 0)
   928 		{
   929 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device not configured"));
   930 		return KErrGeneral;
   931 		}
   932 	const TInt number = aPacket.iIndex;
   933 	if (!InterfaceExists(number))
   934 		{
   935 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad interface index: %d", number));
   936 		return KErrGeneral;
   937 		}
   938 	// Send alternate setting code of iCurrentInterface of Interface(set) <number> of the current
   939 	// config (iCurrentConfig).
   940 	const TUint8 setting = InterfaceNumber2InterfacePointer(number)->iCurrentInterface;
   941 	__KTRACE_OPT(KUSB, Kern::Printf("  Reporting interface setting %d", setting));
   942 	if (SetupEndpointZeroWrite(&setting, 1) == KErrNone)
   943 		{
   944 		iEp0WritePending = ETrue;
   945 		}
   946 	return KErrNone;
   947 	}
   948 
   949 
   950 TInt DUsbClientController::ProcessSetInterface(const TUsbcSetup& aPacket)
   951 	{
   952 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetInterface()"));
   953 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   954 		{
   955 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
   956 		return KErrGeneral;
   957 		}
   958 	if (iCurrentConfig == 0)
   959 		{
   960 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device not configured"));
   961 		return KErrGeneral;
   962 		}
   963 	const TInt number = aPacket.iIndex;
   964 	if (!InterfaceExists(number))
   965 		{
   966 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad interface index: %d", number));
   967 		return KErrGeneral;
   968 		}
   969 	const TInt setting = aPacket.iValue;
   970 	TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(number);
   971 	RPointerArray<TUsbcInterface>& ifcs = ifcset_ptr->iInterfaces;
   972 	if (setting >= ifcs.Count())
   973 		{
   974 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Alt Setting >= bNumAltSettings: %d", setting));
   975 		return KErrGeneral;
   976 		}
   977 	__KTRACE_OPT(KUSB, Kern::Printf("  Interface setting:: %d", setting));
   978 	// Set iCurrentInterface of Interface(set) <number> of the current config
   979 	// (iCurrentConfig) to alternate setting <setting>.
   980 	ChangeInterface(ifcs[setting]);
   981 	// In 9.4.5 under GET_STATUS we read, that after SET_INTERFACE the HALT feature
   982 	// for all endpoints (of the now current interface setting) is reset to zero.
   983 	RPointerArray<TUsbcLogicalEndpoint>& eps = ifcset_ptr->CurrentInterface()->iEndpoints;
   984 	const TInt num_eps = eps.Count();
   985 	for (TInt i = 0; i < num_eps; i++)
   986 		{
   987 		const TInt ep_num = EpAddr2Idx(eps[i]->iPEndpoint->iEndpointAddr);
   988 		(TAny) ClearHaltFeature(ep_num);
   989 		}
   990 	SendEp0ZeroByteStatusPacket();							// success: zero bytes data during status stage
   991 	return KErrNone;
   992 	}
   993 
   994 
   995 TInt DUsbClientController::ProcessSynchFrame(const TUsbcSetup& aPacket)
   996 	{
   997 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSynchFrame()"));
   998 	if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
   999 		{
  1000 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
  1001 		return KErrGeneral;
  1002 		}
  1003 	const TInt ep = aPacket.iIndex;
  1004 	if (EndpointExists(ep) == EFalse)
  1005 		{
  1006 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint does not exist"));
  1007 		return KErrGeneral;
  1008 		}
  1009 	if (iRealEndpoints[EpAddr2Idx(ep)].iLEndpoint->iInfo.iType != KUsbEpTypeIsochronous)
  1010 		{
  1011 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint is not isochronous"));
  1012 		return KErrGeneral;
  1013 		}
  1014 	// We always send 0:
  1015 	*reinterpret_cast<TUint16*>(iEp0_TxBuf) = 0x00;
  1016 	if (SetupEndpointZeroWrite(iEp0_TxBuf, 2) == KErrNone)
  1017 		{
  1018 		iEp0WritePending = ETrue;
  1019 		}
  1020 	return KErrNone;
  1021 	}
  1022 
  1023 
  1024 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
  1025 void DUsbClientController::ProceedSetDescriptor()
  1026 	{
  1027 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProceedSetDescriptor()"));
  1028 	// iEp0DataReceived already reflects the current buffer state
  1029 	if (iEp0DataReceived < iSetup.iLength)
  1030 		{
  1031 		// Not yet all data received => proceed
  1032 		return;
  1033 		}
  1034 	if (iEp0DataReceived > iSetup.iLength)
  1035 		{
  1036 		// Error: more data received than expected
  1037 		// but we don't care...
  1038 		}
  1039 	// at this point: iEp0DataReceived == iSetup.iLength
  1040 	const TUint8 type = HighByte(iSetup.iValue);
  1041 	if (type == KUsbDescType_String)
  1042 		{
  1043 		// set/add new string descriptor
  1044 		}
  1045 	else
  1046 		{
  1047 		// set/add new ordinary descriptor
  1048 		}
  1049 	TUint8 index = LowByte(iSetup.iValue);
  1050 	TUint16 langid = iSetup.iIndex;
  1051 	TUint16 length_total = iSetup.iLength;
  1052 	}
  1053 #endif
  1054 
  1055 
  1056 // --- Secondary (Helper) Functions
  1057 
  1058 void DUsbClientController::SetClearHaltFeature(TInt aRealEndpoint, TUint8 aRequest)
  1059 	{
  1060 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetClearHaltFeature()"));
  1061 	if (aRequest == KUsbRequest_SetFeature)
  1062 		{
  1063 		if (iRealEndpoints[aRealEndpoint].iHalt)
  1064 			{
  1065 			// (This condition is not really an error)
  1066 			__KTRACE_OPT(KUSB, Kern::Printf("  Warning: HALT feature already set"));
  1067 			return;
  1068 			}
  1069 		__KTRACE_OPT(KUSB, Kern::Printf("  setting HALT feature for real endpoint %d",
  1070 										aRealEndpoint));
  1071 		StallEndpoint(aRealEndpoint);
  1072 		iRealEndpoints[aRealEndpoint].iHalt = ETrue;
  1073 		}
  1074 	else													// KUsbRequest_ClearFeature
  1075 		{
  1076 		if (iRealEndpoints[aRealEndpoint].iHalt == EFalse)
  1077 			{
  1078 			// In this case, before we return, the data toggles are reset to DATA0.
  1079 			__KTRACE_OPT(KUSB, Kern::Printf("  Warning: HALT feature already cleared"));
  1080 			ResetDataToggle(aRealEndpoint);
  1081 			return;
  1082 			}
  1083 		__KTRACE_OPT(KUSB, Kern::Printf("  clearing HALT feature for real endpoint %d",
  1084 										aRealEndpoint));
  1085 		ResetDataToggle(aRealEndpoint);
  1086 		ClearStallEndpoint(aRealEndpoint);
  1087 		iRealEndpoints[aRealEndpoint].iHalt = EFalse;
  1088 		}
  1089 	EpStatusNotify(aRealEndpoint);							// only called if actually something changed
  1090 	}
  1091 
  1092 
  1093 TInt DUsbClientController::ClearHaltFeature(TInt aRealEndpoint)
  1094 	{
  1095 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ClearHaltFeature()"));
  1096 	if (iRealEndpoints[aRealEndpoint].iHalt != EFalse)
  1097 		{
  1098 		ClearStallEndpoint(aRealEndpoint);
  1099 		iRealEndpoints[aRealEndpoint].iHalt = EFalse;
  1100 		}
  1101 	return KErrNone;
  1102 	}
  1103 
  1104 
  1105 void DUsbClientController::ChangeConfiguration(TUint16 aValue)
  1106 	{
  1107 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ChangeConfiguration()"));
  1108 	// New configuration is the same as the old one: 0
  1109 	if (iCurrentConfig == 0 && aValue == 0)
  1110 		{
  1111 		// no-op
  1112 		__KTRACE_OPT(KUSB, Kern::Printf("  Configuration: New == Old == 0 --> exiting"));
  1113 		return;
  1114 		}
  1115 	// New configuration is the same as the old one (but not 0)
  1116 	if (iCurrentConfig == aValue)
  1117 		{
  1118 		// no-op
  1119 		__KTRACE_OPT(KUSB, Kern::Printf("  Configuration: New == Old == %d --> exiting", aValue));
  1120 		return;
  1121 		}
  1122 	// Device is already configured
  1123 	if (iCurrentConfig != 0)
  1124 		{
  1125 		__KTRACE_OPT(KUSB, Kern::Printf("  Device was configured: %d", iCurrentConfig));
  1126 		// Tear down all interface(set)s of the old configuration
  1127 		RPointerArray<TUsbcInterfaceSet>& ifcsets = CurrentConfig()->iInterfaceSets;
  1128 		for (TInt i = 0; i < ifcsets.Count(); ++i)
  1129 			{
  1130 			__KTRACE_OPT(KUSB, Kern::Printf("  Tearing down InterfaceSet %d", i));
  1131 			InterfaceSetTeardown(ifcsets[i]);
  1132 			}
  1133 		iCurrentConfig = 0;
  1134 		// Enter Address state (from Configured)
  1135 		if (iDeviceState == EUsbcDeviceStateConfigured)
  1136 			NextDeviceState(EUsbcDeviceStateAddress);
  1137 		}
  1138 	// Device gets a new configuration
  1139 	if (aValue != 0)
  1140 		{
  1141 		__KTRACE_OPT(KUSB, Kern::Printf("  Device gets new configuration..."));
  1142 		// Setup all alternate settings 0 of all interfaces
  1143 		// (Don't separate the next two lines of code.)
  1144 		iCurrentConfig = aValue;
  1145 		RPointerArray<TUsbcInterfaceSet>& ifcsets = CurrentConfig()->iInterfaceSets;
  1146 		const TInt n = ifcsets.Count();
  1147 		for (TInt i = 0; i < n; ++i)
  1148 			{
  1149 			__KTRACE_OPT(KUSB, Kern::Printf("  Setting up InterfaceSet %d", i));
  1150 			InterfaceSetup(ifcsets[i]->iInterfaces[0]);
  1151 			}
  1152 		// Enter Configured state (from Address or Configured)
  1153 		NextDeviceState(EUsbcDeviceStateConfigured);
  1154 		}
  1155 	__KTRACE_OPT(KUSB, Kern::Printf("  New configuration: %d", iCurrentConfig));
  1156 	return;
  1157 	}
  1158 
  1159 
  1160 void DUsbClientController::InterfaceSetup(TUsbcInterface* aIfc)
  1161 	{
  1162 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::InterfaceSetup()"));
  1163 	const TInt num_eps = aIfc->iEndpoints.Count();
  1164 	for (TInt i = 0; i < num_eps; i++)
  1165 		{
  1166 		// Prepare this endpoint for I/O
  1167 		TUsbcLogicalEndpoint* const ep = aIfc->iEndpoints[i];
  1168 		// (TUsbcLogicalEndpoint's FS/HS endpoint sizes and interval values got
  1169 		//  adjusted in its constructor.)
  1170 		if (iHighSpeed)
  1171 			{
  1172 			__KTRACE_OPT(KUSB, Kern::Printf("  Setting Ep info size to %d (HS)", ep->iEpSize_Hs));
  1173 			ep->iInfo.iSize = ep->iEpSize_Hs;
  1174 			}
  1175 		else
  1176 			{
  1177 			__KTRACE_OPT(KUSB, Kern::Printf("  Setting Ep info size to %d (FS)", ep->iEpSize_Fs));
  1178 			ep->iInfo.iSize = ep->iEpSize_Fs;
  1179 			}
  1180 		const TInt idx = EpAddr2Idx(ep->iPEndpoint->iEndpointAddr);
  1181 		if (ConfigureEndpoint(idx, ep->iInfo) != KErrNone)
  1182 			{
  1183 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint %d configuration failed", idx));
  1184 			continue;
  1185 			}
  1186 		// Should there be a problem with it then we could try resetting the ep
  1187 		// data toggle at this point (or before the Configure) as well.
  1188 		__KTRACE_OPT(KUSB, Kern::Printf("  Connecting real ep addr 0x%02x & logical ep #%d",
  1189 										ep->iPEndpoint->iEndpointAddr, ep->iLEndpointNum));
  1190 		ep->iPEndpoint->iLEndpoint = ep;
  1191 		}
  1192 	aIfc->iInterfaceSet->iCurrentInterface = aIfc->iSettingCode;
  1193 	return;
  1194 	}
  1195 
  1196 
  1197 void DUsbClientController::InterfaceSetTeardown(TUsbcInterfaceSet* aIfcSet)
  1198 	{
  1199 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::InterfaceSetTeardown()"));
  1200 	if (aIfcSet->iInterfaces.Count() == 0)
  1201 		{
  1202 		__KTRACE_OPT(KUSB, Kern::Printf("  No interfaces exist - returning"));
  1203 		return;
  1204 		}
  1205 	RPointerArray<TUsbcLogicalEndpoint>& eps = aIfcSet->CurrentInterface()->iEndpoints;
  1206 	const TInt num_eps = eps.Count();
  1207 	for (TInt i = 0; i < num_eps; i++)
  1208 		{
  1209 		TUsbcLogicalEndpoint* const ep = eps[i];
  1210 		const TInt idx = EpAddr2Idx(ep->iPEndpoint->iEndpointAddr);
  1211 
  1212 		CancelTransferRequests(idx);
  1213 
  1214 		if (!ep->iPEndpoint->iLEndpoint)
  1215 			{
  1216 			__KTRACE_OPT(KUSB, Kern::Printf("  real ep %d not configured: skipping", idx));
  1217 			continue;
  1218 			}
  1219 		if (ResetDataToggle(idx) != KErrNone)
  1220 			{
  1221 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint %d data toggle reset failed", idx));
  1222 			}
  1223 		if (DeConfigureEndpoint(idx) != KErrNone)
  1224 			{
  1225 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint %d de-configuration failed", idx));
  1226 			}
  1227 
  1228 		__KTRACE_OPT(KUSB, Kern::Printf("  disconnecting real ep & logical ep"));
  1229 		ep->iPEndpoint->iLEndpoint = NULL;
  1230 		}
  1231 	if (aIfcSet->CurrentInterface() != 0)
  1232 		{
  1233 		__KTRACE_OPT(KUSB, Kern::Printf("  Resetting alternate interface setting to 0"));
  1234 		aIfcSet->iCurrentInterface = 0;
  1235 		}
  1236 	return;
  1237 	}
  1238 
  1239 
  1240 void DUsbClientController::ChangeInterface(TUsbcInterface* aIfc)
  1241 	{
  1242 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ChangeInterface()"));
  1243 	TUsbcInterfaceSet* ifcset = aIfc->iInterfaceSet;
  1244 	const TUint8 setting = aIfc->iSettingCode;
  1245 	if (ifcset->iCurrentInterface == setting)
  1246 		{
  1247 		__KTRACE_OPT(KUSB, Kern::Printf("  New Ifc == old Ifc: nothing to do"));
  1248 		return;
  1249 		}
  1250 	__KTRACE_OPT(KUSB, Kern::Printf("  Setting new interface setting #%d", setting));
  1251 	InterfaceSetTeardown(ifcset);
  1252 	InterfaceSetup(aIfc);
  1253 	StatusNotify(static_cast<TUsbcDeviceState>(KUsbAlternateSetting | setting), ifcset->iClientId);
  1254 	}
  1255 
  1256 
  1257 // aFunction gets called, successively, with the endpoint index of every ep in-use as its argument.
  1258 // (BTW: The declaration "type (class::*name)(params)" makes <name> a "pointer to element function".)
  1259 //
  1260 TInt DUsbClientController::DoForEveryEndpointInUse(TInt (DUsbClientController::*aFunction)(TInt), TInt& aCount)
  1261 	{
  1262 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DoForEveryEndpointInUse()"));
  1263 	aCount = 0;
  1264 	TUsbcConfiguration* const config = CurrentConfig();
  1265 	if (!config)
  1266 		{
  1267 		__KTRACE_OPT(KUSB, Kern::Printf("  Device is not configured - returning"));
  1268 		return KErrNone;
  1269 		}
  1270 	RPointerArray<TUsbcInterfaceSet>& ifcsets = config->iInterfaceSets;
  1271 	const TInt num_ifcsets = ifcsets.Count();
  1272 	for (TInt i = 0; i < num_ifcsets; i++)
  1273 		{
  1274 		RPointerArray<TUsbcLogicalEndpoint>& eps = ifcsets[i]->CurrentInterface()->iEndpoints;
  1275 		const TInt num_eps = eps.Count();
  1276 		for (TInt j = 0; j < num_eps; j++)
  1277 			{
  1278 			const TInt ep_num = EpAddr2Idx(eps[j]->iPEndpoint->iEndpointAddr);
  1279 			const TInt result = (this->*aFunction)(ep_num);
  1280 			++aCount;
  1281 			if (result != KErrNone)
  1282 				{
  1283 				return result;
  1284 				}
  1285 			}
  1286 		}
  1287 	return KErrNone;
  1288 	}
  1289 
  1290 
  1291 // -eof-