diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
new file mode 100644
index 0000000..7c4330e
--- /dev/null
+++ b/drivers/ieee1394/csr1212.c
@@ -0,0 +1,1612 @@
+/*
+ * csr1212.c -- IEEE 1212 Control and Status Register support for Linux
+ *
+ * Copyright (C) 2003 Francois Retief <fgretief@sun.ac.za>
+ *                    Steve Kinneberg <kinnebergsteve@acmsystems.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *    2. 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.
+ *    3. 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.
+ */
+
+
+/* TODO List:
+ * - Verify interface consistency: i.e., public functions that take a size
+ *   parameter expect size to be in bytes.
+ * - Convenience functions for reading a block of data from a given offset.
+ */
+
+#ifndef __KERNEL__
+#include <string.h>
+#endif
+
+#include "csr1212.h"
+
+
+/* Permitted key type for each key id */
+#define __I (1 << CSR1212_KV_TYPE_IMMEDIATE)
+#define __C (1 << CSR1212_KV_TYPE_CSR_OFFSET)
+#define __D (1 << CSR1212_KV_TYPE_DIRECTORY)
+#define __L (1 << CSR1212_KV_TYPE_LEAF)
+static const u_int8_t csr1212_key_id_type_map[0x30] = {
+	0,			/* Reserved */
+	__D | __L,		/* Descriptor */
+	__I | __D | __L,	/* Bus_Dependent_Info */
+	__I | __D | __L,	/* Vendor */
+	__I,			/* Hardware_Version */
+	0, 0,			/* Reserved */
+	__D | __L,		/* Module */
+	0, 0, 0, 0,		/* Reserved */
+	__I,			/* Node_Capabilities */
+	__L,			/* EUI_64 */
+	0, 0, 0,		/* Reserved */
+	__D,			/* Unit */
+	__I,			/* Specifier_ID */
+	__I,			/* Version */
+	__I | __C | __D | __L,	/* Dependent_Info */
+	__L,			/* Unit_Location */
+	0,			/* Reserved */
+	__I,			/* Model */
+	__D,			/* Instance */
+	__L,			/* Keyword */
+	__D,			/* Feature */
+	__L,			/* Extended_ROM */
+	__I,			/* Extended_Key_Specifier_ID */
+	__I,			/* Extended_Key */
+	__I | __C | __D | __L,	/* Extended_Data */
+	__L,			/* Modifiable_Descriptor */
+	__I,			/* Directory_ID */
+	__I,			/* Revision */
+};
+#undef __I
+#undef __C
+#undef __D
+#undef __L
+
+
+#define quads_to_bytes(_q) ((_q) * sizeof(u_int32_t))
+#define bytes_to_quads(_b) (((_b) + sizeof(u_int32_t) - 1) / sizeof(u_int32_t))
+
+static inline void free_keyval(struct csr1212_keyval *kv)
+{
+	if ((kv->key.type == CSR1212_KV_TYPE_LEAF) &&
+	    (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM))
+		CSR1212_FREE(kv->value.leaf.data);
+
+	CSR1212_FREE(kv);
+}
+
+static u_int16_t csr1212_crc16(const u_int32_t *buffer, size_t length)
+{
+	int shift;
+	u_int32_t data;
+	u_int16_t sum, crc = 0;
+
+	for (; length; length--) {
+		data = CSR1212_BE32_TO_CPU(*buffer);
+		buffer++;
+		for (shift = 28; shift >= 0; shift -= 4 ) {
+			sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
+			crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
+		}
+		crc &= 0xffff;
+	}
+
+	return CSR1212_CPU_TO_BE16(crc);
+}
+
+#if 0
+/* Microsoft computes the CRC with the bytes in reverse order.  Therefore we
+ * have a special version of the CRC algorithm to account for their buggy
+ * software. */
+static u_int16_t csr1212_msft_crc16(const u_int32_t *buffer, size_t length)
+{
+	int shift;
+	u_int32_t data;
+	u_int16_t sum, crc = 0;
+
+	for (; length; length--) {
+		data = CSR1212_LE32_TO_CPU(*buffer);
+		buffer++;
+		for (shift = 28; shift >= 0; shift -= 4 ) {
+			sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
+			crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
+		}
+		crc &= 0xffff;
+	}
+
+	return CSR1212_CPU_TO_BE16(crc);
+}
+#endif
+
+static inline struct csr1212_dentry *csr1212_find_keyval(struct csr1212_keyval *dir,
+							 struct csr1212_keyval *kv)
+{
+	struct csr1212_dentry *pos;
+
+	for (pos = dir->value.directory.dentries_head;
+	     pos != NULL; pos = pos->next) {
+		if (pos->kv == kv)
+			return pos;
+	}
+	return NULL;
+}
+
+
+static inline struct csr1212_keyval *csr1212_find_keyval_offset(struct csr1212_keyval *kv_list,
+								u_int32_t offset)
+{
+	struct csr1212_keyval *kv;
+
+	for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next) {
+		if (kv->offset == offset)
+			return kv;
+	}
+	return NULL;
+}
+
+
+/* Creation Routines */
+struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
+				       size_t bus_info_size, void *private)
+{
+	struct csr1212_csr *csr;
+
+	csr = CSR1212_MALLOC(sizeof(*csr));
+	if (!csr)
+		return NULL;
+
+	csr->cache_head =
+		csr1212_rom_cache_malloc(CSR1212_CONFIG_ROM_SPACE_OFFSET,
+					 CSR1212_CONFIG_ROM_SPACE_SIZE);
+	if (!csr->cache_head) {
+		CSR1212_FREE(csr);
+		return NULL;
+	}
+
+	/* The keyval key id is not used for the root node, but a valid key id
+	 * that can be used for a directory needs to be passed to
+	 * csr1212_new_directory(). */
+	csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR);
+	if (!csr->root_kv) {
+		CSR1212_FREE(csr->cache_head);
+		CSR1212_FREE(csr);
+		return NULL;
+	}
+
+	csr->bus_info_data = csr->cache_head->data;
+	csr->bus_info_len = bus_info_size;
+	csr->crc_len = bus_info_size;
+	csr->ops = ops;
+	csr->private = private;
+	csr->cache_tail = csr->cache_head;
+
+	return csr;
+}
+
+
+
+void csr1212_init_local_csr(struct csr1212_csr *csr,
+			    const u_int32_t *bus_info_data, int max_rom)
+{
+	static const int mr_map[] = { 4, 64, 1024, 0 };
+
+	csr->max_rom = mr_map[max_rom];
+	memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
+}
+
+
+static struct csr1212_keyval *csr1212_new_keyval(u_int8_t type, u_int8_t key)
+{
+	struct csr1212_keyval *kv;
+
+	if (key < 0x30 && ((csr1212_key_id_type_map[key] & (1 << type)) == 0))
+		return NULL;
+
+	kv = CSR1212_MALLOC(sizeof(*kv));
+	if (!kv)
+		return NULL;
+
+	kv->key.type = type;
+	kv->key.id = key;
+
+	kv->associate = NULL;
+	kv->refcnt = 1;
+
+	kv->next = NULL;
+	kv->prev = NULL;
+	kv->offset = 0;
+	kv->valid = 0;
+	return kv;
+}
+
+struct csr1212_keyval *csr1212_new_immediate(u_int8_t key, u_int32_t value)
+{
+	struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key);
+
+	if (!kv)
+		return NULL;
+
+	kv->value.immediate = value;
+	kv->valid = 1;
+	return kv;
+}
+
+struct csr1212_keyval *csr1212_new_leaf(u_int8_t key, const void *data, size_t data_len)
+{
+	struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, key);
+
+	if (!kv)
+		return NULL;
+
+	if (data_len > 0) {
+		kv->value.leaf.data = CSR1212_MALLOC(data_len);
+		if (!kv->value.leaf.data) {
+			CSR1212_FREE(kv);
+			return NULL;
+		}
+
+		if (data)
+			memcpy(kv->value.leaf.data, data, data_len);
+	} else {
+		kv->value.leaf.data = NULL;
+	}
+
+	kv->value.leaf.len = bytes_to_quads(data_len);
+	kv->offset = 0;
+	kv->valid = 1;
+
+	return kv;
+}
+
+struct csr1212_keyval *csr1212_new_csr_offset(u_int8_t key, u_int32_t csr_offset)
+{
+	struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_CSR_OFFSET, key);
+
+	if (!kv)
+		return NULL;
+
+	kv->value.csr_offset = csr_offset;
+
+	kv->offset = 0;
+	kv->valid = 1;
+	return kv;
+}
+
+struct csr1212_keyval *csr1212_new_directory(u_int8_t key)
+{
+	struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_DIRECTORY, key);
+
+	if (!kv)
+		return NULL;
+
+	kv->value.directory.len = 0;
+	kv->offset = 0;
+	kv->value.directory.dentries_head = NULL;
+	kv->value.directory.dentries_tail = NULL;
+	kv->valid = 1;
+	return kv;
+}
+
+int csr1212_associate_keyval(struct csr1212_keyval *kv,
+			     struct csr1212_keyval *associate)
+{
+	if (!kv || !associate)
+		return CSR1212_EINVAL;
+
+	if (kv->key.id == CSR1212_KV_ID_DESCRIPTOR ||
+	   (associate->key.id != CSR1212_KV_ID_DESCRIPTOR &&
+	    associate->key.id != CSR1212_KV_ID_DEPENDENT_INFO &&
+	    associate->key.id != CSR1212_KV_ID_EXTENDED_KEY &&
+	    associate->key.id != CSR1212_KV_ID_EXTENDED_DATA &&
+	    associate->key.id < 0x30))
+		return CSR1212_EINVAL;
+
+	if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID &&
+	   associate->key.id != CSR1212_KV_ID_EXTENDED_KEY)
+		return CSR1212_EINVAL;
+
+	if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
+	   associate->key.id != CSR1212_KV_ID_EXTENDED_DATA)
+		return CSR1212_EINVAL;
+
+	if (associate->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
+	   kv->key.id != CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID)
+		return CSR1212_EINVAL;
+
+	if (associate->key.id == CSR1212_KV_ID_EXTENDED_DATA &&
+	   kv->key.id != CSR1212_KV_ID_EXTENDED_KEY)
+		return CSR1212_EINVAL;
+
+	if (kv->associate)
+		csr1212_release_keyval(kv->associate);
+
+	associate->refcnt++;
+	kv->associate = associate;
+
+	return CSR1212_SUCCESS;
+}
+
+int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
+				       struct csr1212_keyval *kv)
+{
+	struct csr1212_dentry *dentry;
+
+	if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
+		return CSR1212_EINVAL;
+
+	dentry = CSR1212_MALLOC(sizeof(*dentry));
+	if (!dentry)
+		return CSR1212_ENOMEM;
+
+	dentry->kv = kv;
+
+	kv->refcnt++;
+
+	dentry->next = NULL;
+	dentry->prev = dir->value.directory.dentries_tail;
+
+	if (!dir->value.directory.dentries_head)
+		dir->value.directory.dentries_head = dentry;
+
+	if (dir->value.directory.dentries_tail)
+		dir->value.directory.dentries_tail->next = dentry;
+	dir->value.directory.dentries_tail = dentry;
+
+	return CSR1212_SUCCESS;
+}
+
+struct csr1212_keyval *csr1212_new_extended_immediate(u_int32_t spec, u_int32_t key,
+						      u_int32_t value)
+{
+	struct csr1212_keyval *kvs, *kvk, *kvv;
+
+	kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
+	kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
+	kvv = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_DATA, value);
+
+	if (!kvs || !kvk || !kvv) {
+		if (kvs)
+			free_keyval(kvs);
+		if (kvk)
+			free_keyval(kvk);
+		if (kvv)
+			free_keyval(kvv);
+		return NULL;
+	}
+
+	/* Don't keep a local reference to the extended key or value. */
+	kvk->refcnt = 0;
+	kvv->refcnt = 0;
+
+	csr1212_associate_keyval(kvk, kvv);
+	csr1212_associate_keyval(kvs, kvk);
+
+	return kvs;
+}
+
+struct csr1212_keyval *csr1212_new_extended_leaf(u_int32_t spec, u_int32_t key,
+						 const void *data, size_t data_len)
+{
+	struct csr1212_keyval *kvs, *kvk, *kvv;
+
+	kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
+	kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
+	kvv = csr1212_new_leaf(CSR1212_KV_ID_EXTENDED_DATA, data, data_len);
+
+	if (!kvs || !kvk || !kvv) {
+		if (kvs)
+			free_keyval(kvs);
+		if (kvk)
+			free_keyval(kvk);
+		if (kvv)
+			free_keyval(kvv);
+		return NULL;
+	}
+
+	/* Don't keep a local reference to the extended key or value. */
+	kvk->refcnt = 0;
+	kvv->refcnt = 0;
+
+	csr1212_associate_keyval(kvk, kvv);
+	csr1212_associate_keyval(kvs, kvk);
+
+	return kvs;
+}
+
+struct csr1212_keyval *csr1212_new_descriptor_leaf(u_int8_t dtype, u_int32_t specifier_id,
+						   const void *data, size_t data_len)
+{
+	struct csr1212_keyval *kv;
+
+	kv = csr1212_new_leaf(CSR1212_KV_ID_DESCRIPTOR, NULL,
+			      data_len + CSR1212_DESCRIPTOR_LEAF_OVERHEAD);
+	if (!kv)
+		return NULL;
+
+	CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, dtype);
+	CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, specifier_id);
+
+	if (data) {
+		memcpy(CSR1212_DESCRIPTOR_LEAF_DATA(kv), data, data_len);
+	}
+
+	return kv;
+}
+
+
+struct csr1212_keyval *csr1212_new_textual_descriptor_leaf(u_int8_t cwidth,
+							   u_int16_t cset,
+							   u_int16_t language,
+							   const void *data,
+							   size_t data_len)
+{
+	struct csr1212_keyval *kv;
+	char *lstr;
+
+	kv = csr1212_new_descriptor_leaf(0, 0, NULL, data_len +
+					 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD);
+	if (!kv)
+		return NULL;
+
+	CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_WIDTH(kv, cwidth);
+	CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_CHAR_SET(kv, cset);
+	CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
+
+	lstr = (char*)CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(kv);
+
+	/* make sure last quadlet is zeroed out */
+	*((u_int32_t*)&(lstr[(data_len - 1) & ~0x3])) = 0;
+
+	/* don't copy the NUL terminator */
+	memcpy(lstr, data, data_len);
+
+	return kv;
+}
+
+static int csr1212_check_minimal_ascii(const char *s)
+{
+	static const char minimal_ascii_table[] = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+		0x00, 0x00, 0x0a, 0x00, 0x0C, 0x0D, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x20, 0x21, 0x22, 0x00, 0x00, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+		0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5f,
+		0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+		0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+		0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+		0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
+	};
+	for (; *s; s++) {
+		if (minimal_ascii_table[*s & 0x7F] != *s)
+			return -1; /* failed */
+	}
+	/* String conforms to minimal-ascii, as specified by IEEE 1212,
+	 * par. 7.4 */
+	return 0;
+}
+
+struct csr1212_keyval *csr1212_new_string_descriptor_leaf(const char *s)
+{
+	/* Check if string conform to minimal_ascii format */
+	if (csr1212_check_minimal_ascii(s))
+		return NULL;
+
+	/* IEEE 1212, par. 7.5.4.1  Textual descriptors (minimal ASCII) */
+	return csr1212_new_textual_descriptor_leaf(0, 0, 0, s, strlen(s));
+}
+
+struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version,
+							u_int8_t palette_depth,
+							u_int8_t color_space,
+							u_int16_t language,
+							u_int16_t hscan,
+							u_int16_t vscan,
+							u_int32_t *palette,
+							u_int32_t *pixels)
+{
+	static const int pd[4] = { 0, 4, 16, 256 };
+	static const int cs[16] = { 4, 2 };
+	struct csr1212_keyval *kv;
+	int palette_size = pd[palette_depth] * cs[color_space];
+	int pixel_size = (hscan * vscan + 3) & ~0x3;
+
+	if ((palette_depth && !palette) || !pixels)
+		return NULL;
+
+	kv = csr1212_new_descriptor_leaf(1, 0, NULL,
+					 palette_size + pixel_size +
+					 CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
+	if (!kv)
+		return NULL;
+
+	CSR1212_ICON_DESCRIPTOR_LEAF_SET_VERSION(kv, version);
+	CSR1212_ICON_DESCRIPTOR_LEAF_SET_PALETTE_DEPTH(kv, palette_depth);
+	CSR1212_ICON_DESCRIPTOR_LEAF_SET_COLOR_SPACE(kv, color_space);
+	CSR1212_ICON_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
+	CSR1212_ICON_DESCRIPTOR_LEAF_SET_HSCAN(kv, hscan);
+	CSR1212_ICON_DESCRIPTOR_LEAF_SET_VSCAN(kv, vscan);
+
+	if (palette_size)
+		memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PALETTE(kv), palette,
+		       palette_size);
+
+	memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PIXELS(kv), pixels, pixel_size);
+
+	return kv;
+}
+
+struct csr1212_keyval *csr1212_new_modifiable_descriptor_leaf(u_int16_t max_size,
+							      u_int64_t address)
+{
+	struct csr1212_keyval *kv;
+
+	/* IEEE 1212, par. 7.5.4.3  Modifiable descriptors */
+	kv = csr1212_new_leaf(CSR1212_KV_ID_MODIFIABLE_DESCRIPTOR, NULL, sizeof(u_int64_t));
+	if(!kv)
+		return NULL;
+
+	CSR1212_MODIFIABLE_DESCRIPTOR_SET_MAX_SIZE(kv, max_size);
+	CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_HI(kv, address);
+	CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_LO(kv, address);
+
+	return kv;
+}
+
+static int csr1212_check_keyword(const char *s)
+{
+	for (; *s; s++) {
+
+		if (('A' <= *s) && (*s <= 'Z'))
+			continue;
+		if (('0' <= *s) && (*s <= '9'))
+			continue;
+		if (*s == '-')
+			continue;
+
+		return -1; /* failed */
+	}
+	/* String conforms to keyword, as specified by IEEE 1212,
+	 * par. 7.6.5 */
+	return CSR1212_SUCCESS;
+}
+
+struct csr1212_keyval *csr1212_new_keyword_leaf(int strc, const char *strv[])
+{
+	struct csr1212_keyval *kv;
+	char *buffer;
+	int i, data_len = 0;
+
+	/* Check all keywords to see if they conform to restrictions:
+	 * Only the following characters is allowed ['A'..'Z','0'..'9','-']
+	 * Each word is zero-terminated.
+	 * Also calculate the total length of the keywords.
+	 */
+	for (i = 0; i < strc; i++) {
+		if (!strv[i] || csr1212_check_keyword(strv[i])) {
+			return NULL;
+		}
+		data_len += strlen(strv[i]) + 1; /* Add zero-termination char. */
+	}
+
+	/* IEEE 1212, par. 7.6.5 Keyword leaves */
+	kv = csr1212_new_leaf(CSR1212_KV_ID_KEYWORD, NULL, data_len);
+	if (!kv)
+		return NULL;
+
+	buffer = (char *)kv->value.leaf.data;
+
+	/* make sure last quadlet is zeroed out */
+	*((u_int32_t*)&(buffer[(data_len - 1) & ~0x3])) = 0;
+
+	/* Copy keyword(s) into leaf data buffer */
+	for (i = 0; i < strc; i++) {
+		int len = strlen(strv[i]) + 1;
+		memcpy(buffer, strv[i], len);
+		buffer += len;
+	}
+	return kv;
+}
+
+
+/* Destruction Routines */
+
+void csr1212_detach_keyval_from_directory(struct csr1212_keyval *dir,
+					  struct csr1212_keyval *kv)
+{
+	struct csr1212_dentry *dentry;
+
+	if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
+		return;
+
+	dentry = csr1212_find_keyval(dir, kv);
+
+	if (!dentry)
+		return;
+
+	if (dentry->prev)
+		dentry->prev->next = dentry->next;
+	if (dentry->next)
+		dentry->next->prev = dentry->prev;
+	if (dir->value.directory.dentries_head == dentry)
+		dir->value.directory.dentries_head = dentry->next;
+	if (dir->value.directory.dentries_tail == dentry)
+		dir->value.directory.dentries_tail = dentry->prev;
+
+	CSR1212_FREE(dentry);
+
+	csr1212_release_keyval(kv);
+}
+
+
+void csr1212_disassociate_keyval(struct csr1212_keyval *kv)
+{
+	if (kv->associate) {
+		csr1212_release_keyval(kv->associate);
+	}
+
+	kv->associate = NULL;
+}
+
+
+/* This function is used to free the memory taken by a keyval.  If the given
+ * keyval is a directory type, then any keyvals contained in that directory
+ * will be destroyed as well if their respective refcnts are 0.  By means of
+ * list manipulation, this routine will descend a directory structure in a
+ * non-recursive manner. */
+void _csr1212_destroy_keyval(struct csr1212_keyval *kv)
+{
+	struct csr1212_keyval *k, *a;
+	struct csr1212_dentry dentry;
+	struct csr1212_dentry *head, *tail;
+
+	dentry.kv = kv;
+	dentry.next = NULL;
+	dentry.prev = NULL;
+
+	head = &dentry;
+	tail = head;
+
+	while (head) {
+		k = head->kv;
+
+		while (k) {
+			k->refcnt--;
+
+			if (k->refcnt > 0)
+				break;
+
+			a = k->associate;
+
+			if (k->key.type == CSR1212_KV_TYPE_DIRECTORY) {
+				/* If the current entry is a directory, then move all
+				 * the entries to the destruction list. */
+				if (k->value.directory.dentries_head) {
+					tail->next = k->value.directory.dentries_head;
+					k->value.directory.dentries_head->prev = tail;
+					tail = k->value.directory.dentries_tail;
+				}
+			}
+			free_keyval(k);
+			k = a;
+		}
+
+		head = head->next;
+		if (head) {
+			if (head->prev && head->prev != &dentry) {
+				CSR1212_FREE(head->prev);
+			}
+			head->prev = NULL;
+		} else if (tail != &dentry)
+			CSR1212_FREE(tail);
+	}
+}
+
+
+void csr1212_destroy_csr(struct csr1212_csr *csr)
+{
+	struct csr1212_csr_rom_cache *c, *oc;
+	struct csr1212_cache_region *cr, *ocr;
+
+	csr1212_release_keyval(csr->root_kv);
+
+	c = csr->cache_head;
+	while (c) {
+		oc = c;
+		cr = c->filled_head;
+		while (cr) {
+			ocr = cr;
+			cr = cr->next;
+			CSR1212_FREE(ocr);
+		}
+		c = c->next;
+		CSR1212_FREE(oc);
+	}
+
+	CSR1212_FREE(csr);
+}
+
+
+
+/* CSR Image Creation */
+
+static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
+{
+	struct csr1212_csr_rom_cache *cache;
+	u_int64_t csr_addr;
+
+	if (!csr || !csr->ops->allocate_addr_range ||
+	    !csr->ops->release_addr)
+		return CSR1212_ENOMEM;
+
+	/* ROM size must be a multiple of csr->max_rom */
+	romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
+
+	csr_addr = csr->ops->allocate_addr_range(romsize, csr->max_rom, csr->private);
+	if (csr_addr == ~0ULL) {
+		return CSR1212_ENOMEM;
+	}
+	if (csr_addr < CSR1212_REGISTER_SPACE_BASE) {
+		/* Invalid address returned from allocate_addr_range(). */
+		csr->ops->release_addr(csr_addr, csr->private);
+		return CSR1212_ENOMEM;
+	}
+
+	cache = csr1212_rom_cache_malloc(csr_addr - CSR1212_REGISTER_SPACE_BASE, romsize);
+	if (!cache) {
+		csr->ops->release_addr(csr_addr, csr->private);
+		return CSR1212_ENOMEM;
+	}
+
+	cache->ext_rom = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, CSR1212_KV_ID_EXTENDED_ROM);
+	if (!cache->ext_rom) {
+		csr->ops->release_addr(csr_addr, csr->private);
+		CSR1212_FREE(cache);
+		return CSR1212_ENOMEM;
+	}
+
+	if (csr1212_attach_keyval_to_directory(csr->root_kv, cache->ext_rom) != CSR1212_SUCCESS) {
+		csr1212_release_keyval(cache->ext_rom);
+		csr->ops->release_addr(csr_addr, csr->private);
+		CSR1212_FREE(cache);
+		return CSR1212_ENOMEM;
+	}
+	cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE;
+	cache->ext_rom->value.leaf.len = -1;
+	cache->ext_rom->value.leaf.data = cache->data;
+
+	/* Add cache to tail of cache list */
+	cache->prev = csr->cache_tail;
+	csr->cache_tail->next = cache;
+	csr->cache_tail = cache;
+	return CSR1212_SUCCESS;
+}
+
+static inline void csr1212_remove_cache(struct csr1212_csr *csr,
+					struct csr1212_csr_rom_cache *cache)
+{
+	if (csr->cache_head == cache)
+		csr->cache_head = cache->next;
+	if (csr->cache_tail == cache)
+		csr->cache_tail = cache->prev;
+
+	if (cache->prev)
+		cache->prev->next = cache->next;
+	if (cache->next)
+		cache->next->prev = cache->prev;
+
+	if (cache->ext_rom) {
+		csr1212_detach_keyval_from_directory(csr->root_kv, cache->ext_rom);
+		csr1212_release_keyval(cache->ext_rom);
+	}
+
+	CSR1212_FREE(cache);
+}
+
+static int csr1212_generate_layout_subdir(struct csr1212_keyval *dir,
+					  struct csr1212_keyval **layout_tail)
+{
+	struct csr1212_dentry *dentry;
+	struct csr1212_keyval *dkv;
+	struct csr1212_keyval *last_extkey_spec = NULL;
+	struct csr1212_keyval *last_extkey = NULL;
+	int num_entries = 0;
+
+	for (dentry = dir->value.directory.dentries_head; dentry;
+	     dentry = dentry->next) {
+		for (dkv = dentry->kv; dkv; dkv = dkv->associate) {
+			/* Special Case: Extended Key Specifier_ID */
+			if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
+				if (last_extkey_spec == NULL) {
+					last_extkey_spec = dkv;
+				} else if (dkv->value.immediate != last_extkey_spec->value.immediate) {
+					last_extkey_spec = dkv;
+				} else {
+					continue;
+				}
+			/* Special Case: Extended Key */
+			} else if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
+				if (last_extkey == NULL) {
+					last_extkey = dkv;
+				} else if (dkv->value.immediate != last_extkey->value.immediate) {
+					last_extkey = dkv;
+				} else {
+					continue;
+				}
+			}
+
+			num_entries += 1;
+
+			switch(dkv->key.type) {
+			default:
+			case CSR1212_KV_TYPE_IMMEDIATE:
+			case CSR1212_KV_TYPE_CSR_OFFSET:
+				break;
+			case CSR1212_KV_TYPE_LEAF:
+			case CSR1212_KV_TYPE_DIRECTORY:
+				/* Remove from list */
+				if (dkv->prev && (dkv->prev->next == dkv))
+					dkv->prev->next = dkv->next;
+				if (dkv->next && (dkv->next->prev == dkv))
+					dkv->next->prev = dkv->prev;
+				//if (dkv == *layout_tail)
+				//	*layout_tail = dkv->prev;
+
+				/* Special case: Extended ROM leafs */
+				if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
+					dkv->value.leaf.len = -1;
+					/* Don't add Extended ROM leafs in the layout list,
+					 * they are handled differently. */
+					break;
+				}
+
+				/* Add to tail of list */
+				dkv->next = NULL;
+				dkv->prev = *layout_tail;
+				(*layout_tail)->next = dkv;
+				*layout_tail = dkv;
+				break;
+			}
+		}
+	}
+	return num_entries;
+}
+
+size_t csr1212_generate_layout_order(struct csr1212_keyval *kv)
+{
+	struct csr1212_keyval *ltail = kv;
+	size_t agg_size = 0;
+
+	while(kv) {
+		switch(kv->key.type) {
+		case CSR1212_KV_TYPE_LEAF:
+			/* Add 1 quadlet for crc/len field */
+			agg_size += kv->value.leaf.len + 1;
+			break;
+
+		case CSR1212_KV_TYPE_DIRECTORY:
+			kv->value.directory.len = csr1212_generate_layout_subdir(kv, &ltail);
+			/* Add 1 quadlet for crc/len field */
+			agg_size += kv->value.directory.len + 1;
+			break;
+		}
+		kv = kv->next;
+	}
+	return quads_to_bytes(agg_size);
+}
+
+struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *cache,
+						  struct csr1212_keyval *start_kv,
+						  int start_pos)
+{
+	struct csr1212_keyval *kv = start_kv;
+	struct csr1212_keyval *okv = start_kv;
+	int pos = start_pos;
+	int kv_len = 0, okv_len = 0;
+
+	cache->layout_head = kv;
+
+	while(kv && pos < cache->size) {
+		/* Special case: Extended ROM leafs */
+		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
+			kv->offset = cache->offset + pos;
+		}
+
+		switch(kv->key.type) {
+		case CSR1212_KV_TYPE_LEAF:
+			kv_len = kv->value.leaf.len;
+			break;
+
+		case CSR1212_KV_TYPE_DIRECTORY:
+			kv_len = kv->value.directory.len;
+			break;
+
+		default:
+			/* Should never get here */
+			break;
+		}
+
+		pos += quads_to_bytes(kv_len + 1);
+
+		if (pos <= cache->size) {
+			okv = kv;
+			okv_len = kv_len;
+			kv = kv->next;
+		}
+	}
+
+	cache->layout_tail = okv;
+	cache->len = (okv->offset - cache->offset) + quads_to_bytes(okv_len + 1);
+
+	return kv;
+}
+
+static void csr1212_generate_tree_subdir(struct csr1212_keyval *dir,
+					 u_int32_t *data_buffer)
+{
+	struct csr1212_dentry *dentry;
+	struct csr1212_keyval *last_extkey_spec = NULL;
+	struct csr1212_keyval *last_extkey = NULL;
+	int index = 0;
+
+	for (dentry = dir->value.directory.dentries_head; dentry; dentry = dentry->next) {
+		struct csr1212_keyval *a;
+
+		for (a = dentry->kv; a; a = a->associate) {
+			u_int32_t value = 0;
+
+			/* Special Case: Extended Key Specifier_ID */
+			if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
+				if (last_extkey_spec == NULL) {
+					last_extkey_spec = a;
+				} else if (a->value.immediate != last_extkey_spec->value.immediate) {
+					last_extkey_spec = a;
+				} else {
+					continue;
+				}
+			/* Special Case: Extended Key */
+			} else if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
+				if (last_extkey == NULL) {
+					last_extkey = a;
+				} else if (a->value.immediate != last_extkey->value.immediate) {
+					last_extkey = a;
+				} else {
+					continue;
+				}
+			}
+
+			switch(a->key.type) {
+			case CSR1212_KV_TYPE_IMMEDIATE:
+				value = a->value.immediate;
+				break;
+			case CSR1212_KV_TYPE_CSR_OFFSET:
+				value = a->value.csr_offset;
+				break;
+			case CSR1212_KV_TYPE_LEAF:
+				value = a->offset;
+				value -= dir->offset + quads_to_bytes(1+index);
+				value = bytes_to_quads(value);
+				break;
+			case CSR1212_KV_TYPE_DIRECTORY:
+				value = a->offset;
+				value -= dir->offset + quads_to_bytes(1+index);
+				value = bytes_to_quads(value);
+				break;
+			default:
+				/* Should never get here */
+				break; /* GDB breakpoint */
+			}
+
+			value |= (a->key.id & CSR1212_KV_KEY_ID_MASK) << CSR1212_KV_KEY_SHIFT;
+			value |= (a->key.type & CSR1212_KV_KEY_TYPE_MASK) <<
+				(CSR1212_KV_KEY_SHIFT + CSR1212_KV_KEY_TYPE_SHIFT);
+			data_buffer[index] = CSR1212_CPU_TO_BE32(value);
+			index++;
+		}
+	}
+}
+
+void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache)
+{
+	struct csr1212_keyval *kv, *nkv;
+	struct csr1212_keyval_img *kvi;
+
+	for (kv = cache->layout_head; kv != cache->layout_tail->next; kv = nkv) {
+		kvi = (struct csr1212_keyval_img *)
+			(cache->data + bytes_to_quads(kv->offset - cache->offset));
+		switch(kv->key.type) {
+		default:
+		case CSR1212_KV_TYPE_IMMEDIATE:
+		case CSR1212_KV_TYPE_CSR_OFFSET:
+			/* Should never get here */
+			break; /* GDB breakpoint */
+
+		case CSR1212_KV_TYPE_LEAF:
+			/* Don't copy over Extended ROM areas, they are
+			 * already filled out! */
+			if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
+				memcpy(kvi->data, kv->value.leaf.data,
+				       quads_to_bytes(kv->value.leaf.len));
+
+			kvi->length = CSR1212_CPU_TO_BE16(kv->value.leaf.len);
+			kvi->crc = csr1212_crc16(kvi->data, kv->value.leaf.len);
+			break;
+
+		case CSR1212_KV_TYPE_DIRECTORY:
+			csr1212_generate_tree_subdir(kv, kvi->data);
+
+			kvi->length = CSR1212_CPU_TO_BE16(kv->value.directory.len);
+			kvi->crc = csr1212_crc16(kvi->data, kv->value.directory.len);
+			break;
+		}
+
+		nkv = kv->next;
+		if (kv->prev)
+			kv->prev->next = NULL;
+		if (kv->next)
+			kv->next->prev = NULL;
+		kv->prev = NULL;
+		kv->next = NULL;
+	}
+}
+
+int csr1212_generate_csr_image(struct csr1212_csr *csr)
+{
+	struct csr1212_bus_info_block_img *bi;
+	struct csr1212_csr_rom_cache *cache;
+	struct csr1212_keyval *kv;
+	size_t agg_size;
+	int ret;
+	int init_offset;
+
+	if (!csr)
+		return CSR1212_EINVAL;
+
+	cache = csr->cache_head;
+
+	bi = (struct csr1212_bus_info_block_img*)cache->data;
+
+	bi->length = bytes_to_quads(csr->bus_info_len) - 1;
+	bi->crc_length = bi->length;
+	bi->crc = csr1212_crc16(bi->data, bi->crc_length);
+
+	csr->root_kv->next = NULL;
+	csr->root_kv->prev = NULL;
+
+	agg_size = csr1212_generate_layout_order(csr->root_kv);
+
+	init_offset = csr->bus_info_len;
+
+	for (kv = csr->root_kv, cache = csr->cache_head; kv; cache = cache->next) {
+		if (!cache) {
+			/* Estimate approximate number of additional cache
+			 * regions needed (it assumes that the cache holding
+			 * the first 1K Config ROM space always exists). */
+			int est_c = agg_size / (CSR1212_EXTENDED_ROM_SIZE -
+						(2 * sizeof(u_int32_t))) + 1;
+
+			/* Add additional cache regions, extras will be
+			 * removed later */
+			for (; est_c; est_c--) {
+				ret = csr1212_append_new_cache(csr, CSR1212_EXTENDED_ROM_SIZE);
+				if (ret != CSR1212_SUCCESS)
+					return ret;
+			}
+			/* Need to re-layout for additional cache regions */
+			agg_size = csr1212_generate_layout_order(csr->root_kv);
+			kv = csr->root_kv;
+			cache = csr->cache_head;
+			init_offset = csr->bus_info_len;
+		}
+		kv = csr1212_generate_positions(cache, kv, init_offset);
+		agg_size -= cache->len;
+		init_offset = sizeof(u_int32_t);
+	}
+
+	/* Remove unused, excess cache regions */
+	while (cache) {
+		struct csr1212_csr_rom_cache *oc = cache;
+
+		cache = cache->next;
+		csr1212_remove_cache(csr, oc);
+	}
+
+	/* Go through the list backward so that when done, the correct CRC
+	 * will be calculated for the Extended ROM areas. */
+	for(cache = csr->cache_tail; cache; cache = cache->prev) {
+		/* Only Extended ROM caches should have this set. */
+		if (cache->ext_rom) {
+			int leaf_size;
+
+			/* Make sure the Extended ROM leaf is a multiple of
+			 * max_rom in size. */
+			leaf_size = (cache->len + (csr->max_rom - 1)) &
+				~(csr->max_rom - 1);
+
+			/* Zero out the unused ROM region */
+			memset(cache->data + bytes_to_quads(cache->len), 0x00,
+			       leaf_size - cache->len);
+
+			/* Subtract leaf header */
+			leaf_size -= sizeof(u_int32_t);
+
+			/* Update the Extended ROM leaf length */
+			cache->ext_rom->value.leaf.len =
+				bytes_to_quads(leaf_size);
+		} else {
+			/* Zero out the unused ROM region */
+			memset(cache->data + bytes_to_quads(cache->len), 0x00,
+			       cache->size - cache->len);
+		}
+
+		/* Copy the data into the cache buffer */
+		csr1212_fill_cache(cache);
+
+		if (cache != csr->cache_head) {
+			/* Set the length and CRC of the extended ROM. */
+			struct csr1212_keyval_img *kvi =
+				(struct csr1212_keyval_img*)cache->data;
+
+			kvi->length = CSR1212_CPU_TO_BE16(bytes_to_quads(cache->len) - 1);
+			kvi->crc = csr1212_crc16(kvi->data,
+						 bytes_to_quads(cache->len) - 1);
+
+		}
+	}
+
+	return CSR1212_SUCCESS;
+}
+
+int csr1212_read(struct csr1212_csr *csr, u_int32_t offset, void *buffer, u_int32_t len)
+{
+	struct csr1212_csr_rom_cache *cache;
+
+	for (cache = csr->cache_head; cache; cache = cache->next) {
+		if (offset >= cache->offset &&
+		    (offset + len) <= (cache->offset + cache->size)) {
+			memcpy(buffer,
+			       &cache->data[bytes_to_quads(offset - cache->offset)],
+			       len);
+			return CSR1212_SUCCESS;
+		}
+	}
+	return CSR1212_ENOENT;
+}
+
+
+
+/* Parse a chunk of data as a Config ROM */
+
+static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
+{
+	struct csr1212_bus_info_block_img *bi;
+	struct csr1212_cache_region *cr;
+	int i;
+	int ret;
+
+	/* IEEE 1212 says that the entire bus info block should be readable in
+	 * a single transaction regardless of the max_rom value.
+	 * Unfortunately, many IEEE 1394 devices do not abide by that, so the
+	 * bus info block will be read 1 quadlet at a time.  The rest of the
+	 * ConfigROM will be read according to the max_rom field. */
+	for (i = 0; i < csr->bus_info_len; i += sizeof(csr1212_quad_t)) {
+		ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
+					 sizeof(csr1212_quad_t),
+					 &csr->cache_head->data[bytes_to_quads(i)],
+					 csr->private);
+		if (ret != CSR1212_SUCCESS)
+			return ret;
+	}
+
+	bi = (struct csr1212_bus_info_block_img*)csr->cache_head->data;
+	csr->crc_len = quads_to_bytes(bi->crc_length);
+
+	/* IEEE 1212 recommends that crc_len be equal to bus_info_len, but that is not
+	 * always the case, so read the rest of the crc area 1 quadlet at a time. */
+	for (i = csr->bus_info_len; i <= csr->crc_len; i += sizeof(csr1212_quad_t)) {
+		ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
+					 sizeof(csr1212_quad_t),
+					 &csr->cache_head->data[bytes_to_quads(i)],
+					 csr->private);
+		if (ret != CSR1212_SUCCESS)
+			return ret;
+	}
+
+	if (bytes_to_quads(csr->bus_info_len - sizeof(csr1212_quad_t)) != bi->length)
+		return CSR1212_EINVAL;
+
+#if 0
+	/* Apparently there are too many differnt wrong implementations of the
+	 * CRC algorithm that verifying them is moot. */
+	if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
+	    (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
+		return CSR1212_EINVAL;
+#endif
+
+	cr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+	if (!cr)
+		return CSR1212_ENOMEM;
+
+	cr->next = NULL;
+	cr->prev = NULL;
+	cr->offset_start = 0;
+	cr->offset_end = csr->crc_len + 4;
+
+	csr->cache_head->filled_head = cr;
+	csr->cache_head->filled_tail = cr;
+
+	return CSR1212_SUCCESS;
+}
+
+static int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
+				   csr1212_quad_t ki,
+				   u_int32_t kv_pos)
+{
+	int ret = CSR1212_SUCCESS;
+	struct csr1212_keyval *k = NULL;
+	u_int32_t offset;
+
+	switch(CSR1212_KV_KEY_TYPE(ki)) {
+	case CSR1212_KV_TYPE_IMMEDIATE:
+		k = csr1212_new_immediate(CSR1212_KV_KEY_ID(ki),
+					  CSR1212_KV_VAL(ki));
+		if (!k) {
+			ret = CSR1212_ENOMEM;
+			goto fail;
+		}
+
+		k->refcnt = 0;	/* Don't keep local reference when parsing. */
+		break;
+
+	case CSR1212_KV_TYPE_CSR_OFFSET:
+		k = csr1212_new_csr_offset(CSR1212_KV_KEY_ID(ki),
+					   CSR1212_KV_VAL(ki));
+		if (!k) {
+			ret = CSR1212_ENOMEM;
+			goto fail;
+		}
+		k->refcnt = 0;	/* Don't keep local reference when parsing. */
+		break;
+
+	default:
+		/* Compute the offset from 0xffff f000 0000. */
+		offset = quads_to_bytes(CSR1212_KV_VAL(ki)) + kv_pos;
+		if (offset == kv_pos) {
+			/* Uh-oh.  Can't have a relative offset of 0 for Leaves
+			 * or Directories.  The Config ROM image is most likely
+			 * messed up, so we'll just abort here. */
+			ret = CSR1212_EIO;
+			goto fail;
+		}
+
+		k = csr1212_find_keyval_offset(dir, offset);
+
+		if (k)
+			break;		/* Found it. */
+
+		if (CSR1212_KV_KEY_TYPE(ki) == CSR1212_KV_TYPE_DIRECTORY) {
+			k = csr1212_new_directory(CSR1212_KV_KEY_ID(ki));
+		} else {
+			k = csr1212_new_leaf(CSR1212_KV_KEY_ID(ki), NULL, 0);
+		}
+		if (!k) {
+			ret = CSR1212_ENOMEM;
+			goto fail;
+		}
+		k->refcnt = 0;	/* Don't keep local reference when parsing. */
+		k->valid = 0;	/* Contents not read yet so it's not valid. */
+		k->offset = offset;
+
+		k->prev = dir;
+		k->next = dir->next;
+		dir->next->prev = k;
+		dir->next = k;
+	}
+	ret = csr1212_attach_keyval_to_directory(dir, k);
+
+fail:
+	if (ret != CSR1212_SUCCESS) {
+		if (k)
+			free_keyval(k);
+	}
+	return ret;
+}
+
+
+int csr1212_parse_keyval(struct csr1212_keyval *kv,
+			 struct csr1212_csr_rom_cache *cache)
+{
+	struct csr1212_keyval_img *kvi;
+	int i;
+	int ret = CSR1212_SUCCESS;
+	int kvi_len;
+
+	kvi = (struct csr1212_keyval_img*)&cache->data[bytes_to_quads(kv->offset -
+								      cache->offset)];
+	kvi_len = CSR1212_BE16_TO_CPU(kvi->length);
+
+#if 0
+	/* Apparently there are too many differnt wrong implementations of the
+	 * CRC algorithm that verifying them is moot. */
+	if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
+	    (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) {
+		ret = CSR1212_EINVAL;
+		goto fail;
+	}
+#endif
+
+	switch(kv->key.type) {
+	case CSR1212_KV_TYPE_DIRECTORY:
+		for (i = 0; i < kvi_len; i++) {
+			csr1212_quad_t ki = kvi->data[i];
+
+			/* Some devices put null entries in their unit
+			 * directories.  If we come across such an entry,
+			 * then skip it. */
+			if (ki == 0x0)
+				continue;
+			ret = csr1212_parse_dir_entry(kv, ki,
+						      (kv->offset +
+						       quads_to_bytes(i + 1)));
+		}
+		kv->value.directory.len = kvi_len;
+		break;
+
+	case CSR1212_KV_TYPE_LEAF:
+		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
+			kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
+			if (!kv->value.leaf.data)
+			{
+				ret = CSR1212_ENOMEM;
+				goto fail;
+			}
+
+			kv->value.leaf.len = kvi_len;
+			memcpy(kv->value.leaf.data, kvi->data, quads_to_bytes(kvi_len));
+		}
+		break;
+	}
+
+	kv->valid = 1;
+
+fail:
+	return ret;
+}
+
+
+int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
+{
+	struct csr1212_cache_region *cr, *ncr, *newcr = NULL;
+	struct csr1212_keyval_img *kvi = NULL;
+	struct csr1212_csr_rom_cache *cache;
+	int cache_index;
+	u_int64_t addr;
+	u_int32_t *cache_ptr;
+	u_int16_t kv_len = 0;
+
+	if (!csr || !kv)
+		return CSR1212_EINVAL;
+
+	/* First find which cache the data should be in (or go in if not read
+	 * yet). */
+	for (cache = csr->cache_head; cache; cache = cache->next) {
+		if (kv->offset >= cache->offset &&
+		    kv->offset < (cache->offset + cache->size))
+			break;
+	}
+
+	if (!cache) {
+		csr1212_quad_t q;
+		u_int32_t cache_size;
+
+		/* Only create a new cache for Extended ROM leaves. */
+		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
+			return CSR1212_EINVAL;
+
+		if (csr->ops->bus_read(csr,
+				       CSR1212_REGISTER_SPACE_BASE + kv->offset,
+				       sizeof(csr1212_quad_t), &q, csr->private)) {
+			return CSR1212_EIO;
+		}
+
+		kv->value.leaf.len = CSR1212_BE32_TO_CPU(q) >> 16;
+
+		cache_size = (quads_to_bytes(kv->value.leaf.len + 1) +
+			      (csr->max_rom - 1)) & ~(csr->max_rom - 1);
+
+		cache = csr1212_rom_cache_malloc(kv->offset, cache_size);
+		if (!cache)
+			return CSR1212_ENOMEM;
+
+		kv->value.leaf.data = &cache->data[1];
+		csr->cache_tail->next = cache;
+		cache->prev = csr->cache_tail;
+		cache->next = NULL;
+		csr->cache_tail = cache;
+		cache->filled_head =
+			CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+		if (!cache->filled_head) {
+			return CSR1212_ENOMEM;
+		}
+
+		cache->filled_head->offset_start = 0;
+		cache->filled_head->offset_end = sizeof(csr1212_quad_t);
+		cache->filled_tail = cache->filled_head;
+		cache->filled_head->next = NULL;
+		cache->filled_head->prev = NULL;
+		cache->data[0] = q;
+
+		/* Don't read the entire extended ROM now.  Pieces of it will
+		 * be read when entries inside it are read. */
+		return csr1212_parse_keyval(kv, cache);
+	}
+
+	cache_index = kv->offset - cache->offset;
+
+	/* Now seach read portions of the cache to see if it is there. */
+	for (cr = cache->filled_head; cr; cr = cr->next) {
+		if (cache_index < cr->offset_start) {
+			newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+			if (!newcr)
+				return CSR1212_ENOMEM;
+
+			newcr->offset_start = cache_index & ~(csr->max_rom - 1);
+			newcr->offset_end = newcr->offset_start;
+			newcr->next = cr;
+			newcr->prev = cr->prev;
+			cr->prev = newcr;
+			cr = newcr;
+			break;
+		} else if ((cache_index >= cr->offset_start) &&
+			   (cache_index < cr->offset_end)) {
+			kvi = (struct csr1212_keyval_img*)
+				(&cache->data[bytes_to_quads(cache_index)]);
+			kv_len = quads_to_bytes(CSR1212_BE16_TO_CPU(kvi->length) +
+						1);
+			break;
+		} else if (cache_index == cr->offset_end)
+			break;
+	}
+
+	if (!cr) {
+		cr = cache->filled_tail;
+		newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+		if (!newcr)
+			return CSR1212_ENOMEM;
+
+		newcr->offset_start = cache_index & ~(csr->max_rom - 1);
+		newcr->offset_end = newcr->offset_start;
+		newcr->prev = cr;
+		newcr->next = cr->next;
+		cr->next = newcr;
+		cr = newcr;
+		cache->filled_tail = newcr;
+	}
+
+	while(!kvi || cr->offset_end < cache_index + kv_len) {
+		cache_ptr = &cache->data[bytes_to_quads(cr->offset_end &
+							~(csr->max_rom - 1))];
+
+		addr = (CSR1212_CSR_ARCH_REG_SPACE_BASE + cache->offset +
+			cr->offset_end) & ~(csr->max_rom - 1);
+
+		if (csr->ops->bus_read(csr, addr, csr->max_rom, cache_ptr,
+				       csr->private)) {
+			if (csr->max_rom == 4)
+				/* We've got problems! */
+				return CSR1212_EIO;
+
+			/* Apperently the max_rom value was a lie, set it to
+			 * do quadlet reads and try again. */
+			csr->max_rom = 4;
+			continue;
+		}
+
+		cr->offset_end += csr->max_rom - (cr->offset_end &
+						  (csr->max_rom - 1));
+
+		if (!kvi && (cr->offset_end > cache_index)) {
+			kvi = (struct csr1212_keyval_img*)
+				(&cache->data[bytes_to_quads(cache_index)]);
+			kv_len = quads_to_bytes(CSR1212_BE16_TO_CPU(kvi->length) +
+						1);
+		}
+
+		if ((kv_len + (kv->offset - cache->offset)) > cache->size) {
+			/* The Leaf or Directory claims its length extends
+			 * beyond the ConfigROM image region and thus beyond the
+			 * end of our cache region.  Therefore, we abort now
+			 * rather than seg faulting later. */
+			return CSR1212_EIO;
+		}
+
+		ncr = cr->next;
+
+		if (ncr && (cr->offset_end >= ncr->offset_start)) {
+			/* consolidate region entries */
+			ncr->offset_start = cr->offset_start;
+
+			if (cr->prev)
+				cr->prev->next = cr->next;
+			ncr->prev = cr->prev;
+			if (cache->filled_head == cr)
+				cache->filled_head = ncr;
+			CSR1212_FREE(cr);
+			cr = ncr;
+		}
+	}
+
+	return csr1212_parse_keyval(kv, cache);
+}
+
+
+
+int csr1212_parse_csr(struct csr1212_csr *csr)
+{
+	static const int mr_map[] = { 4, 64, 1024, 0 };
+	struct csr1212_dentry *dentry;
+	int ret;
+
+	if (!csr || !csr->ops->bus_read)
+		return CSR1212_EINVAL;
+
+	ret = csr1212_parse_bus_info_block(csr);
+	if (ret != CSR1212_SUCCESS)
+		return ret;
+
+	if (!csr->ops->get_max_rom)
+		csr->max_rom = mr_map[0];	/* default value */
+	else
+		csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data,
+							    csr->private)];
+
+	csr->cache_head->layout_head = csr->root_kv;
+	csr->cache_head->layout_tail = csr->root_kv;
+
+	csr->root_kv->offset = (CSR1212_CONFIG_ROM_SPACE_BASE & 0xffff) +
+		csr->bus_info_len;
+
+	csr->root_kv->valid = 0;
+	csr->root_kv->next = csr->root_kv;
+	csr->root_kv->prev = csr->root_kv;
+	csr1212_get_keyval(csr, csr->root_kv);
+
+	/* Scan through the Root directory finding all extended ROM regions
+	 * and make cache regions for them */
+	for (dentry = csr->root_kv->value.directory.dentries_head;
+	     dentry; dentry = dentry->next) {
+		if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
+			csr1212_get_keyval(csr, dentry->kv);
+
+			if (ret != CSR1212_SUCCESS)
+				return ret;
+		}
+	}
+
+	return CSR1212_SUCCESS;
+}
