📄 initunlo.c
字号:
)) {
//
// We couldn't verify that there was actually a
// port. No need to log an error as the port exist
// code will log exactly why.
//
SerialDbgPrintEx(DPFLTR_WARNING_LEVEL, "DoesPortExist test failed for "
"%wZ\n", &pDevExt->DeviceName);
status = STATUS_NO_SUCH_DEVICE;
goto ExtensionCleanup;
}
//
// If the user requested that we disable the port, then
// do it now. Log the fact that the port has been disabled.
//
if (PConfigData->DisablePort) {
SerialDbgPrintEx(DPFLTR_INFO_LEVEL, "disabled port %wZ as requested in "
"configuration\n", &pDevExt->DeviceName);
status = STATUS_NO_SUCH_DEVICE;
SerialLogError(
PDevObj->DriverObject,
PDevObj,
PConfigData->Controller,
SerialPhysicalZero,
0,
0,
0,
57,
STATUS_SUCCESS,
SERIAL_DISABLED_PORT,
pDevExt->DeviceName.Length+sizeof(WCHAR),
pDevExt->DeviceName.Buffer,
0,
NULL
);
goto ExtensionCleanup;
}
//
// Set up the default device control fields.
// Note that if the values are changed after
// the file is open, they do NOT revert back
// to the old value at file close.
//
pDevExt->SpecialChars.XonChar = SERIAL_DEF_XON;
pDevExt->SpecialChars.XoffChar = SERIAL_DEF_XOFF;
pDevExt->HandFlow.ControlHandShake = SERIAL_DTR_CONTROL;
pDevExt->HandFlow.FlowReplace = SERIAL_RTS_CONTROL;
//
// Default Line control protocol. 7E1
//
// Seven data bits.
// Even parity.
// 1 Stop bits.
//
pDevExt->LineControl = SERIAL_7_DATA |
SERIAL_EVEN_PARITY |
SERIAL_NONE_PARITY;
pDevExt->ValidDataMask = 0x7f;
pDevExt->CurrentBaud = 1200;
//
// We set up the default xon/xoff limits.
//
// This may be a bogus value. It looks like the BufferSize
// is not set up until the device is actually opened.
//
pDevExt->HandFlow.XoffLimit = pDevExt->BufferSize >> 3;
pDevExt->HandFlow.XonLimit = pDevExt->BufferSize >> 1;
pDevExt->BufferSizePt8 = ((3*(pDevExt->BufferSize>>2))+
(pDevExt->BufferSize>>4));
SerialDbgPrintEx(SERDIAG1, " The default interrupt read buffer size is: %d\n"
"------ The XoffLimit is : %d\n"
"------ The XonLimit is : %d\n"
"------ The pt 8 size is : %d\n",
pDevExt->BufferSize, pDevExt->HandFlow.XoffLimit,
pDevExt->HandFlow.XonLimit, pDevExt->BufferSizePt8);
//
// Go through all the "named" baud rates to find out which ones
// can be supported with this port.
//
pDevExt->SupportedBauds = SERIAL_BAUD_USER;
{
SHORT junk;
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)75,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_075;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)110,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_110;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)135,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_134_5;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)150,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_150;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)300,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_300;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)600,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_600;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)1200,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_1200;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)1800,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_1800;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)2400,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_2400;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)4800,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_4800;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)7200,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_7200;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)9600,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_9600;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)14400,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_14400;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)19200,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_19200;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)38400,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_38400;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)56000,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_56K;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)57600,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_57600;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)115200,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_115200;
}
if (!NT_ERROR(SerialGetDivisorFromBaud(
pDevExt->ClockRate,
(LONG)128000,
&junk
))) {
pDevExt->SupportedBauds |= SERIAL_BAUD_128K;
}
}
//
// Mark this device as not being opened by anyone. We keep a
// variable around so that spurious interrupts are easily
// dismissed by the ISR.
//
SetDeviceIsOpened(pDevExt, FALSE, FALSE);
//
// Store values into the extension for interval timing.
//
//
// If the interval timer is less than a second then come
// in with a short "polling" loop.
//
// For large (> then 2 seconds) use a 1 second poller.
//
pDevExt->ShortIntervalAmount.QuadPart = -1;
pDevExt->LongIntervalAmount.QuadPart = -10000000;
pDevExt->CutOverAmount.QuadPart = 200000000;
//
// Common error path cleanup. If the status is
// bad, get rid of the device extension, device object
// and any memory associated with it.
//
ExtensionCleanup: ;
if (!NT_SUCCESS(status)) {
if (allocedISRSw) {
ExFreePool(pDevExt->CIsrSw);
pDevExt->CIsrSw = NULL;
}
if (pDevExt->UnMapRegisters) {
MmUnmapIoSpace(pDevExt->Controller, pDevExt->SpanOfController);
}
if (pDevExt->UnMapStatus) {
MmUnmapIoSpace(pDevExt->InterruptStatus,
pDevExt->SpanOfInterruptStatus);
}
}
return status;
}
NTSTATUS
SerialInitOneController(IN PDEVICE_OBJECT PDevObj, IN PCONFIG_DATA PConfigData)
/*++
Routine Description:
This routine will call the real port initialization code. It sets
up the ISR and Context correctly for a one port device.
Arguments:
All args are simply passed along.
Return Value:
Status returned from the controller initialization routine.
--*/
{
NTSTATUS status;
PSERIAL_DEVICE_EXTENSION pDevExt;
PAGED_CODE();
status = SerialInitController(PDevObj, PConfigData);
if (NT_SUCCESS(status)) {
pDevExt = PDevObj->DeviceExtension;
//
// We successfully initialized the single controller.
// Stick the isr routine and the parameter for it
// back into the extension.
//
pDevExt->OurIsr = SerialISR;
pDevExt->OurIsrContext = pDevExt;
pDevExt->TopLevelOurIsr = SerialISR;
pDevExt->TopLevelOurIsrContext = pDevExt;
}
return status;
}
BOOLEAN
SerialDoesPortExist(
IN PSERIAL_DEVICE_EXTENSION Extension,
IN PUNICODE_STRING InsertString,
IN ULONG ForceFifo,
IN ULONG LogFifo
)
/*++
Routine Description:
This routine examines several of what might be the serial device
registers. It ensures that the bits that should be zero are zero.
In addition, this routine will determine if the device supports
fifo's. If it does it will enable the fifo's and turn on a boolean
in the extension that indicates the fifo's presence.
NOTE: If there is indeed a serial port at the address specified
it will absolutely have interrupts inhibited upon return
from this routine.
NOTE: Since this routine should be called fairly early in
the device driver initialization, the only element
that needs to be filled in is the base register address.
NOTE: These tests all assume that this code is the only
code that is looking at these ports or this memory.
This is a not to unreasonable assumption even on
multiprocessor systems.
Arguments:
Extension - A pointer to a serial device extension.
InsertString - String to place in an error log entry.
ForceFifo - !0 forces the fifo to be left on if found.
LogFifo - !0 forces a log message if fifo found.
Return Value:
Will return true if the port really exists, otherwise it
will return false.
--*/
{
UCHAR regContents;
BOOLEAN returnValue = TRUE;
UCHAR oldIERContents;
UCHAR oldLCRContents;
USHORT value1;
USHORT value2;
KIRQL oldIrql;
//
// Save of the line control.
//
oldLCRContents = READ_LINE_CONTROL(Extension->Controller);
//
// Make sure that we are *aren't* accessing the divsior latch.
//
WRITE_LINE_CONTROL(
Extension->Controller,
(UCHAR)(oldLCRContents & ~SERIAL_LCR_DLAB)
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -