home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Serial.c
- **
- ** Serial driver support routines
- **
- ** Copyright © 1990-1996 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- **
- ** :ts=4
- */
-
- #ifndef _GLOBAL_H
- #include "Global.h"
- #endif
-
- /* In case the DSR test is enabled */
-
- STATIC BOOL UseRTS_CTS;
-
- /* Serial write output routines */
-
- STATIC SERWRITE SerWriteRoutine,SerWriteAndProcessRoutine;
-
- STATIC VOID
- WriteAndProcessUserMon(APTR Buffer,LONG Size)
- {
- Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
-
- if(Size > 0)
- {
- StartSerialWrite(Buffer,Size);
-
- if(Marking)
- WindowMarkerStop();
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
-
- BytesOut += Size;
- }
- }
-
- STATIC VOID
- WriteUserMon(APTR Buffer,LONG Size)
- {
- Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
-
- if(Size > 0)
- {
- DoSerialWrite(Buffer,Size);
-
- BytesOut += Size;
- }
- }
-
- STATIC VOID
- WriteAndProcessBypass(APTR Buffer,LONG Size)
- {
- if((*SerWriteBypass)(Buffer,Size))
- {
- StartSerialWrite(Buffer,Size);
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
-
- BytesOut += Size;
- }
- }
-
- STATIC VOID
- WriteBypass(APTR Buffer,LONG Size)
- {
- if((*SerWriteBypass)(Buffer,Size))
- {
- DoSerialWrite(Buffer,Size);
-
- BytesOut += Size;
- }
- }
-
- STATIC VOID
- WriteAndProcessBypassUserMon(APTR Buffer,LONG Size)
- {
- if((*SerWriteBypass)(Buffer,Size))
- {
- Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
-
- if(Size > 0)
- {
- StartSerialWrite(Buffer,Size);
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
-
- BytesOut += Size;
- }
- }
- }
-
- STATIC VOID
- WriteBypassUserMon(APTR Buffer,LONG Size)
- {
- if((*SerWriteBypass)(Buffer,Size))
- {
- Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
-
- if(Size > 0)
- {
- DoSerialWrite(Buffer,Size);
-
- BytesOut += Size;
- }
- }
- }
-
- /* WriteAndProcess(APTR Buffer,LONG Size):
- *
- * At the same time write data to the serial port and
- * process it on the screen.
- */
-
- STATIC VOID
- WriteAndProcess(APTR Buffer,LONG Size)
- {
- StartSerialWrite(Buffer,Size);
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
-
- BytesOut += Size;
- }
-
- /* WriteDirect(APTR Buffer,LONG Size):
- *
- * Output the data and update the byte counter.
- */
-
- STATIC VOID
- WriteDirect(APTR Buffer,LONG Size)
- {
- DoSerialWrite(Buffer,Size);
-
- BytesOut += Size;
- }
-
- /* SetFlags():
- *
- * Set the contents of a serial device request according
- * to the current configuration settings.
- */
-
- STATIC BYTE
- SetFlags(VOID)
- {
- return(SetBothSerialAttributes(
- SERA_Baud, Config->SerialConfig->BaudRate,
- SERA_BreakTime, Config->SerialConfig->BreakLength,
- SERA_BitsPerChar, Config->SerialConfig->BitsPerChar,
- SERA_StopBits, Config->SerialConfig->StopBits,
- SERA_BufferSize, Config->SerialConfig->SerialBufferSize,
- SERA_Parity, Config->SerialConfig->Parity,
- SERA_Handshaking, UseRTS_CTS ? Config->SerialConfig->HandshakingProtocol : HANDSHAKING_NONE,
- SERA_HighSpeed, Config->SerialConfig->HighSpeed,
- SERA_Shared, Config->SerialConfig->Shared,
- TAG_DONE));
- }
-
- /* SendBreak():
- *
- * Transmit a break signal.
- */
-
- VOID
- SendBreak()
- {
- PushStatus(STATUS_BREAKING);
-
- DoSerialCmd(SDCMD_BREAK);
-
- PopStatus();
- }
-
- /* HangUp():
- *
- * Hang up the line.
- */
-
- VOID
- HangUp()
- {
- PushStatus(STATUS_HANGUP);
-
- StopSerialWrite();
-
- /* Are we to drop the DTR line
- * before sending the hangup
- * string?
- */
-
- if(Config->ModemConfig->DropDTR)
- {
- if(!DropDTR(Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber))
- {
- DeleteSerial();
-
- if(!ShowRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber))
- MainTerminated = TRUE;
- }
- }
-
- /* Transmit the hangup command. */
-
- if(Config->ModemConfig->ModemHangup[0] && !MainTerminated)
- SerialCommand(Config->ModemConfig->ModemHangup);
-
- /* Reset to old status. */
-
- PopStatus();
- }
-
- /* CopyWriteFlags():
- *
- * Update configuration with serial settings.
- */
-
- VOID
- CopyWriteFlags()
- {
- ULONG Baud,
- BreakTime,
- BitsPerChar,
- StopBits,
- BufferSize,
- Parity,
- Handshaking,
- HighSpeed,
- Shared;
-
- GetSerialWriteAttributes(
- SERA_Baud, &Baud,
- SERA_BreakTime, &BreakTime,
- SERA_BitsPerChar, &BitsPerChar,
- SERA_StopBits, &StopBits,
- SERA_BufferSize, &BufferSize,
- SERA_Parity, &Parity,
- SERA_Handshaking, &Handshaking,
- SERA_HighSpeed, &HighSpeed,
- SERA_Shared, &Shared,
- TAG_DONE);
-
- Config->SerialConfig->BaudRate = Baud;
- Config->SerialConfig->BreakLength = BreakTime;
- Config->SerialConfig->BitsPerChar = BitsPerChar;
- Config->SerialConfig->StopBits = StopBits;
- Config->SerialConfig->SerialBufferSize = BufferSize;
- Config->SerialConfig->Parity = Parity;
- Config->SerialConfig->HandshakingProtocol = Handshaking;
- Config->SerialConfig->HighSpeed = HighSpeed;
- Config->SerialConfig->Shared = Shared;
- }
-
- /* SerWriteVerbatim(APTR Buffer,LONG Size,BOOL Echo):
- *
- * The `no fancy features' version of SerWrite().
- */
-
- VOID
- SerWriteVerbatim(APTR Buffer,LONG Size,BOOL Echo)
- {
- if(XProtocolBase && (TransferBits & XPRS_USERMON))
- Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
-
- if(Size > 0)
- {
- if(Echo)
- WriteAndProcess(Buffer,Size);
- else
- DoSerialWrite(Buffer,Size);
-
- BytesOut += Size;
- }
- }
-
- /* SerWriteUpdate():
- *
- * Choose the right data output routine for the job.
- */
-
- VOID
- SerWriteUpdate()
- {
- if(SerWriteBypass)
- {
- if(XProtocolBase && (TransferBits & XPRS_USERMON))
- {
- SerWriteRoutine = (SERWRITE)WriteBypassUserMon;
- SerWriteAndProcessRoutine = (SERWRITE)WriteAndProcessBypassUserMon;
- }
- else
- {
- SerWriteRoutine = (SERWRITE)WriteBypass;
- SerWriteAndProcessRoutine = (SERWRITE)WriteAndProcessBypass;
- }
- }
- else
- {
- if(XProtocolBase && (TransferBits & XPRS_USERMON))
- {
- SerWriteRoutine = (SERWRITE)WriteUserMon;
- SerWriteAndProcessRoutine = (SERWRITE)WriteAndProcessUserMon;
- }
- else
- {
- SerWriteRoutine = (SERWRITE)WriteDirect;
- SerWriteAndProcessRoutine = (SERWRITE)WriteAndProcess;
- }
- }
- }
-
- /* SerWrite(APTR Buffer,LONG Size):
- *
- * Send a number of bytes across the serial line.
- */
-
- VOID
- SerWrite(APTR Buffer,LONG Size)
- {
- if(Size < 0)
- Size = strlen(Buffer);
-
- if(Size > 0)
- {
- if(RememberInput)
- {
- RememberInputText(Buffer,Size);
-
- if(((UBYTE *)Buffer)[Size - 1] == '\r' && RecordingLine)
- {
- RememberSpill();
-
- RecordingLine = FALSE;
-
- RememberOutput = TRUE;
- RememberInput = FALSE;
-
- CheckItem(MEN_RECORD_LINE,FALSE);
- }
- }
- else
- {
- if(RememberOutput)
- {
- RememberInputText(Buffer,Size);
-
- RememberSpill();
- }
- }
-
- if(WriteRequest)
- {
- if(SendTable)
- {
- struct TranslationHandle Handle;
- UBYTE TranslateData[256];
-
- /* Set up for buffer translation. */
-
- TranslateSetup(&Handle,Buffer,Size,TranslateData,sizeof(TranslateData),SendTable);
-
- /* Full or half duplex? */
-
- if(Config->SerialConfig->Duplex == DUPLEX_FULL)
- {
- /* Process the data... */
-
- while(Size = TranslateBuffer(&Handle))
- (*SerWriteRoutine)(TranslateData,Size);
- }
- else
- {
- while(Size = TranslateBuffer(&Handle))
- (*SerWriteAndProcessRoutine)(TranslateData,Size);
- }
- }
- else
- {
- if(Config->SerialConfig->Duplex == DUPLEX_FULL)
- (*SerWriteRoutine)(Buffer,Size);
- else
- (*SerWriteAndProcessRoutine)(Buffer,Size);
- }
- }
- }
- }
-
- /* RestartSerial():
- *
- * Restart read/write activity on the serial line.
- */
-
- VOID
- RestartSerial()
- {
- /* Blow away the cache if there is anything left of it. */
-
- if(DataHold)
- {
- DataHold = NULL;
-
- UpdateSerialJob();
- }
-
- StartSerialRead(&ReadChar,1);
- }
-
- /* ClearSerial():
- *
- * Terminate all read/write activity on the serial line.
- */
-
- VOID
- ClearSerial()
- {
- /* Blow away the cache if there is anything left of it. */
-
- if(DataHold)
- {
- DataHold = NULL;
-
- UpdateSerialJob();
- }
-
- StopSerialRead();
-
- FlushSerialRead();
- }
-
- /* DeleteSerial():
- *
- * Close the serial device and release all associated
- * resources.
- */
-
- VOID
- DeleteSerial()
- {
- StopSerialRead();
- StopSerialWrite();
-
- if(ReadRequest)
- {
- if(ReadRequest->IOSer.io_Device)
- {
- UBYTE Name[MAX_FILENAME_LENGTH];
- struct Device *Device;
-
- /* Unless the device was opened in shared */
- /* access mode we'll reset it here */
-
- if(!Config->SerialConfig->Shared)
- {
- ReadRequest->IOSer.io_Command = CMD_RESET;
-
- DoIO((struct IORequest *)ReadRequest);
- }
-
- /* Remember the device name, we'll need it after */
- /* closing time */
-
- LimitedStrcpy(sizeof(Name),Name,ReadRequest->IOSer.io_Device->dd_Library.lib_Node.ln_Name);
-
- /* Close the device */
-
- CloseDevice((struct IORequest *)ReadRequest);
-
- /* And remove it from memory */
-
- Forbid();
-
- if(Device = (struct Device *)FindName(&SysBase->DeviceList,Name))
- RemDevice(Device);
-
- Permit();
- }
-
- DeleteIORequest(ReadRequest);
- ReadRequest = NULL;
- }
-
- if(WriteRequest)
- {
- DeleteIORequest(WriteRequest);
- WriteRequest = NULL;
- }
-
- if(WritePort)
- {
- DeleteMsgPort(WritePort);
- WritePort = NULL;
- }
-
- if(ReadPort)
- {
- DeleteMsgPort(ReadPort);
- ReadPort = NULL;
- }
-
- FreeVecPooled(ReadBuffer);
- ReadBuffer = NULL;
-
- FreeVecPooled(HostReadBuffer);
- HostReadBuffer = NULL;
-
- FreeVecPooled(StripBuffer);
- StripBuffer = NULL;
-
- UnlockDevice();
-
- UpdateSerialJob();
- }
-
- /* GetSerialError(LONG Error,BOOL *Reset):
- *
- * Return an error message for each possible serial device error.
- */
-
- STRPTR
- GetSerialError(LONG Error,BOOL *ResetPtr)
- {
- BOOL Reset;
- LONG ID;
-
- Reset = FALSE;
- ID = -1;
-
- switch(Error)
- {
- case IOERR_BADLENGTH:
- case IOERR_BADADDRESS:
- case IOERR_SELFTEST:
- case IOERR_OPENFAIL:
-
- ID = MSG_SERIAL_OPENFAILURE_TXT;
- break;
-
- case SerErr_DevBusy:
-
- ID = MSG_SERIAL_ERROR_DEVBUSY_TXT;
- break;
-
- case SerErr_BaudMismatch:
- case 3: /* MultiFaceCard duart.device uses this. */
-
- Reset = TRUE;
- ID = MSG_SERIAL_ERROR_BAUDMISMATCH_TXT;
- break;
-
- case SerErr_BufErr:
-
- Reset = TRUE;
- ID = MSG_SERIAL_ERROR_BUFERR_TXT;
- break;
-
- case SerErr_InvParam:
-
- Reset = TRUE;
- ID = MSG_SERIAL_ERROR_INVPARAM_TXT;
- break;
-
- case SerErr_LineErr:
-
- ID = MSG_SERIAL_ERROR_LINEERR_TXT;
- break;
-
- case SerErr_ParityErr:
-
- Reset = TRUE;
- ID = MSG_SERIAL_ERROR_PARITYERR_TXT;
- break;
-
- case SerErr_TimerErr:
-
- ID = MSG_SERIAL_ERROR_TIMERERR_TXT;
- break;
-
- case SerErr_BufOverflow:
-
- Reset = TRUE;
- ID = MSG_SERIAL_ERROR_BUFOVERFLOW_TXT;
- break;
-
- case SerErr_NoDSR:
-
- ID = MSG_SERIAL_ERROR_NODSR_TXT;
- break;
-
- /* case SerErr_UnitBusy: */
- case IOERR_UNITBUSY:
- case 16:
-
- ID = MSG_SERIAL_ERROR_UNIT_BUSY_TXT;
- break;
- }
-
- if(ID != -1)
- {
- if(ResetPtr)
- *ResetPtr = Reset;
-
- return(LocaleString(ID));
- }
- else
- return(NULL);
- }
-
- /* CreateSerial():
- *
- * Create handles for the serial device and open it.
- */
-
- BOOL
- CreateSerial(STRPTR ErrorBuffer,LONG ErrorBufferSize)
- {
- BYTE Error = 0;
- LONG ID = -1;
-
- /* Try to lock the serial device driver if necessary */
-
- if(Config->SerialConfig->UseOwnDevUnit && !(Config->SerialConfig->Shared && Config->SerialConfig->NoODUIfShared))
- {
- if(!LockDevice(Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber,ErrorBuffer,ErrorBufferSize))
- return(FALSE);
- }
-
- /* Propagate the serial read buffer size to the translation routines */
-
- Update_CR_LF_Translation();
-
- /* Now allocate the required resources... */
-
- if(ReadBuffer = AllocVecPooled(Config->SerialConfig->SerialBufferSize,MEMF_ANY))
- {
- if(StripBuffer = AllocVecPooled(Config->SerialConfig->SerialBufferSize,MEMF_ANY))
- {
- if(XProtocolBase && (TransferBits & XPRS_HOSTNOWAIT))
- HostReadBuffer = AllocVecPooled(Config->SerialConfig->SerialBufferSize,MEMF_ANY);
-
- if(ReadPort = (struct MsgPort *)CreateMsgPort())
- {
- if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
- {
- if(WritePort = (struct MsgPort *)CreateMsgPort())
- {
- if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
- {
- /* Unless the user doesn't want RTS/CTS handshaking */
- /* we'll assume it should be enabled. This also concerns */
- /* the RTS/CTS+DSR test mode which will also start */
- /* with having RTS/CTS handshaking enabled. */
-
- UseRTS_CTS = (BOOL)(Config->SerialConfig->HandshakingProtocol != HANDSHAKING_NONE);
-
- /* Set the default opening parameters */
-
- SetSerialReadAttributes(
- SERA_Baud, Config->SerialConfig->BaudRate,
- SERA_BreakTime, Config->SerialConfig->BreakLength,
- SERA_BitsPerChar, Config->SerialConfig->BitsPerChar,
- SERA_StopBits, Config->SerialConfig->StopBits,
- SERA_BufferSize, Config->SerialConfig->SerialBufferSize,
- SERA_Parity, Config->SerialConfig->Parity,
- SERA_Handshaking, Config->SerialConfig->HandshakingProtocol,
- SERA_HighSpeed, Config->SerialConfig->HighSpeed,
- SERA_Shared, Config->SerialConfig->Shared,
- TAG_DONE);
-
- /* Open the device driver */
-
- if(!(Error = OpenSerialDevice(Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber)))
- {
- /* Should we perform a DSR signal test before */
- /* proceeding? */
-
- if(Config->SerialConfig->HandshakingProtocol == HANDSHAKING_RTSCTS_DSR)
- {
- /* Now check if the DSR signal is enabled. */
-
- if(GetSerialStatus() & CIAF_COMDSR)
- {
- /* If this is the first time the driver gets initialized, */
- /* skip the notification message and just drop the RTS/CTS */
- /* handshaking bit. */
-
- if(FirstInvocation)
- UseRTS_CTS = FALSE;
- else
- {
- do
- {
- if(!ShowRequest(Window,LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_TXT),LocaleString(MSG_SERIAL_RETRY_CANCEL_TXT)))
- UseRTS_CTS = FALSE;
- }
- while(UseRTS_CTS && (GetSerialStatus() & CIAF_COMDSR));
- }
- }
- }
-
- /* Update the driver data */
-
- ResetSerialRead();
- ResetSerialWrite();
-
- /* Set the parameters */
-
- SetFlags();
-
- /* And ask for a byte */
-
- RestartSerial();
-
- UpdateSerialJob();
-
- return(TRUE);
- }
- }
- }
- else
- ID = MSG_SERIAL_FAILED_TO_CREATE_WRITE_PORT_TXT;
- }
- }
- else
- ID = MSG_SERIAL_FAILED_TO_CREATE_READ_PORT_TXT;
- }
- }
-
- /* If we get here something must be wrong. */
-
- DeleteSerial();
-
- /* If we got an open error, we'll try to make it into */
- /* a readable description */
-
- if(Error != 0)
- {
- STRPTR String;
-
- if(!(String = GetSerialError(Error,NULL)))
- String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
-
- LimitedSPrintf(ErrorBufferSize,ErrorBuffer,String,Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber);
- }
- else
- {
- /* If no open error has occured a problem must have */
- /* hit us before the device was ready to open. */
- /* If the error message ID is negative we'll use the */
- /* default message which indicates memory allocation */
- /* problems. */
-
- if(ID == -1)
- ID = MSG_SERIAL_NOT_ENOUGH_MEMORY_TXT;
-
- strcpy(ErrorBuffer,LocaleString(ID));
- }
-
- return(FALSE);
- }
-
- /* ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig):
- *
- * Reconfigure the serial driver according to the new
- * serial settings.
- */
-
- LONG
- ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig)
- {
- LONG Success = RECONFIGURE_NOCHANGE;
-
- /* Are new settings to be installed or have they already */
- /* been copied to the correct locations? */
-
- if(CompareConfigEntries(Config->SerialConfig,SerialConfig ? SerialConfig : PrivateConfig->SerialConfig,PREF_SERIAL))
- {
- BOOL SameDevice = TRUE;
-
- /* Any new data to swap in? */
-
- if(SerialConfig)
- {
- /* Store the previous settings. */
-
- SaveConfig(Config,PrivateConfig);
-
- /* Install the new settings */
-
- PutConfigEntry(Config,SerialConfig,PREF_SERIAL);
- }
-
- /* Any device name or unit number change? */
-
- if(strcmp(PrivateConfig->SerialConfig->SerialDevice,Config->SerialConfig->SerialDevice) || PrivateConfig->SerialConfig->UnitNumber != Config->SerialConfig->UnitNumber || PrivateConfig->SerialConfig->UseOwnDevUnit != Config->SerialConfig->UseOwnDevUnit)
- SameDevice = FALSE;
-
- /* Handshaking mode changed? */
-
- if((PrivateConfig->SerialConfig->HandshakingProtocol == HANDSHAKING_NONE && Config->SerialConfig->HandshakingProtocol != HANDSHAKING_NONE) || (PrivateConfig->SerialConfig->HandshakingProtocol != HANDSHAKING_NONE && Config->SerialConfig->HandshakingProtocol == HANDSHAKING_NONE))
- SameDevice = FALSE;
-
- /* Did the ODU options change? */
-
- if(PrivateConfig->SerialConfig->NoODUIfShared != Config->SerialConfig->NoODUIfShared && Config->SerialConfig->Shared)
- SameDevice = FALSE;
-
- /* Is the device currently closed, i.e. should we open it? */
-
- if(!ReadRequest)
- SameDevice = FALSE;
-
- /* Stop any IO activity. */
-
- ClearSerial();
-
- /* No dramatic changes? Simply change the parameters. */
-
- if(SameDevice)
- {
- LONG Error;
-
- /* Did the buffer size change? */
-
- if(PrivateConfig->SerialConfig->SerialBufferSize != Config->SerialConfig->SerialBufferSize)
- {
- STRPTR NewReadBuffer;
- STRPTR NewStripBuffer;
-
- /* Allocate two new buffers */
-
- NewReadBuffer = AllocVecPooled(Config->SerialConfig->SerialBufferSize,MEMF_ANY);
- NewStripBuffer = AllocVecPooled(Config->SerialConfig->SerialBufferSize,MEMF_ANY);
-
- /* Did we get both? */
-
- if(NewReadBuffer && NewStripBuffer)
- {
- /* Release the old buffers */
-
- FreeVecPooled(ReadBuffer);
- FreeVecPooled(StripBuffer);
-
- /* And put the new ones in */
-
- ReadBuffer = NewReadBuffer;
- StripBuffer = NewStripBuffer;
- }
- else
- {
- /* Release whatever we had allocated */
-
- FreeVecPooled(NewReadBuffer);
- FreeVecPooled(NewStripBuffer);
-
- /* And change back to the old buffer size */
-
- Config->SerialConfig->SerialBufferSize = PrivateConfig->SerialConfig->SerialBufferSize;
- }
- }
-
- /* Propagate the buffer size to the translation routines */
-
- Update_CR_LF_Translation();
-
- /* Use new parameters */
-
- if(Error = SetFlags())
- {
- UBYTE LocalBuffer[256];
- STRPTR String;
- BOOL Reset;
-
- /* Get the error message. */
-
- if(!(String = GetSerialError(Error,&Reset)))
- String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
-
- /* Build the device name/unit number string. */
-
- LimitedSPrintf(sizeof(LocalBuffer),LocalBuffer,String,Config->SerialConfig->SerialDevice,Config->SerialConfig->UnitNumber);
-
- /* Display the error requester. */
-
- ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocalBuffer);
-
- /* Is a serial driver reset required? */
-
- if(Reset)
- {
- /* Execute the reset command. */
-
- DoSerialCmd(CMD_RESET);
-
- /* Copy the serial driver settings */
- /* to the global configuration. */
-
- CopyWriteFlags();
-
- /* Also set the read request driver flags */
-
- SetFlags();
- }
- }
-
- /* Restart read request */
-
- RestartSerial();
- }
- else
- {
- UBYTE LocalBuffer[256];
-
- /* Shut down the serial device driver */
-
- DeleteSerial();
-
- /* Reinitialize the serial device driver */
-
- if(!CreateSerial(LocalBuffer,sizeof(LocalBuffer)))
- {
- /* Display the error requester */
-
- ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocalBuffer);
-
- /* That didn't work */
-
- Success = RECONFIGURE_FAILURE;
- }
- }
- }
-
- return(Success);
- }
-
- /* ReopenSerial():
- *
- * Reopen the serial driver.
- */
-
- VOID
- ReopenSerial()
- {
- BOOL SerialClosed = TRUE;
- UBYTE LocalBuffer[256];
-
- do
- {
- if(CreateSerial(LocalBuffer,sizeof(LocalBuffer)))
- SerialClosed = FALSE;
- else
- {
- switch(ShowRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),LocalBuffer))
- {
- case 0:
-
- MainTerminated = TRUE;
- break;
-
- case 2:
-
- SerialClosed = FALSE;
- break;
- }
- }
- }
- while(SerialClosed && !MainTerminated);
- }
-
- /* HandleSerialJob():
- *
- * Handle the data coming in from the serial line.
- */
-
- BOOL
- HandleSerialJob(JobNode *UnusedJob)
- {
- BOOL MoreData;
-
- if(HostReadBuffer)
- {
- LONG Length = XProtocolHostMon(XprIO,HostReadBuffer,0,SerialBufferSize);
-
- if(Translate_CR_LF && Length > 0)
- Length = (*Translate_CR_LF)(HostReadBuffer,Length);
-
- if(Length > 0)
- {
- ConProcess(HostReadBuffer,Length);
-
- if(Get_xOFF())
- return(FALSE);
- }
-
- MoreData = TRUE;
- }
- else
- MoreData = FALSE;
-
- /* Any news? */
-
- if(CheckSerialRead())
- {
- /* Terminate the read request properly. */
-
- if(!WaitSerialRead())
- {
- ULONG Length;
-
- /* We got another byte. */
-
- ReadBuffer[0] = ReadChar;
-
- /* Check if there is anything waiting to be read. */
-
- if(Length = GetSerialWaiting())
- {
- ULONG MaxSize;
-
- /* This is how many characters fill still fit into
- * the read buffer.
- */
-
- MaxSize = SerialBufferSize - 1;
-
- /* Check if there is more data waiting
- * than will fit into the buffer.
- */
-
- if(Length > MaxSize)
- Length = MaxSize;
-
- /* Check if there is more data waiting than
- * the serial quantum allows.
- */
-
- if(Length > Config->SerialConfig->Quantum)
- Length = Config->SerialConfig->Quantum;
-
- /* Read the data still waiting. */
-
- if(DoSerialRead(&ReadBuffer[1],Length))
- Length = 0;
- }
-
- /* One byte was added earlier. */
-
- Length++;
-
- /* Process the data. */
-
- BytesIn += Length;
-
- (*ConTransfer)(ReadBuffer,Length);
- }
-
- /* If something is in the cache, don't overwrite
- * it by requesting another byte. Serial I/O
- * processing will be restarted when the cache
- * gets drained.
- */
-
- if(!DataHold && ProcessIO)
- {
- /* Yes, there is more to come. */
-
- MoreData = TRUE;
-
- StartSerialRead(&ReadChar,1);
- }
- }
-
- return(MoreData);
- }
-
- /* UpdateSerialJob():
- *
- * Either activate or suspend the serial I/O job.
- */
-
- VOID
- UpdateSerialJob()
- {
- ULONG Mask;
-
- if(!Get_xOFF() && ReadPort && ProcessIO)
- Mask = SIG_SERIAL;
- else
- Mask = NULL;
-
- if(Mask)
- {
- if(DataHold)
- {
- Mask = NULL;
-
- ActivateJob(MainJobQueue,SerialCacheJob);
- }
- else
- SuspendJob(MainJobQueue,SerialCacheJob);
- }
-
- UpdateJob(MainJobQueue,SerialJob,Mask);
-
- /* Now pick the right simplified access routines
- * for the job.
- */
-
- if(DataHold)
- {
- SerialWaitForData = SerialCacheWaitForData;
- SerialGetWaiting = SerialCacheGetWaiting;
- SerialRead = SerialCacheRead;
- }
- else
- {
- SerialWaitForData = SerialStdWaitForData;
- SerialGetWaiting = SerialStdGetWaiting;
- SerialRead = SerialStdRead;
- }
- }
-
- /* HandleSerialCacheJob(JobNode *UnusedJob):
- *
- * Does what HandleSerialJob() does, but picks the
- * data from the cache.
- */
-
- BOOL
- HandleSerialCacheJob(JobNode *UnusedJob)
- {
- STRPTR Data = DataHold;
- LONG Size = DataSize;
-
- /* These two are no longer valid. */
-
- DataHold = NULL;
- DataSize = 0;
-
- /* If there was anything in the buffer,
- * process it.
- */
-
- if(Size > 0)
- (*ConTransfer)(Data,Size);
-
- RestartSerial();
-
- UpdateSerialJob();
-
- return(TRUE);
- }
-
-
- /**********************************************************************/
-
-
- /* SerialStdWaitForData(ULONG OtherBits):
- *
- * Wait for new data to arrive or other events to
- * take place.
- */
-
- ULONG
- SerialStdWaitForData(ULONG OtherBits)
- {
- return(Wait(SIG_SERIAL | OtherBits));
- }
-
- /* SerialCacheWaitForData(ULONG OtherBits):
- *
- * Checks if other events took place and always flag
- * new serial data to be available.
- */
-
- ULONG
- SerialCacheWaitForData(ULONG OtherBits)
- {
- return((SetSignal(0,OtherBits) & OtherBits) | SIG_SERIAL);
- }
-
- /* SerialStdGetWaiting():
- *
- * Get the number of bytes still waiting to be read.
- */
-
- ULONG
- SerialStdGetWaiting()
- {
- return(GetSerialWaiting());
- }
-
- /* SerialCacheGetWaiting():
- *
- * Return the number of bytes still in the cache and
- * the number of bytes waiting in the serial read
- * buffer.
- */
-
- ULONG
- SerialCacheGetWaiting()
- {
- return(DataSize + SerialStdGetWaiting());
- }
-
- /* SerialStdRead(UBYTE *Buffer,LONG Len):
- *
- * Reads a number of bytes from the serial line and
- * puts them into the buffer. This routine assumes a
- * read request had been queued earlier. It waits
- * for the queued request to terminate, grabs the
- * character that was read and fills the remaining
- * buffer with the data to follow. Eventually, the
- * read request gets queued again.
- */
-
- LONG
- SerialStdRead(UBYTE *Buffer,LONG Len)
- {
- LONG Total;
-
- /* Wait for the read request to terminate. */
-
- WaitSerialRead();
-
- /* Put the byte into the buffer. */
-
- *Buffer++ = ReadChar;
- Len--;
-
- /* So far, one byte was read. */
-
- Total = 1;
-
- /* Any more data requested? */
-
- if(Len > 0)
- {
- /* Read the rest. */
-
- if(!DoSerialRead(Buffer,Len))
- Total += Len;
- }
-
- /* Restart the read request. */
-
- StartSerialRead(&ReadChar,1);
-
- /* Return the number of bytes read so far. */
-
- return(Total);
- }
-
- /* SerialCacheRead(UBYTE *Buffer,LONG Size):
- *
- * Read a number of bytes from the cache and the
- * serial buffer. Switch back to normal operation
- * if the cache is exhausted.
- */
-
- LONG
- SerialCacheRead(UBYTE *Buffer,LONG Size)
- {
- LONG Total;
-
- /* Nothing has been read yet. */
-
- Total = 0;
-
- /* Check if there is anything left in the cache. */
-
- if(DataSize > 0)
- {
- LONG Count;
-
- /* If there is more data in the cache than
- * requested, just read the requested number
- * of bytes from it.
- */
-
- if(DataSize > Size)
- Count = Size;
- else
- Count = DataSize;
-
- /* Copy the data from the cache into the buffer. */
-
- CopyMem(DataHold,Buffer,Count);
-
- /* This is how many bytes went into the buffer so far. */
-
- Total += Count;
-
- /* Update the buffer data. */
-
- Buffer += Count;
- Size -= Count;
-
- /* Update the cache data. */
-
- DataHold += Count;
- DataSize -= Count;
- }
-
- /* If no data is left in the cache, switch the read routines
- * back to the standard versions. This is done inside
- * RestartSerial().
- */
-
- if(DataSize == 0)
- RestartSerial();
-
- /* If there is still data to be read, read it from the standard
- * channel, otherwise return the number of bytes already read.
- */
-
- if(Size > 0)
- return(Total + SerialStdRead(Buffer,Size));
- else
- return(Total);
- }
-