diff --git a/src/kernel/boot/platform/openfirmware/devices.cpp b/src/kernel/boot/platform/openfirmware/devices.cpp index 452cf00af8..c61ad97224 100644 --- a/src/kernel/boot/platform/openfirmware/devices.cpp +++ b/src/kernel/boot/platform/openfirmware/devices.cpp @@ -4,27 +4,115 @@ */ +#include "Handle.h" +#include "openfirmware.h" + #include #include #include #include -#include "Handle.h" -#include "openfirmware.h" +#include + + +/** Gets all device types of the specified type by doing a + * depth-first searchi of the OpenFirmware device tree. + * + * The cookie has to be initialized to zero. + */ + +static status_t +get_next_device(int *_cookie, const char *type, char *path, size_t pathSize) +{ + int node = *_cookie; + + if (node == 0) + node = of_peer(0); + + while (true) { + int next = of_child(node); + if (next == OF_FAILED) + return B_ERROR; + + if (next == 0) { + // no child node found + next = of_peer(node); + if (next == OF_FAILED) + return B_ERROR; + + while (next == 0) { + // no peer node found, we are using the device + // tree itself as our search stack + + next = of_parent(node); + if (next == OF_FAILED) + return B_ERROR; + + if (next == 0) { + // We have searched the whole device tree + return B_ENTRY_NOT_FOUND; + } + + // look into the next tree + node = next; + next = of_peer(node); + } + } + + *_cookie = node = next; + + char nodeType[16]; + int length; + if (of_getprop(node, "device_type", nodeType, sizeof(nodeType)) == OF_FAILED + || strcmp(nodeType, type) + || (length = of_package_to_path(node, path, pathSize - 1)) == OF_FAILED) + continue; + + path[length] = '\0'; + return B_OK; + } +} status_t platform_get_boot_devices(stage2_args *args, list *devicesList) { - int handle; + int node; - if ((handle = of_finddevice("ide0")) != OF_FAILED) { - Handle *device = new Handle(handle, false); + // print out the boot path (to be removed later?) + + char bootPath[128]; + of_getprop(gChosen, "bootpath", bootPath, sizeof(bootPath)); + printf("boot path = \"%s\"\n", bootPath); + + node = of_finddevice(bootPath); + if (node != OF_FAILED) { + char type[16]; + of_getprop(node, "device_type", type, sizeof(type)); + printf("boot type = %s\n", type); + } else + printf("could not open boot path.\n"); + + // add all block devices to the list of possible boot devices + + int cookie = 0; + char path[256]; + status_t status; + while ((status = get_next_device(&cookie, "block", path, sizeof(path))) == B_OK) { + printf("\t%s\n", path); + int handle = of_open(path); + if (handle == OF_FAILED) { + puts("\t\t(failed)"); + continue; + } + + printf("\t\t(could open device, handle = %p)\n", (void *)handle); + Handle *device = new Handle(handle); - printf("Found IDE device, handle = %d.\n", handle); list_add_item(devicesList, device); } - puts("platform_get_boot_devices() end."); + printf("\t(loop ended with %ld)\n", status); + return B_OK; }