From 61519711005ed03dfcd324aa36d9cb5933488db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 13 Sep 2003 15:48:46 +0000 Subject: [PATCH] Implemented scanning the whole device tree for bootable devices (that are understood by the OpenFirmware). That makes it work on both, the Pegasos and the PowerMac G4 (any Mac with OpenFirmware v3 should do, though). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4671 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../boot/platform/openfirmware/devices.cpp | 102 ++++++++++++++++-- 1 file changed, 95 insertions(+), 7 deletions(-) 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; }