Index: kernel/genarch/src/kbd/i8042.c
===================================================================
--- kernel/genarch/src/kbd/i8042.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
+++ kernel/genarch/src/kbd/i8042.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -81,9 +81,8 @@
 static void i8042_resume(chardev_t *);
 
-chardev_t kbrd;
 static chardev_operations_t ops = {
 	.suspend = i8042_suspend,
 	.resume = i8042_resume,
-	.read = key_read
+	.read = i8042_key_read
 };
 
@@ -174,5 +173,5 @@
 }
 
-char key_read(chardev_t *d)
+char i8042_key_read(chardev_t *d)
 {
 	char ch;	
Index: kernel/genarch/src/kbd/key.c
===================================================================
--- kernel/genarch/src/kbd/key.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
+++ kernel/genarch/src/kbd/key.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -54,4 +54,6 @@
 #define ACTIVE_READ_BUFF_SIZE 16 	/* Must be power of 2 */
 
+chardev_t kbrd;
+
 static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE];
 
Index: kernel/genarch/src/kbd/ns16550.c
===================================================================
--- kernel/genarch/src/kbd/ns16550.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
+++ kernel/genarch/src/kbd/ns16550.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -60,9 +60,8 @@
 static void ns16550_resume(chardev_t *);
 
-chardev_t kbrd;
 static chardev_operations_t ops = {
 	.suspend = ns16550_suspend,
 	.resume = ns16550_resume,
-	.read = key_read
+	.read = ns16550_key_read
 };
 
@@ -119,5 +118,5 @@
 }
 
-char key_read(chardev_t *d)
+char ns16550_key_read(chardev_t *d)
 {
 	char ch;	
Index: kernel/genarch/src/kbd/z8530.c
===================================================================
--- kernel/genarch/src/kbd/z8530.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
+++ kernel/genarch/src/kbd/z8530.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -63,9 +63,8 @@
 static void z8530_resume(chardev_t *);
 
-chardev_t kbrd;
 static chardev_operations_t ops = {
 	.suspend = z8530_suspend,
 	.resume = z8530_resume,
-	.read = key_read
+	.read = z8530_key_read
 };
 
@@ -142,5 +141,5 @@
 }
 
-char key_read(chardev_t *d)
+char z8530_key_read(chardev_t *d)
 {
 	char ch;	
Index: kernel/genarch/src/ofw/ebus.c
===================================================================
--- kernel/genarch/src/ofw/ebus.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
+++ kernel/genarch/src/ofw/ebus.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup ofw
+ * @{
+ */
+/**
+ * @file
+ * @brief	EBUS 'reg' and 'ranges' properties handling.
+ *
+ */
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/memstr.h>
+#include <func.h>
+#include <panic.h>
+#include <macros.h>
+
+bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
+{
+	ofw_tree_property_t *prop;
+	ofw_ebus_range_t *range;
+	count_t ranges;
+
+	prop = ofw_tree_getprop(node, "ranges");
+	if (!prop)
+		return false;
+		
+	ranges = prop->size / sizeof(ofw_ebus_range_t);
+	range = prop->value;
+	
+	int i;
+	
+	for (i = 0; i < ranges; i++) {
+		if (reg->space != range[i].child_space)
+			continue;
+		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
+			ofw_pci_reg_t pci_reg;
+			
+			pci_reg.space = range[i].parent_space;
+			pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base);
+			pci_reg.size = reg->size;
+			
+			return ofw_pci_apply_ranges(node->parent, &pci_reg, pa);
+		}
+	}
+
+	return false;
+}
+
+/** @}
+ */
Index: kernel/genarch/src/ofw/fhc.c
===================================================================
--- kernel/genarch/src/ofw/fhc.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
+++ kernel/genarch/src/ofw/fhc.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup ofw
+ * @{
+ */
+/**
+ * @file
+ * @brief	FHC 'reg' and 'ranges' properties handling.
+ *
+ */
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/memstr.h>
+#include <func.h>
+#include <panic.h>
+#include <macros.h>
+
+bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa)
+{
+	ofw_tree_property_t *prop;
+	ofw_fhc_range_t *range;
+	count_t ranges;
+
+	prop = ofw_tree_getprop(node, "ranges");
+	if (!prop)
+		return false;
+		
+	ranges = prop->size / sizeof(ofw_fhc_range_t);
+	range = prop->value;
+	
+	int i;
+	
+	for (i = 0; i < ranges; i++) {
+		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
+			uintptr_t addr;
+			
+			addr = range[i].parent_base + (reg->addr - range[i].child_base);
+			if (!node->parent->parent) {
+				*pa = addr;
+				return true;
+			}
+			if (strcmp(ofw_tree_node_name(node->parent), "central") != 0)
+				panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent));
+			
+			ofw_central_reg_t central_reg;
+			
+			central_reg.addr = addr;
+			central_reg.size = reg->size;
+			
+			return ofw_central_apply_ranges(node->parent, &central_reg, pa);
+		}
+	}
+
+	return false;
+}
+
+bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa)
+{
+	if (node->parent->parent)
+		panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent));
+	
+	ofw_tree_property_t *prop;
+	ofw_central_range_t *range;
+	count_t ranges;
+	
+	prop = ofw_tree_getprop(node, "ranges");
+	if (!prop)
+		return false;
+		
+	ranges = prop->size / sizeof(ofw_central_range_t);
+	range = prop->value;
+	
+	int i;
+	
+	for (i = 0; i < ranges; i++) {
+		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
+			*pa = range[i].parent_base + (reg->addr - range[i].child_base);
+			return true;
+		}
+	}
+	
+	return false;
+}
+
+/** @}
+ */
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision 16529d53af40d438671e67b8969cbe09086dc68f)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -52,4 +52,23 @@
 }
 
