1139823Simp/* 244165Sjulian * Copyright 2003-2005, Axel D��rfler, axeld@pinc-software.de. All rights reserved. 344165Sjulian * Distributed under the terms of the MIT License. 444165Sjulian */ 544165Sjulian 644165Sjulian#include <platform/openfirmware/devices.h> 744165Sjulian#include <platform/openfirmware/openfirmware.h> 844165Sjulian#include <util/kernel_cpp.h> 944165Sjulian 1044165Sjulian#include <string.h> 1144165Sjulian 1244165Sjulian 1344165Sjulian/** Gets all device types of the specified type by doing a 1444165Sjulian * depth-first search of the OpenFirmware device tree. 1544165Sjulian * If a root != 0 is given, the function only traverses the subtree spanned 1644165Sjulian * by the root (inclusively). Otherwise the whole device tree is searched. 1744165Sjulian * 1844165Sjulian * The cookie has to be initialized to zero. 1944165Sjulian */ 2044165Sjulianstatus_t 2144165Sjulianof_get_next_device(intptr_t *_cookie, intptr_t root, const char *type, 2244165Sjulian char *path, size_t pathSize) 2344165Sjulian{ 2444165Sjulian intptr_t node = *_cookie; 2544165Sjulian 2644165Sjulian while (true) { 2744165Sjulian intptr_t next; 2844165Sjulian 2944165Sjulian if (node == 0) { 3044165Sjulian // node is NULL, meaning that this is the initial function call. 3144165Sjulian // If a root was supplied, we take that, otherwise the device tree 3244165Sjulian // root. 3350477Speter if (root != 0) 3444165Sjulian node = root; 3544165Sjulian else 3644165Sjulian node = of_peer(0); 3744165Sjulian 3844165Sjulian if (node == OF_FAILED) 3944165Sjulian return B_ERROR; 4044165Sjulian if (node == 0) 4144165Sjulian return B_ENTRY_NOT_FOUND; 4244165Sjulian 4344165Sjulian // We want to visit the root first. 44112305Smdodd next = node; 4544165Sjulian } else 4644165Sjulian next = of_child(node); 4758313Slile 4844165Sjulian if (next == OF_FAILED) 4944165Sjulian return B_ERROR; 50112305Smdodd 51112305Smdodd if (next == 0) { 52112305Smdodd // no child node found 53112305Smdodd next = of_peer(node); 54112305Smdodd if (next == OF_FAILED) 5544165Sjulian return B_ERROR; 56112305Smdodd 57112305Smdodd while (next == 0) { 5844165Sjulian // no peer node found, we are using the device 59112305Smdodd // tree itself as our search stack 60112305Smdodd 61112305Smdodd next = of_parent(node); 6244165Sjulian if (next == OF_FAILED) 6344165Sjulian return B_ERROR; 6458313Slile 6544165Sjulian if (next == root || next == 0) { 6658313Slile // We have searched the whole device tree 67112305Smdodd return B_ENTRY_NOT_FOUND; 68112305Smdodd } 69112305Smdodd 70112305Smdodd // look into the next tree 7144165Sjulian node = next; 72112305Smdodd next = of_peer(node); 7358313Slile } 7444165Sjulian } 7558313Slile 7644165Sjulian *_cookie = node = next; 7758313Slile 7874407Smdodd char nodeType[16]; 7974407Smdodd int length; 8074407Smdodd if (of_getprop(node, "device_type", nodeType, sizeof(nodeType)) 8144165Sjulian == OF_FAILED 8244165Sjulian || strcmp(nodeType, type) 8344165Sjulian || (length = of_package_to_path(node, path, pathSize - 1)) 8444165Sjulian == OF_FAILED) { 8544165Sjulian continue; 8644165Sjulian } 8744165Sjulian 88145002Smdodd path[length] = '\0'; 89145002Smdodd return B_OK; 90145002Smdodd } 91145002Smdodd} 92145002Smdodd 93145002Smdodd