toolsandutils/wintunnel/src_beech/d_comm.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 // Copyright (c) 1995-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 // Evil communications corrupt good manners. 
       
    15 // 1 corinthians  xv. 33.
       
    16 // 
       
    17 //
       
    18 
       
    19 
       
    20 #include <k32std.h>
       
    21 #include "d_comm.h"
       
    22 #include <e32hal.h>
       
    23 
       
    24 const TInt KIdleTimeoutPeriod=20*1000000;  // 20 seconds
       
    25 const TUint KXoffSignal=0x80000000;
       
    26 //
       
    27 const TInt KInputHeldFree=(-1);
       
    28 const TInt KInputHeld=(-2);
       
    29 //
       
    30 const TUint KTransmitting=0x01;
       
    31 const TUint KBreaking=0x02;
       
    32 const TUint KBreakPending=0x04;
       
    33 //
       
    34 enum TPanic
       
    35 	{
       
    36 	ESetConfigWhileRequestPending,
       
    37 	ESetSignalsSetAndClear,
       
    38 	EResetBuffers,
       
    39 	ESetReceiveBufferLength,
       
    40 //	EDoubleTxBufFill,
       
    41 	};
       
    42 
       
    43 EXPORT_C DLogicalDevice *CreateLogicalDevice()
       
    44 //
       
    45 // Create a new device
       
    46 //
       
    47 	{
       
    48 	return(new DDeviceComm);
       
    49 	}
       
    50 
       
    51 DDeviceComm::DDeviceComm()
       
    52 //
       
    53 // Constructor
       
    54 //
       
    55 	{
       
    56 	iParseMask=KDeviceAllowAll;
       
    57 	iUnitsMask=0xffffffff; // Leave units decision to the driver
       
    58 	iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
       
    59 	}
       
    60 
       
    61 TInt DDeviceComm::Install()
       
    62 //
       
    63 // Install the device driver.
       
    64 //
       
    65 	{
       
    66     TPtrC name=_L("Comm");
       
    67 	return(SetName(&name));
       
    68 	}
       
    69 
       
    70 void DDeviceComm::GetCaps(TDes8 &aDes) const
       
    71 //
       
    72 // Return the Comm capabilities.
       
    73 //
       
    74 	{
       
    75 
       
    76 	TCapsDevCommV01 b;
       
    77 	b.version=iVersion;
       
    78 	aDes.FillZ(aDes.MaxLength());
       
    79 	aDes.Copy((TUint8 *)&b,Min(aDes.MaxLength(),sizeof(b)));
       
    80 	}
       
    81 
       
    82 DLogicalChannel *DDeviceComm::CreateL()
       
    83 //
       
    84 // Create a channel on the device.
       
    85 //
       
    86 	{
       
    87 
       
    88 	return(new(ELeave) DChannelComm(this));
       
    89 	}
       
    90 
       
    91 TInt DChannelComm::CallDfc(TAny* aDChannelComm)
       
    92 //
       
    93 // Dfc call back - cast the pointer to a DChannel comm and call DoDfc
       
    94 //
       
    95 	{
       
    96 	((DChannelComm *)aDChannelComm)->DfcHandler();
       
    97 	return KErrNone;
       
    98 	}
       
    99 
       
   100 //
       
   101 // Comms power handler
       
   102 //
       
   103 // Active tx requests keep power requirement up.
       
   104 // Completed tx requests keep power requirement up for KIdleTimeoutPeriod.
       
   105 // Rx requests don't effect power requirement
       
   106 // 
       
   107 DCommPowerHandler::DCommPowerHandler(DChannelComm *aLdd) : iLdd(aLdd)
       
   108 	{}
       
   109 
       
   110 void DCommPowerHandler::RequestPending()
       
   111 //
       
   112 // Tx request made
       
   113 //
       
   114 	{
       
   115 	iTimer.Cancel();
       
   116 	if (iRequirement == 0)
       
   117 		SetRequirement(1); /* EPowerCpu */
       
   118 	}
       
   119 
       
   120 void DCommPowerHandler::RequestComplete()
       
   121 //
       
   122 // Tx request completed, set the timer
       
   123 //
       
   124 	{
       
   125 	iTimer.Cancel();
       
   126 	iTimer.OneShotInMicroSeconds(TTimeIntervalMicroSeconds32(KIdleTimeoutPeriod), DCommPowerHandler::Timeout, this);
       
   127 	}
       
   128 
       
   129 void DCommPowerHandler::Timeout(TAny *aHandler, TInt)
       
   130 //
       
   131 // Timeout following last Tx request (in DFC)
       
   132 //
       
   133 	{
       
   134 
       
   135 	DCommPowerHandler& handler=*(DCommPowerHandler*)aHandler;
       
   136 	handler.SetRequirement(0);  // EPowerNone
       
   137 	handler.iLdd->DoPowerDown(); 
       
   138 	handler.iLdd->ResetDevice();
       
   139 	handler.iLdd->CompleteAll(KErrAbort); // Complete all outstanding client requests
       
   140 	}
       
   141 
       
   142 TInt DCommPowerHandler::DoPowerOn()
       
   143 //
       
   144 // Machine power up event
       
   145 // Serial driver ignores machine power up events and instead powers up the
       
   146 // device in response to user requests 
       
   147 //
       
   148 	{
       
   149 	return(KErrNone);
       
   150 	}
       
   151 
       
   152 void DCommPowerHandler::DoPowerEmergencyStandby()
       
   153 //
       
   154 // Machine emergency power down event
       
   155 // Can't ignore these events - need to power down the device
       
   156 //
       
   157 	{
       
   158 	iLdd->DoEmergencyPowerDown();
       
   159 	}
       
   160 
       
   161 void DCommPowerHandler::DoPowerStandby()
       
   162 //
       
   163 // Machine normal power down event
       
   164 // Serial driver ignores machine normal power down events and instead uses an
       
   165 // inactivity timer on Tx requests to control power down.
       
   166 //
       
   167 	{
       
   168 	}
       
   169 
       
   170 #pragma warning( disable : 4705 )	// statement has no effect
       
   171 #pragma warning( disable : 4355 )	// this used in intializer list
       
   172 DChannelComm::DChannelComm(DLogicalDevice *aDevice)
       
   173 //
       
   174 // Constructor
       
   175 //
       
   176 : DLogicalChannel(aDevice), iDfc(TCallBack(DChannelComm::CallDfc,this))
       
   177 	{
       
   178 
       
   179 //
       
   180 // Require power notifications and 3 valid requests
       
   181 //
       
   182 	SetBehaviour(RBusDevComm::ERequestReadCancel|RBusDevComm::ERequestWriteCancel|RBusDevComm::ERequestBreakCancel|RBusDevComm::ERequestNotifySignalChangeCancel);
       
   183 //
       
   184 // Setup the default config
       
   185 //
       
   186 	iConfig.iRate=EBps9600;
       
   187 	iConfig.iDataBits=EData8;
       
   188 	iConfig.iStopBits=EStop1;
       
   189 	iConfig.iParity=EParityNone;
       
   190 	iConfig.iFifo=EFifoEnable;
       
   191 	iConfig.iHandshake=KConfigObeyCTS;
       
   192 	iConfig.iParityError=KConfigParityErrorFail;
       
   193 	iConfig.iSIREnable=ESIRDisable;
       
   194 //	iConfig.iTerminatorCount=0;
       
   195 //	iConfig.iTerminator[0]=0;
       
   196 //	iConfig.iTerminator[1]=0;
       
   197 //	iConfig.iTerminator[2]=0;
       
   198 //	iConfig.iTerminator[3]=0;
       
   199 	iConfig.iXonChar=0x11; // XON
       
   200 	iConfig.iXoffChar=0x13; // XOFF
       
   201 //	iConfig.iSpecialRate=0;
       
   202 //	iConfig.iParityErrorChar=0;
       
   203 //	iDriver=NULL;
       
   204 	iStatus=ENotActive;
       
   205 	iInputHeld=KInputHeldFree;
       
   206 //	iOutputHeld=0;
       
   207 //	iReceiveOneOrMore=0;
       
   208 //	iReceiveError=0;
       
   209 //	iReceiveErrorLength=0;
       
   210 //	iReceiveLength=0;
       
   211 //	iReceiveOffset=0;
       
   212 //	iTransmitLength=0;
       
   213 //	iTransmitOffset=0;
       
   214 //	iFlags=0;
       
   215 //	iSignals=0;
       
   216 //	iLowWaterMark=0;
       
   217 //	iHighWaterMark=0;
       
   218 //	iHalfFullMark=0;
       
   219 //	iReceivePtr=NULL;
       
   220 //	iTransmitPtr=NULL;
       
   221 //	iRxBuf=NULL;
       
   222 //	iTxBuf=NULL;
       
   223 //	iIsReading=EFalse;
       
   224 //	iIsWriting=EFalse;
       
   225 //	iDrainingRxBuf=EFalse;
       
   226 //	iFillingTxBuf=EFalse;
       
   227 //	iRunningDfc=EFalse;
       
   228 //	iSignalChangeNotification=EFalse;
       
   229 //	iSignalChangePtr=NULL;
       
   230 //	iSignalMask=0;
       
   231 //  iSignalChangeInfo=0;
       
   232 //	iDataAvailableNotification=EFalse;
       
   233 	}
       
   234 #pragma warning( default : 4705 )
       
   235 #pragma warning( disable : 4355 )
       
   236 
       
   237 DChannelComm::~DChannelComm()
       
   238 //
       
   239 // Destructor
       
   240 //
       
   241 	{
       
   242 	// Complete any outstanding requests
       
   243 	CompleteAll(KErrAbort);
       
   244 
       
   245 	// Power down h/w, disable interrupts
       
   246 	iPowerHandler->iTimer.Cancel();
       
   247 	iPowerHandler->PowerStandby();  	// Doesn't do anything in inactivity power policy case, hence DoPowerDown() call below.
       
   248 	DoPowerDown(); 
       
   249 
       
   250 	// clean up the power handler
       
   251 //	iPowerHandler->SetRequirement(0);	// No need for this, done in DoPowerDown().
       
   252 	Power::RemovePowerHandler(*iPowerHandler);
       
   253 	delete iPowerHandler;
       
   254 
       
   255 	TInt clearMask=0;
       
   256 	if (!(iConfig.iHandshake&KConfigFreeRTS))
       
   257 		clearMask|=KSignalRTS;
       
   258 	if (!(iConfig.iHandshake&KConfigFreeDTR))
       
   259 		clearMask|=KSignalDTR;
       
   260 	iDriver->SetSignals(0,clearMask);
       
   261 
       
   262 	delete iDriver;
       
   263 
       
   264 	delete iRxBuf;
       
   265 	delete iTxBuf;
       
   266 	}
       
   267 
       
   268 void DChannelComm::DoCreateL(TInt /*aUnit*/,CBase *aDriver,const TDesC * /*anInfo*/,const TVersion &aVer)
       
   269 //
       
   270 // Create the channel from the passed info.
       
   271 //
       
   272 	{
       
   273 	iDriver=(DComm *)aDriver; // Must do this to ensure the driver is destroyed by the destructor
       
   274 	if (!User::QueryVersionSupported(TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber),aVer))
       
   275 		User::Leave(KErrNotSupported);
       
   276 	// get power managed
       
   277 	iPowerHandler=new (ELeave) DCommPowerHandler(this);
       
   278 	User::LeaveIfError(Power::AddPowerHandler(*iPowerHandler));
       
   279 //	iRxBuf=new(ELeave) CCirBuf<TInt>;
       
   280 //	iTxBuf=new(ELeave) CCirBuffer;
       
   281 	iTxBuf=new(ELeave) CCommTxBuf;
       
   282 	iRxBuf=new(ELeave) CCommRxBuf;
       
   283 	User::LeaveIfError(SetRxBufferSize(KDefaultRxBufferSize));
       
   284 	iTxBuf->SetLengthL(KTxBufferSize);
       
   285 	((DComm *)aDriver)->SetComm(this); // Rog
       
   286 	iDriver->CheckConfig(iConfig);
       
   287 	StateIsr(iDriver->Signals());
       
   288 
       
   289 	iPowerHandler->PowerOn();	// Ask the PowerManager to power us up
       
   290 	}
       
   291 
       
   292 void DChannelComm::DfcHandler()
       
   293 //
       
   294 // Called as a Dfc. Handles all buffer draining and filling and message completions.
       
   295 //
       
   296 	{	
       
   297 	iDriver->DisableInterrupts();
       
   298 	while (iDfcRequest!=0)
       
   299 		{
       
   300 		if (iDfcRequest & EDrainRxBufferRequired)
       
   301 			{
       
   302 #ifdef _DEBUG_DEVCOMM
       
   303 			iDfcHandlerSeq = iRxBuf->iRemSeqNum.Int();
       
   304 #endif
       
   305 			iDfcRequest &= ~EDrainRxBufferRequired;
       
   306 			iDriver->EnableInterrupts();
       
   307 			if (!iDrainingRxBuf)
       
   308 				DoDrainRxBuffer();
       
   309 			iDriver->DisableInterrupts();
       
   310 			continue;
       
   311 			}
       
   312 		if (iDfcRequest & ECompleteWrite)
       
   313 			{
       
   314 			iDfcRequest &= ~ECompleteWrite;
       
   315 			iDriver->EnableInterrupts();
       
   316 			if (iIsWriting)
       
   317 				{
       
   318 				iIsWriting = EFalse;
       
   319 				iWriteZero = EFalse;
       
   320 				if (iIsClientWriting)
       
   321 					Complete(RBusDevComm::ERequestWrite,iWriteError);
       
   322 				iIsClientWriting = EFalse;
       
   323 				iWriteError = KErrNone;
       
   324 				}
       
   325 			iDriver->DisableInterrupts();
       
   326 			continue;
       
   327 			}
       
   328 		else if (iDfcRequest & EEarlyCompleteWrite)
       
   329 			{
       
   330 			iDfcRequest &= ~EEarlyCompleteWrite;
       
   331 			iDriver->EnableInterrupts();
       
   332 			if (iIsClientWriting)
       
   333 				{
       
   334 				iIsClientWriting = EFalse;
       
   335 				Complete(RBusDevComm::ERequestWrite,iWriteError);
       
   336 				iWriteError = KErrNone;
       
   337 				}
       
   338 			iDriver->DisableInterrupts();
       
   339 			continue;
       
   340 			}
       
   341 		if (iDfcRequest & ECompleteEmergency)
       
   342 			{
       
   343 			iDfcRequest &= ~ECompleteEmergency;
       
   344 			ResetDevice();
       
   345 			CompleteAll(KErrBadPower);
       
   346 			continue;
       
   347 			}
       
   348 		if (iDfcRequest & EFillTxBufferRequired)
       
   349 			{
       
   350 			iDfcRequest &= ~EFillTxBufferRequired;
       
   351 			iDriver->EnableInterrupts();
       
   352 			if (!iFillingTxBuf)
       
   353 				DoFillTxBuffer();
       
   354 			iDriver->DisableInterrupts();
       
   355 			continue;
       
   356 			}
       
   357 		if (iDfcRequest & ECompleteSignalChange)
       
   358 			{
       
   359 			iDfcRequest &= ~ECompleteSignalChange;
       
   360     		iThread->Write(iSignalChangePtr,(TUint8*)&iSignalChangeInfo,(TInt)sizeof(TUint));
       
   361 			iSignalChangeNotification=EFalse;
       
   362 			Complete(RBusDevComm::ERequestNotifySignalChange);
       
   363 			continue;
       
   364 			}
       
   365 		if (iDfcRequest & ECompleteDataAvailable)
       
   366 			{
       
   367 			iDfcRequest &= ~ECompleteDataAvailable;
       
   368 			iDataAvailableNotification=EFalse;
       
   369 			Complete(RBusDevComm::ERequestRead);
       
   370 			continue;
       
   371 			}
       
   372 		}
       
   373 #ifdef _DEBUG_DEVCOMM
       
   374 	--iDfcCount;
       
   375 #endif
       
   376 	iRunningDfc=EFalse;
       
   377 	iPowerHandler->RequestComplete();
       
   378 	iDriver->EnableInterrupts();
       
   379 	}
       
   380 
       
   381 void DChannelComm::RestoreDtrRrs()
       
   382 //
       
   383 // Check if driver is configured not to auto control RTS/DTR and restore state
       
   384 // of these signals acording to current config. (as specified by driver
       
   385 // client) if necessary
       
   386 //
       
   387 	{
       
   388 
       
   389 	TUint hand=iConfig.iHandshake;
       
   390 	if ((hand&KConfigFreeRTS))
       
   391 		{
       
   392 		if (iSignals&KSignalRTS)
       
   393 			iDriver->SetSignals(KSignalRTS,0);
       
   394 		else
       
   395 			iDriver->SetSignals(0,KSignalRTS);
       
   396 		}
       
   397 	if (!iPowerHandler->PowerGood())
       
   398 		return;
       
   399 	if (hand&KConfigFreeDTR)
       
   400 		{
       
   401 		if (iSignals&KSignalDTR)
       
   402 			iDriver->SetSignals(KSignalDTR,0);
       
   403 		else
       
   404 			iDriver->SetSignals(0,KSignalDTR);
       
   405 		}
       
   406 	}
       
   407 
       
   408 void DChannelComm::Start()
       
   409 //
       
   410 // Start the driver receiving.
       
   411 //
       
   412 	{
       
   413 
       
   414 	// If waiting for driver to be closed then just return
       
   415 	if (iStatus==EClosed)
       
   416 		return;
       
   417 
       
   418 	if (iStatus!=EActive)
       
   419 		ResetBuffers();	// Reset RX/TX buffers
       
   420 
       
   421 	iDriver->Configure(iConfig);
       
   422 	iDriver->Start();
       
   423 	if (iConfig.iHandshake & KConfigSendXoff && iInputHeld>=0)
       
   424 		EnableTransmit(); // Send XOn if there is one
       
   425 
       
   426 	if (iStatus!=EActive)
       
   427 		{
       
   428 		// If driver configured not to auto control RTS/DTR then restore state of
       
   429 		// these signals acording to current config. (as specified by driver client).
       
   430 		TUint hand=iConfig.iHandshake;
       
   431 		if (hand&(KConfigFreeRTS|KConfigFreeDTR))
       
   432 			RestoreDtrRrs();
       
   433 		}
       
   434 	iStatus=EActive;
       
   435 	}
       
   436 
       
   437 void DChannelComm::Stop(TStopMode aMode)
       
   438 //
       
   439 // Stop the driver.
       
   440 //
       
   441 	{
       
   442 	iDriver->Stop(aMode);
       
   443 	}
       
   444 
       
   445 void DChannelComm::BreakOn()
       
   446 //
       
   447 // Start the driver breaking.
       
   448 //
       
   449 	{
       
   450 
       
   451 	if (iFlags&KTransmitting)
       
   452 		iFlags|=KBreakPending;
       
   453 	else
       
   454 		{
       
   455 		iFlags&=(~KBreakPending);
       
   456 		iFlags|=KBreaking;
       
   457 		iDriver->Break(ETrue);
       
   458 		}
       
   459 	}
       
   460 
       
   461 void DChannelComm::BreakOff()
       
   462 //
       
   463 // Stop the driver breaking.
       
   464 //
       
   465 	{
       
   466 
       
   467 	iDriver->Break(EFalse);
       
   468 	iFlags&=(~(KBreakPending|KBreaking));
       
   469 	}
       
   470 
       
   471 void DChannelComm::EnableTransmit()
       
   472 //
       
   473 // Make sure we are transmitting
       
   474 //
       
   475 	{
       
   476 
       
   477 	if ((iFlags & KTransmitting)==0)
       
   478 		{
       
   479 		iFlags |= KTransmitting; // Signal the fact the we are transmitting
       
   480 		iDriver->EnableTransmit(); // Start transmitting
       
   481 		}
       
   482 	}
       
   483 
       
   484 TInt DChannelComm::SetRxBufferSize(TInt aSize)
       
   485 //
       
   486 // Set the receive buffer size.
       
   487 //
       
   488 	{
       
   489 
       
   490 	TRAPD(r,iRxBuf->SetLengthL(aSize));
       
   491 	if (r==KErrNone)
       
   492 		{
       
   493 		iLowWaterMark=(aSize>>2); // 25 %
       
   494 		iHalfFullMark=(aSize>>1); // 50 %
       
   495 		if (iConfig.iParityError & KConfigXonXoffDebug)
       
   496 			{
       
   497 			iHighWaterMark=iHalfFullMark-5;
       
   498 			}
       
   499 		else
       
   500 			iHighWaterMark=aSize-iLowWaterMark; // 75%
       
   501 		}
       
   502 	return(r);
       
   503 	}
       
   504 
       
   505 void DChannelComm::ResetBuffers()
       
   506 //
       
   507 // Reset the receive and transmit buffers.
       
   508 //
       
   509 	{
       
   510 
       
   511 	iIsWriting=EFalse;
       
   512 	iRxBuf->Reset();
       
   513 	iTxBuf->Reset();
       
   514 
       
   515 	iReceiveError=KErrNone;
       
   516 	if (iStatus==EActive)
       
   517 		{
       
   518 		if ((iConfig.iHandshake & KConfigFreeRTS)==0)
       
   519             iDriver->SetSignals(KSignalRTS,0); // Assert RTS
       
   520 		if ((iConfig.iHandshake & KConfigFreeDTR)==0)
       
   521             iDriver->SetSignals(KSignalDTR,0); // Assert DTR
       
   522         if (iConfig.iHandshake&KConfigSendXoff) // Doing input XON/XOFF
       
   523             {
       
   524             iInputHeld=iConfig.iXonChar; // set up to send Xon
       
   525 			EnableTransmit(); // Make sure we are transmitting
       
   526             }
       
   527 		else
       
   528 			iInputHeld=KInputHeldFree;
       
   529 		}
       
   530 	iReceiveErrorLength=0;
       
   531 	}
       
   532 
       
   533 TBool DChannelComm::IsLineFail(TUint aHandshake)
       
   534 //
       
   535 // True if any line fail errors occured.
       
   536 //
       
   537     {
       
   538 
       
   539 	if ((iSignals&KSignalCTS)==0 &&
       
   540 		(aHandshake&(KConfigObeyCTS|KConfigFailCTS))==(KConfigObeyCTS|KConfigFailCTS) ||
       
   541 		(iSignals&KSignalDSR)==0 &&
       
   542 		(aHandshake&(KConfigObeyDSR|KConfigFailDSR))==(KConfigObeyDSR|KConfigFailDSR) ||
       
   543 		(iSignals&KSignalDCD)==0 &&
       
   544 		(aHandshake&(KConfigObeyDCD|KConfigFailDCD))==(KConfigObeyDCD|KConfigFailDCD))
       
   545 		return(TRUE);
       
   546 	return(FALSE);
       
   547     }
       
   548 
       
   549 
       
   550 void DChannelComm::DoDrainRxBuffer()
       
   551 //
       
   552 // Drain the receive buffer
       
   553 //
       
   554 	{
       
   555 	iDriver->DisableInterrupts();
       
   556 	if (!IsReading())
       
   557 		{
       
   558 		iDriver->EnableInterrupts();
       
   559 		return;
       
   560 		}
       
   561 	if (iDrainingRxBuf)
       
   562 		{
       
   563 		iDriver->EnableInterrupts();
       
   564 		return;
       
   565 		}
       
   566 	iDrainingRxBuf = ETrue;
       
   567 
       
   568 #ifdef _DEBUG_DEVCOMM
       
   569 	iDoDrainSeq = iRxBuf->iRemSeqNum.Int();
       
   570 #endif
       
   571 
       
   572 	TUint status;
       
   573 	TInt res = iRxBuf->ClientWrite(status, iDriver, iThread, iReceivePtr, iReceiveLength, iReceiveOffset, KChunkShiftBy0);
       
   574 	if (res<0 && iReceiveError==KErrNone) // Buffer empty
       
   575 		{
       
   576 		iDrainingRxBuf = EFalse;
       
   577 		iDriver->EnableInterrupts();
       
   578 		return;
       
   579 		}
       
   580 
       
   581 	if (res>0 || (status & KReceiveIsrMaskComplete) || iReceiveError!=KErrNone) // Complete client op
       
   582 		{
       
   583 		if (iReceiveError==KErrNone && (status & KReceiveIsrMaskError))
       
   584 			{
       
   585 			if (status & KReceiveIsrOverrunError)
       
   586 				iReceiveError = KErrCommsOverrun;
       
   587 			else if (status & KReceiveIsrFrameError)
       
   588 				iReceiveError = KErrCommsFrame;
       
   589 			else if ((status & KReceiveIsrParityError) && !(iConfig.iParityError & KConfigParityErrorIgnore))
       
   590 				iReceiveError = KErrCommsParity;
       
   591 			}
       
   592 		
       
   593 		Complete(RBusDevComm::ERequestRead, iReceiveError);
       
   594 		iReceiveError = KErrNone;
       
   595 		iIsReading=EFalse;
       
   596 		}
       
   597 
       
   598 	if (iRxBuf->Count()<=iLowWaterMark && iInputHeld==KInputHeld) // At or below the low water mark and input held
       
   599         {
       
   600 		if ((iConfig.iHandshake & KConfigFreeRTS)==0)
       
   601             iDriver->SetSignals(KSignalRTS,0); // Assert RTS
       
   602 		if ((iConfig.iHandshake & KConfigFreeDTR)==0)
       
   603             iDriver->SetSignals(KSignalDTR,0); // Assert DTR
       
   604         if (iConfig.iHandshake&KConfigSendXoff) // Doing input XON/XOFF
       
   605             {
       
   606             iInputHeld=iConfig.iXonChar; // set up to send Xon
       
   607 			EnableTransmit(); // Make sure we are transmitting
       
   608             }
       
   609         else
       
   610             iInputHeld=KInputHeldFree; // Mark input free 
       
   611 		}
       
   612 	iDrainingRxBuf = EFalse;
       
   613 	iDriver->EnableInterrupts();
       
   614 	}
       
   615 
       
   616 
       
   617 void DChannelComm::DoFillTxBuffer()
       
   618 //
       
   619 // Fill the transmit buffer
       
   620 //
       
   621 	{
       
   622 	iDriver->DisableInterrupts();
       
   623 	if (iFillingTxBuf)
       
   624 		{
       
   625 		iDriver->EnableInterrupts();
       
   626 		return;
       
   627 		}
       
   628 	iFillingTxBuf=ETrue;
       
   629 	iDriver->EnableInterrupts();
       
   630 
       
   631 	if (iTxBuf->ClientRead(iDriver, iThread, iTransmitPtr, iTransmitLength, iTransmitOffset, KChunkShiftBy0)==KErrNone)
       
   632 		EnableTransmit();
       
   633 
       
   634 	if (iIsClientWriting && (iTransmitPtr==NULL || iTransmitLength==0) && (iConfig.iHandshake & KConfigWriteBufferedComplete))
       
   635 		EarlyCompleteWrite();
       
   636 	iFillingTxBuf=EFalse;
       
   637 	}
       
   638 
       
   639 void DChannelComm::ReceiveIsr(TUint aChar)
       
   640 //
       
   641 // Handle a received character from the ISR.
       
   642 //
       
   643 	{
       
   644 
       
   645 	if (iDataAvailableNotification)
       
   646 		CompleteDataAvailable();
       
   647 
       
   648 	if (iConfig.iHandshake & KConfigObeyXoff) // Doing output XON/XOFF
       
   649         {
       
   650         if (aChar==iConfig.iXonChar) // Output now allowed
       
   651             { // May get multiple XON's in quick succession
       
   652             iOutputHeld &= ~KXoffSignal; // Mark output ok. for XON/XOFF
       
   653 #ifdef _DEBUG_DEVCOMM
       
   654 			iRxXon++;
       
   655 #endif
       
   656 			EnableTransmit();
       
   657 			return;
       
   658             }
       
   659         if (aChar==iConfig.iXoffChar) // Output now disallowed
       
   660             {
       
   661 #ifdef _DEBUG_DEVCOMM
       
   662 			iRxXoff++;
       
   663 #endif
       
   664             iOutputHeld |= KXoffSignal; // Mark output held for XON/XOFF
       
   665 			DrainRxBuffer();
       
   666 			return;
       
   667             }
       
   668         }
       
   669 
       
   670 #ifdef _DEBUG_DEVCOMM
       
   671 	iRxChars++;
       
   672 #endif
       
   673 
       
   674 	TBool doDrainRxBuffer=EFalse;
       
   675 
       
   676 	TInt count = iRxBuf->Count();
       
   677 
       
   678     if (count>=iHighWaterMark && (count & 1)) // At or above the high water mark send xoff every other character
       
   679         {
       
   680 		// Copes with the S/W and H/W handshaking
       
   681         if ((iConfig.iHandshake & KConfigFreeRTS)==0) // RTS enabled
       
   682 			iDriver->SetSignals(0,KSignalRTS); // Drop RTS
       
   683 		else if ((iConfig.iHandshake & KConfigFreeDTR)==0) // DTR enabled, but not RTS
       
   684 			iDriver->SetSignals(0,KSignalDTR); // Drop DTR
       
   685         
       
   686 		if (iConfig.iHandshake & KConfigSendXoff) // Doing input XON/XOFF
       
   687 			{
       
   688 			iInputHeld=iConfig.iXoffChar; // Mark input held
       
   689 			EnableTransmit(); // Make sure we are transmitting
       
   690             }
       
   691 		else
       
   692 			iInputHeld=KInputHeld; // Mark input held
       
   693 
       
   694 		doDrainRxBuffer=ETrue;
       
   695         }
       
   696 
       
   697 	// Check for parity errors and replace char if so configured.
       
   698 	if (aChar & KReceiveIsrParityError)
       
   699 		{
       
   700 		// Replace bad character
       
   701 		if (iConfig.iParityError==KConfigParityErrorReplaceChar)
       
   702 			aChar = aChar & ~(0xff|KReceiveIsrParityError) | iConfig.iParityErrorChar;
       
   703 		// Ignore parity error
       
   704 		if (iConfig.iParityError==KConfigParityErrorIgnore)
       
   705 			aChar = aChar & ~KReceiveIsrParityError;
       
   706 		}
       
   707 	
       
   708 	// Check for terminating character
       
   709 	for (TInt i=0; i<iConfig.iTerminatorCount; i++)
       
   710 		{
       
   711 		if (iConfig.iTerminator[i]==aChar)
       
   712 			{
       
   713 			aChar |= KReceiveIsrTermChar;
       
   714 			doDrainRxBuffer=ETrue;
       
   715 			break;
       
   716 			}
       
   717 		}
       
   718 
       
   719 	TInt e;
       
   720 	if (e = iRxBuf->PutChar(aChar), e!=0)
       
   721 		{
       
   722 		if (e<0)
       
   723 			{
       
   724 			if (e==KErrOverflow)
       
   725 				e = KErrCommsOverrun;
       
   726 			iReceiveError = e;
       
   727 			}
       
   728 		doDrainRxBuffer = ETrue;
       
   729 		}
       
   730 
       
   731 	// Determine if the request will be completed by the arrival of the character
       
   732     if (IsReading() && iReceiveLength>0)
       
   733         {
       
   734 		// If the buffer is full enough to complete the request
       
   735 		// or over the half full mark the drain the buffer
       
   736 		TInt count=iRxBuf->Count();
       
   737         if (iReceiveLength<=count || count>=iHalfFullMark || (aChar & KReceiveIsrMaskComplete))
       
   738             doDrainRxBuffer=ETrue;
       
   739         }
       
   740 
       
   741 	if (doDrainRxBuffer)
       
   742 		DrainRxBuffer();
       
   743 	}
       
   744 
       
   745 	
       
   746 TInt DChannelComm::TransmitIsr()
       
   747 //
       
   748 // Return the next character to be transmitted to the ISR
       
   749 //
       
   750 	{
       
   751 
       
   752 	TInt tChar=KTransmitIrqEmpty; // No character to be sent
       
   753     if (iInputHeld>=0) // Control character to send
       
   754         {
       
   755         tChar=iInputHeld; // Send the control character
       
   756 #ifdef _DEBUG_DEVCOMM
       
   757 		if (tChar==iConfig.iXonChar)
       
   758 			iTxXon++;
       
   759 		else
       
   760 			iTxXoff++;
       
   761 #endif
       
   762         iInputHeld=(tChar==iConfig.iXonChar ? KInputHeldFree : KInputHeld);        
       
   763 		}
       
   764     else if (iOutputHeld==0) // Is the output free
       
   765         {
       
   766         if (IsWriting()) // Anything to be transmitted
       
   767             {
       
   768 			tChar=iTxBuf->Get();
       
   769 		    if (tChar<0 && iTransmitLength==0) // No characters left to send
       
   770 				{
       
   771 				tChar=KTransmitIrqEmpty;
       
   772 				if (iWriteZero)
       
   773 					{
       
   774 					TUint stat = iDriver->Signals();
       
   775 					stat &= (KSignalCTS|KSignalDSR|KSignalDCD|KXoffSignal);
       
   776 					stat ^= (KSignalCTS|KSignalDSR|KSignalDCD);
       
   777 					if (!(iConfig.iHandshake & KConfigObeyCTS)) // If ignoring CTS
       
   778 						stat &= (~KSignalCTS);
       
   779 					if (!(iConfig.iHandshake & KConfigObeyDSR)) // If ignoring DSR
       
   780 						stat &= (~KSignalDSR);
       
   781 					if (!(iConfig.iHandshake & KConfigObeyDCD)) // If ignoring DCD
       
   782 						stat &= (~KSignalDCD);
       
   783 					if (iOutputHeld & KXoffSignal)
       
   784 						stat |= KXoffSignal; // Leave the xon/xoff handshake bit
       
   785 					if ((stat & ~KXoffSignal)==0)
       
   786 						CompleteWrite();
       
   787 					}
       
   788 				else
       
   789 					{
       
   790 					if (!(iConfig.iHandshake&KConfigWriteBufferedComplete))
       
   791 						CompleteWrite();
       
   792 					}
       
   793 				}
       
   794 			else if (iTransmitLength!=0 && iTxBuf->Count()<(KTxBufferSize>>1)) // Less than half full
       
   795 				FillTxBuffer();
       
   796 #ifdef _DEBUG_DEVCOMM
       
   797 			if (tChar!=KTransmitIrqEmpty)
       
   798 				iTxChars++;
       
   799 #endif
       
   800             }
       
   801         }
       
   802 
       
   803     if (tChar!=KTransmitIrqEmpty) // Character to be sent
       
   804         iFlags|=KTransmitting;
       
   805 	else
       
   806 		iFlags&=(~KTransmitting);
       
   807 
       
   808     return(tChar);
       
   809 	}
       
   810 
       
   811 void DChannelComm::StateIsr(TUint aStatus)
       
   812 //
       
   813 // Handle a state change from the ISR
       
   814 //
       
   815 	{
       
   816 	if (iSignalChangeNotification && ((iSignals^aStatus)&iSignalMask))
       
   817 		{
       
   818         iSignalChangeInfo=(((iSignals^aStatus)&iSignalMask)<<12)|(aStatus&iSignalMask);
       
   819 		CompleteSignalChange();
       
   820 		}
       
   821     iSignals=aStatus; // Update the status
       
   822     TUint handshake=iConfig.iHandshake; // Get the handshake characteristic
       
   823 
       
   824     if (IsLineFail(handshake))
       
   825 		{
       
   826 //		CompleteAll(KErrCommsLineFail);	// Can't just complete reads from interrupts.
       
   827 //		iIsReading=EFalse;
       
   828 		iReceiveError=KErrCommsLineFail;
       
   829 		DrainRxBuffer();
       
   830 
       
   831 		if (IsWriting())
       
   832 			{
       
   833 			iWriteError = KErrCommsLineFail;
       
   834 			CompleteWrite();
       
   835 			}
       
   836 		}
       
   837 		
       
   838 //
       
   839 // Now we must determine if output is to be held
       
   840 //
       
   841 	aStatus &= (KSignalCTS|KSignalDSR|KSignalDCD|KXoffSignal);
       
   842     aStatus ^= (KSignalCTS|KSignalDSR|KSignalDCD);
       
   843 
       
   844     if (!(handshake & KConfigObeyCTS)) // If ignoring CTS
       
   845         aStatus &= (~KSignalCTS);
       
   846 
       
   847     if (!(handshake & KConfigObeyDSR)) // If ignoring DSR
       
   848         aStatus &= (~KSignalDSR);
       
   849 
       
   850     if (!(handshake & KConfigObeyDCD)) // If ignoring DCD
       
   851         aStatus &= (~KSignalDCD);
       
   852 
       
   853     if (iOutputHeld & KXoffSignal)
       
   854         aStatus |= KXoffSignal; // Leave the xon/xoff handshake bit
       
   855 
       
   856 //
       
   857 // For write zero, we complete if the lines indicate we could write....
       
   858 //
       
   859 	if (iWriteZero && (aStatus & ~KXoffSignal)==0)
       
   860 		{
       
   861 		if (iIsClientWriting && iTxBuf->Count()==0)
       
   862 			{
       
   863 			CompleteWrite();
       
   864 			return;
       
   865 			}
       
   866 		}
       
   867 
       
   868 //
       
   869 // If request outstanding AND we were holding AND not held anymore
       
   870 //
       
   871     if (aStatus==0 && /*iTransmitPtr!=0*/ IsWriting() /*&& iOutputHeld!=0*/) 
       
   872         {
       
   873         iOutputHeld=0; // Not holding any more
       
   874         EnableTransmit(); // Start transmitting again
       
   875         }
       
   876     else
       
   877         iOutputHeld=aStatus; // Set the held bits
       
   878 	}
       
   879 
       
   880 
       
   881 void DChannelComm::DoCancel(TInt aReqNo)
       
   882 //
       
   883 // Cancel an outstanding request.
       
   884 //
       
   885 	{
       
   886 
       
   887 	switch (aReqNo)
       
   888 		{
       
   889 	case RBusDevComm::ERequestRead:
       
   890 		iIsReading=EFalse;
       
   891 		iDataAvailableNotification=EFalse;
       
   892 		break;
       
   893 	case RBusDevComm::ERequestWrite:
       
   894 		iIsClientWriting=EFalse;
       
   895 		iWriteZero=EFalse;
       
   896 		iIsWriting=EFalse;
       
   897 		iTxBuf->Reset();
       
   898 		break;
       
   899 	case RBusDevComm::ERequestBreak:
       
   900 		BreakOff();
       
   901 		break;
       
   902 	case RBusDevComm::ERequestNotifySignalChange:
       
   903 		iSignalChangeNotification=EFalse;
       
   904 		break;
       
   905 		}
       
   906 	}
       
   907 
       
   908 void DChannelComm::DoRequest(TInt aReqNo,TAny *a1,TAny *a2)
       
   909 //
       
   910 // Async requests.
       
   911 //
       
   912 	{
       
   913 
       
   914 	TBool dataAvailReq=aReqNo&KDataAvailableNotifyFlag;
       
   915 	aReqNo&=(~KChanRequestNoReservedMask); // Mask off device specific flags
       
   916 
       
   917 	//
       
   918 	// First check if we have started
       
   919 	//
       
   920 	if (iStatus==ENotActive)
       
   921 		{
       
   922 		Start();
       
   923 		if (!(iConfig.iHandshake & KConfigFreeDTR))
       
   924 			iDriver->SetSignals(KSignalDTR,0); // Assert DTR
       
   925 		if (!(iConfig.iHandshake & KConfigFreeRTS))
       
   926 			iDriver->SetSignals(KSignalRTS,0); // Assert RTS
       
   927 		if (iConfig.iHandshake & KConfigSendXoff)
       
   928 			iInputHeld = iConfig.iXonChar;
       
   929 		else
       
   930 			iInputHeld = KInputHeldFree;
       
   931 		}
       
   932 
       
   933 	//
       
   934 	// Next we check for a line fail
       
   935 	//
       
   936 	if (IsLineFail(iConfig.iHandshake))
       
   937 		{
       
   938 		Complete(aReqNo,KErrCommsLineFail);
       
   939 		return;
       
   940 		}
       
   941 
       
   942 	//
       
   943 	// Now we can dispatch the request
       
   944 	//
       
   945 	TInt len;
       
   946 	switch (aReqNo)
       
   947 		{
       
   948 	case RBusDevComm::ERequestRead:
       
   949 		{
       
   950 		if (dataAvailReq)
       
   951 			{
       
   952 			iPowerHandler->RequestPending();
       
   953 			iDataAvailableNotification=ETrue;
       
   954 			}
       
   955 		else
       
   956 			{
       
   957 			iDriver->DisableInterrupts();
       
   958 			iReceivePtr=(TUint8 *)a1;
       
   959 			len=(*((TInt *)a2));
       
   960 			if (len<0)
       
   961 				{
       
   962 				iReceiveOneOrMore=TRUE;
       
   963 				iReceiveLength=Min(-len,iRxBuf->Count());
       
   964 				if (iReceiveLength==0)
       
   965 					iReceiveLength=1;
       
   966 				}
       
   967 			else
       
   968 				{
       
   969 				TInt maxLength=iThread->GetDesMaxLength(a1);
       
   970 				if(len>maxLength || maxLength<0)
       
   971 					{
       
   972 					iDriver->EnableInterrupts();
       
   973 					Complete(RBusDevComm::ERequestRead,KErrGeneral);
       
   974 					break;
       
   975 					}
       
   976 				iReceiveOneOrMore=FALSE;
       
   977 				iReceiveLength=len;
       
   978 				if (iReceiveLength==0)
       
   979 					{
       
   980 					iDriver->EnableInterrupts();
       
   981 					Complete(RBusDevComm::ERequestRead);
       
   982 					break;
       
   983 					}
       
   984 				}
       
   985 			if (iReceiveError && iReceiveLength>iReceiveErrorLength)
       
   986 				iReceiveLength=iReceiveErrorLength;
       
   987 			iReceiveOffset=0;
       
   988 			iIsReading=ETrue;
       
   989 			iPowerHandler->RequestPending();
       
   990 			iDriver->EnableInterrupts();
       
   991 			if(iConfig.iHandshake&KConfigSendXoff)
       
   992 				{
       
   993 				iInputHeld=iConfig.iXonChar;
       
   994 				EnableTransmit();
       
   995 				}
       
   996 			
       
   997 			DoDrainRxBuffer();
       
   998 			}
       
   999 		}
       
  1000 		break;
       
  1001 	case RBusDevComm::ERequestWrite:
       
  1002 		if (iStatus==EClosed)
       
  1003 			{
       
  1004 			Complete(aReqNo,KErrNotReady);
       
  1005 			iPowerHandler->RequestComplete();
       
  1006 			break;
       
  1007 			}
       
  1008 		iPowerHandler->RequestPending();
       
  1009 		iDriver->DisableInterrupts();
       
  1010 		if ((iTransmitLength=(*((TInt *)a2)))==0)
       
  1011 			{
       
  1012 			iWriteZero=ETrue;
       
  1013 			iIsWriting=ETrue;
       
  1014 			iIsClientWriting=ETrue;
       
  1015 			iDriver->EnableInterrupts();
       
  1016 			}
       
  1017 		else
       
  1018 			{
       
  1019 			iTransmitPtr=(TUint8 *)a1;
       
  1020 			iTransmitOffset=0;
       
  1021 			iIsClientWriting=ETrue;
       
  1022 			if((iFlags&KTransmitting) && iIsWriting) // let the transmit isr deal with it
       
  1023 			    {
       
  1024 				iDriver->EnableInterrupts();
       
  1025 				StateIsr(iDriver->Signals());
       
  1026 				break;
       
  1027 			    }
       
  1028 			iIsWriting=EFalse;
       
  1029 			iDriver->EnableInterrupts();
       
  1030 			DoFillTxBuffer();
       
  1031 			iIsWriting=ETrue;
       
  1032 			}
       
  1033 		StateIsr(iDriver->Signals());
       
  1034 		break;
       
  1035 	case RBusDevComm::ERequestBreak:
       
  1036 		Complete(aReqNo,KErrNotSupported);
       
  1037 		break;
       
  1038 	case RBusDevComm::ERequestNotifySignalChange:
       
  1039 		iSignalChangePtr=(TUint*)a1;
       
  1040 		iSignalMask=*(TUint*)a2;
       
  1041 		iSignalChangeNotification=ETrue;
       
  1042 		break;
       
  1043 		}
       
  1044 	}
       
  1045 
       
  1046 TInt DChannelComm::DoControl(TInt aFunction,TAny *a1,TAny *a2)
       
  1047 //
       
  1048 // Sync requests.
       
  1049 //
       
  1050 	{
       
  1051 
       
  1052 	TCommConfigV01 c;
       
  1053 	TInt len;
       
  1054 	TInt r=KErrNone;
       
  1055 
       
  1056 	TBool restart = EFalse;
       
  1057 	TBool purge = EFalse;
       
  1058 	TBool rescan = EFalse;
       
  1059 
       
  1060 	switch (aFunction)
       
  1061 		{
       
  1062 	case RBusDevComm::EControlConfig:
       
  1063 		((TDes8 *)a1)->FillZ(((TDes8 *)a1)->MaxLength());
       
  1064 		len=Min(((TDes8 *)a1)->MaxLength(),sizeof(iConfig));
       
  1065 		((TDes8 *)a1)->Copy((TUint8 *)&iConfig,len);
       
  1066 		break;
       
  1067 	case RBusDevComm::EControlSetConfig:
       
  1068 		if (AreAnyPending())
       
  1069 //			iThread->Panic(_L("D32COMM"),ESetConfigWhileRequestPending);
       
  1070 			Kern::PanicCurrentThread(_L("D32COMM"), ESetConfigWhileRequestPending);
       
  1071 		else
       
  1072 			{
       
  1073 			Mem::FillZ(&c,sizeof(c));
       
  1074 			len=Min(((TDesC8 *)a1)->Length(),sizeof(c));
       
  1075 			Mem::Copy(&c,((TDesC8 *)a1)->Ptr(),len);
       
  1076 			if(c.iTerminatorCount>KConfigMaxTerminators)
       
  1077 				{
       
  1078 				r=KErrNotSupported;
       
  1079 				break;
       
  1080 				}
       
  1081 			if (c.iRate==EBpsAutobaud)
       
  1082 				{
       
  1083 				r=KErrNotSupported;
       
  1084 				break;
       
  1085 				}
       
  1086 			if ((r=iDriver->Validate(c))!=KErrNone)
       
  1087 				break;
       
  1088 			if (IsLineFail(c.iHandshake))
       
  1089 				{
       
  1090 				r=KErrCommsLineFail;
       
  1091 				break;
       
  1092 				}
       
  1093 			if (c.iSIREnable==ESIREnable)
       
  1094 				{
       
  1095 				c.iHandshake=0;
       
  1096 				c.iStopBits=EStop1;
       
  1097 				c.iDataBits=EData8;
       
  1098 				}
       
  1099 			if (iConfig.iRate != c.iRate
       
  1100 				|| iConfig.iDataBits != c.iDataBits
       
  1101 				|| iConfig.iStopBits != c.iStopBits
       
  1102 				|| iConfig.iParity != c.iParity
       
  1103 				|| iConfig.iFifo != c.iFifo
       
  1104 				|| iConfig.iSpecialRate != c.iSpecialRate
       
  1105 				|| iConfig.iSIREnable != c.iSIREnable
       
  1106 				|| iConfig.iSIRSettings != c.iSIRSettings)
       
  1107 				{
       
  1108 				restart = ETrue;
       
  1109 				}
       
  1110 			else if (iConfig.iParityErrorChar != c.iParityErrorChar
       
  1111 				|| iConfig.iParityError != c.iParityError
       
  1112 				|| iConfig.iXonChar != c.iXonChar
       
  1113 				|| iConfig.iXoffChar != c.iXoffChar
       
  1114 				|| (iConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
       
  1115 					!= (c.iHandshake&(KConfigObeyXoff|KConfigSendXoff)))
       
  1116 				{
       
  1117 				purge = ETrue;
       
  1118 				}
       
  1119 			else
       
  1120 				{
       
  1121 				if (iConfig.iTerminatorCount==c.iTerminatorCount)
       
  1122 					{
       
  1123 					for (TInt i=0; i<iConfig.iTerminatorCount; i++)
       
  1124 						{
       
  1125 						if (iConfig.iTerminator[i]!=c.iTerminator[i])
       
  1126 							{
       
  1127 							rescan=ETrue;
       
  1128 							break;
       
  1129 							}
       
  1130 						}
       
  1131 					}
       
  1132 				else
       
  1133 					rescan=ETrue;
       
  1134 				
       
  1135 				if (!rescan && c.iHandshake == iConfig.iHandshake)
       
  1136 					break;	// nothing to do.
       
  1137 				}
       
  1138 			if (iStatus==EActive && (restart || purge))
       
  1139 				{
       
  1140 				if (!(iConfig.iHandshake&KConfigFreeRTS))
       
  1141 					iDriver->SetSignals(0,KSignalRTS); // Drop RTS
       
  1142 				Stop(EStopNormal);
       
  1143 				if(purge)
       
  1144 					ResetBuffers();
       
  1145 				iConfig=c;
       
  1146 				Start();
       
  1147 				if (!(iConfig.iHandshake&KConfigFreeRTS))
       
  1148 					iDriver->SetSignals(KSignalRTS,0); // Assert RTS
       
  1149 				iDriver->DisableInterrupts();
       
  1150 				}
       
  1151 			else
       
  1152 				{
       
  1153 				iDriver->DisableInterrupts();
       
  1154 				if(purge)
       
  1155 					ResetBuffers();
       
  1156 				iConfig=c;
       
  1157 				}				
       
  1158 			if(!(iConfig.iHandshake&KConfigObeyXoff))
       
  1159 				iOutputHeld&=~KXoffSignal;
       
  1160 			if(iConfig.iHandshake&KConfigSendXoff)
       
  1161 				{
       
  1162 				iInputHeld=iConfig.iXonChar;
       
  1163 				iHighWaterMark=iHalfFullMark-5;
       
  1164 				}
       
  1165 			else
       
  1166 				{
       
  1167 				iInputHeld=KInputHeldFree;
       
  1168 				iHighWaterMark=iRxBuf->Length()-iLowWaterMark; // 75%
       
  1169 				}
       
  1170 			if(iConfig.iHandshake&KConfigObeyCTS || iConfig.iHandshake&KConfigObeyDSR)
       
  1171 				iInputHeld=KInputHeld;
       
  1172 			iDriver->EnableInterrupts();
       
  1173 
       
  1174 			if (rescan)
       
  1175 				iRxBuf->RescanTerminators(iDriver, iConfig.iTerminatorCount, iConfig.iTerminator);
       
  1176 			}
       
  1177 		break;
       
  1178 	case RBusDevComm::EControlCaps:
       
  1179 		iDriver->Caps(*((TDes8 *)a1));
       
  1180 		break;
       
  1181 	case RBusDevComm::EControlSignals:
       
  1182 		r=iDriver->Signals();
       
  1183 		break;
       
  1184 	case RBusDevComm::EControlSetSignals:
       
  1185 		if (((TUint)a1)&((TUint)a2))
       
  1186 //			iThread->Panic(_L("D32COMM"),ESetSignalsSetAndClear);
       
  1187 			Kern::PanicCurrentThread(_L("D32COMM"), ESetSignalsSetAndClear);
       
  1188 		else
       
  1189 			{
       
  1190 			TUint set=(TUint)a1;
       
  1191 			if (iStatus==ENotActive)
       
  1192 				{
       
  1193 				Start();
       
  1194 				if (!(iConfig.iHandshake & KConfigFreeDTR) && !((TUint)a2 & KSignalDTR))
       
  1195 					set|=KSignalDTR; // Assert DTR
       
  1196 				if (!(iConfig.iHandshake & KConfigFreeRTS) && !((TUint)a2 & KSignalRTS))
       
  1197 					set|=KSignalRTS; // Assert RTS
       
  1198 				if (iConfig.iHandshake & KConfigSendXoff)
       
  1199 					iInputHeld = iConfig.iXonChar;
       
  1200 				else
       
  1201 					iInputHeld = KInputHeldFree;
       
  1202 				}
       
  1203 			iDriver->SetSignals(set,(TUint)a2);
       
  1204 			iSignals=(iSignals|set)&(~(TUint)a2);
       
  1205 			}
       
  1206 		break;
       
  1207 	case RBusDevComm::EControlQueryReceiveBuffer:
       
  1208 		r=iRxBuf->Count();
       
  1209 		break;
       
  1210 	case RBusDevComm::EControlResetBuffers:
       
  1211 		if (AreAnyPending())
       
  1212 //			iThread->Panic(_L("D32COMM"),EResetBuffers);
       
  1213 			Kern::PanicCurrentThread(_L("D32COMM"), EResetBuffers);
       
  1214 		else
       
  1215 			ResetBuffers();
       
  1216 		break;
       
  1217 	case RBusDevComm::EControlReceiveBufferLength:
       
  1218 		r=iRxBuf->Length();
       
  1219 		break;
       
  1220 
       
  1221 	// ***************************************
       
  1222 	// This one runs in the supervisor context
       
  1223 	// ***************************************
       
  1224 	case RBusDevComm::EControlSetReceiveBufferLength:
       
  1225 		if (AreAnyPending())
       
  1226 			iThread->Panic(_L("D32COMM"),ESetReceiveBufferLength);
       
  1227 		else
       
  1228 			r=SetRxBufferSize((TInt)a1);
       
  1229 		break;
       
  1230 	// ***************************************
       
  1231 
       
  1232 	case KChannelControlLateOpen:
       
  1233 		r=iDriver->CompleteSlowOpen((DThread*)a1,(TRequestStatus*)a2);
       
  1234 		break;
       
  1235 #ifdef _DEBUG_DEVCOMM
       
  1236 	case RBusDevComm::EControlDebugInfo:
       
  1237 		{
       
  1238 		TCommDebugInfo info;
       
  1239 		iDriver->DisableInterrupts();
       
  1240 		info.iRxBusy = iIsReading;
       
  1241 		info.iRxHeld = iOutputHeld!=0;
       
  1242 		info.iRxLength = iReceiveLength;
       
  1243 		info.iRxOffset = iReceiveOffset;
       
  1244 		info.iRxIntCount = iDriver->iRxIntCount;
       
  1245 		info.iRxErrCount = iDriver->iRxErrCount;
       
  1246 		info.iRxBufCount = iRxBuf->Count();
       
  1247 		info.iTxBusy = iIsWriting;
       
  1248 		info.iTxHeld = iInputHeld!=KInputHeldFree;
       
  1249 		info.iTxLength = iTransmitLength;
       
  1250 		info.iTxOffset = iTransmitOffset;
       
  1251 		info.iTxIntCount = iDriver->iTxIntCount;
       
  1252 		info.iTxErrCount = iDriver->iTxErrCount;
       
  1253 		info.iTxBufCount = iTxBuf->Count();
       
  1254 		info.iDrainingRxBuf = iDrainingRxBuf!=0;
       
  1255 		info.iFillingTxBuf = iFillingTxBuf!=0;
       
  1256 		info.iRunningDfc = iRunningDfc!=0;
       
  1257 		info.iDfcCount = iDfcCount;
       
  1258 		info.iDfcReqSeq = iDfcReqSeq;
       
  1259 		info.iDfcHandlerSeq = iDfcHandlerSeq;
       
  1260 		info.iRxXon = iRxXon;
       
  1261 		info.iRxXoff = iRxXoff;
       
  1262 		info.iTxXon = iTxXon;
       
  1263 		info.iTxXoff = iTxXoff;
       
  1264 		info.iRxChars = iRxChars;
       
  1265 		info.iTxChars = iTxChars;
       
  1266 		info.iDoDrainSeq = iDoDrainSeq;
       
  1267 		info.iTxDfcPend = (iDfcRequest&EFillTxBufferRequired)!=0;
       
  1268 		info.iRxDfcPend = (iDfcRequest&EDrainRxBufferRequired)!=0;
       
  1269 		iDriver->EnableInterrupts();
       
  1270 		((TDes8 *)a1)->FillZ(((TDes8 *)a1)->MaxLength());
       
  1271 		len=Min(((TDes8 *)a1)->MaxLength(),sizeof(TCommDebugInfo));
       
  1272 		((TDes8 *)a1)->Copy((TUint8 *)&info,len);
       
  1273 		}
       
  1274 #endif
       
  1275 	default:
       
  1276 		r=KErrNotSupported;
       
  1277 		}
       
  1278 	return(r);
       
  1279 	}
       
  1280 
       
  1281 void DChannelComm::QueueDfc(TUint aRequestMask)
       
  1282 //
       
  1283 // Set the flag to drain RX Buffer and queue the DFC if required.
       
  1284 //
       
  1285 	{
       
  1286     if (aRequestMask!=ECompleteEmergency)
       
  1287         iDriver->DisableInterrupts();
       
  1288 
       
  1289 	iDfcRequest |= aRequestMask;
       
  1290 
       
  1291 	if (!iRunningDfc)
       
  1292 		{
       
  1293 #ifdef _DEBUG_DEVCOMM
       
  1294 		if (aRequestMask & EDrainRxBufferRequired)
       
  1295 			{
       
  1296 			iDfcReqSeq = iRxBuf->iRemSeqNum.Int();
       
  1297 			++iDfcCount;
       
  1298 			}
       
  1299 #endif
       
  1300 		iRunningDfc=ETrue;
       
  1301 		Kern::Add(iDfc);
       
  1302 		}
       
  1303 
       
  1304     if (aRequestMask!=ECompleteEmergency)
       
  1305 	    iDriver->EnableInterrupts();
       
  1306 	}
       
  1307 
       
  1308 void DChannelComm::ResetDevice()
       
  1309 //
       
  1310 // Reset driver variables following device power down.
       
  1311 //
       
  1312     {
       
  1313 
       
  1314 	iIsClientWriting=EFalse;
       
  1315 //
       
  1316 // Must leave iDfcRunning set as the Dfc may remain pending
       
  1317 // This is no problem as the DfcHandler is happy if it finds
       
  1318 // it has nothing to do
       
  1319 //
       
  1320 	iIsReading=iIsWriting=iDrainingRxBuf=iFillingTxBuf=EFalse;
       
  1321 	iFlags=iDfcRequest=0;
       
  1322 
       
  1323 	iStatus=ENotActive;
       
  1324 	}
       
  1325 
       
  1326 void DChannelComm::DoPowerDown()
       
  1327 //
       
  1328 // Called at switch off and on Closing.
       
  1329 //
       
  1330     {
       
  1331 
       
  1332 	if (iStatus==EActive)
       
  1333 		Stop(EStopPwrDown);
       
  1334 	iPowerHandler->SetRequirement(0);
       
  1335 	}
       
  1336 
       
  1337 void DChannelComm::DoEmergencyPowerDown()
       
  1338 //
       
  1339 // Called when the batteries run out or fall out.
       
  1340 //
       
  1341     {
       
  1342 
       
  1343 	if (iStatus==EActive)
       
  1344 		Stop(EStopEmergency);
       
  1345 	QueueDfc(ECompleteEmergency);
       
  1346     }
       
  1347 
       
  1348 GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
       
  1349 //
       
  1350 // DLL entry point
       
  1351 //
       
  1352 	{
       
  1353 
       
  1354 	return KErrNone;
       
  1355 	}