+/** Get OpenFirmware node property.
+ *
+ * @param node Node in which to lookup the property.
+ * @param name Name of the property.
+ *
+ * @return Pointer to the property structure or NULL if no such property.
+ */
+ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
+{
+	int i;
+	
+	for (i = 0; i < node->properties; i++) {
+		if (strcmp(node->property[i].name, name) == 0)
+			return &node->property[i];
+	}
+
+	return NULL;
+}
+
 /** Return value of the 'name' property.
  *
@@ -60,15 +79,14 @@
 const char *ofw_tree_node_name(const ofw_tree_node_t *node)
 {
-	int i;
+	ofw_tree_property_t *prop;
 	
-	for (i = 0; i < node->properties; i++) {
-		if (strncmp(node->property[i].name, "name", strlen("name")) == 0) {
-			if (node->property[i].size < 2)
-				panic("Invalid name property.\n");
-			return node->property[i].value;
-		}
-	}
+	prop = ofw_tree_getprop(node, "name");
+	if (!prop)
+		panic("Node without name property.\n");
+		
+	if (prop->size < 2)
+		panic("Invalid name property.\n");
 	
-	panic("Node without name property.\n");
+	return prop->value;
 }
 
@@ -76,17 +94,32 @@
  *
  * @param node Node whose child is being looked up.
- * @param da_name Disambigued name of the child being looked up.
+ * @param name Name of the child being looked up.
  *
  * @return NULL if there is no such child or pointer to the matching child node.
  */
-static ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *da_name)
+static ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
 {
 	ofw_tree_node_t *cur;
 	
+	/*
+	 * Try to find the disambigued name.
+	 */
 	for (cur = node->child; cur; cur = cur->peer) {
-		if (strncmp(cur->da_name, da_name, strlen(da_name)) == 0)
+		if (strcmp(cur->da_name, name) == 0)
 			return cur;
 	}
 	
+	/*
+	 * Disambigued name not found.
+	 * Lets try our luck with possibly ambiguous "name" property.
+	 *
+	 * We need to do this because paths stored in "/aliases"
+	 * are not always fully-qualified.
+	 */
+	for (cur = node->child; cur; cur = cur->peer) {
+		if (strcmp(ofw_tree_node_name(cur), name) == 0)
+			return cur;
+	}
+		
 	return NULL;
 }
Index: kernel/genarch/src/ofw/pci.c
===================================================================
--- kernel/genarch/src/ofw/pci.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
+++ kernel/genarch/src/ofw/pci.c	(revision 28ecadba2f66309e3ea4c819f1e768f64d97b699)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup ofw
+ * @{
+ */
+/**
+ * @file
+ * @brief	PCI 'reg' and 'ranges' properties handling.
+ *
+ */
+
+#include <genarch/ofw/ofw_tree.h>
+#include <arch/memstr.h>
+#include <func.h>
+#include <panic.h>
+#include <macros.h>
+
+#define PCI_SPACE_MASK	0x03000000
+
+bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
+{
+	ofw_tree_property_t *prop;
+	ofw_pci_range_t *range;
+	count_t ranges;
+
+	prop = ofw_tree_getprop(node, "ranges");
+	if (!prop) {
+		if (strcmp(ofw_tree_node_name(node->parent), "pci") == 0)
+			return ofw_pci_apply_ranges(node->parent, reg, pa);
+		return false;
+	}
+		
+	ranges = prop->size / sizeof(ofw_pci_range_t);
+	range = prop->value;
+	
+	int i;
+	
+	for (i = 0; i < ranges; i++) {
+		if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK))
+			continue;
+		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
+			*pa = range[i].parent_base + (reg->addr - range[i].child_base);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/** @}
+ */
