441 } |
441 } |
442 __SPIN_UNLOCK_IRQRESTORE(iSpinLock,intState); |
442 __SPIN_UNLOCK_IRQRESTORE(iSpinLock,intState); |
443 |
443 |
444 if(r == KErrNone) |
444 if(r == KErrNone) |
445 { |
445 { |
|
446 // Use placement new to re-initialise the iClientTimeoutDfc callback object (don't re-allocate the memory) |
|
447 new (iClientTimeoutDfc) TDfc(SlaveStaticCB,(TAny*)this, 7); // Highest Dfc priority |
446 iClient->Open(); |
448 iClient->Open(); |
447 aCallback->iChannel=this; |
449 aCallback->iChannel=this; |
448 iNotif = aCallback; |
450 iNotif = aCallback; |
449 iConfigHeader=aConfigHdr; // Header alread checked, so just assign it |
451 iConfigHeader=aConfigHdr; // Header alread checked, so just assign it |
450 |
452 |
454 aChannelId = 0; // the client should read iChannelId from the callback object. |
456 aChannelId = 0; // the client should read iChannelId from the callback object. |
455 r=DoRequest(EAsyncConfigPwrUp); |
457 r=DoRequest(EAsyncConfigPwrUp); |
456 } |
458 } |
457 else |
459 else |
458 r=DoRequest(ESyncConfigPwrUp); |
460 r=DoRequest(ESyncConfigPwrUp); |
459 |
|
460 if(r == KErrNone) |
461 if(r == KErrNone) |
461 { |
462 { |
462 if(!aAsynch) // For asynchronous version there is nothing more to do until the callback is invoked |
463 if(!aAsynch) // For asynchronous version there is nothing more to do until the callback is invoked |
463 { |
464 { |
464 SetChannelId(aChannelId); |
465 SetChannelId(aChannelId); |
492 return r; |
494 return r; |
493 StopTimer(); |
495 StopTimer(); |
494 r=DoRequest(EPowerDown); |
496 r=DoRequest(EPowerDown); |
495 if(r == KErrNone) |
497 if(r == KErrNone) |
496 { |
498 { |
|
499 if(iClientTimeoutDfc != NULL) |
|
500 { |
|
501 iClientTimeoutDfc->~TDfc(); // call destructor directly, ie don't free the memory |
|
502 } |
497 TInt intState=__SPIN_LOCK_IRQSAVE(iSpinLock); |
503 TInt intState=__SPIN_LOCK_IRQSAVE(iSpinLock); |
498 iClient=NULL; |
504 iClient=NULL; |
499 iChannelInUse=0; // Channel now available for capture by other clients |
505 iChannelInUse=0; // Channel now available for capture by other clients |
500 __SPIN_UNLOCK_IRQRESTORE(iSpinLock,intState); |
506 __SPIN_UNLOCK_IRQRESTORE(iSpinLock,intState); |
501 pT->AsyncClose(); // Allow Client thread to close now channel has been released |
507 pT->AsyncClose(); // Allow Client thread to close now channel has been released |
800 } |
806 } |
801 #endif/*SLAVE_MODE*/ |
807 #endif/*SLAVE_MODE*/ |
802 |
808 |
803 DIicBusChannelSlave::DIicBusChannelSlave(TBusType aBusType, TChannelDuplex aChanDuplex, TInt16 aChannelId) |
809 DIicBusChannelSlave::DIicBusChannelSlave(TBusType aBusType, TChannelDuplex aChanDuplex, TInt16 aChannelId) |
804 : DIicBusChannel(DIicBusChannel::ESlave, aBusType, aChanDuplex), |
810 : DIicBusChannel(DIicBusChannel::ESlave, aBusType, aChanDuplex), |
805 iChannelId(aChannelId), iTimerState(EInactive), |
811 iChannelId(aChannelId), iClientTimeoutDfc(NULL), iTimerState(EInactive), |
806 iMasterWaitTime(KSlaveDefMWaitTime), iClientWaitTime(KSlaveDefCWaitTime), |
812 iMasterWaitTime(KSlaveDefMWaitTime), iClientWaitTime(KSlaveDefCWaitTime), |
807 iSpinLock(TSpinLock::EOrderGenericIrqLow2) // Semi-arbitrary, low priority value |
813 iSpinLock(TSpinLock::EOrderGenericIrqLow2) // Semi-arbitrary, low priority value |
808 { |
814 { |
809 #ifndef STANDALONE_CHANNEL |
815 #ifndef STANDALONE_CHANNEL |
810 iController = NULL; |
816 iController = NULL; |
811 #endif |
817 #endif |
812 } |
818 } |
813 |
819 |
814 DIicBusChannelSlave::~DIicBusChannelSlave() |
820 DIicBusChannelSlave::~DIicBusChannelSlave() |
815 { |
821 { |
816 delete iClientTimeoutDfc; |
822 if(iClientTimeoutDfc != NULL) |
|
823 { |
|
824 delete iClientTimeoutDfc; |
|
825 iClientTimeoutDfc = NULL; |
|
826 } |
|
827 return; |
817 } |
828 } |
818 |
829 |
819 void DIicBusChannelSlave::SlaveStaticCB(TAny* aPtr) |
830 void DIicBusChannelSlave::SlaveStaticCB(TAny* aPtr) |
820 { |
831 { |
821 DIicBusChannelSlave* chan = (DIicBusChannelSlave*)aPtr; |
832 DIicBusChannelSlave* chan = (DIicBusChannelSlave*)aPtr; |
1137 }; |
1148 }; |
1138 |
1149 |
1139 |
1150 |
1140 TInt DIicBusChannelMasterSlave::ReleaseChannel() |
1151 TInt DIicBusChannelMasterSlave::ReleaseChannel() |
1141 { |
1152 { |
1142 iMasterChannel->Lock(); |
|
1143 TInt r=iSlaveChannel->ReleaseChannel(); |
1153 TInt r=iSlaveChannel->ReleaseChannel(); |
1144 iMasterChannel->Unlock(); |
|
1145 return r; |
1154 return r; |
1146 }; |
1155 }; |
1147 |
1156 |
1148 TInt DIicBusChannelMasterSlave::StaticExtension(TUint /*aFunction*/, TAny* /*aParam1*/, TAny* /*aParam*/) |
1157 TInt DIicBusChannelMasterSlave::StaticExtension(TUint /*aFunction*/, TAny* /*aParam1*/, TAny* /*aParam*/) |
1149 { |
1158 { |