mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Add legacy detection of COM3 and COM4
Be ready for PnP serial ports Don't hardcode base addresses and irq twice svn path=/trunk/; revision=14216
This commit is contained in:
parent
fcc7d2acc7
commit
abb9dfec3b
3 changed files with 117 additions and 80 deletions
|
@ -77,7 +77,11 @@ DetectLegacyDevice(
|
||||||
{
|
{
|
||||||
ULONG ResourceListSize;
|
ULONG ResourceListSize;
|
||||||
PCM_RESOURCE_LIST ResourceList;
|
PCM_RESOURCE_LIST ResourceList;
|
||||||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
|
||||||
BOOLEAN ConflictDetected, FoundPort;
|
BOOLEAN ConflictDetected, FoundPort;
|
||||||
|
PDEVICE_OBJECT Pdo = NULL;
|
||||||
|
PDEVICE_OBJECT Fdo;
|
||||||
|
KIRQL Dirql;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Create resource list */
|
/* Create resource list */
|
||||||
|
@ -91,18 +95,23 @@ DetectLegacyDevice(
|
||||||
ResourceList->List[0].PartialResourceList.Version = 1;
|
ResourceList->List[0].PartialResourceList.Version = 1;
|
||||||
ResourceList->List[0].PartialResourceList.Revision = 1;
|
ResourceList->List[0].PartialResourceList.Revision = 1;
|
||||||
ResourceList->List[0].PartialResourceList.Count = 2;
|
ResourceList->List[0].PartialResourceList.Count = 2;
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort;
|
ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDriverExclusive;
|
ResourceDescriptor->Type = CmResourceTypePort;
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_PORT_IO;
|
ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
|
||||||
// FIXME ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start = ComPortBase;
|
ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 8;
|
ResourceDescriptor->u.Port.Start.u.HighPart = 0;
|
||||||
|
ResourceDescriptor->u.Port.Start.u.LowPart = ComPortBase;
|
||||||
|
ResourceDescriptor->u.Port.Length = 8;
|
||||||
|
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypeInterrupt;
|
ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDriverExclusive;
|
ResourceDescriptor->Type = CmResourceTypeInterrupt;
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[1].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
ResourceDescriptor->ShareDisposition = CmResourceShareShared;
|
||||||
/* FIXME: ResourceList->List[0].PartialResourceList.PartialDescriptors[1].u.Interrupt.Level = ;
|
ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[1].u.Interrupt.Vector = ;
|
ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(
|
||||||
ResourceList->List[0].PartialResourceList.PartialDescriptors[1].u.Interrupt.Affinity = ;*/
|
Internal, 0, 0, Irq,
|
||||||
|
&Dirql,
|
||||||
|
&ResourceDescriptor->u.Interrupt.Affinity);
|
||||||
|
ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
|
||||||
|
|
||||||
/* Report resource list */
|
/* Report resource list */
|
||||||
Status = IoReportResourceForDetection(
|
Status = IoReportResourceForDetection(
|
||||||
|
@ -125,7 +134,15 @@ DetectLegacyDevice(
|
||||||
ResourceList->List[0].InterfaceType, ResourceList->List[0].BusNumber, -1/*FIXME*/,
|
ResourceList->List[0].InterfaceType, ResourceList->List[0].BusNumber, -1/*FIXME*/,
|
||||||
ResourceList, NULL,
|
ResourceList, NULL,
|
||||||
TRUE,
|
TRUE,
|
||||||
NULL);
|
&Pdo);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = SerialAddDeviceInternal(DriverObject, Pdo, &Fdo);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = SerialPnpStartDevice(Fdo, ResourceList);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -143,20 +160,19 @@ NTSTATUS
|
||||||
DetectLegacyDevices(
|
DetectLegacyDevices(
|
||||||
IN PDRIVER_OBJECT DriverObject)
|
IN PDRIVER_OBJECT DriverObject)
|
||||||
{
|
{
|
||||||
ULONG ComPortBase[] = { 0x3f8, 0x2f8 };
|
ULONG ComPortBase[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||||
ULONG Irq[] = { 4, 3 };
|
ULONG Irq[] = { 4, 3, 4, 3 };
|
||||||
ULONG i;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
NTSTATUS ReturnedStatus = STATUS_SUCCESS;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(ComPortBase)/sizeof(ComPortBase[0]); i++)
|
for (i = 0; i < sizeof(ComPortBase)/sizeof(ComPortBase[0]); i++)
|
||||||
{
|
{
|
||||||
Status = DetectLegacyDevice(DriverObject, ComPortBase[i], Irq[i]);
|
Status = DetectLegacyDevice(DriverObject, ComPortBase[i], Irq[i]);
|
||||||
DPRINT("Serial: Legacy device at 0x%x (IRQ %lu): status = 0x%08x\n", ComPortBase[i], Irq[i], Status);
|
if (!NT_SUCCESS(Status) && Status != STATUS_DEVICE_NOT_CONNECTED)
|
||||||
if (Status == STATUS_DEVICE_NOT_CONNECTED)
|
ReturnedStatus = Status;
|
||||||
Status = STATUS_SUCCESS;
|
DPRINT("Serial: Legacy device at 0x%x (IRQ %lu): status = 0x%08lx\n", ComPortBase[i], Irq[i], Status);
|
||||||
else if (!NT_SUCCESS(Status))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return ReturnedStatus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,10 @@
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
SerialAddDevice(
|
SerialAddDeviceInternal(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDEVICE_OBJECT Pdo)
|
IN PDEVICE_OBJECT Pdo,
|
||||||
|
OUT PDEVICE_OBJECT* pFdo OPTIONAL)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT Fdo = NULL;
|
PDEVICE_OBJECT Fdo = NULL;
|
||||||
PSERIAL_DEVICE_EXTENSION DeviceExtension = NULL;
|
PSERIAL_DEVICE_EXTENSION DeviceExtension = NULL;
|
||||||
|
@ -26,7 +27,7 @@ SerialAddDevice(
|
||||||
//UNICODE_STRING SymbolicLinkName;
|
//UNICODE_STRING SymbolicLinkName;
|
||||||
static ULONG DeviceNumber = 0;
|
static ULONG DeviceNumber = 0;
|
||||||
|
|
||||||
DPRINT("Serial: SerialAddDevice called\n");
|
DPRINT("Serial: SerialAddDeviceInternal called\n");
|
||||||
|
|
||||||
/* Create new device object */
|
/* Create new device object */
|
||||||
swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceNumber);
|
swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceNumber);
|
||||||
|
@ -81,6 +82,10 @@ SerialAddDevice(
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
}
|
}
|
||||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
if (pFdo)
|
||||||
|
{
|
||||||
|
*pFdo = Fdo;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -94,13 +99,35 @@ ByeBye:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
SerialAddDevice(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PDEVICE_OBJECT Pdo)
|
||||||
|
{
|
||||||
|
/* Serial.sys is a legacy driver. AddDevice is called once
|
||||||
|
* with a NULL Pdo just after the driver initialization.
|
||||||
|
* Detect this case and return success.
|
||||||
|
*/
|
||||||
|
if (Pdo == NULL)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* 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, NULL);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
SerialPnpStartDevice(
|
SerialPnpStartDevice(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PCM_RESOURCE_LIST ResourceList)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack;
|
|
||||||
//PCM_RESOURCE_LIST ResourceList;
|
|
||||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||||
WCHAR DeviceNameBuffer[32];
|
WCHAR DeviceNameBuffer[32];
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
|
@ -108,16 +135,17 @@ SerialPnpStartDevice(
|
||||||
UNICODE_STRING LinkName;
|
UNICODE_STRING LinkName;
|
||||||
WCHAR ComPortBuffer[32];
|
WCHAR ComPortBuffer[32];
|
||||||
UNICODE_STRING ComPort;
|
UNICODE_STRING ComPort;
|
||||||
ULONG Vector;
|
ULONG Vector = 0;
|
||||||
//ULONG i, j;
|
ULONG i, j;
|
||||||
KIRQL Dirql;
|
KIRQL Dirql;
|
||||||
KAFFINITY Affinity;
|
KAFFINITY Affinity;
|
||||||
|
KINTERRUPT_MODE InterruptMode = Latched;
|
||||||
|
BOOLEAN ShareInterrupt = TRUE;
|
||||||
OBJECT_ATTRIBUTES objectAttributes;
|
OBJECT_ATTRIBUTES objectAttributes;
|
||||||
UNICODE_STRING KeyName;
|
UNICODE_STRING KeyName;
|
||||||
HANDLE hKey;
|
HANDLE hKey;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
/* FIXME: actually, IRP_MN_START_DEVICE is sent twice to each serial device:
|
/* FIXME: actually, IRP_MN_START_DEVICE is sent twice to each serial device:
|
||||||
|
@ -128,66 +156,47 @@ SerialPnpStartDevice(
|
||||||
*/
|
*/
|
||||||
if (DeviceExtension->PnpState == dsStarted) return STATUS_SUCCESS;
|
if (DeviceExtension->PnpState == dsStarted) return STATUS_SUCCESS;
|
||||||
|
|
||||||
#if 1
|
DeviceExtension->ComPort = DeviceExtension->SerialPortNumber + 1;
|
||||||
/* FIXME: PnP isn't correctly implemented and doesn't give us a list
|
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
||||||
* of our own resources. Use default values instead.
|
DeviceExtension->BaseAddress = 0;
|
||||||
*/
|
Dirql = 0;
|
||||||
switch (DeviceExtension->SerialPortNumber)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
DPRINT("Serial: creating COM1:\n");
|
|
||||||
DeviceExtension->ComPort = 1;
|
|
||||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
|
||||||
DeviceExtension->BaseAddress = 0x3F8;
|
|
||||||
DeviceExtension->Irq = 4;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
DPRINT("Serial: creating COM2:\n");
|
|
||||||
DeviceExtension->ComPort = 2;
|
|
||||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
|
||||||
DeviceExtension->BaseAddress = 0x2F8;
|
|
||||||
DeviceExtension->Irq = 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DPRINT1("Serial: too much ports detected. Forgetting this one...\n");
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
DPRINT1("Serial: ResourceList %p, ResourceListTranslated %p\n",
|
|
||||||
Stack->Parameters.StartDevice.AllocatedResources,
|
|
||||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
|
||||||
ResourceList = Stack->Parameters.StartDevice.AllocatedResourcesTranslated;
|
|
||||||
for (i = 0; i < ResourceList->Count; i++)
|
for (i = 0; i < ResourceList->Count; i++)
|
||||||
{
|
{
|
||||||
DPRINT1("Serial: Interface type = 0x%x\n", ResourceList->List[i].InterfaceType);
|
for (j = 0; j < ResourceList->List[i].PartialResourceList.Count; j++)
|
||||||
DPRINT1("Serial: Bus number = 0x%x\n", ResourceList->List[i].BusNumber);
|
|
||||||
for (j = 0; i < ResourceList->List[i].PartialResourceList.Count; j++)
|
|
||||||
{
|
{
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[i].PartialResourceList.PartialDescriptors[j];
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[i].PartialResourceList.PartialDescriptors[j];
|
||||||
DPRINT1("Serial: Type 0x%x, Share disposition 0x%x, Flags 0x%x\n",
|
|
||||||
PartialDescriptor->Type,
|
|
||||||
PartialDescriptor->ShareDisposition,
|
|
||||||
PartialDescriptor->Flags);
|
|
||||||
switch (PartialDescriptor->Type)
|
switch (PartialDescriptor->Type)
|
||||||
{
|
{
|
||||||
case CmResourceTypePort:
|
case CmResourceTypePort:
|
||||||
|
if (PartialDescriptor->u.Port.Length < 8)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
if (DeviceExtension->BaseAddress != 0)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
||||||
DPRINT1("Serial: CmResourceTypePort = %lu\n", DeviceExtension->BaseAddress);
|
|
||||||
break;
|
break;
|
||||||
case CmResourceTypeInterrupt:
|
case CmResourceTypeInterrupt:
|
||||||
/* FIXME: Detect if interrupt is shareable and/or latched */
|
if (Dirql != 0)
|
||||||
/* FIXME: use also ->u.Interrupt.Vector and ->u.Interrupt.Affinity
|
return STATUS_UNSUCCESSFUL;
|
||||||
* to remove call to HalGetInterruptVector(...) */
|
Dirql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
|
||||||
DeviceExtension->Irq = PartialDescriptor->u.Interrupt.Level;
|
Vector = PartialDescriptor->u.Interrupt.Vector;
|
||||||
DPRINT1("Serial: Irq = %lu\n", DeviceExtension->Irq);
|
Affinity = PartialDescriptor->u.Interrupt.Affinity;
|
||||||
|
if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
|
||||||
|
InterruptMode = Latched;
|
||||||
|
else
|
||||||
|
InterruptMode = LevelSensitive;
|
||||||
|
ShareInterrupt = (PartialDescriptor->ShareDisposition == CmResourceShareShared);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
|
DPRINT("Serial: New COM port. Base = 0x%lx, Irql = %u\n",
|
||||||
/* FIXME: use polling if no interrupt was found? */
|
DeviceExtension->BaseAddress, Dirql);
|
||||||
DeviceExtension->ComPort = 5; /* FIXME: use incremental value, or find it in resource list */
|
if (!DeviceExtension->BaseAddress)
|
||||||
#endif
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
/* FIXME: we should be able to continue and use polling method
|
||||||
|
* for read/write if we don't have an interrupt */
|
||||||
|
if (!Dirql)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
/* Get current settings */
|
/* Get current settings */
|
||||||
DeviceExtension->IER = READ_PORT_UCHAR(SER_IER((PUCHAR)DeviceExtension->BaseAddress));
|
DeviceExtension->IER = READ_PORT_UCHAR(SER_IER((PUCHAR)DeviceExtension->BaseAddress));
|
||||||
|
@ -229,11 +238,11 @@ SerialPnpStartDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect interrupt and enable them */
|
/* Connect interrupt and enable them */
|
||||||
Vector = HalGetInterruptVector(Internal, 0, 0, DeviceExtension->Irq, &Dirql, &Affinity);
|
|
||||||
Status = IoConnectInterrupt(
|
Status = IoConnectInterrupt(
|
||||||
&DeviceExtension->Interrupt, SerialInterruptService,
|
&DeviceExtension->Interrupt, SerialInterruptService,
|
||||||
DeviceObject, NULL, Vector, Dirql, Dirql, Latched,
|
DeviceObject, NULL,
|
||||||
FALSE /* FIXME: or TRUE to share interrupt on PCI bus? */,
|
Vector, Dirql, Dirql,
|
||||||
|
InterruptMode, ShareInterrupt,
|
||||||
Affinity, FALSE);
|
Affinity, FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -288,7 +297,9 @@ SerialPnp(
|
||||||
/* Call lower driver */
|
/* Call lower driver */
|
||||||
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = SerialPnpStartDevice(DeviceObject, Irp);
|
Status = SerialPnpStartDevice(
|
||||||
|
DeviceObject,
|
||||||
|
Stack->Parameters.StartDevice.AllocatedResources);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* IRP_MN_QUERY_STOP_DEVICE (FIXME: required) */
|
/* IRP_MN_QUERY_STOP_DEVICE (FIXME: required) */
|
||||||
|
|
|
@ -70,7 +70,6 @@ typedef struct _SERIAL_DEVICE_EXTENSION
|
||||||
ULONG ComPort;
|
ULONG ComPort;
|
||||||
ULONG BaudRate;
|
ULONG BaudRate;
|
||||||
ULONG BaseAddress;
|
ULONG BaseAddress;
|
||||||
ULONG Irq;
|
|
||||||
PKINTERRUPT Interrupt;
|
PKINTERRUPT Interrupt;
|
||||||
|
|
||||||
SERIAL_LINE_CONTROL SerialLineControl;
|
SERIAL_LINE_CONTROL SerialLineControl;
|
||||||
|
@ -234,11 +233,22 @@ SerialInterruptService(
|
||||||
|
|
||||||
/************************************ pnp.c */
|
/************************************ pnp.c */
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
SerialAddDeviceInternal(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PDEVICE_OBJECT Pdo,
|
||||||
|
OUT PDEVICE_OBJECT* pFdo OPTIONAL);
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
SerialAddDevice(
|
SerialAddDevice(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDEVICE_OBJECT Pdo);
|
IN PDEVICE_OBJECT Pdo);
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
SerialPnpStartDevice(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PCM_RESOURCE_LIST ResourceList);
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
SerialPnp(
|
SerialPnp(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
Loading…
Reference in a new issue