Implement IRP_MN_QUERY_RESOURCES (Irq, IO ports, DMA) Modified: trunk/reactos/drivers/bus/acpi/ospm/fdo.c Modified: trunk/reactos/drivers/bus/acpi/ospm/include/acpisys.h Modified: trunk/reactos/drivers/bus/acpi/ospm/pdo.c _____
Modified: trunk/reactos/drivers/bus/acpi/ospm/fdo.c --- trunk/reactos/drivers/bus/acpi/ospm/fdo.c 2005-04-05 05:12:16 UTC (rev 14498) +++ trunk/reactos/drivers/bus/acpi/ospm/fdo.c 2005-04-05 12:00:13 UTC (rev 14499) @@ -4,6 +4,7 @@
* FILE: acpi/ospm/fdo.c * PURPOSE: ACPI device object dispatch routines * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * HervÚ Poussineau (hpoussin@reactos.com) * UPDATE HISTORY: * 08-08-2001 CSH Created */ @@ -115,6 +116,149 @@ }
+static BOOLEAN +AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList, + PULONG ResourceListSize, + RESOURCE* resources) +{ + BOOLEAN Done; + ULONG NumberOfResources = 0; + PCM_RESOURCE_LIST ResourceList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; + RESOURCE* resource; + ULONG i; + KIRQL Dirql; + + /* Count number of resources */ + Done = FALSE; + resource = resources; + while (!Done) + { + switch (resource->id) + { + case irq: + { + IRQ_RESOURCE *irq_data = (IRQ_RESOURCE*) &resource->data; + NumberOfResources += irq_data->number_of_interrupts; + break; + } + case dma: + { + DMA_RESOURCE *dma_data = (DMA_RESOURCE*) &resource->data; + NumberOfResources += dma_data->number_of_channels; + break; + } + case io: + { + NumberOfResources++; + break; + } + case end_tag: + { + Done = TRUE; + break; + } + } + resource = (RESOURCE *) ((NATIVE_UINT) resource + (NATIVE_UINT) resource->length); + } + + /* Allocate memory */ + *ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1); + ResourceList = (PCM_RESOURCE_LIST)ExAllocatePool(PagedPool, *ResourceListSize); + *pResourceList = ResourceList; + if (!ResourceList) + return FALSE; + ResourceList->Count = 1; + ResourceList->List[0].InterfaceType = Internal; /* FIXME */ + ResourceList->List[0].BusNumber = 0; /* We're the only ACPI bus device in the system */ + ResourceList->List[0].PartialResourceList.Version = 1; + ResourceList->List[0].PartialResourceList.Revision = 1; + ResourceList->List[0].PartialResourceList.Count = NumberOfResources; + ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; + + /* Fill resources list structure */ + Done = FALSE; + resource = resources; + while (!Done) + { + switch (resource->id) + { + case irq: + { + IRQ_RESOURCE *irq_data = (IRQ_RESOURCE*) &resource->data; + for (i = 0; i < irq_data->number_of_interrupts; i++) + { + ResourceDescriptor->Type = CmResourceTypeInterrupt; + + ResourceDescriptor->ShareDisposition = + (irq_data->shared_exclusive == SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); + ResourceDescriptor->Flags = + (irq_data->edge_level == LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); + ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector( + Internal, 0, 0, irq_data->interrupts[i], + &Dirql, + &ResourceDescriptor->u.Interrupt.Affinity); + ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql; + ResourceDescriptor++; + } + break; + } + case dma: + { + DMA_RESOURCE *dma_data = (DMA_RESOURCE*) &resource->data; + for (i = 0; i < dma_data->number_of_channels; i++) + { + ResourceDescriptor->Type = CmResourceTypeDma; + ResourceDescriptor->Flags = 0; + switch (dma_data->type) + { + case TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; + case TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; + case TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; + } + if (dma_data->bus_master == BUS_MASTER) + ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; + switch (dma_data->transfer) + { + case TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break; + case TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break; + case TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; + } + ResourceDescriptor->u.Dma.Channel = dma_data->channels[i]; + ResourceDescriptor++; + } + break; + } + case io: + { + IO_RESOURCE *io_data = (IO_RESOURCE*) &resource->data; + ResourceDescriptor->Type = CmResourceTypePort; + ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive; + ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; + if (io_data->io_decode == DECODE_16) + ResourceDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE; + else + ResourceDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE; + ResourceDescriptor->u.Port.Start.u.HighPart = 0; + ResourceDescriptor->u.Port.Start.u.LowPart = io_data->min_base_address; + ResourceDescriptor->u.Port.Length = io_data->range_length; + ResourceDescriptor++; + break; + } + case end_tag: + { + Done = TRUE; + break; + } + } + resource = (RESOURCE *) ((NATIVE_UINT) resource + (NATIVE_UINT) resource->length); + } + + acpi_rs_dump_resource_list(resource); + return TRUE; +} + + static NTSTATUS FdoQueryBusRelations( IN PDEVICE_OBJECT DeviceObject, @@ -149,6 +293,7 @@ CurrentEntry = DeviceExtension->DeviceListHead.Flink; while (CurrentEntry != &DeviceExtension->DeviceListHead) { + ACPI_BUFFER Buffer; Device = CONTAINING_RECORD(CurrentEntry, ACPI_DEVICE, DeviceListEntry);
/* FIXME: For ACPI namespace devices on the motherboard create filter DOs @@ -200,6 +345,34 @@ AcpiStatus = bm_get_node(Device->BmHandle, 0, &Node); if (ACPI_SUCCESS(AcpiStatus)) { + /* Get current resources */ + Buffer.length = 0; + Status = acpi_get_current_resources(Node->device.acpi_handle, &Buffer); + if ((Status & ACPI_OK) == 0) + { + ASSERT(FALSE); + } + if (Buffer.length > 0) + { + Buffer.pointer = ExAllocatePool(PagedPool, Buffer.length); + if (!Buffer.pointer) + { + ASSERT(FALSE); + } + Status = acpi_get_current_resources(Node->device.acpi_handle, &Buffer); + if (ACPI_FAILURE(Status)) + { + ASSERT(FALSE); + } + if (!AcpiCreateResourceList(&PdoDeviceExtension->ResourceList, + &PdoDeviceExtension->ResourceListSize, + (RESOURCE*)Buffer.pointer)) + { + ASSERT(FALSE); + } + ExFreePool(Buffer.pointer); + } + /* Add Device ID string */ if (!AcpiCreateDeviceIDString(&PdoDeviceExtension->DeviceID, Node)) _____
Modified: trunk/reactos/drivers/bus/acpi/ospm/include/acpisys.h --- trunk/reactos/drivers/bus/acpi/ospm/include/acpisys.h 2005-04-05 05:12:16 UTC (rev 14498) +++ trunk/reactos/drivers/bus/acpi/ospm/include/acpisys.h 2005-04-05 12:00:13 UTC (rev 14499) @@ -47,6 +47,9 @@
UNICODE_STRING InstanceID; // Hardware IDs UNICODE_STRING HardwareIDs; + // Resource list + PCM_RESOURCE_LIST ResourceList; + ULONG ResourceListSize; } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
_____
Modified: trunk/reactos/drivers/bus/acpi/ospm/pdo.c --- trunk/reactos/drivers/bus/acpi/ospm/pdo.c 2005-04-05 05:12:16 UTC (rev 14498) +++ trunk/reactos/drivers/bus/acpi/ospm/pdo.c 2005-04-05 12:00:13 UTC (rev 14499) @@ -108,6 +108,35 @@
static NTSTATUS +PdoQueryResources( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PPDO_DEVICE_EXTENSION DeviceExtension; + PCM_RESOURCE_LIST ResourceList; + + DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (DeviceExtension->ResourceListSize == 0) + { + return Irp->IoStatus.Status; + } + + ResourceList = ExAllocatePool(PagedPool, DeviceExtension->ResourceListSize); + if (!ResourceList) + { + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory(ResourceList, DeviceExtension->ResourceList, DeviceExtension->ResourceListSize); + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + return STATUS_SUCCESS; +} + + +static NTSTATUS PdoSetPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, @@ -201,6 +230,9 @@ break;
case IRP_MN_QUERY_RESOURCES: + Status = PdoQueryResources(DeviceObject, + Irp, + IrpSp); break;
case IRP_MN_QUERY_STOP_DEVICE: @@ -213,6 +245,7 @@ break;
case IRP_MN_START_DEVICE: + Status = STATUS_SUCCESS; break;
case IRP_MN_STOP_DEVICE: