mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Use translated resources list to get informations about interrupt
svn path=/trunk/; revision=15401
This commit is contained in:
parent
3d90c8bdad
commit
3e43a2215b
3 changed files with 68 additions and 37 deletions
|
@ -83,12 +83,13 @@ DetectLegacyDevice(
|
|||
{
|
||||
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;
|
||||
KIRQL Dirql;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Create resource list */
|
||||
|
@ -96,29 +97,60 @@ DetectLegacyDevice(
|
|||
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;
|
||||
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];
|
||||
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;
|
||||
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];
|
||||
ResourceDescriptor->Type = CmResourceTypeInterrupt;
|
||||
ResourceDescriptor->ShareDisposition = CmResourceShareShared;
|
||||
ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
||||
ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(
|
||||
Internal, 0, 0, Irq,
|
||||
&Dirql,
|
||||
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);
|
||||
ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
|
||||
ResourceDescriptorTranslated->u.Interrupt.Affinity = ResourceDescriptor->u.Interrupt.Affinity;
|
||||
|
||||
/* Report resource list */
|
||||
Status = IoReportResourceForDetection(
|
||||
|
@ -129,11 +161,13 @@ DetectLegacyDevice(
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -154,7 +188,7 @@ DetectLegacyDevice(
|
|||
Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = SerialPnpStartDevice(Fdo, ResourceList);
|
||||
Status = SerialPnpStartDevice(Fdo, ResourceList, ResourceListTranslated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +202,7 @@ DetectLegacyDevice(
|
|||
Status = STATUS_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
ExFreePoolWithTag(ResourceList, SERIAL_TAG);
|
||||
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,8 @@ SerialAddDevice(
|
|||
NTSTATUS STDCALL
|
||||
SerialPnpStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PCM_RESOURCE_LIST ResourceList)
|
||||
IN PCM_RESOURCE_LIST ResourceList,
|
||||
IN PCM_RESOURCE_LIST ResourceListTranslated)
|
||||
{
|
||||
PSERIAL_DEVICE_EXTENSION DeviceExtension;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
|
@ -174,8 +175,8 @@ SerialPnpStartDevice(
|
|||
case CmResourceTypeInterrupt:
|
||||
if (Dirql != 0)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Dirql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
|
||||
Vector = PartialDescriptor->u.Interrupt.Vector;
|
||||
Dirql = (KIRQL)ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Level;
|
||||
Vector = ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Vector;
|
||||
Affinity = PartialDescriptor->u.Interrupt.Affinity;
|
||||
if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
|
||||
InterruptMode = Latched;
|
||||
|
@ -338,16 +339,9 @@ SerialPnp(
|
|||
BOOLEAN ConflictDetected;
|
||||
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
|
||||
/* FIXME: first HACK: PnP manager can send multiple
|
||||
* IRP_MN_START_DEVICE for one device
|
||||
*/
|
||||
if (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState != dsStopped)
|
||||
{
|
||||
DPRINT1("Serial: device already started. Ignoring this irp!\n");
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
/* FIXME: second HACK: verify that we have some allocated resources.
|
||||
ASSERT(((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState == dsStopped);
|
||||
|
||||
/* FIXME: HACK: verify that we have some allocated resources.
|
||||
* It seems not to be always the case on some hardware
|
||||
*/
|
||||
if (Stack->Parameters.StartDevice.AllocatedResources == NULL)
|
||||
|
@ -357,7 +351,7 @@ SerialPnp(
|
|||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
/* FIXME: third HACK: verify that we don't have resource conflict,
|
||||
/* FIXME: HACK: verify that we don't have resource conflict,
|
||||
* because PnP manager doesn't do it automatically
|
||||
*/
|
||||
Status = IoReportResourceForDetection(
|
||||
|
@ -377,7 +371,8 @@ SerialPnp(
|
|||
if (NT_SUCCESS(Status))
|
||||
Status = SerialPnpStartDevice(
|
||||
DeviceObject,
|
||||
Stack->Parameters.StartDevice.AllocatedResources);
|
||||
Stack->Parameters.StartDevice.AllocatedResources,
|
||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
|
||||
|
|
|
@ -327,7 +327,8 @@ SerialAddDevice(
|
|||
NTSTATUS STDCALL
|
||||
SerialPnpStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PCM_RESOURCE_LIST ResourceList);
|
||||
IN PCM_RESOURCE_LIST ResourceList,
|
||||
IN PCM_RESOURCE_LIST ResourceListTranslated);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
SerialPnp(
|
||||
|
|
Loading…
Reference in a new issue