Use translated resources list to get informations about interrupt

svn path=/trunk/; revision=15401
This commit is contained in:
Hervé Poussineau 2005-05-18 21:48:41 +00:00
parent 3d90c8bdad
commit 3e43a2215b
3 changed files with 68 additions and 37 deletions

View file

@ -83,12 +83,13 @@ DetectLegacyDevice(
{ {
ULONG ResourceListSize; ULONG ResourceListSize;
PCM_RESOURCE_LIST ResourceList; PCM_RESOURCE_LIST ResourceList;
PCM_RESOURCE_LIST ResourceListTranslated;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptorTranslated;
BOOLEAN ConflictDetected; BOOLEAN ConflictDetected;
UART_TYPE UartType; UART_TYPE UartType;
PDEVICE_OBJECT Pdo = NULL; PDEVICE_OBJECT Pdo = NULL;
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo;
KIRQL Dirql;
NTSTATUS Status; NTSTATUS Status;
/* Create resource list */ /* Create resource list */
@ -96,29 +97,60 @@ DetectLegacyDevice(
ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG); ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
if (!ResourceList) if (!ResourceList)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
ResourceList->Count = 1; ResourceListTranslated = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
ResourceList->List[0].InterfaceType = InterfaceTypeUndefined; if (!ResourceListTranslated)
ResourceList->List[0].BusNumber = -1; /* unknown */ {
ResourceList->List[0].PartialResourceList.Version = 1; ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ResourceList->List[0].PartialResourceList.Revision = 1; return STATUS_INSUFFICIENT_RESOURCES;
ResourceList->List[0].PartialResourceList.Count = 2; }
/* 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 = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
ResourceDescriptor->Type = CmResourceTypePort; ResourceDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[0];
ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive; ResourceDescriptor->Type = ResourceDescriptorTranslated->Type
ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; = CmResourceTypePort;
ResourceDescriptor->u.Port.Start.u.HighPart = 0; ResourceDescriptor->ShareDisposition = ResourceDescriptorTranslated->ShareDisposition
ResourceDescriptor->u.Port.Start.u.LowPart = ComPortBase; = CmResourceShareDriverExclusive;
ResourceDescriptor->u.Port.Length = 8; 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 = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];
ResourceDescriptor->Type = CmResourceTypeInterrupt; ResourceDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[1];
ResourceDescriptor->ShareDisposition = CmResourceShareShared; ResourceDescriptor->Type = ResourceDescriptorTranslated->Type
ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; = CmResourceTypeInterrupt;
ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector( ResourceDescriptor->ShareDisposition = ResourceDescriptorTranslated->ShareDisposition
Internal, 0, 0, Irq, = CmResourceShareShared;
&Dirql, 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.Affinity);
ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql; ResourceDescriptorTranslated->u.Interrupt.Affinity = ResourceDescriptor->u.Interrupt.Affinity;
/* Report resource list */ /* Report resource list */
Status = IoReportResourceForDetection( Status = IoReportResourceForDetection(
@ -129,11 +161,13 @@ DetectLegacyDevice(
{ {
DPRINT("Serial: conflict detected for serial port at 0x%lx (Irq %lu)\n", ComPortBase, Irq); DPRINT("Serial: conflict detected for serial port at 0x%lx (Irq %lu)\n", ComPortBase, Irq);
ExFreePoolWithTag(ResourceList, SERIAL_TAG); ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
return STATUS_DEVICE_NOT_CONNECTED; return STATUS_DEVICE_NOT_CONNECTED;
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ExFreePoolWithTag(ResourceList, SERIAL_TAG); ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
return Status; return Status;
} }
@ -154,7 +188,7 @@ DetectLegacyDevice(
Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo); Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Status = SerialPnpStartDevice(Fdo, ResourceList); Status = SerialPnpStartDevice(Fdo, ResourceList, ResourceListTranslated);
} }
} }
} }
@ -168,6 +202,7 @@ DetectLegacyDevice(
Status = STATUS_DEVICE_NOT_CONNECTED; Status = STATUS_DEVICE_NOT_CONNECTED;
} }
ExFreePoolWithTag(ResourceList, SERIAL_TAG); ExFreePoolWithTag(ResourceList, SERIAL_TAG);
ExFreePoolWithTag(ResourceListTranslated, SERIAL_TAG);
return Status; return Status;
} }

View file

@ -126,7 +126,8 @@ SerialAddDevice(
NTSTATUS STDCALL NTSTATUS STDCALL
SerialPnpStartDevice( SerialPnpStartDevice(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PCM_RESOURCE_LIST ResourceList) IN PCM_RESOURCE_LIST ResourceList,
IN PCM_RESOURCE_LIST ResourceListTranslated)
{ {
PSERIAL_DEVICE_EXTENSION DeviceExtension; PSERIAL_DEVICE_EXTENSION DeviceExtension;
WCHAR DeviceNameBuffer[32]; WCHAR DeviceNameBuffer[32];
@ -174,8 +175,8 @@ SerialPnpStartDevice(
case CmResourceTypeInterrupt: case CmResourceTypeInterrupt:
if (Dirql != 0) if (Dirql != 0)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
Dirql = (KIRQL)PartialDescriptor->u.Interrupt.Level; Dirql = (KIRQL)ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Level;
Vector = PartialDescriptor->u.Interrupt.Vector; Vector = ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j].u.Interrupt.Vector;
Affinity = PartialDescriptor->u.Interrupt.Affinity; Affinity = PartialDescriptor->u.Interrupt.Affinity;
if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
InterruptMode = Latched; InterruptMode = Latched;
@ -338,16 +339,9 @@ SerialPnp(
BOOLEAN ConflictDetected; BOOLEAN ConflictDetected;
DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
/* FIXME: first HACK: PnP manager can send multiple ASSERT(((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState == dsStopped);
* IRP_MN_START_DEVICE for one device
*/ /* FIXME: HACK: verify that we have some allocated resources.
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.
* It seems not to be always the case on some hardware * It seems not to be always the case on some hardware
*/ */
if (Stack->Parameters.StartDevice.AllocatedResources == NULL) if (Stack->Parameters.StartDevice.AllocatedResources == NULL)
@ -357,7 +351,7 @@ SerialPnp(
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
break; 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 * because PnP manager doesn't do it automatically
*/ */
Status = IoReportResourceForDetection( Status = IoReportResourceForDetection(
@ -377,7 +371,8 @@ SerialPnp(
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
Status = SerialPnpStartDevice( Status = SerialPnpStartDevice(
DeviceObject, DeviceObject,
Stack->Parameters.StartDevice.AllocatedResources); Stack->Parameters.StartDevice.AllocatedResources,
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
break; break;
} }
case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */ case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */

View file

@ -327,7 +327,8 @@ SerialAddDevice(
NTSTATUS STDCALL NTSTATUS STDCALL
SerialPnpStartDevice( SerialPnpStartDevice(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PCM_RESOURCE_LIST ResourceList); IN PCM_RESOURCE_LIST ResourceList,
IN PCM_RESOURCE_LIST ResourceListTranslated);
NTSTATUS STDCALL NTSTATUS STDCALL
SerialPnp( SerialPnp(