kernel/eka/drivers/usbcc/ps_usbc.cpp
changeset 90 947f0dc9f7a8
parent 0 a41df078684a
child 253 d37db4dcc88d
equal deleted inserted replaced
52:2d65c2f76d7b 90:947f0dc9f7a8
   178 		// (If the hardware is NOT activated at this point, we can only be in
   178 		// (If the hardware is NOT activated at this point, we can only be in
   179 		//	state EUsbcDeviceStateAttached, so we don't have to move to it.)
   179 		//	state EUsbcDeviceStateAttached, so we don't have to move to it.)
   180 		}
   180 		}
   181 	DeActivateHardwareController();					 // turn off UDC altogether
   181 	DeActivateHardwareController();					 // turn off UDC altogether
   182 	iStackIsActive = EFalse;
   182 	iStackIsActive = EFalse;
       
   183 	// Notify registered clients on the user side about a USB device state
       
   184 	// change event and a transition to the "Undefined" state.
       
   185 	// Note: the state should be changed to "Undefined" before calling RunClientCallbacks(), 
       
   186 	//       otherwise the "Undefined" state will probably be lost.
       
   187 	NextDeviceState(EUsbcDeviceStateUndefined);
   183 	// Complete all pending requests, returning KErrDisconnected
   188 	// Complete all pending requests, returning KErrDisconnected
   184 	RunClientCallbacks();
   189 	RunClientCallbacks();
   185 	// Notify registered clients on the user side about a USB device state
       
   186 	// change event and a transition to the "Undefined" state.
       
   187 	NextDeviceState(EUsbcDeviceStateUndefined);
       
   188 	}
   190 	}
   189 
   191 
   190 
   192 
   191 /** To be called by the OTG/Host stack in an OTG setup to enable USB device
   193 /** To be called by the OTG/Host stack in an OTG setup to enable USB device
   192 	functionality.
   194 	functionality.
   670 	{
   672 	{
   671 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::UsbConnect()"));
   673 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::UsbConnect()"));
   672 #ifdef USB_OTG_CLIENT
   674 #ifdef USB_OTG_CLIENT
   673 	iClientSupportReady = ETrue;
   675 	iClientSupportReady = ETrue;
   674 	const TInt r = EvaluateOtgConnectFlags();
   676 	const TInt r = EvaluateOtgConnectFlags();
   675 	const TInt irq = NKern::DisableAllInterrupts();
   677     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
   676 	if (iUsbResetDeferred) // implies (iOtgHnpHandledByHw == ETrue)
   678 	if (iUsbResetDeferred) // implies (iOtgHnpHandledByHw == ETrue)
   677 		{
   679 		{
   678 		__KTRACE_OPT(KUSB, Kern::Printf("  Resetting USB Reset 'defer' flag"));
   680 		__KTRACE_OPT(KUSB, Kern::Printf("  Resetting USB Reset 'defer' flag"));
   679 		iUsbResetDeferred = EFalse;
   681 		iUsbResetDeferred = EFalse;
   680 		(void) ProcessResetEvent(EFalse);
   682 		(void) ProcessResetEvent(EFalse);
   681 		}
   683 		}
   682 	NKern::RestoreInterrupts(irq);
   684     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   683 #else
   685 #else
   684 	const TInt r = UdcConnect();
   686 	const TInt r = UdcConnect();
   685 #endif // USB_OTG_CLIENT
   687 #endif // USB_OTG_CLIENT
   686 	return r;
   688 	return r;
   687 	}
   689 	}
   741 	if (IsInTheStatusList(aCallback))
   743 	if (IsInTheStatusList(aCallback))
   742 		{
   744 		{
   743 		__KTRACE_OPT(KUSB, Kern::Printf("  Error: StatusCallback @ 0x%x already registered", &aCallback));
   745 		__KTRACE_OPT(KUSB, Kern::Printf("  Error: StatusCallback @ 0x%x already registered", &aCallback));
   744 		return KErrGeneral;
   746 		return KErrGeneral;
   745 		}
   747 		}
   746 	const TInt irq = NKern::DisableAllInterrupts();
   748     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
   747 	iStatusCallbacks.AddLast(aCallback);
   749 	iStatusCallbacks.AddLast(aCallback);
   748 	NKern::RestoreInterrupts(irq);
   750     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   749 	return KErrNone;
   751 	return KErrNone;
   750 	}
   752 	}
   751 
   753 
   752 
   754 
   753 /** De-registers (removes from the list of pending requests) a notification callback for the USB device
   755 /** De-registers (removes from the list of pending requests) a notification callback for the USB device
   759 */
   761 */
   760 EXPORT_C TInt DUsbClientController::DeRegisterForStatusChange(const DBase* aClientId)
   762 EXPORT_C TInt DUsbClientController::DeRegisterForStatusChange(const DBase* aClientId)
   761 	{
   763 	{
   762 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForStatusChange()"));
   764 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForStatusChange()"));
   763 	__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
   765 	__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
   764 	const TInt irq = NKern::DisableAllInterrupts();
   766     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
   765 	TSglQueIter<TUsbcStatusCallback> iter(iStatusCallbacks);
   767 	TSglQueIter<TUsbcStatusCallback> iter(iStatusCallbacks);
   766 	TUsbcStatusCallback* p;
   768 	TUsbcStatusCallback* p;
   767 	while ((p = iter++) != NULL)
   769 	while ((p = iter++) != NULL)
   768 		{
   770 		{
   769 		if (p->Owner() == aClientId)
   771 		if (p->Owner() == aClientId)
   770 			{
   772 			{
   771 			__KTRACE_OPT(KUSB, Kern::Printf("  removing StatusCallback @ 0x%x", p));
   773 			__KTRACE_OPT(KUSB, Kern::Printf("  removing StatusCallback @ 0x%x", p));
   772 			iStatusCallbacks.Remove(*p);
   774 			iStatusCallbacks.Remove(*p);
   773 			NKern::RestoreInterrupts(irq);
   775 		    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   774 			return KErrNone;
   776 			return KErrNone;
   775 			}
   777 			}
   776 		}
   778 		}
   777 	__KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
   779 	__KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
   778 	NKern::RestoreInterrupts(irq);
   780     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   779 	return KErrNotFound;
   781 	return KErrNotFound;
   780 	}
   782 	}
   781 
   783 
   782 
   784 
   783 /** Registers a notification callback for changes of the state of endpoints.
   785 /** Registers a notification callback for changes of the state of endpoints.
   807 	if (IsInTheEpStatusList(aCallback))
   809 	if (IsInTheEpStatusList(aCallback))
   808 		{
   810 		{
   809 		__KTRACE_OPT(KUSB, Kern::Printf("  Error: EpStatusCallback @ 0x%x already registered", &aCallback));
   811 		__KTRACE_OPT(KUSB, Kern::Printf("  Error: EpStatusCallback @ 0x%x already registered", &aCallback));
   810 		return KErrGeneral;
   812 		return KErrGeneral;
   811 		}
   813 		}
   812 	const TInt irq = NKern::DisableAllInterrupts();
   814     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
   813 	iEpStatusCallbacks.AddLast(aCallback);
   815 	iEpStatusCallbacks.AddLast(aCallback);
   814 	NKern::RestoreInterrupts(irq);
   816     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   815 	return KErrNone;
   817 	return KErrNone;
   816 	}
   818 	}
   817 
   819 
   818 
   820 
   819 /** De-registers (removes from the list of pending requests) a notification callback for changes of the state
   821 /** De-registers (removes from the list of pending requests) a notification callback for changes of the state
   825 */
   827 */
   826 EXPORT_C TInt DUsbClientController::DeRegisterForEndpointStatusChange(const DBase* aClientId)
   828 EXPORT_C TInt DUsbClientController::DeRegisterForEndpointStatusChange(const DBase* aClientId)
   827 	{
   829 	{
   828 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForEndpointStatusChange()"));
   830 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForEndpointStatusChange()"));
   829 	__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
   831 	__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
   830 	const TInt irq = NKern::DisableAllInterrupts();
   832     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
   831 	TSglQueIter<TUsbcEndpointStatusCallback> iter(iEpStatusCallbacks);
   833 	TSglQueIter<TUsbcEndpointStatusCallback> iter(iEpStatusCallbacks);
   832 	TUsbcEndpointStatusCallback* p;
   834 	TUsbcEndpointStatusCallback* p;
   833 	while ((p = iter++) != NULL)
   835 	while ((p = iter++) != NULL)
   834 		{
   836 		{
   835 		if (p->Owner() == aClientId)
   837 		if (p->Owner() == aClientId)
   836 			{
   838 			{
   837 			__KTRACE_OPT(KUSB, Kern::Printf("  removing EpStatusCallback @ 0x%x", p));
   839 			__KTRACE_OPT(KUSB, Kern::Printf("  removing EpStatusCallback @ 0x%x", p));
   838 			iEpStatusCallbacks.Remove(*p);
   840 			iEpStatusCallbacks.Remove(*p);
   839 			NKern::RestoreInterrupts(irq);
   841 		    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   840 			return KErrNone;
   842 			return KErrNone;
   841 			}
   843 			}
   842 		}
   844 		}
   843 	__KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
   845 	__KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
   844 	NKern::RestoreInterrupts(irq);
   846     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
   845 	return KErrNotFound;
   847 	return KErrNotFound;
   846 	}
   848 	}
   847 
   849 
   848 
   850 
   849 /** Returns the number of the currently active alternate interface setting for this interface.
   851 /** Returns the number of the currently active alternate interface setting for this interface.
  1054 			__KTRACE_OPT(KUSB, Kern::Printf("  RequestCallback @ 0x%x already registered", &aCallback));
  1056 			__KTRACE_OPT(KUSB, Kern::Printf("  RequestCallback @ 0x%x already registered", &aCallback));
  1055 			return KErrNone;
  1057 			return KErrNone;
  1056 			}
  1058 			}
  1057 		// Ep0 reads don't need to be prepared - there's always one pending
  1059 		// Ep0 reads don't need to be prepared - there's always one pending
  1058 		__KTRACE_OPT(KUSB, Kern::Printf("  adding RequestCallback @ 0x%x (ep0)", &aCallback));
  1060 		__KTRACE_OPT(KUSB, Kern::Printf("  adding RequestCallback @ 0x%x (ep0)", &aCallback));
  1059 		TInt irq = NKern::DisableAllInterrupts();
  1061 	    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
  1060 		iEp0ReadRequestCallbacks.AddLast(aCallback);
  1062 		iEp0ReadRequestCallbacks.AddLast(aCallback);
  1061 		NKern::RestoreInterrupts(irq);
  1063         __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  1062 		err = KErrNone;
  1064 		err = KErrNone;
  1063 		if (iEp0_RxExtraData)
  1065 		if (iEp0_RxExtraData)
  1064 			{
  1066 			{
  1065 			__KTRACE_OPT(KUSB, Kern::Printf("  iEp0_RxExtraData: trying again..."));
  1067 			__KTRACE_OPT(KUSB, Kern::Printf("  iEp0_RxExtraData: trying again..."));
  1066 			const TBool rx_data = iEp0DataReceiving;
  1068 			const TBool rx_data = iEp0DataReceiving;
  1067 			const TInt irq = NKern::DisableAllInterrupts();
  1069 		    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
  1068 			err = ProcessEp0ReceiveDone(iEp0_RxExtraCount);
  1070 			err = ProcessEp0ReceiveDone(iEp0_RxExtraCount);
  1069 			NKern::RestoreInterrupts(irq);
  1071 	        __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  1070 			if (err == KErrNone)
  1072 			if (err == KErrNone)
  1071 				{
  1073 				{
  1072 				iEp0_RxExtraData = EFalse;
  1074 				iEp0_RxExtraData = EFalse;
  1073 				// Queue a new Ep0 read (because xxxProceed only re-enables the interrupt)
  1075 				// Queue a new Ep0 read (because xxxProceed only re-enables the interrupt)
  1074 				SetupEndpointZeroRead();
  1076 				SetupEndpointZeroRead();
  1641 	if (IsInTheOtgFeatureList(aCallback))
  1643 	if (IsInTheOtgFeatureList(aCallback))
  1642 		{
  1644 		{
  1643 		__KTRACE_OPT(KUSB, Kern::Printf("  Error: OtgFeatureCallback @ 0x%x already registered", &aCallback));
  1645 		__KTRACE_OPT(KUSB, Kern::Printf("  Error: OtgFeatureCallback @ 0x%x already registered", &aCallback));
  1644 		return KErrAlreadyExists;
  1646 		return KErrAlreadyExists;
  1645 		}
  1647 		}
  1646 	const TInt irq = NKern::DisableAllInterrupts();
  1648     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
  1647 	iOtgCallbacks.AddLast(aCallback);
  1649 	iOtgCallbacks.AddLast(aCallback);
  1648 	NKern::RestoreInterrupts(irq);
  1650     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  1649 	return KErrNone;
  1651 	return KErrNone;
  1650 	}
  1652 	}
  1651 
  1653 
  1652 
  1654 
  1653 /** De-registers (removes from the list of pending requests) a notification callback for
  1655 /** De-registers (removes from the list of pending requests) a notification callback for
  1659 */
  1661 */
  1660 EXPORT_C TInt DUsbClientController::DeRegisterForOtgFeatureChange(const DBase* aClientId)
  1662 EXPORT_C TInt DUsbClientController::DeRegisterForOtgFeatureChange(const DBase* aClientId)
  1661 	{
  1663 	{
  1662 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForOtgFeatureChange()"));
  1664 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForOtgFeatureChange()"));
  1663 	__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
  1665 	__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
  1664 	const TInt irq = NKern::DisableAllInterrupts();
  1666     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
  1665 	TSglQueIter<TUsbcOtgFeatureCallback> iter(iOtgCallbacks);
  1667 	TSglQueIter<TUsbcOtgFeatureCallback> iter(iOtgCallbacks);
  1666 	TUsbcOtgFeatureCallback* p;
  1668 	TUsbcOtgFeatureCallback* p;
  1667 	while ((p = iter++) != NULL)
  1669 	while ((p = iter++) != NULL)
  1668 		{
  1670 		{
  1669 		if (!aClientId || p->Owner() == aClientId)
  1671 		if (!aClientId || p->Owner() == aClientId)
  1670 			{
  1672 			{
  1671 			__KTRACE_OPT(KUSB, Kern::Printf("  removing OtgFeatureCallback @ 0x%x", p));
  1673 			__KTRACE_OPT(KUSB, Kern::Printf("  removing OtgFeatureCallback @ 0x%x", p));
  1672 			iOtgCallbacks.Remove(*p);
  1674 			iOtgCallbacks.Remove(*p);
  1673 			NKern::RestoreInterrupts(irq);
  1675             __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  1674 			return KErrNone;
  1676 			return KErrNone;
  1675 			}
  1677 			}
  1676 		}
  1678 		}
  1677 	__KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
  1679 	__KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
  1678 	NKern::RestoreInterrupts(irq);
  1680     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  1679 	return KErrNotFound;
  1681 	return KErrNotFound;
  1680 	}
  1682 	}
  1681 
  1683 
  1682 
  1684 
  1683 /** Returns a specific standard USB interface descriptor.
  1685 /** Returns a specific standard USB interface descriptor.
  2879 	  iStatusCallbacks(_FOFF(TUsbcStatusCallback, iLink)),
  2881 	  iStatusCallbacks(_FOFF(TUsbcStatusCallback, iLink)),
  2880 	  iEpStatusCallbacks(_FOFF(TUsbcEndpointStatusCallback, iLink)),
  2882 	  iEpStatusCallbacks(_FOFF(TUsbcEndpointStatusCallback, iLink)),
  2881 	  iOtgCallbacks(_FOFF(TUsbcOtgFeatureCallback, iLink)),
  2883 	  iOtgCallbacks(_FOFF(TUsbcOtgFeatureCallback, iLink)),
  2882 	  iReconnectTimer(ReconnectTimerCallback, this),
  2884 	  iReconnectTimer(ReconnectTimerCallback, this),
  2883 	  iCableStatusTimer(CableStatusTimerCallback, this),
  2885 	  iCableStatusTimer(CableStatusTimerCallback, this),
       
  2886       iUsbLock(TSpinLock::EOrderGenericIrqLow3),	  
  2884 	  iPowerUpDfc(PowerUpDfc, this, 3),
  2887 	  iPowerUpDfc(PowerUpDfc, this, 3),
  2885 	  iPowerDownDfc(PowerDownDfc, this, 3),
  2888 	  iPowerDownDfc(PowerDownDfc, this, 3),
  2886 	  iStandby(EFalse),
  2889 	  iStandby(EFalse),
  2887 #ifdef USB_OTG_CLIENT
  2890 #ifdef USB_OTG_CLIENT
  2888 	  // In the OTG case the device starts out disabled
  2891 	  // In the OTG case the device starts out disabled
  3709 	if (idx == KErrNotFound)
  3712 	if (idx == KErrNotFound)
  3710 		{
  3713 		{
  3711 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface not found in array"));
  3714 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface not found in array"));
  3712 		return;
  3715 		return;
  3713 		}
  3716 		}
       
  3717 	//Add this mutex to protect the interface set data structure
       
  3718 	if (NKern::CurrentContext() == EThread)
       
  3719 	    {
       
  3720         NKern::FMWait(&iMutex);
       
  3721 	    }
       
  3722 	
  3714 	iConfigs[0]->iInterfaceSets.Remove(idx);
  3723 	iConfigs[0]->iInterfaceSets.Remove(idx);
       
  3724 	if (NKern::CurrentContext() == EThread)
       
  3725 	    {
       
  3726         NKern::FMSignal(&iMutex);	
       
  3727 	    }
  3715 	delete ifcset_ptr;
  3728 	delete ifcset_ptr;
  3716 	}
  3729 	}
  3717 
  3730 
  3718 
  3731 
  3719 void DUsbClientController::DeleteInterface(TInt aIfcSet, TInt aIfc)
  3732 void DUsbClientController::DeleteInterface(TInt aIfcSet, TInt aIfc)
  3728 	if (ifcset_ptr->iInterfaces.Count() <= aIfc)
  3741 	if (ifcset_ptr->iInterfaces.Count() <= aIfc)
  3729 		{
  3742 		{
  3730 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface setting: %d", aIfc));
  3743 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface setting: %d", aIfc));
  3731 		return;
  3744 		return;
  3732 		}
  3745 		}
       
  3746 	//Add this mutex to protect the interface set data structure
       
  3747 	if (NKern::CurrentContext() == EThread)
       
  3748 	    {
       
  3749         NKern::FMWait(&iMutex);
       
  3750 	    }	
  3733 	TUsbcInterface* const ifc_ptr = ifcset_ptr->iInterfaces[aIfc];
  3751 	TUsbcInterface* const ifc_ptr = ifcset_ptr->iInterfaces[aIfc];
  3734 	// Always first remove, then delete (see ~TUsbcLogicalEndpoint() for the reason why)
  3752 	// Always first remove, then delete (see ~TUsbcLogicalEndpoint() for the reason why)
  3735 	ifcset_ptr->iInterfaces.Remove(aIfc);
  3753 	ifcset_ptr->iInterfaces.Remove(aIfc);
  3736 	delete ifc_ptr;
  3754 
  3737 	if (aIfc == ifcset_ptr->iCurrentInterface)
  3755 	if (aIfc == ifcset_ptr->iCurrentInterface)
  3738 		{
  3756 		{
  3739 		__KTRACE_OPT(KUSB, Kern::Printf(" > Warning: deleting current interface setting"));
  3757 		__KTRACE_OPT(KUSB, Kern::Printf(" > Warning: deleting current interface setting"));
  3740 		ifcset_ptr->iCurrentInterface = 0;
  3758 		ifcset_ptr->iCurrentInterface = 0;
  3741 		}
  3759 		}
       
  3760 	if (NKern::CurrentContext() == EThread)
       
  3761 	    {
       
  3762         NKern::FMSignal(&iMutex);
       
  3763 	    }	
       
  3764 	delete ifc_ptr;
  3742 	}
  3765 	}
  3743 
  3766 
  3744 
  3767 
  3745 void DUsbClientController::CancelTransferRequests(TInt aRealEndpoint)
  3768 void DUsbClientController::CancelTransferRequests(TInt aRealEndpoint)
  3746 	{
  3769 	{
  3763 	{
  3786 	{
  3764 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallback()"));
  3787 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallback()"));
  3765 	// Ep0 OUT
  3788 	// Ep0 OUT
  3766 	if (aEndpointNum == 0)
  3789 	if (aEndpointNum == 0)
  3767 		{
  3790 		{
  3768 		const TInt irq = NKern::DisableAllInterrupts();
  3791 	    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
  3769 		TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
  3792 		TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
  3770 		TUsbcRequestCallback* p;
  3793 		TUsbcRequestCallback* p;
  3771 		while ((p = iter++) != NULL)
  3794 		while ((p = iter++) != NULL)
  3772 			{
  3795 			{
  3773 			if (p->Owner() == aClientId)
  3796 			if (p->Owner() == aClientId)
  3776 				__ASSERT_DEBUG((p->iTransferDir == EControllerRead), Kern::Fault(KUsbPILPanicCat, __LINE__));
  3799 				__ASSERT_DEBUG((p->iTransferDir == EControllerRead), Kern::Fault(KUsbPILPanicCat, __LINE__));
  3777 				__KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x (ep0)", p));
  3800 				__KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x (ep0)", p));
  3778 				iEp0ReadRequestCallbacks.Remove(*p);
  3801 				iEp0ReadRequestCallbacks.Remove(*p);
  3779 				}
  3802 				}
  3780 			}
  3803 			}
  3781 		NKern::RestoreInterrupts(irq);
  3804         __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  3782 		return;
  3805 		return;
  3783 		}
  3806 		}
  3784 	// Other endpoints
  3807 	// Other endpoints
  3785 	TUsbcRequestCallback* const p = iRequestCallbacks[aEndpointNum];
  3808 	TUsbcRequestCallback* const p = iRequestCallbacks[aEndpointNum];
  3786 	if (p)
  3809 	if (p)
  3796 void DUsbClientController::DeleteRequestCallbacks(const DBase* aClientId)
  3819 void DUsbClientController::DeleteRequestCallbacks(const DBase* aClientId)
  3797 	{
  3820 	{
  3798 	// aClientId being NULL means: delete all requests for *all* clients.
  3821 	// aClientId being NULL means: delete all requests for *all* clients.
  3799 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallbacks()"));
  3822 	__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallbacks()"));
  3800 	// Ep0 OUT
  3823 	// Ep0 OUT
  3801 	const TInt irq = NKern::DisableAllInterrupts();
  3824     const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
  3802 	TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
  3825 	TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
  3803 	TUsbcRequestCallback* p;
  3826 	TUsbcRequestCallback* p;
  3804 	while ((p = iter++) != NULL)
  3827 	while ((p = iter++) != NULL)
  3805 		{
  3828 		{
  3806 		if (!aClientId || p->Owner() == aClientId)
  3829 		if (!aClientId || p->Owner() == aClientId)
  3807 			{
  3830 			{
  3808 			__KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x (ep0)", p));
  3831 			__KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x (ep0)", p));
  3809 			iEp0ReadRequestCallbacks.Remove(*p);
  3832 			iEp0ReadRequestCallbacks.Remove(*p);
  3810 			}
  3833 			}
  3811 		}
  3834 		}
  3812 	NKern::RestoreInterrupts(irq);
  3835     __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
  3813 	// Other endpoints
  3836 	// Other endpoints
  3814 	for (TInt i = 1; i < KUsbcEpArraySize; i++)
  3837 	for (TInt i = 1; i < KUsbcEpArraySize; i++)
  3815 		{
  3838 		{
  3816 		TUsbcRequestCallback* const p = iRequestCallbacks[i];
  3839 		TUsbcRequestCallback* const p = iRequestCallbacks[i];
  3817 		if (p && (!aClientId || p->Owner() == aClientId))
  3840 		if (p && (!aClientId || p->Owner() == aClientId))
  4276 			iDPlusEnabled = enableDPlus;
  4299 			iDPlusEnabled = enableDPlus;
  4277 			// First we move to Suspend state to trigger a state change
  4300 			// First we move to Suspend state to trigger a state change
  4278 			// notification in any case, even if no cable and/or host are
  4301 			// notification in any case, even if no cable and/or host are
  4279 			// connected. The next Reset will get us out of it again.
  4302 			// connected. The next Reset will get us out of it again.
  4280 			iDeviceStateB4Suspend = iDeviceState;
  4303 			iDeviceStateB4Suspend = iDeviceState;
  4281 			NextDeviceState(EUsbcDeviceStateSuspended);
  4304 			// Please pay attention to that the above comment now is not accurate!
       
  4305 			// It's not updated according the below modification just for keeping the original comment!
       
  4306 			//
       
  4307 			// Moving to Suspend state arbitrarily will cause DEFECT EDHO-7Y3AAD.
       
  4308 			// DEFECT EDHO-7Y3AAD: Connected to the USB Charger, the UI displayed wrongly connected as default mode
       
  4309 			//                     since the iDeviceState changed wrongly from Undefined to Suspended, and keep 
       
  4310 			//                     always Suspended becauseof NO Reset coming next!
       
  4311 			// So, to fix this defect, the state change notification is modified to be triggerred by loop the current state again
       
  4312 			// if the current state is Undefined!
       
  4313 			if (EUsbcDeviceStateUndefined != iDeviceState)
       
  4314 				{
       
  4315 				NextDeviceState(EUsbcDeviceStateSuspended);
       
  4316 				}
       
  4317 			else
       
  4318 				{
       
  4319 				NextDeviceState(iDeviceState);
       
  4320 				}
  4282 			r = (*iEnablePullUpOnDPlus)(iOtgContext);
  4321 			r = (*iEnablePullUpOnDPlus)(iOtgContext);
  4283 			if (r != KErrNone)
  4322 			if (r != KErrNone)
  4284 				{
  4323 				{
  4285 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: iEnablePullUpOnDPlus() = %d", r));
  4324 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: iEnablePullUpOnDPlus() = %d", r));
  4286 				}
  4325 				}