-/* $Id:\r
- * \r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: drivers/dd/serial/circularbuffer.c\r
- * PURPOSE: Operations on a circular buffer\r
- * \r
- * PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)\r
- */\r
-\r
-#define NDEBUG\r
-#include "serial.h"\r
-\r
-NTSTATUS\r
-InitializeCircularBuffer(\r
- IN PCIRCULAR_BUFFER pBuffer,\r
- IN ULONG BufferSize)\r
-{\r
- DPRINT("Serial: InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize);\r
- pBuffer->Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG);\r
- if (!pBuffer->Buffer)\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- pBuffer->Length = BufferSize;\r
- pBuffer->ReadPosition = pBuffer->WritePosition = 0;\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-NTSTATUS\r
-FreeCircularBuffer(\r
- IN PCIRCULAR_BUFFER pBuffer)\r
-{\r
- DPRINT("Serial: FreeCircularBuffer(pBuffer %p)\n", pBuffer);\r
- ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-IsCircularBufferEmpty(\r
- IN PCIRCULAR_BUFFER pBuffer)\r
-{\r
- DPRINT("Serial: IsCircularBufferEmpty(pBuffer %p)\n", pBuffer);\r
- return (pBuffer->ReadPosition == pBuffer->WritePosition);\r
-}\r
-\r
-NTSTATUS\r
-PushCircularBufferEntry(\r
- IN PCIRCULAR_BUFFER pBuffer,\r
- IN UCHAR Entry)\r
-{\r
- ULONG NextPosition;\r
- DPRINT("Serial: PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry);\r
- ASSERT(pBuffer->Length);\r
- NextPosition = (pBuffer->WritePosition + 1) % pBuffer->Length;\r
- if (NextPosition == pBuffer->ReadPosition)\r
- return STATUS_BUFFER_TOO_SMALL;\r
- pBuffer->Buffer[pBuffer->WritePosition] = Entry;\r
- pBuffer->WritePosition = NextPosition;\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-NTSTATUS\r
-PopCircularBufferEntry(\r
- IN PCIRCULAR_BUFFER pBuffer,\r
- OUT PUCHAR Entry)\r
-{\r
- DPRINT("Serial: PopCircularBufferEntry(pBuffer %p)\n", pBuffer);\r
- ASSERT(pBuffer->Length);\r
- if (IsCircularBufferEmpty(pBuffer))\r
- return STATUS_ARRAY_BOUNDS_EXCEEDED;\r
- *Entry = pBuffer->Buffer[pBuffer->ReadPosition];\r
- pBuffer->ReadPosition = (pBuffer->ReadPosition + 1) % pBuffer->Length;\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-NTSTATUS\r
-IncreaseCircularBufferSize(\r
- IN PCIRCULAR_BUFFER pBuffer,\r
- IN ULONG NewBufferSize)\r
-{\r
- PUCHAR NewBuffer;\r
- \r
- DPRINT("Serial: IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize);\r
- ASSERT(pBuffer->Length);\r
- if (pBuffer->Length > NewBufferSize)\r
- return STATUS_INVALID_PARAMETER;\r
- else if (pBuffer->Length == NewBufferSize)\r
- return STATUS_SUCCESS;\r
- \r
- NewBuffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, NewBufferSize * sizeof(UCHAR), SERIAL_TAG);\r
- if (!NewBuffer)\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- RtlCopyMemory(NewBuffer, pBuffer->Buffer, pBuffer->Length * sizeof(UCHAR));\r
- ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);\r
- pBuffer->Buffer = NewBuffer;\r
- pBuffer->Length = NewBufferSize;\r
- return STATUS_SUCCESS;\r
-}\r
+/* $Id:
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/dd/serial/circularbuffer.c
+ * PURPOSE: Operations on a circular buffer
+ *
+ * PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS
+InitializeCircularBuffer(
+ IN PCIRCULAR_BUFFER pBuffer,
+ IN ULONG BufferSize)
+{
+ DPRINT("Serial: InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize);
+ pBuffer->Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG);
+ if (!pBuffer->Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ pBuffer->Length = BufferSize;
+ pBuffer->ReadPosition = pBuffer->WritePosition = 0;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+FreeCircularBuffer(
+ IN PCIRCULAR_BUFFER pBuffer)
+{
+ DPRINT("Serial: FreeCircularBuffer(pBuffer %p)\n", pBuffer);
+ ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN
+IsCircularBufferEmpty(
+ IN PCIRCULAR_BUFFER pBuffer)
+{
+ DPRINT("Serial: IsCircularBufferEmpty(pBuffer %p)\n", pBuffer);
+ return (pBuffer->ReadPosition == pBuffer->WritePosition);
+}
+
+NTSTATUS
+PushCircularBufferEntry(
+ IN PCIRCULAR_BUFFER pBuffer,
+ IN UCHAR Entry)
+{
+ ULONG NextPosition;
+ DPRINT("Serial: PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry);
+ ASSERT(pBuffer->Length);
+ NextPosition = (pBuffer->WritePosition + 1) % pBuffer->Length;
+ if (NextPosition == pBuffer->ReadPosition)
+ return STATUS_BUFFER_TOO_SMALL;
+ pBuffer->Buffer[pBuffer->WritePosition] = Entry;
+ pBuffer->WritePosition = NextPosition;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+PopCircularBufferEntry(
+ IN PCIRCULAR_BUFFER pBuffer,
+ OUT PUCHAR Entry)
+{
+ DPRINT("Serial: PopCircularBufferEntry(pBuffer %p)\n", pBuffer);
+ ASSERT(pBuffer->Length);
+ if (IsCircularBufferEmpty(pBuffer))
+ return STATUS_ARRAY_BOUNDS_EXCEEDED;
+ *Entry = pBuffer->Buffer[pBuffer->ReadPosition];
+ pBuffer->ReadPosition = (pBuffer->ReadPosition + 1) % pBuffer->Length;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+IncreaseCircularBufferSize(
+ IN PCIRCULAR_BUFFER pBuffer,
+ IN ULONG NewBufferSize)
+{
+ PUCHAR NewBuffer;
+
+ DPRINT("Serial: IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize);
+ ASSERT(pBuffer->Length);
+ if (pBuffer->Length > NewBufferSize)
+ return STATUS_INVALID_PARAMETER;
+ else if (pBuffer->Length == NewBufferSize)
+ return STATUS_SUCCESS;
+
+ NewBuffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, NewBufferSize * sizeof(UCHAR), SERIAL_TAG);
+ if (!NewBuffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlCopyMemory(NewBuffer, pBuffer->Buffer, pBuffer->Length * sizeof(UCHAR));
+ ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
+ pBuffer->Buffer = NewBuffer;
+ pBuffer->Length = NewBufferSize;
+ return STATUS_SUCCESS;
+}
-/* $Id:\r
- * \r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: drivers/bus/serial/legacy.c\r
- * PURPOSE: Legacy serial port enumeration\r
- * \r
- * PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)\r
- * Mark Junker (mjscod@gmx.de)\r
- */\r
-\r
-#define NDEBUG\r
-#include "serial.h"\r
-\r
-UART_TYPE\r
-SerialDetectUartType(\r
- IN PUCHAR BaseAddress)\r
-{\r
- UCHAR Lcr, TestLcr;\r
- UCHAR OldScr, Scr5A, ScrA5;\r
- BOOLEAN FifoEnabled;\r
- UCHAR NewFifoStatus;\r
- \r
- Lcr = READ_PORT_UCHAR(SER_LCR(BaseAddress));\r
- WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr ^ 0xFF);\r
- TestLcr = READ_PORT_UCHAR(SER_LCR(BaseAddress)) ^ 0xFF;\r
- WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr);\r
- \r
- /* Accessing the LCR must work for a usable serial port */\r
- if (TestLcr != Lcr)\r
- return UartUnknown;\r
- \r
- /* Ensure that all following accesses are done as required */\r
- READ_PORT_UCHAR(SER_RBR(BaseAddress));\r
- READ_PORT_UCHAR(SER_IER(BaseAddress));\r
- READ_PORT_UCHAR(SER_IIR(BaseAddress));\r
- READ_PORT_UCHAR(SER_LCR(BaseAddress));\r
- READ_PORT_UCHAR(SER_MCR(BaseAddress));\r
- READ_PORT_UCHAR(SER_LSR(BaseAddress));\r
- READ_PORT_UCHAR(SER_MSR(BaseAddress));\r
- READ_PORT_UCHAR(SER_SCR(BaseAddress));\r
- \r
- /* Test scratch pad */\r
- OldScr = READ_PORT_UCHAR(SER_SCR(BaseAddress));\r
- WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0x5A);\r
- Scr5A = READ_PORT_UCHAR(SER_SCR(BaseAddress));\r
- WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0xA5);\r
- ScrA5 = READ_PORT_UCHAR(SER_SCR(BaseAddress));\r
- WRITE_PORT_UCHAR(SER_SCR(BaseAddress), OldScr);\r
- \r
- /* When non-functional, we have a 8250 */\r
- if (Scr5A != 0x5A || ScrA5 != 0xA5)\r
- return Uart8250;\r
- \r
- /* Test FIFO type */\r
- FifoEnabled = (READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0x80) != 0;\r
- WRITE_PORT_UCHAR(SER_FCR(BaseAddress), SR_FCR_ENABLE_FIFO);\r
- NewFifoStatus = READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0xC0;\r
- if (!FifoEnabled)\r
- WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);\r
- switch (NewFifoStatus)\r
- {\r
- case 0x00:\r
- return Uart16450;\r
- case 0x40:\r
- case 0x80:\r
- /* Not sure about this but the documentation says that 0x40\r
- * indicates an unusable FIFO but my tests only worked\r
- * with 0x80 */\r
- return Uart16550;\r
- }\r
- \r
- /* FIFO is only functional for 16550A+ */\r
- return Uart16550A;\r
-}\r
-\r
-static NTSTATUS\r
-DetectLegacyDevice(\r
- IN PDRIVER_OBJECT DriverObject,\r
- IN ULONG ComPortBase,\r
- IN ULONG Irq,\r
- IN PULONG pComPortNumber OPTIONAL)\r
-{\r
- ULONG ResourceListSize;\r
- PCM_RESOURCE_LIST ResourceList;\r
- PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;\r
- BOOLEAN ConflictDetected;\r
- UART_TYPE UartType;\r
- PDEVICE_OBJECT Pdo = NULL;\r
- PDEVICE_OBJECT Fdo;\r
- KIRQL Dirql;\r
- NTSTATUS Status;\r
- \r
- /* Create resource list */\r
- ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);\r
- ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);\r
- if (!ResourceList)\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- ResourceList->Count = 1;\r
- ResourceList->List[0].InterfaceType = InterfaceTypeUndefined;\r
- ResourceList->List[0].BusNumber = -1; /* unknown */\r
- ResourceList->List[0].PartialResourceList.Version = 1;\r
- ResourceList->List[0].PartialResourceList.Revision = 1;\r
- ResourceList->List[0].PartialResourceList.Count = 2;\r
- ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];\r
- ResourceDescriptor->Type = CmResourceTypePort;\r
- ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;\r
- ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;\r
- ResourceDescriptor->u.Port.Start.u.HighPart = 0;\r
- ResourceDescriptor->u.Port.Start.u.LowPart = ComPortBase;\r
- ResourceDescriptor->u.Port.Length = 8;\r
- \r
- ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];\r
- ResourceDescriptor->Type = CmResourceTypeInterrupt;\r
- ResourceDescriptor->ShareDisposition = CmResourceShareShared;\r
- ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;\r
- ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(\r
- Internal, 0, 0, Irq,\r
- &Dirql,\r
- &ResourceDescriptor->u.Interrupt.Affinity);\r
- ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;\r
- \r
- /* Report resource list */\r
- Status = IoReportResourceForDetection(\r
- DriverObject, ResourceList, ResourceListSize,\r
- NULL, NULL, 0,\r
- &ConflictDetected);\r
- if (Status == STATUS_CONFLICTING_ADDRESSES)\r
- {\r
- DPRINT("Serial: conflict detected for serial port at 0x%lx (Irq %lu)\n", ComPortBase, Irq);\r
- ExFreePoolWithTag(ResourceList, SERIAL_TAG);\r
- return STATUS_DEVICE_NOT_CONNECTED;\r
- }\r
- if (!NT_SUCCESS(Status))\r
- {\r
- ExFreePoolWithTag(ResourceList, SERIAL_TAG);\r
- return Status;\r
- }\r
- \r
- /* Test if port exists */\r
- UartType = SerialDetectUartType((PUCHAR)ComPortBase);\r
- \r
- /* Report device if detected... */\r
- if (UartType != UartUnknown)\r
- {\r
- Status = IoReportDetectedDevice(\r
- DriverObject,\r
- ResourceList->List[0].InterfaceType, ResourceList->List[0].BusNumber, -1 /* unknown */,\r
- ResourceList, NULL,\r
- TRUE,\r
- &Pdo);\r
- if (NT_SUCCESS(Status))\r
- {\r
- Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);\r
- if (NT_SUCCESS(Status))\r
- {\r
- Status = SerialPnpStartDevice(Fdo, ResourceList);\r
- }\r
- }\r
- }\r
- else\r
- {\r
- /* Release resources */\r
- Status = IoReportResourceForDetection(\r
- DriverObject, NULL, 0,\r
- NULL, NULL, 0,\r
- &ConflictDetected);\r
- Status = STATUS_DEVICE_NOT_CONNECTED;\r
- }\r
- ExFreePoolWithTag(ResourceList, SERIAL_TAG);\r
- return Status;\r
-}\r
-\r
-NTSTATUS\r
-DetectLegacyDevices(\r
- IN PDRIVER_OBJECT DriverObject)\r
-{\r
- ULONG ComPortBase[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };\r
- ULONG Irq[] = { 4, 3, 4, 3 };\r
- ULONG ComPortNumber[] = { 1, 2, 3, 4 };\r
- ULONG i;\r
- NTSTATUS Status;\r
- NTSTATUS ReturnedStatus = STATUS_SUCCESS;\r
- \r
- for (i = 0; i < sizeof(ComPortBase)/sizeof(ComPortBase[0]); i++)\r
- {\r
- Status = DetectLegacyDevice(DriverObject, ComPortBase[i], Irq[i], &ComPortNumber[i]);\r
- if (!NT_SUCCESS(Status) && Status != STATUS_DEVICE_NOT_CONNECTED)\r
- ReturnedStatus = Status;\r
- DPRINT("Serial: Legacy device at 0x%x (IRQ %lu): status = 0x%08lx\n", ComPortBase[i], Irq[i], Status);\r
- }\r
- \r
- return ReturnedStatus;\r
-}\r
+/* $Id:
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/bus/serial/legacy.c
+ * PURPOSE: Legacy serial port enumeration
+ *
+ * PROGRAMMERS: Hervé Poussineau (poussine@freesurf.fr)
+ * Mark Junker (mjscod@gmx.de)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+UART_TYPE
+SerialDetectUartType(
+ IN PUCHAR BaseAddress)
+{
+ UCHAR Lcr, TestLcr;
+ UCHAR OldScr, Scr5A, ScrA5;
+ BOOLEAN FifoEnabled;
+ UCHAR NewFifoStatus;
+
+ Lcr = READ_PORT_UCHAR(SER_LCR(BaseAddress));
+ WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr ^ 0xFF);
+ TestLcr = READ_PORT_UCHAR(SER_LCR(BaseAddress)) ^ 0xFF;
+ WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr);
+
+ /* Accessing the LCR must work for a usable serial port */
+ if (TestLcr != Lcr)
+ return UartUnknown;
+
+ /* Ensure that all following accesses are done as required */
+ READ_PORT_UCHAR(SER_RBR(BaseAddress));
+ READ_PORT_UCHAR(SER_IER(BaseAddress));
+ READ_PORT_UCHAR(SER_IIR(BaseAddress));
+ READ_PORT_UCHAR(SER_LCR(BaseAddress));
+ READ_PORT_UCHAR(SER_MCR(BaseAddress));
+ READ_PORT_UCHAR(SER_LSR(BaseAddress));
+ READ_PORT_UCHAR(SER_MSR(BaseAddress));
+ READ_PORT_UCHAR(SER_SCR(BaseAddress));
+
+ /* Test scratch pad */
+ OldScr = READ_PORT_UCHAR(SER_SCR(BaseAddress));
+ WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0x5A);
+ Scr5A = READ_PORT_UCHAR(SER_SCR(BaseAddress));
+ WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0xA5);
+ ScrA5 = READ_PORT_UCHAR(SER_SCR(BaseAddress));
+ WRITE_PORT_UCHAR(SER_SCR(BaseAddress), OldScr);
+
+ /* When non-functional, we have a 8250 */
+ if (Scr5A != 0x5A || ScrA5 != 0xA5)
+ return Uart8250;
+
+ /* Test FIFO type */
+ FifoEnabled = (READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0x80) != 0;
+ WRITE_PORT_UCHAR(SER_FCR(BaseAddress), SR_FCR_ENABLE_FIFO);
+ NewFifoStatus = READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0xC0;
+ if (!FifoEnabled)
+ WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);
+ switch (NewFifoStatus)
+ {
+ case 0x00:
+ return Uart16450;
+ case 0x40:
+ case 0x80:
+ /* Not sure about this but the documentation says that 0x40
+ * indicates an unusable FIFO but my tests only worked
+ * with 0x80 */
+ return Uart16550;
+ }
+
+ /* FIFO is only functional for 16550A+ */
+ return Uart16550A;
+}
+
+static NTSTATUS
+DetectLegacyDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN ULONG ComPortBase,
+ IN ULONG Irq,
+ IN PULONG pComPortNumber OPTIONAL)
+{
+ ULONG ResourceListSize;
+ PCM_RESOURCE_LIST ResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
+ BOOLEAN ConflictDetected;
+ UART_TYPE UartType;
+ PDEVICE_OBJECT Pdo = NULL;
+ PDEVICE_OBJECT Fdo;
+ KIRQL Dirql;
+ NTSTATUS Status;
+
+ /* Create resource list */
+ ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
+ if (!ResourceList)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ ResourceList->Count = 1;
+ 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;
+ ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
+ ResourceDescriptor->Type = CmResourceTypePort;
+ ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
+ ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
+ ResourceDescriptor->u.Port.Start.u.HighPart = 0;
+ ResourceDescriptor->u.Port.Start.u.LowPart = ComPortBase;
+ ResourceDescriptor->u.Port.Length = 8;
+
+ ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];
+ ResourceDescriptor->Type = CmResourceTypeInterrupt;
+ ResourceDescriptor->ShareDisposition = CmResourceShareShared;
+ ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+ ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(
+ Internal, 0, 0, Irq,
+ &Dirql,
+ &ResourceDescriptor->u.Interrupt.Affinity);
+ ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
+
+ /* Report resource list */
+ Status = IoReportResourceForDetection(
+ DriverObject, ResourceList, ResourceListSize,
+ 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);
+
+ /* Report device if detected... */
+ if (UartType != UartUnknown)
+ {
+ Status = IoReportDetectedDevice(
+ DriverObject,
+ ResourceList->List[0].InterfaceType, ResourceList->List[0].BusNumber, -1 /* unknown */,
+ ResourceList, NULL,
+ TRUE,
+ &Pdo);
+ if (NT_SUCCESS(Status))
+ {
+ Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);
+ if (NT_SUCCESS(Status))
+ {
+ Status = SerialPnpStartDevice(Fdo, ResourceList);
+ }
+ }
+ }
+ else
+ {
+ /* Release resources */
+ Status = IoReportResourceForDetection(
+ DriverObject, NULL, 0,
+ NULL, NULL, 0,
+ &ConflictDetected);
+ Status = STATUS_DEVICE_NOT_CONNECTED;
+ }
+ ExFreePoolWithTag(ResourceList, SERIAL_TAG);
+ return Status;
+}
+
+NTSTATUS
+DetectLegacyDevices(
+ IN PDRIVER_OBJECT DriverObject)
+{
+ 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], &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);
+ }
+
+ return ReturnedStatus;
+}