📄 initunlo.c
字号:
SerialDump(SERERRORS, ("SERIAL: Could not map memory for interrupt "
"status for %wZ\n",
&pDevExt->DeviceName));
//
// Manually unmap the other register here if necessary
//
if (pDevExt->UnMapRegisters) {
MmUnmapIoSpace((PVOID)PConfigData->TrController.QuadPart,
PConfigData->SpanOfController);
}
pDevExt->UnMapRegisters = FALSE;
pDevExt->UnMapStatus = FALSE;
status = STATUS_NONE_MAPPED;
goto ExtensionCleanup;
}
pDevExt->OriginalInterruptStatus = PConfigData->InterruptStatus;
pDevExt->SpanOfInterruptStatus = PConfigData->SpanOfInterruptStatus;
}
//
// Shareable interrupt?
//
if ((BOOLEAN)PConfigData->PermitSystemWideShare) {
pDevExt->InterruptShareable = TRUE;
}
//
// Save off the interface type and the bus number.
//
pDevExt->InterfaceType = PConfigData->InterfaceType;
pDevExt->BusNumber = PConfigData->BusNumber;
pDevExt->PortIndex = PConfigData->PortIndex;
pDevExt->Indexed = (BOOLEAN)PConfigData->Indexed;
pDevExt->MaskInverted = PConfigData->MaskInverted;
//
// Get the translated interrupt vector, level, and affinity
//
pDevExt->OriginalIrql = PConfigData->OriginalIrql;
pDevExt->OriginalVector = PConfigData->OriginalVector;
//
// PnP uses the passed translated values rather than calling
// HalGetInterruptVector()
//
pDevExt->Vector = PConfigData->TrVector;
pDevExt->Irql = (UCHAR)PConfigData->TrIrql;
//
// Set up the Isr.
//
pDevExt->OurIsr = SerialISR;
pDevExt->OurIsrContext = pDevExt;
//
// If the user said to permit sharing within the device, propagate this
// through.
//
pDevExt->PermitShare = PConfigData->PermitShare;
//
// Before we test whether the port exists (which will enable the FIFO)
// convert the rx trigger value to what should be used in the register.
//
// If a bogus value was given - crank them down to 1.
//
switch (PConfigData->RxFIFO) {
case 1:
pDevExt->RxFifoTrigger = SERIAL_1_BYTE_HIGH_WATER;
break;
case 4:
pDevExt->RxFifoTrigger = SERIAL_4_BYTE_HIGH_WATER;
break;
case 8:
pDevExt->RxFifoTrigger = SERIAL_8_BYTE_HIGH_WATER;
break;
case 14:
pDevExt->RxFifoTrigger = SERIAL_14_BYTE_HIGH_WATER;
break;
default:
pDevExt->RxFifoTrigger = SERIAL_1_BYTE_HIGH_WATER;
break;
}
if ((PConfigData->TxFIFO > 16) ||
(PConfigData->TxFIFO < 1)) {
pDevExt->TxFifoAmount = 1;
} else {
pDevExt->TxFifoAmount = PConfigData->TxFIFO;
}
if (!SerialDoesPortExist(
pDevExt,
&pDevExt->DeviceName,
PConfigData->ForceFifoEnable,
PConfigData->LogFifo
)) {
//
// 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.
//
SerialDump(
SERERRORS,
("SERIAL: Does Port exist 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) {
SerialDump(
SERERRORS,
("SERIAL: 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));
SerialDump(
SERDIAG1,
("SERIAL: 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.
//
pDevExt->DeviceIsOpened = 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.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -