mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
Allow ACPI detection and legacy detection for serial ports
Detect serial debug port and prevent its management by serial driver Activate serial driver in registry svn path=/trunk/; revision=14491
This commit is contained in:
@@ -674,13 +674,14 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Null","Type",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","ErrorControl",0x00010001,0x00000000
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Group",0x00000000,"Base"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","ImagePath",0x00020000,"system32\drivers\serial.sys"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Start",0x00010001,0x00000004
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Start",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Type",0x00010001,0x00000001
|
||||
;hard coded values
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","0",0x00000000,"ACPI\PNP0501"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","Count",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","NextInstance",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\0000","Service",0x00000000,"serial"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\1","Service",0x00000000,"serial"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\2","Service",0x00000000,"serial"
|
||||
|
||||
; Packet driver
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x00010001,0x00000001
|
||||
|
||||
@@ -74,11 +74,12 @@ SerialDetectUartType(
|
||||
return Uart16550A;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
static NTSTATUS
|
||||
DetectLegacyDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN ULONG ComPortBase,
|
||||
IN ULONG Irq)
|
||||
IN ULONG Irq,
|
||||
IN PULONG pComPortNumber OPTIONAL)
|
||||
{
|
||||
ULONG ResourceListSize;
|
||||
PCM_RESOURCE_LIST ResourceList;
|
||||
@@ -125,9 +126,16 @@ DetectLegacyDevice(
|
||||
NULL, NULL, 0,
|
||||
&ConflictDetected);
|
||||
if (Status == STATUS_CONFLICTING_ADDRESSES)
|
||||
{
|
||||
DPRINT("Serial: conflict detected for serial port at 0x%lx (Irq %lu)\n", ComPortBase, Irq);
|
||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
||||
return STATUS_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Test if port exists */
|
||||
UartType = SerialDetectUartType((PUCHAR)ComPortBase);
|
||||
@@ -143,7 +151,7 @@ DetectLegacyDevice(
|
||||
&Pdo);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, &Fdo);
|
||||
Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = SerialPnpStartDevice(Fdo, ResourceList);
|
||||
@@ -159,6 +167,7 @@ DetectLegacyDevice(
|
||||
&ConflictDetected);
|
||||
Status = STATUS_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -168,13 +177,14 @@ DetectLegacyDevices(
|
||||
{
|
||||
ULONG ComPortBase[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||
ULONG Irq[] = { 4, 3, 4, 3 };
|
||||
ULONG ComPortNumber[] = { 1, 2, 3, 4 };
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
NTSTATUS ReturnedStatus = STATUS_SUCCESS;
|
||||
|
||||
for (i = 0; i < sizeof(ComPortBase)/sizeof(ComPortBase[0]); i++)
|
||||
{
|
||||
Status = DetectLegacyDevice(DriverObject, ComPortBase[i], Irq[i]);
|
||||
Status = DetectLegacyDevice(DriverObject, ComPortBase[i], Irq[i], &ComPortNumber[i]);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_DEVICE_NOT_CONNECTED)
|
||||
ReturnedStatus = Status;
|
||||
DPRINT("Serial: Legacy device at 0x%x (IRQ %lu): status = 0x%08lx\n", ComPortBase[i], Irq[i], Status);
|
||||
|
||||
@@ -18,6 +18,7 @@ SerialAddDeviceInternal(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo,
|
||||
IN UART_TYPE UartType,
|
||||
IN PULONG pComPortNumber OPTIONAL,
|
||||
OUT PDEVICE_OBJECT* pFdo OPTIONAL)
|
||||
{
|
||||
PDEVICE_OBJECT Fdo = NULL;
|
||||
@@ -27,6 +28,7 @@ SerialAddDeviceInternal(
|
||||
UNICODE_STRING DeviceName;
|
||||
//UNICODE_STRING SymbolicLinkName;
|
||||
static ULONG DeviceNumber = 0;
|
||||
static ULONG ComPortNumber = 1;
|
||||
|
||||
DPRINT("Serial: SerialAddDeviceInternal called\n");
|
||||
|
||||
@@ -68,6 +70,10 @@ SerialAddDeviceInternal(
|
||||
#endif
|
||||
|
||||
DeviceExtension->SerialPortNumber = DeviceNumber++;
|
||||
if (pComPortNumber == NULL)
|
||||
DeviceExtension->ComPort = ComPortNumber++;
|
||||
else
|
||||
DeviceExtension->ComPort = *pComPortNumber;
|
||||
DeviceExtension->Pdo = Pdo;
|
||||
DeviceExtension->PnpState = dsStopped;
|
||||
DeviceExtension->UartType = UartType;
|
||||
@@ -122,13 +128,9 @@ SerialAddDevice(
|
||||
/* We have here a PDO that does not correspond to a legacy
|
||||
* serial port. So call the internal AddDevice function.
|
||||
*/
|
||||
DPRINT1("Serial: SerialAddDevice() called. Pdo 0x%p (should be NULL)\n", Pdo);
|
||||
/* FIXME: due to a bug, previously described AddDevice is
|
||||
* not called with a NULL Pdo. Block this call (blocks
|
||||
* unfortunately all the other PnP serial ports devices).
|
||||
*/
|
||||
return SerialAddDeviceInternal(DriverObject, Pdo, UartUnknown, NULL);
|
||||
//return STATUS_UNSUCCESSFUL;
|
||||
return SerialAddDeviceInternal(DriverObject, Pdo, UartUnknown, NULL, NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
@@ -160,7 +162,6 @@ SerialPnpStartDevice(
|
||||
|
||||
ASSERT(DeviceExtension->PnpState == dsStopped);
|
||||
|
||||
DeviceExtension->ComPort = DeviceExtension->SerialPortNumber + 1;
|
||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
||||
DeviceExtension->BaseAddress = 0;
|
||||
Dirql = 0;
|
||||
@@ -330,15 +331,16 @@ SerialPnp(
|
||||
KIRQL Dirql;
|
||||
ULONG ComPortBase;
|
||||
ULONG Irq;
|
||||
BOOLEAN ConflictDetected;
|
||||
|
||||
DPRINT1("Serial: no allocated resources for this device! Creating fake list\n");
|
||||
switch (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->SerialPortNumber)
|
||||
switch (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ComPort)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
ComPortBase = 0x3f8;
|
||||
Irq = 4;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
ComPortBase = 0x2f8;
|
||||
Irq = 3;
|
||||
break;
|
||||
@@ -350,10 +352,15 @@ SerialPnp(
|
||||
ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
||||
ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
|
||||
if (!ResourceList)
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
ResourceList->Count = 1;
|
||||
ResourceList->List[0].InterfaceType = Isa;
|
||||
ResourceList->List[0].BusNumber = -1; /* FIXME */
|
||||
ResourceList->List[0].InterfaceType = InterfaceTypeUndefined;
|
||||
ResourceList->List[0].BusNumber = -1; /* unknown */
|
||||
ResourceList->List[0].PartialResourceList.Version = 1;
|
||||
ResourceList->List[0].PartialResourceList.Revision = 1;
|
||||
ResourceList->List[0].PartialResourceList.Count = 2;
|
||||
@@ -375,6 +382,19 @@ SerialPnp(
|
||||
&ResourceDescriptor->u.Interrupt.Affinity);
|
||||
ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
|
||||
|
||||
/* Verify that this COM port is not the serial debug port */
|
||||
Status = IoReportResourceForDetection(
|
||||
DeviceObject->DriverObject, ResourceList, 0,
|
||||
NULL, NULL, 0,
|
||||
&ConflictDetected);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Stack->Parameters.StartDevice.AllocatedResources =
|
||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated =
|
||||
ResourceList;
|
||||
|
||||
@@ -41,6 +41,18 @@ DriverEntry(
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = SerialQueryInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = SerialPnp;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = SerialPower;
|
||||
|
||||
return DetectLegacyDevices(DriverObject);
|
||||
|
||||
/* FIXME: It seems that DriverEntry function may be called more
|
||||
* than once. Do only legacy detection the first time. */
|
||||
static BOOLEAN FirstTime = TRUE;
|
||||
if (FirstTime)
|
||||
{
|
||||
FirstTime = FALSE;
|
||||
return DetectLegacyDevices(DriverObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Serial: DriverEntry called for the second time!\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +313,7 @@ SerialAddDeviceInternal(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo,
|
||||
IN UART_TYPE UartType,
|
||||
IN PULONG pComPortNumber OPTIONAL,
|
||||
OUT PDEVICE_OBJECT* pFdo OPTIONAL);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
||||
@@ -80,8 +80,49 @@ IoReportResourceForDetection(
|
||||
IN ULONG DeviceListSize OPTIONAL,
|
||||
OUT PBOOLEAN ConflictDetected)
|
||||
{
|
||||
DPRINT1("IoReportResourceForDetection UNIMPLEMENTED but returns success.\n");
|
||||
*ConflictDetected = FALSE;
|
||||
DPRINT1("IoReportResourceForDetection unimplemented\n");
|
||||
|
||||
if (PopSystemPowerDeviceNode != NULL && DriverListSize > 0)
|
||||
{
|
||||
/* We hope serial ports will be enumerated by ACPI */
|
||||
*ConflictDetected = TRUE;
|
||||
return STATUS_CONFLICTING_ADDRESSES;
|
||||
}
|
||||
|
||||
/* HACK: check if serial debug output is enabled. If yes,
|
||||
* prevent serial port driver to detect this serial port
|
||||
* by indicating a conflict
|
||||
*/
|
||||
if ((KdDebugState & KD_DEBUG_SERIAL) && DriverList != NULL)
|
||||
{
|
||||
ULONG ComPortBase = 0;
|
||||
ULONG i;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
|
||||
|
||||
switch (LogPortInfo.ComPort)
|
||||
{
|
||||
case 1: ComPortBase = 0x3f8; break;
|
||||
case 2: ComPortBase = 0x2f8; break;
|
||||
case 3: ComPortBase = 0x3e8; break;
|
||||
case 4: ComPortBase = 0x2e8; break;
|
||||
}
|
||||
|
||||
/* search for this port address in DriverList */
|
||||
for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
|
||||
{
|
||||
ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
|
||||
if (ResourceDescriptor->Type == CmResourceTypePort)
|
||||
{
|
||||
if (ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase
|
||||
&& ResourceDescriptor->u.Port.Start.u.LowPart + ResourceDescriptor->u.Port.Length > ComPortBase)
|
||||
{
|
||||
*ConflictDetected = TRUE;
|
||||
return STATUS_CONFLICTING_ADDRESSES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user