/* $Id: acpienum.c 21698 2006-04-22 05:55:17Z tretiakov $ * * PROJECT: ReactOS ACPI bus driver * FILE: acpi/ospm/acpienum.c * PURPOSE: ACPI namespace enumerator * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) * UPDATE HISTORY: * 01-05-2001 CSH Created */ #include #include #include #include #include #define NDEBUG #include #define HAS_CHILDREN(d) ((d)->children.next != &((d)->children)) #define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children)) #define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node)) extern struct acpi_device *acpi_root; NTSTATUS Bus_PlugInDevice ( struct acpi_device *Device, PFDO_DEVICE_DATA FdoData ) { PDEVICE_OBJECT pdo; PPDO_DEVICE_DATA pdoData; NTSTATUS status; ULONG index; WCHAR temp[256]; PLIST_ENTRY entry; PAGED_CODE (); //Don't enumerate the root device if (Device->handle == ACPI_ROOT_OBJECT) return STATUS_SUCCESS; /* Check we didnt add this already */ for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { pdoData = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); //dont duplicate devices if(pdoData->AcpiHandle == Device->handle) return STATUS_SUCCESS; } DPRINT("Exposing PDO\n" "======AcpiHandle: %p\n" "======HardwareId: %s\n", Device->handle, Device->pnp.hardware_id); // // Create the PDO // DPRINT("FdoData->NextLowerDriver = 0x%p\n", FdoData->NextLowerDriver); status = IoCreateDevice(FdoData->Common.Self->DriverObject, sizeof(PDO_DEVICE_DATA), NULL, FILE_DEVICE_CONTROLLER, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pdo); if (!NT_SUCCESS (status)) { return status; } pdoData = (PPDO_DEVICE_DATA) pdo->DeviceExtension; pdoData->AcpiHandle = Device->handle; // // Copy the hardware IDs // index = 0; index += swprintf(&temp[index], L"ACPI\\%hs", Device->pnp.hardware_id); index++; index += swprintf(&temp[index], L"*%hs", Device->pnp.hardware_id); index++; temp[index] = UNICODE_NULL; pdoData->HardwareIDs = ExAllocatePool(NonPagedPool, index*sizeof(WCHAR)); if (!pdoData->HardwareIDs) { IoDeleteDevice(pdo); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyMemory (pdoData->HardwareIDs, temp, index*sizeof(WCHAR)); Bus_InitializePdo (pdo, FdoData); // // Device Relation changes if a new pdo is created. So let // the PNP system now about that. This forces it to send bunch of pnp // queries and cause the function driver to be loaded. // //IoInvalidateDeviceRelations (FdoData->UnderlyingPDO, BusRelations); return status; } /* looks alot like acpi_bus_walk doesnt it */ NTSTATUS ACPIEnumerateDevices(PFDO_DEVICE_DATA DeviceExtension) { ULONG Count = 0; struct acpi_device *Device = acpi_root; while(Device) { if (Device->status.present && Device->status.enabled && Device->flags.hardware_id) { Bus_PlugInDevice(Device, DeviceExtension); Count++; } if (HAS_CHILDREN(Device)) { Device = NODE_TO_DEVICE(Device->children.next); continue; } if (HAS_SIBLINGS(Device)) { Device = NODE_TO_DEVICE(Device->node.next); continue; } while ((Device = Device->parent)) { if (HAS_SIBLINGS(Device)) { Device = NODE_TO_DEVICE(Device->node.next); break; } } } DPRINT("acpi device count: %d\n", Count); return STATUS_SUCCESS; } /* EOF */