kernel/eka/drivers/usbcc/chapter9.cpp
changeset 0 a41df078684a
child 87 2f92ad2dc5db
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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-