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
This commit is contained in:
@@ -4,27 +4,115 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "Handle.h"
|
||||
#include "openfirmware.h"
|
||||
|
||||
#include <boot/platform.h>
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/stdio.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include "Handle.h"
|
||||
#include "openfirmware.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user