mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 09:50:02 +00:00
Don't try to detect serial ports at known I/O addresses. They have to be written in registry and enumerated by Root bus enumerator.
Get interrupt informations from AllocatedResourcesTranslated in IRP_MN_START_DEVICE svn path=/trunk/; revision=15695
This commit is contained in:
parent
907751c162
commit
eddf35ba2a
4 changed files with 7 additions and 166 deletions
|
@ -73,157 +73,3 @@ SerialDetectUartType(
|
||||||
/* FIFO is only functional for 16550A+ */
|
/* FIFO is only functional for 16550A+ */
|
||||||
return Uart16550A;
|
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_RESOURCE_LIST ResourceListTranslated;
|
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
|
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptorTranslated;
|
|
||||||
BOOLEAN ConflictDetected;
|
|
||||||
UART_TYPE UartType;
|
|
||||||
PDEVICE_OBJECT Pdo = NULL;
|
|
||||||
PDEVICE_OBJECT Fdo;
|
|
||||||
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;
|
|
||||||
ResourceListTranslated = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
|
|
||||||
if (!ResourceListTranslated)
|
|
||||||
{
|
|
||||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Resource header */
|
|
||||||
ResourceList->Count = ResourceListTranslated->Count
|
|
||||||
= 1;
|
|
||||||
ResourceList->List[0].InterfaceType = ResourceListTranslated->List[0].InterfaceType
|
|
||||||
= InterfaceTypeUndefined;
|
|
||||||
ResourceList->List[0].BusNumber = ResourceListTranslated->List[0].BusNumber
|
|
||||||
= -1; /* unknown */
|
|
||||||
ResourceList->List[0].PartialResourceList.Version = ResourceListTranslated->List[0].PartialResourceList.Version
|
|
||||||
= 1;
|
|
||||||
ResourceList->List[0].PartialResourceList.Revision = ResourceListTranslated->List[0].PartialResourceList.Revision
|
|
||||||
= 1;
|
|
||||||
ResourceList->List[0].PartialResourceList.Count = ResourceListTranslated->List[0].PartialResourceList.Count
|
|
||||||
= 2;
|
|
||||||
|
|
||||||
/* I/O port */
|
|
||||||
ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
|
|
||||||
ResourceDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[0];
|
|
||||||
ResourceDescriptor->Type = ResourceDescriptorTranslated->Type
|
|
||||||
= CmResourceTypePort;
|
|
||||||
ResourceDescriptor->ShareDisposition = ResourceDescriptorTranslated->ShareDisposition
|
|
||||||
= CmResourceShareDriverExclusive;
|
|
||||||
ResourceDescriptor->Flags = ResourceDescriptorTranslated->Flags
|
|
||||||
= CM_RESOURCE_PORT_IO;
|
|
||||||
ResourceDescriptor->u.Port.Start.u.HighPart = ResourceDescriptorTranslated->u.Port.Start.u.HighPart
|
|
||||||
= 0;
|
|
||||||
ResourceDescriptor->u.Port.Start.u.LowPart = ResourceDescriptorTranslated->u.Port.Start.u.LowPart
|
|
||||||
= ComPortBase;
|
|
||||||
ResourceDescriptor->u.Port.Length = ResourceDescriptorTranslated->u.Port.Length
|
|
||||||
= 8;
|
|
||||||
|
|
||||||
ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];
|
|
||||||
ResourceDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[1];
|
|
||||||
ResourceDescriptor->Type = ResourceDescriptorTranslated->Type
|
|
||||||
= CmResourceTypeInterrupt;
|
|
||||||
ResourceDescriptor->ShareDisposition = ResourceDescriptorTranslated->ShareDisposition
|
|
||||||
= CmResourceShareShared;
|
|
||||||
ResourceDescriptor->Flags = ResourceDescriptorTranslated->Flags
|
|
||||||
= CM_RESOURCE_INTERRUPT_LATCHED;
|
|
||||||
ResourceDescriptor->u.Interrupt.Level = Irq;
|
|
||||||
ResourceDescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
|
|
||||||
ResourceList->List[0].InterfaceType,
|
|
||||||
ResourceList->List[0].BusNumber,
|
|
||||||
ResourceDescriptor->u.Interrupt.Level,
|
|
||||||
ResourceDescriptor->u.Interrupt.Vector,
|
|
||||||
(PKIRQL)&ResourceDescriptorTranslated->u.Interrupt.Level,
|
|
||||||
&ResourceDescriptor->u.Interrupt.Affinity);
|
|
||||||
ResourceDescriptorTranslated->u.Interrupt.Affinity = ResourceDescriptor->u.Interrupt.Affinity;
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
|
|
||||||
return STATUS_DEVICE_NOT_CONNECTED;
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
|
||||||
ExFreePoolWithTag(ResourceListTranslated, 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, ResourceListTranslated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Release resources */
|
|
||||||
Status = IoReportResourceForDetection(
|
|
||||||
DriverObject, NULL, 0,
|
|
||||||
NULL, NULL, 0,
|
|
||||||
&ConflictDetected);
|
|
||||||
Status = STATUS_DEVICE_NOT_CONNECTED;
|
|
||||||
}
|
|
||||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
|
||||||
ExFreePoolWithTag(ResourceListTranslated, 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -163,6 +163,7 @@ SerialPnpStartDevice(
|
||||||
for (j = 0; j < ResourceList->List[i].PartialResourceList.Count; j++)
|
for (j = 0; j < 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];
|
||||||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated = &ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
|
||||||
switch (PartialDescriptor->Type)
|
switch (PartialDescriptor->Type)
|
||||||
{
|
{
|
||||||
case CmResourceTypePort:
|
case CmResourceTypePort:
|
||||||
|
@ -173,16 +174,14 @@ SerialPnpStartDevice(
|
||||||
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
||||||
break;
|
break;
|
||||||
case CmResourceTypeInterrupt:
|
case CmResourceTypeInterrupt:
|
||||||
if (Dirql != 0)
|
Dirql = (KIRQL)PartialDescriptorTranslated->u.Interrupt.Level;
|
||||||
return STATUS_UNSUCCESSFUL;
|
Vector = PartialDescriptorTranslated->u.Interrupt.Vector;
|
||||||
Dirql = (KIRQL)ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Level;
|
Affinity = PartialDescriptorTranslated->u.Interrupt.Affinity;
|
||||||
Vector = ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Vector;
|
if (PartialDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
|
||||||
Affinity = PartialDescriptor->u.Interrupt.Affinity;
|
|
||||||
if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
|
|
||||||
InterruptMode = Latched;
|
InterruptMode = Latched;
|
||||||
else
|
else
|
||||||
InterruptMode = LevelSensitive;
|
InterruptMode = LevelSensitive;
|
||||||
ShareInterrupt = (PartialDescriptor->ShareDisposition == CmResourceShareShared);
|
ShareInterrupt = (PartialDescriptorTranslated->ShareDisposition == CmResourceShareShared);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,5 +42,5 @@ DriverEntry(
|
||||||
DriverObject->MajorFunction[IRP_MJ_PNP] = SerialPnp;
|
DriverObject->MajorFunction[IRP_MJ_PNP] = SerialPnp;
|
||||||
DriverObject->MajorFunction[IRP_MJ_POWER] = SerialPower;
|
DriverObject->MajorFunction[IRP_MJ_POWER] = SerialPower;
|
||||||
|
|
||||||
return DetectLegacyDevices(DriverObject);
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,10 +274,6 @@ UART_TYPE
|
||||||
SerialDetectUartType(
|
SerialDetectUartType(
|
||||||
IN PUCHAR ComPortBase);
|
IN PUCHAR ComPortBase);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
DetectLegacyDevices(
|
|
||||||
IN PDRIVER_OBJECT DriverObject);
|
|
||||||
|
|
||||||
/************************************ misc.c */
|
/************************************ misc.c */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue