[ros-diffs] [hpoussin] 14491: Allow ACPI detection and legacy detection for serial ports

hpoussin at svn.reactos.com hpoussin at svn.reactos.com
Tue Apr 5 01:00:56 CEST 2005


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
Modified: trunk/reactos/bootdata/hivesys.inf
Modified: trunk/reactos/drivers/dd/serial/legacy.c
Modified: trunk/reactos/drivers/dd/serial/pnp.c
Modified: trunk/reactos/drivers/dd/serial/serial.c
Modified: trunk/reactos/drivers/dd/serial/serial.h
Modified: trunk/reactos/ntoskrnl/io/pnpreport.c
  _____  

Modified: trunk/reactos/bootdata/hivesys.inf
--- trunk/reactos/bootdata/hivesys.inf	2005-04-04 22:48:51 UTC (rev
14490)
+++ trunk/reactos/bootdata/hivesys.inf	2005-04-04 23:00:52 UTC (rev
14491)
@@ -674,13 +674,14 @@

 
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","ErrorControl",0x0001000
1,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,0x00
000004
+HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Start",0x00010001,0x00
000001
 
HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Type",0x00010001,0x0000
0001
 ;hard coded values
 
HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","0",0x00000000,"ACP
I\PNP0501"
 
HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","Count",0x00010001,
0x00000001
 
HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","NextInstance",0x00
010001,0x00000001
-HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\0000","Service",0x0000
0000,"serial"
+HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\1","Service",0x0000000
0,"serial"
+HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\2","Service",0x0000000
0,"serial"
 
 ; Packet driver
 
HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x0001000
1,0x00000001
  _____  

Modified: trunk/reactos/drivers/dd/serial/legacy.c
--- trunk/reactos/drivers/dd/serial/legacy.c	2005-04-04 22:48:51 UTC
(rev 14490)
+++ trunk/reactos/drivers/dd/serial/legacy.c	2005-04-04 23:00:52 UTC
(rev 14491)
@@ -74,11 +74,12 @@

 	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 @@
 		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 @@
 			&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 @@
 			&ConflictDetected);
 		Status = STATUS_DEVICE_NOT_CONNECTED;
 	}
+	ExFreePoolWithTag(ResourceList, SERIAL_TAG);
 	return Status;
 }
 
@@ -168,13 +177,14 @@
 {
 	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);
  _____  

Modified: trunk/reactos/drivers/dd/serial/pnp.c
--- trunk/reactos/drivers/dd/serial/pnp.c	2005-04-04 22:48:51 UTC
(rev 14490)
+++ trunk/reactos/drivers/dd/serial/pnp.c	2005-04-04 23:00:52 UTC
(rev 14491)
@@ -18,6 +18,7 @@

 	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 @@
 	UNICODE_STRING DeviceName;
 	//UNICODE_STRING SymbolicLinkName;
 	static ULONG DeviceNumber = 0;
+	static ULONG ComPortNumber = 1;
 
 	DPRINT("Serial: SerialAddDeviceInternal called\n");
    
@@ -68,6 +70,10 @@
 #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 @@
 	/* 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 @@
 	
 	ASSERT(DeviceExtension->PnpState == dsStopped);
 	
-	DeviceExtension->ComPort = DeviceExtension->SerialPortNumber +
1;
 	DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
 	DeviceExtension->BaseAddress = 0;
 	Dirql = 0;
@@ -330,15 +331,16 @@
 				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)->SerialPortNu
mber)
+				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 @@
 				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 @@
 
&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;
  _____  

Modified: trunk/reactos/drivers/dd/serial/serial.c
--- trunk/reactos/drivers/dd/serial/serial.c	2005-04-04 22:48:51 UTC
(rev 14490)
+++ trunk/reactos/drivers/dd/serial/serial.c	2005-04-04 23:00:52 UTC
(rev 14491)
@@ -41,6 +41,18 @@

 	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;
+	}
 }
  _____  

Modified: trunk/reactos/drivers/dd/serial/serial.h
--- trunk/reactos/drivers/dd/serial/serial.h	2005-04-04 22:48:51 UTC
(rev 14490)
+++ trunk/reactos/drivers/dd/serial/serial.h	2005-04-04 23:00:52 UTC
(rev 14491)
@@ -313,6 +313,7 @@

 	IN PDRIVER_OBJECT DriverObject,
 	IN PDEVICE_OBJECT Pdo,
 	IN UART_TYPE UartType,
+	IN PULONG pComPortNumber OPTIONAL,
 	OUT PDEVICE_OBJECT* pFdo OPTIONAL);
 
 NTSTATUS STDCALL
  _____  

Modified: trunk/reactos/ntoskrnl/io/pnpreport.c
--- trunk/reactos/ntoskrnl/io/pnpreport.c	2005-04-04 22:48:51 UTC
(rev 14490)
+++ trunk/reactos/ntoskrnl/io/pnpreport.c	2005-04-04 23:00:52 UTC
(rev 14491)
@@ -80,8 +80,49 @@

   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;
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20050405/d2bf762a/attachment.html


More information about the Ros-diffs mailing list