toolsandutils/wintunnel/src_cedar/serialldd.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 // Copyright (c) 2002-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 "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 // wins/specific/serialldd.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "winscomm.h"
       
    19 #include <kernel/kern_priv.h>
       
    20 #include <e32hal.h>
       
    21 #include <e32uid.h>
       
    22 
       
    23 _LIT(KLddName,"Comm");
       
    24 
       
    25 
       
    26 enum TPanic
       
    27 	{
       
    28 	ESetConfigWhileRequestPending,
       
    29 	ESetSignalsSetAndClear,
       
    30 	EResetBuffers,
       
    31 	ESetReceiveBufferLength,
       
    32 	};
       
    33 
       
    34 
       
    35 inline TUint32 SafeSwap(TUint32 aNewValue, TUint32& aWord)
       
    36 	{ return (TUint32)NKern::SafeSwap((TAny*)aNewValue, (TAny*&)aWord); }
       
    37 
       
    38 DECLARE_STANDARD_LDD()
       
    39 	{
       
    40 	return new DDeviceComm;
       
    41 	}
       
    42 
       
    43 
       
    44 DDeviceComm::DDeviceComm()
       
    45 	{
       
    46 	iParseMask = KDeviceAllowAll;
       
    47 	iUnitsMask = 0xffffffff; // Leave units decision to the PDD
       
    48 	iVersion = TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
       
    49 	}
       
    50 
       
    51 TInt DDeviceComm::Install()
       
    52 	{
       
    53 	return(SetName(&KLddName));
       
    54 	}
       
    55 
       
    56 void DDeviceComm::GetCaps(TDes8& aDes) const
       
    57 	{
       
    58 	TPckgBuf<TCapsDevCommV01> b;
       
    59 	b().version = TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
       
    60 	Kern::InfoCopy(aDes,b);
       
    61 	}
       
    62 
       
    63 TInt DDeviceComm::Create(DLogicalChannelBase*& aChannel)
       
    64 	{
       
    65 	aChannel = new DChannelComm;
       
    66 	return aChannel?KErrNone:KErrNoMemory;
       
    67 	}
       
    68 
       
    69 
       
    70 DChannelComm::DChannelComm()
       
    71 	:
       
    72 		iRxCompleteDfc(DChannelComm::CompleteRxDfc,this,2),
       
    73 		iTxCompleteDfc(DChannelComm::CompleteTxDfc,this,2),
       
    74 		iRxDataAvailableDfc(DChannelComm::RxDataAvailableDfc,this,2),
       
    75 		iSigNotifyDfc(DChannelComm::SignalNotifyDfc,this,2),
       
    76 //		iTurnaroundMinMilliSeconds(0),
       
    77 //		iTurnaroundTimerRunning(EFalse),
       
    78 //		iTurnaroundTransmitDelayed(EFalse),
       
    79 		iTurnaroundTimer(DChannelComm::TurnaroundStartDfc, this),
       
    80 		iTurnaroundDfc(DChannelComm::TurnaroundTimeout, this, 2)
       
    81 //		iTurnaroundTxDesPtr(0),
       
    82 //		iTurnaroundTxDesLength(0)
       
    83 	{
       
    84 	iConfig.iRate = EBps9600;
       
    85 	iConfig.iDataBits = EData8;
       
    86 	iConfig.iStopBits = EStop1;
       
    87 	iConfig.iParity = EParityNone;
       
    88 	iConfig.iHandshake = KConfigObeyCTS;
       
    89 	iConfig.iParityError = KConfigParityErrorFail;
       
    90 	iConfig.iFifo = EFifoEnable;
       
    91 	iConfig.iTerminatorCount = 0;
       
    92 	iConfig.iXonChar = 0x11;
       
    93 	iConfig.iXoffChar = 0x13;
       
    94 	iConfig.iSIREnable = ESIRDisable;
       
    95 
       
    96 	iTxError = KErrNone;
       
    97 	iRxError = KErrNone;
       
    98 	iRxDAError = KErrNone;
       
    99 	iSignalError = KErrNone;
       
   100 	iClientDestPtr = 0;
       
   101 	iClientSignalResultPtr = 0;
       
   102 	iClient = &Kern::CurrentThread();
       
   103 	iClient->Open();
       
   104 	}
       
   105 
       
   106 
       
   107 DChannelComm::~DChannelComm()
       
   108 	{
       
   109 	Kern::SafeClose((DObject*&)iClient, NULL);
       
   110 	}
       
   111 
       
   112 void DChannelComm::Shutdown()
       
   113 	{
       
   114 	// clean-up...
       
   115 	if (iStatus == EActive)
       
   116 		Stop(EStopPwrDown);			// stop PDD
       
   117 
       
   118 	Complete(EAll, KErrAbort);
       
   119 
       
   120 	iRxCompleteDfc.Cancel();
       
   121 	iTxCompleteDfc.Cancel();
       
   122 	iTurnaroundTimer.Cancel();
       
   123 	iTurnaroundDfc.Cancel();
       
   124 	iSigNotifyDfc.Cancel();
       
   125 	iRxDataAvailableDfc.Cancel();
       
   126 	}
       
   127 
       
   128 TInt DChannelComm::TurnaroundSet(TUint aNewTurnaroundMilliSeconds)
       
   129 	{
       
   130 	TInt r = KErrNone;
       
   131 	(void)TurnaroundStopTimer();
       
   132 	iTurnaroundMinMilliSeconds = aNewTurnaroundMilliSeconds;
       
   133 	return r;
       
   134 	}
       
   135 
       
   136 TBool DChannelComm::TurnaroundStopTimer()
       
   137 // Stop the timer and DFC
       
   138 	{
       
   139 	TInt irq = 0;
       
   140 	irq = NKern::DisableInterrupts(1);
       
   141 	TBool result = iTurnaroundTimerRunning;
       
   142 	if(result)
       
   143 		{
       
   144 		iTurnaroundTimerRunning = EFalse;
       
   145 		iTurnaroundTimer.Cancel();
       
   146 		iTurnaroundDfc.Cancel();
       
   147 		}
       
   148 	NKern::RestoreInterrupts(irq);
       
   149 	return result;
       
   150 	}
       
   151 
       
   152 TInt DChannelComm::TurnaroundClear()
       
   153 // Clear any old timer
       
   154 // Called for any change: from T > 0 to T == 0 or (T = t1 > 0) to (T = t2 > 0)
       
   155 // POLICY: If a write has already been delayed, it will be started immediately (next reschedule)
       
   156 	{
       
   157 	TInt r = KErrNone;
       
   158 
       
   159 	if(TurnaroundStopTimer())
       
   160 		{
       
   161 		// if a write is waiting, start a DFC to run it
       
   162 		TurnaroundStartDfcImplementation(EFalse);
       
   163 		}
       
   164 
       
   165 	iTurnaroundMinMilliSeconds = 0;
       
   166 	return r;
       
   167 	}
       
   168 
       
   169 void DChannelComm::TurnaroundStartDfc(TAny* aSelf)
       
   170 	{
       
   171 	DChannelComm* self = (DChannelComm*)aSelf;
       
   172 	self->TurnaroundStartDfcImplementation(ETrue);
       
   173 	}
       
   174 
       
   175 void DChannelComm::TurnaroundStartDfcImplementation(TBool inIsr)
       
   176 	{
       
   177 	TInt irq = 0;
       
   178 	if(!inIsr)
       
   179 		{
       
   180 		irq = NKern::DisableInterrupts(1);
       
   181 		}
       
   182 	iTurnaroundTimerRunning = EFalse;
       
   183 	if(iTurnaroundTransmitDelayed)
       
   184 		{
       
   185 		if(inIsr)
       
   186 			iTurnaroundDfc.Add();
       
   187 		else
       
   188 			{
       
   189 			NKern::RestoreInterrupts(irq);
       
   190 			iTurnaroundDfc.Enque();
       
   191 			}
       
   192 		return;
       
   193 		}
       
   194 	if(!inIsr)
       
   195 		{
       
   196 		NKern::RestoreInterrupts(irq);
       
   197 		}
       
   198 	}
       
   199 
       
   200 void DChannelComm::TurnaroundTimeout(TAny* aSelf)
       
   201 	{
       
   202 	DChannelComm* self = (DChannelComm*)aSelf;
       
   203 	self->TurnaroundTimeoutImplementation();
       
   204 	}
       
   205 
       
   206 void DChannelComm::TurnaroundTimeoutImplementation(void)
       
   207 	{
       
   208 	TInt irq = NKern::DisableInterrupts(1);
       
   209 	if(iTurnaroundTransmitDelayed)
       
   210 		{
       
   211 		iTurnaroundTransmitDelayed = EFalse;	// protected -> prevent reentrant ISR
       
   212 		NKern::RestoreInterrupts(irq);
       
   213 		if (iStatus==EClosed)
       
   214 			{
       
   215 			iTurnaroundTxDesPtr = 0;
       
   216 			iTurnaroundTxDesLength = 0;
       
   217 			Complete(ETx,KErrNotReady);
       
   218 			return;
       
   219 			}
       
   220 
       
   221 		// fail signals checked in the PDD
       
   222 		InitiateWrite(iTurnaroundTxDesPtr, iTurnaroundTxDesLength);
       
   223 		iTurnaroundTxDesPtr = 0;
       
   224 		iTurnaroundTxDesLength = 0;
       
   225 		}
       
   226 	else 
       
   227 		NKern::RestoreInterrupts(irq);
       
   228 	}
       
   229 
       
   230 TInt DChannelComm::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion &aVer)
       
   231 	{
       
   232 	if(!Kern::CurrentThreadHasCapability(ECapabilityCommDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by ECOMM.LDD (Comm Driver)")))
       
   233    		return KErrPermissionDenied;		
       
   234 	if (!Kern::QueryVersionSupported(TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber),aVer))
       
   235 		return KErrNotSupported;
       
   236 
       
   237 	// set up the correct DFC queue
       
   238 	SetDfcQ(((DComm*)iPdd)->DfcQ(aUnit));
       
   239 	iRxCompleteDfc.SetDfcQ(iDfcQ);
       
   240 	iTxCompleteDfc.SetDfcQ(iDfcQ);
       
   241 	iRxDataAvailableDfc.SetDfcQ(iDfcQ);
       
   242 	iSigNotifyDfc.SetDfcQ(iDfcQ);
       
   243 	iTurnaroundDfc.SetDfcQ(iDfcQ);
       
   244 	iMsgQ.Receive();
       
   245 
       
   246 	((DComm *)iPdd)->iLdd = this;
       
   247 
       
   248 	//setup the initial port configuration
       
   249 	PddConfigure(iConfig);
       
   250 	
       
   251 	return KErrNone;
       
   252 	}
       
   253 
       
   254 
       
   255 
       
   256 
       
   257 void DChannelComm::Start()
       
   258 	{
       
   259 	if (iStatus != EClosed)
       
   260 		{
       
   261 		PddStart();
       
   262 		iStatus = EActive;
       
   263 		}
       
   264 	}
       
   265 
       
   266 
       
   267 
       
   268 
       
   269 void DChannelComm::HandleMsg(TMessageBase* aMsg)
       
   270 	{
       
   271 	TThreadMessage& m = *(TThreadMessage*)aMsg;
       
   272 	TInt id = m.iValue;
       
   273 	if (id == (TInt)ECloseMsg)
       
   274 		{
       
   275 		Shutdown();
       
   276 		iStatus = EClosed;
       
   277 		m.Complete(KErrNone, EFalse);
       
   278 		return;
       
   279 		}
       
   280 	else if (id == KMaxTInt)
       
   281 		{
       
   282 		// DoCancel
       
   283 		DoCancel(m.Int0());
       
   284 		m.Complete(KErrNone, ETrue);
       
   285 		return;
       
   286 		}
       
   287 
       
   288 	if (id < 0)
       
   289 		{
       
   290 		// DoRequest
       
   291 		TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
       
   292 		TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
       
   293 		if (r != KErrNone)
       
   294 			Kern::RequestComplete(iClient, pS, r);
       
   295 		m.Complete(KErrNone, ETrue);
       
   296 		}
       
   297 	else
       
   298 		{
       
   299 		// DoControl
       
   300 		TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
       
   301 		m.Complete(r, ETrue);
       
   302 		}
       
   303 	}
       
   304 
       
   305 
       
   306 TInt DChannelComm::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
       
   307 	{
       
   308 
       
   309 	//
       
   310 	// First check if we have started
       
   311 	//
       
   312 	if (iStatus == EOpen)
       
   313 		{
       
   314 		Start();
       
   315 		}
       
   316 
       
   317 	// Now we can dispatch the request
       
   318 	TInt r = KErrNone;
       
   319 	TInt len = 0;
       
   320 	switch (aReqNo)
       
   321 		{
       
   322 		case RBusDevComm::ERequestRead:
       
   323 			if (a2)
       
   324 				//get the size of the client data 
       
   325 				r = Kern::ThreadRawRead(iClient, a2, &len, sizeof(len));
       
   326 			if (r == KErrNone)
       
   327 				{
       
   328 				if (a1)	//doing a read
       
   329 					{
       
   330 					iRxStatus = aStatus;
       
   331 					//start the read
       
   332 					InitiateRead(a1,len);
       
   333 					}
       
   334 				else	//notify read data availiable
       
   335 					{
       
   336 					iRxDAStatus = aStatus;
       
   337 					NotifyReadDataAvailable();
       
   338 					}
       
   339 				}
       
   340 			break;
       
   341 		
       
   342 		case RBusDevComm::ERequestWrite:
       
   343 			{
       
   344 			if (iStatus == EClosed)
       
   345 				return KErrNotReady;
       
   346 			if (!a1)
       
   347 				a1 = (TAny*)1;
       
   348 			r = Kern::ThreadRawRead(iClient, a2, &len, sizeof(len));	//get the length of the data to write
       
   349 			if (r == KErrNone)
       
   350 				{
       
   351 				iTxStatus = aStatus;
       
   352 				TInt irq = NKern::DisableInterrupts(1);
       
   353 				if(iTurnaroundTimerRunning)
       
   354 					{
       
   355 					iTurnaroundTransmitDelayed = ETrue;
       
   356 					iTurnaroundTxDesPtr = a1;
       
   357 					iTurnaroundTxDesLength = len;
       
   358 					NKern::RestoreInterrupts(irq);
       
   359 					}
       
   360 				else
       
   361 					{
       
   362 					NKern::RestoreInterrupts(irq);
       
   363 					InitiateWrite(a1, len); //a1 is ptr to data to write (on client side)
       
   364 					}
       
   365 				}
       
   366 			break;
       
   367 			}
       
   368 
       
   369 		case RBusDevComm::ERequestNotifySignalChange:
       
   370 			{
       
   371 			//a1 has place to put the result
       
   372 			//a2 has the signal mask
       
   373 			if (!a1)
       
   374 				{
       
   375 				r = KErrArgument;
       
   376 				break;
       
   377 				}
       
   378 			
       
   379 			//start the signal request
       
   380 			TInt mask = 0;
       
   381 			r = Kern::ThreadRawRead(iClient, a2, &mask, sizeof(mask));	//get the signal mask
       
   382 			if (r == KErrNone)
       
   383 				{
       
   384 				iSignalStatus = aStatus;
       
   385 				InitiateNotifySignals(a1, mask);
       
   386 				}
       
   387 			break;
       
   388 			}
       
   389 
       
   390 		
       
   391 		case RBusDevComm::ERequestBreak:
       
   392 			Complete(aReqNo, KErrNotSupported);
       
   393 			break;
       
   394 
       
   395 		default:
       
   396 			r = KErrNotSupported;
       
   397 			break;
       
   398 
       
   399 		}
       
   400 	return r;
       
   401 	}
       
   402 
       
   403 TInt DChannelComm::SetConfig(TCommConfigV01& c)
       
   404 	{
       
   405 	iConfig = c;
       
   406 	PddConfigure(iConfig);
       
   407 	return KErrNone;
       
   408 	}
       
   409 
       
   410 TInt DChannelComm::DoControl(TInt aFunction, TAny* a1, TAny* a2)
       
   411 	{
       
   412 
       
   413 	TCommConfigV01 c;
       
   414 	TInt r = KErrNone;
       
   415 
       
   416 	switch (aFunction)
       
   417 		{
       
   418 		case RBusDevComm::EControlConfig:
       
   419 			{
       
   420 			//get the current configuration
       
   421 			TPtrC8 cfg((const TUint8*)&iConfig, sizeof(iConfig));
       
   422 			r = Kern::ThreadDesWrite(iClient, a1, cfg, 0, KTruncateToMaxLength, iClient);
       
   423 			break;
       
   424 			}
       
   425 
       
   426 		case RBusDevComm::EControlSetConfig:
       
   427 			{
       
   428 			if (AreAnyPending())	
       
   429 				Kern::PanicCurrentThread(_L("D32COMM"), ESetConfigWhileRequestPending);
       
   430 			else
       
   431 				{
       
   432 				memclr(&c, sizeof(c));
       
   433 				TPtr8 cfg((TUint8*)&c, 0, sizeof(c));
       
   434 				r = Kern::ThreadDesRead(iClient, a1, cfg, 0, 0);
       
   435 				if (r == KErrNone)
       
   436 					r = SetConfig(c);	//set the new configuration
       
   437 				}
       
   438 			break;
       
   439 			}
       
   440 
       
   441 		case RBusDevComm::EControlCaps:
       
   442 			{
       
   443 			//get capabilities
       
   444 			TCommCaps2 caps;
       
   445 			PddCaps(caps);	//call ipdd->Caps
       
   446 			r = Kern::ThreadDesWrite(iClient, a1, caps, 0, KTruncateToMaxLength, iClient);
       
   447 			break;
       
   448 			}
       
   449 
       
   450 		case RBusDevComm::EControlSignals:
       
   451 			{
       
   452 			r = Signals();
       
   453 			break;
       
   454 			}
       
   455 
       
   456 		case RBusDevComm::EControlSetSignals:
       
   457 			{
       
   458 //			if (((TUint)a1)&((TUint)a2))	//can't set and clear at same time
       
   459 //				{
       
   460 //				Kern::PanicCurrentThread(_L("D32COMM"), ESetSignalsSetAndClear);
       
   461 //				}
       
   462 //			else
       
   463 				{
       
   464 
       
   465 				SetSignals((TUint)a1, (TUint)a2);
       
   466 				}
       
   467 			break;
       
   468 			}
       
   469 
       
   470 		case RBusDevComm::EControlQueryReceiveBuffer:
       
   471 			r = RxCount();
       
   472 			break;
       
   473 
       
   474 		case RBusDevComm::EControlResetBuffers:
       
   475 			if (AreAnyPending())
       
   476 				Kern::PanicCurrentThread(_L("D32COMM"), EResetBuffers);
       
   477 			else
       
   478 				ResetBuffers(ETrue);
       
   479 			break;
       
   480 
       
   481 		case RBusDevComm::EControlReceiveBufferLength:
       
   482 			r = RxBufferSize();
       
   483 			break;
       
   484 
       
   485 		case RBusDevComm::EControlSetReceiveBufferLength:
       
   486 			if (AreAnyPending())
       
   487 				Kern::PanicCurrentThread(_L("D32COMM"), ESetReceiveBufferLength);
       
   488 			else
       
   489 				r = SetRxBufferSize((TInt)a1);
       
   490 			break;
       
   491 
       
   492 		case RBusDevComm::EControlMinTurnaroundTime:
       
   493 			r = iTurnaroundMicroSeconds;			// used saved value
       
   494 			break;
       
   495 
       
   496 		case RBusDevComm::EControlSetMinTurnaroundTime:
       
   497 				{
       
   498 				if ((TInt)a1<0)
       
   499 					a1=(TAny*)0;
       
   500 				iTurnaroundMicroSeconds = (TUint)a1;			// save this
       
   501 				TUint newTurnaroundMilliSeconds = (TUint)a1/1000;	// convert to ms
       
   502 				if(newTurnaroundMilliSeconds != iTurnaroundMinMilliSeconds)
       
   503 					{
       
   504 					// POLICY: if a new turnaround time is set before the previous running timer has expired and a
       
   505 					// write request has been queued, the transmission goes ahead immediately
       
   506 					TurnaroundClear();
       
   507 					if(newTurnaroundMilliSeconds > 0)
       
   508 						{
       
   509 						r = TurnaroundSet(newTurnaroundMilliSeconds);
       
   510 						}
       
   511 					}
       
   512 				}
       
   513 			break;
       
   514 
       
   515 		default:
       
   516 			r = KErrNotSupported;
       
   517 			}
       
   518 		return(r);
       
   519 		}
       
   520 
       
   521 
       
   522 void DChannelComm::SignalNotifyDfc(TAny* aPtr)
       
   523 	{
       
   524 	DChannelComm* pC = (DChannelComm*)aPtr;
       
   525 	pC->DoSignalNotify();
       
   526 	}
       
   527 
       
   528 void DChannelComm::RxDataAvailableDfc(TAny* aPtr)
       
   529 	{
       
   530 	DChannelComm* pC = (DChannelComm*)aPtr;
       
   531 	pC->DoRxDataAvailable();
       
   532 	}
       
   533 
       
   534 void DChannelComm::DoRxDataAvailable()
       
   535 	{
       
   536 	Complete(ERxDA, iRxDAError);
       
   537 	iRxDAError = KErrNone;
       
   538 	}
       
   539 
       
   540 void DChannelComm::DoSignalNotify()
       
   541 	{
       
   542 	//copy the data back to the client
       
   543 	if (iSignalError == KErrNone)
       
   544 		iSignalError = Kern::ThreadRawWrite(iClient, iClientSignalResultPtr,&iSignalResult, sizeof(iSignalResult), iClient);
       
   545 	Complete(ESigChg, iSignalError);
       
   546 	iSignalError = KErrNone;
       
   547 	}
       
   548 
       
   549 void DChannelComm::CompleteTxDfc(TAny* aPtr)
       
   550 	{
       
   551 	DChannelComm* pC = (DChannelComm*)aPtr;
       
   552 	pC->DoCompleteTx();
       
   553 	}
       
   554 
       
   555 void DChannelComm::DoCompleteTx()
       
   556 	{
       
   557 	Complete(ETx, iTxError);
       
   558 	iTxError = KErrNone;
       
   559 	}
       
   560 
       
   561 void DChannelComm::CompleteRxDfc(TAny* aPtr)
       
   562 	{
       
   563 	DChannelComm* pC = (DChannelComm*)aPtr;
       
   564 	pC->DoCompleteRx();
       
   565 	}
       
   566 
       
   567 void DChannelComm::DoCompleteRx()
       
   568 	{
       
   569 	if (iRxError == KErrNone)
       
   570 		{
       
   571 		//copy the data back to the client
       
   572 		iRxError = Kern::ThreadDesWrite(iClient, (TDes8*)iClientDestPtr, *RxBuffer(), 0, KChunkShiftBy0, iClient);
       
   573 		}
       
   574 	Complete(ERx, iRxError);
       
   575 	iRxError = KErrNone;
       
   576 	TInt irq = NKern::DisableInterrupts(1);
       
   577 	if(iTurnaroundMinMilliSeconds > 0)
       
   578 		{
       
   579 		// POLICY: if timer is running from a previous read, stop it and re-start it
       
   580 		if(iTurnaroundTimerRunning)
       
   581 			{
       
   582 			iTurnaroundTimer.Cancel();
       
   583 			iTurnaroundDfc.Cancel();
       
   584 			}
       
   585 		iTurnaroundTimerRunning = ETrue;
       
   586 		TInt timeout = NKern::TimerTicks(iTurnaroundMinMilliSeconds);
       
   587 		iTurnaroundTimer.OneShot(timeout);
       
   588 		}
       
   589 	NKern::RestoreInterrupts(irq);
       
   590 	}
       
   591 
       
   592 void DChannelComm::DoCancel(TInt aMask)
       
   593 	{
       
   594 	if (aMask & RBusDevComm::ERequestReadCancel)
       
   595 		{
       
   596 		ReadCancel();
       
   597 		}
       
   598 
       
   599 	if (aMask & RBusDevComm::ERequestWriteCancel)
       
   600 		{
       
   601 		TInt irq = NKern::DisableInterrupts(1);
       
   602 		if(iTurnaroundTransmitDelayed)
       
   603 			{
       
   604 			iTurnaroundTxDesPtr = 0;
       
   605 			iTurnaroundTxDesLength = 0;
       
   606 			iTurnaroundTransmitDelayed = EFalse;
       
   607 			}
       
   608 		NKern::RestoreInterrupts(irq);
       
   609 
       
   610 		WriteCancel();
       
   611 		}
       
   612 
       
   613 	if (aMask & RBusDevComm::ERequestNotifySignalChangeCancel)
       
   614 		{
       
   615 		SignalChangeCancel();
       
   616 		Complete(ESigChg,KErrCancel);
       
   617 		}
       
   618 
       
   619 	}
       
   620 
       
   621 
       
   622 void DChannelComm::InitiateWrite(TAny *aTxDes, TInt aLength)
       
   623 	{
       
   624 
       
   625 //aTxDes has client side data
       
   626 //aLength has the len
       
   627 	
       
   628 	if (!aTxDes)
       
   629 		{
       
   630 		Complete(ETx, KErrArgument);
       
   631 		return;
       
   632 		}
       
   633 	// call the pdd to fill its buffer and write the data
       
   634 	Write(iClient, aTxDes, aLength);
       
   635 	}
       
   636 
       
   637 void DChannelComm::InitiateRead(TAny *aRxDes, TInt aLength)
       
   638 	{
       
   639 
       
   640 	// Complete zero-length read immediately.  maybe not
       
   641 
       
   642 //	if (aLength == 0)
       
   643 //		{
       
   644 //		Complete(ERx, KErrNone);
       
   645 //		return;
       
   646 //		}
       
   647 	TInt max=Kern::ThreadGetDesMaxLength(iClient,aRxDes);
       
   648 
       
   649 	if (max < Abs(aLength) || max < 0)
       
   650 		Complete(ERx, KErrGeneral);
       
   651 		// do not start the Turnaround timer (invalid Descriptor this read never starts)
       
   652 	else
       
   653 		{
       
   654 		iClientDestPtr = aRxDes;
       
   655 		Read(iClient, aRxDes, aLength);
       
   656 		}
       
   657 	}
       
   658 
       
   659 void DChannelComm::InitiateNotifySignals(TAny *aSignalResultPtr, TInt aMask)
       
   660 	{
       
   661 	//aMask has the mask of signals we require
       
   662 	//aSignalResultPtr is a pointer to the clients area for the result
       
   663 	iClientSignalResultPtr = (TUint*)aSignalResultPtr;
       
   664 	NotifySignals(iClient, aMask);
       
   665 	}
       
   666 
       
   667 void DChannelComm::NotifyReadDataAvailable()
       
   668 	{
       
   669 	NotifyDataAvailable();
       
   670 	}
       
   671 
       
   672 
       
   673 void DChannelComm::Complete(TInt aMask, TInt aReason)
       
   674 	{
       
   675 	if (aMask & ERx)
       
   676 		Kern::RequestComplete(iClient, iRxStatus, aReason);
       
   677 	if (aMask & ETx)
       
   678 		Kern::RequestComplete(iClient, iTxStatus, aReason);
       
   679 	if (aMask & ESigChg)
       
   680 		Kern::RequestComplete(iClient, iSignalStatus, aReason);
       
   681 	if (aMask & ERxDA)
       
   682 		Kern::RequestComplete(iClient, iRxDAStatus, aReason);
       
   683 	}
       
   684 
       
   685