📄 ser16550.c
字号:
pHWHead->PowerDown = FALSE;
pHWHead->bSuspendResume = FALSE;
InstallSoftwareISR(pHWHead,pHWHead->pVirtualStaticAddr,RegStride);
// Clear any interrupts which may be pending. Normally only
// happens if we were warm reset.
ClearPendingInts( pHWHead );
DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_INIT, 0x%X\r\n"), pHWHead));
}
//
// @doc OEM
// @func void | SL_PostInit | This routine takes care of final initialization.
//
// @rdesc None.
//
BOOL
SL_PostInit(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_INIT,(TEXT("+SL_PostInit, 0x%X\r\n"), pHWHead));
// Since we are just a library which might get used for
// builtin ports which init at boot, or by PCMCIA ports
// which init at Open, we can't do anything too fancy.
// Lets just make sure we cancel any pending interrupts so
// that if we are being used with an edge triggered PIC, he
// will see an edge after the MDD hooks the interrupt.
ClearPendingInts( pHWHead );
DEBUGMSG (ZONE_INIT,(TEXT("-SL_PostInit, 0x%X\r\n"), pHWHead));
return(TRUE);
}
//
// @doc OEM
// @func PVOID | SL_Deinit | De-initializes 16550 device head.
//
VOID
SL_Deinit(
PVOID pHead // @parm points to device head
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_CLOSE,(TEXT("+SL_DEINIT, 0x%X\r\n"), pHWHead));
UninstallSoftwareISR( pHWHead);
DeleteCriticalSection(&(pHWHead->TransmitCritSec));
DeleteCriticalSection(&(pHWHead->RegCritSec));
// Free the flushdone event
if ( pHWHead->FlushDone )
CloseHandle( pHWHead->FlushDone );
DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_DEINIT, 0x%X\r\n"), pHWHead));
}
//
// @doc OEM
// @func void | SL_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
SL_ClearDTR(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
try {
unsigned char byte;
byte = INB((PSER16550_INFO)pHead, pMCR);
OUTB((PSER16550_INFO)pHead, pMCR, byte & ~SERIAL_MCR_DTR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
#pragma prefast(pop)
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearDTR, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_SetDTR | This routine sets DTR.
//
// @rdesc None.
//
VOID
SL_SetDTR(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetDTR, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
try {
unsigned char byte;
byte = INB((PSER16550_INFO)pHead, pMCR);
OUTB((PSER16550_INFO)pHead, pMCR, byte | SERIAL_MCR_DTR);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
#pragma prefast(pop)
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetDTR, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_ClearRTS | This routine clears RTS.
//
// @rdesc None.
//
VOID
SL_ClearRTS(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
try {
unsigned char byte;
byte = INB((PSER16550_INFO)pHead, pMCR);
OUTB((PSER16550_INFO)pHead, pMCR, byte & ~SERIAL_MCR_RTS);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
#pragma prefast(pop)
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearRTS, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_SetRTS | This routine sets RTS.
//
// @rdesc None.
//
VOID
SL_SetRTS(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetRTS, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
try {
unsigned char byte;
byte = INB((PSER16550_INFO)pHead, pMCR);
OUTB((PSER16550_INFO)pHead, pMCR, byte | SERIAL_MCR_RTS);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
#pragma prefast(pop)
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetRTS, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_ClearBreak | This routine clears break.
//
// @rdesc None.
//
VOID
SL_ClearBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearBreak, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
try {
unsigned char byte;
byte = INB((PSER16550_INFO)pHead, pLCR);
OUTB((PSER16550_INFO)pHead, pLCR, byte & ~SERIAL_LCR_BREAK);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
#pragma prefast(pop)
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearBreak, 0x%X\r\n"), pHead));
}
//
// @doc OEM
// @func VOID | SL_SetBreak | This routine sets break.
//
// @rdesc None.
//
VOID
SL_SetBreak(
PVOID pHead // @parm PVOID returned by HWinit.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetBreak, 0x%X\r\n"), pHead));
EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
try {
unsigned char byte;
byte = INB((PSER16550_INFO)pHead, pLCR);
OUTB((PSER16550_INFO)pHead, pLCR, byte | SERIAL_LCR_BREAK);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just exit
}
#pragma prefast(pop)
LeaveCriticalSection(&(pHWHead->RegCritSec));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetBreak, 0x%X\r\n"), pHead));
}
//
// SetBaudRate
//
// Internal function. The only real reason for splitting this out
// is so that we can call it from PowerOn and still allow SL_SetBaud
// to do debug messages, acquire critical sections, etc.
//
BOOL
SetBaudRate(
PVOID pHead,
ULONG BaudRate
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
USHORT divisor;
UCHAR lcr;
// **** Warning ***** Make no system calls, called in power context
divisor = DivisorOfRate(pHead, BaudRate);
if ( divisor ) {
InterruptMask(pHWHead->dwSysIntr,TRUE);
lcr = INB(pHWHead, pLCR);
OUTB(pHWHead, pLCR, lcr | SERIAL_LCR_DLAB);
OUTB(pHWHead, pData, divisor & 0xff); //pData is DivLatch Lo
OUTB(pHWHead, pIER, (divisor >> 8) & 0xff); //pIER is DivLatch Hi
OUTB(pHWHead, pLCR, lcr);
InterruptMask(pHWHead->dwSysIntr,FALSE);
return( TRUE );
} else {
return( FALSE );
}
}
//
// @doc OEM
// @func BOOL | SL_SetBaudRate |
// This routine sets the baud rate of the device.
//
// @rdesc None.
//
BOOL
SL_SetBaudRate(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG BaudRate // @parm ULONG representing decimal baud rate.
)
{
BOOL fRet;
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SL_SetbaudRate 0x%X, x%X\r\n"), pHead, BaudRate));
try {
// Enter critical section before calling function, since
// we can't make sys calls inside SetBaudRate
EnterCriticalSection(&(pHWHead->RegCritSec));
fRet = SetBaudRate(pHead, BaudRate);
LeaveCriticalSection(&(pHWHead->RegCritSec));
}except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
return( FALSE );
}
if ( fRet ) {
pHWHead->dcb.BaudRate = BaudRate;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-SL_SetbaudRate 0x%X (%d Baud)\r\n"),
pHead, BaudRate));
return( TRUE );
} else {
DEBUGMSG (ZONE_FUNCTION | ZONE_ERROR,
(TEXT("-SL_SetbaudRate - Error setting %d, failing to %d\r\n"),
BaudRate, pHWHead->dcb.BaudRate) );
return( FALSE );
}
}
//
// @doc OEM
// @func BOOL | SL_SetByteSize |
// This routine sets the WordSize of the device.
//
// @rdesc None.
//
BOOL
SL_SetByteSize(
PVOID pHead, // @parm PVOID returned by HWInit
ULONG ByteSize // @parm ULONG ByteSize field from DCB.
)
{
PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
UINT8 lcr;
BOOL bRet;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SL_SetByteSize 0x%X, x%X\r\n"), pHead, ByteSize));
bRet = TRUE;
EnterCriticalSection(&(pHWHead->RegCritSec));
try {
lcr = INB(pHWHead, pLCR);
lcr &= ~SERIAL_DATA_MASK;
switch ( ByteSize ) {
case 5:
lcr |= SERIAL_5_DATA;
break;
case 6:
lcr |= SERIAL_6_DATA;
break;
case 7:
lcr |= SERIAL_7_DATA;
break;
case 8:
lcr |= SERIAL_8_DATA;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -