[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / drivers / ieee1394 / csr1212.c
blob7c4330e2e875b8e41d92bfc447e3f9aca5c93bc6
1 /*
2 * csr1212.c -- IEEE 1212 Control and Status Register support for Linux
4 * Copyright (C) 2003 Francois Retief <fgretief@sun.ac.za>
5 * Steve Kinneberg <kinnebergsteve@acmsystems.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /* TODO List:
32 * - Verify interface consistency: i.e., public functions that take a size
33 * parameter expect size to be in bytes.
34 * - Convenience functions for reading a block of data from a given offset.
37 #ifndef __KERNEL__
38 #include <string.h>
39 #endif
41 #include "csr1212.h"
44 /* Permitted key type for each key id */
45 #define __I (1 << CSR1212_KV_TYPE_IMMEDIATE)
46 #define __C (1 << CSR1212_KV_TYPE_CSR_OFFSET)
47 #define __D (1 << CSR1212_KV_TYPE_DIRECTORY)
48 #define __L (1 << CSR1212_KV_TYPE_LEAF)
49 static const u_int8_t csr1212_key_id_type_map[0x30] = {
50 0, /* Reserved */
51 __D | __L, /* Descriptor */
52 __I | __D | __L, /* Bus_Dependent_Info */
53 __I | __D | __L, /* Vendor */
54 __I, /* Hardware_Version */
55 0, 0, /* Reserved */
56 __D | __L, /* Module */
57 0, 0, 0, 0, /* Reserved */
58 __I, /* Node_Capabilities */
59 __L, /* EUI_64 */
60 0, 0, 0, /* Reserved */
61 __D, /* Unit */
62 __I, /* Specifier_ID */
63 __I, /* Version */
64 __I | __C | __D | __L, /* Dependent_Info */
65 __L, /* Unit_Location */
66 0, /* Reserved */
67 __I, /* Model */
68 __D, /* Instance */
69 __L, /* Keyword */
70 __D, /* Feature */
71 __L, /* Extended_ROM */
72 __I, /* Extended_Key_Specifier_ID */
73 __I, /* Extended_Key */
74 __I | __C | __D | __L, /* Extended_Data */
75 __L, /* Modifiable_Descriptor */
76 __I, /* Directory_ID */
77 __I, /* Revision */
79 #undef __I
80 #undef __C
81 #undef __D
82 #undef __L
85 #define quads_to_bytes(_q) ((_q) * sizeof(u_int32_t))
86 #define bytes_to_quads(_b) (((_b) + sizeof(u_int32_t) - 1) / sizeof(u_int32_t))
88 static inline void free_keyval(struct csr1212_keyval *kv)
90 if ((kv->key.type == CSR1212_KV_TYPE_LEAF) &&
91 (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM))
92 CSR1212_FREE(kv->value.leaf.data);
94 CSR1212_FREE(kv);
97 static u_int16_t csr1212_crc16(const u_int32_t *buffer, size_t length)
99 int shift;
100 u_int32_t data;
101 u_int16_t sum, crc = 0;
103 for (; length; length--) {
104 data = CSR1212_BE32_TO_CPU(*buffer);
105 buffer++;
106 for (shift = 28; shift >= 0; shift -= 4 ) {
107 sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
108 crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
110 crc &= 0xffff;
113 return CSR1212_CPU_TO_BE16(crc);
116 #if 0
117 /* Microsoft computes the CRC with the bytes in reverse order. Therefore we
118 * have a special version of the CRC algorithm to account for their buggy
119 * software. */
120 static u_int16_t csr1212_msft_crc16(const u_int32_t *buffer, size_t length)
122 int shift;
123 u_int32_t data;
124 u_int16_t sum, crc = 0;
126 for (; length; length--) {
127 data = CSR1212_LE32_TO_CPU(*buffer);
128 buffer++;
129 for (shift = 28; shift >= 0; shift -= 4 ) {
130 sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
131 crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
133 crc &= 0xffff;
136 return CSR1212_CPU_TO_BE16(crc);
138 #endif
140 static inline struct csr1212_dentry *csr1212_find_keyval(struct csr1212_keyval *dir,
141 struct csr1212_keyval *kv)
143 struct csr1212_dentry *pos;
145 for (pos = dir->value.directory.dentries_head;
146 pos != NULL; pos = pos->next) {
147 if (pos->kv == kv)
148 return pos;
150 return NULL;
154 static inline struct csr1212_keyval *csr1212_find_keyval_offset(struct csr1212_keyval *kv_list,
155 u_int32_t offset)
157 struct csr1212_keyval *kv;
159 for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next) {
160 if (kv->offset == offset)
161 return kv;
163 return NULL;
167 /* Creation Routines */
168 struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
169 size_t bus_info_size, void *private)
171 struct csr1212_csr *csr;
173 csr = CSR1212_MALLOC(sizeof(*csr));
174 if (!csr)
175 return NULL;
177 csr->cache_head =
178 csr1212_rom_cache_malloc(CSR1212_CONFIG_ROM_SPACE_OFFSET,
179 CSR1212_CONFIG_ROM_SPACE_SIZE);
180 if (!csr->cache_head) {
181 CSR1212_FREE(csr);
182 return NULL;
185 /* The keyval key id is not used for the root node, but a valid key id
186 * that can be used for a directory needs to be passed to
187 * csr1212_new_directory(). */
188 csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR);
189 if (!csr->root_kv) {
190 CSR1212_FREE(csr->cache_head);
191 CSR1212_FREE(csr);
192 return NULL;
195 csr->bus_info_data = csr->cache_head->data;
196 csr->bus_info_len = bus_info_size;
197 csr->crc_len = bus_info_size;
198 csr->ops = ops;
199 csr->private = private;
200 csr->cache_tail = csr->cache_head;
202 return csr;
207 void csr1212_init_local_csr(struct csr1212_csr *csr,
208 const u_int32_t *bus_info_data, int max_rom)
210 static const int mr_map[] = { 4, 64, 1024, 0 };
212 csr->max_rom = mr_map[max_rom];
213 memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
217 static struct csr1212_keyval *csr1212_new_keyval(u_int8_t type, u_int8_t key)
219 struct csr1212_keyval *kv;
221 if (key < 0x30 && ((csr1212_key_id_type_map[key] & (1 << type)) == 0))
222 return NULL;
224 kv = CSR1212_MALLOC(sizeof(*kv));
225 if (!kv)
226 return NULL;
228 kv->key.type = type;
229 kv->key.id = key;
231 kv->associate = NULL;
232 kv->refcnt = 1;
234 kv->next = NULL;
235 kv->prev = NULL;
236 kv->offset = 0;
237 kv->valid = 0;
238 return kv;
241 struct csr1212_keyval *csr1212_new_immediate(u_int8_t key, u_int32_t value)
243 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key);
245 if (!kv)
246 return NULL;
248 kv->value.immediate = value;
249 kv->valid = 1;
250 return kv;
253 struct csr1212_keyval *csr1212_new_leaf(u_int8_t key, const void *data, size_t data_len)
255 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, key);
257 if (!kv)
258 return NULL;
260 if (data_len > 0) {
261 kv->value.leaf.data = CSR1212_MALLOC(data_len);
262 if (!kv->value.leaf.data) {
263 CSR1212_FREE(kv);
264 return NULL;
267 if (data)
268 memcpy(kv->value.leaf.data, data, data_len);
269 } else {
270 kv->value.leaf.data = NULL;
273 kv->value.leaf.len = bytes_to_quads(data_len);
274 kv->offset = 0;
275 kv->valid = 1;
277 return kv;
280 struct csr1212_keyval *csr1212_new_csr_offset(u_int8_t key, u_int32_t csr_offset)
282 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_CSR_OFFSET, key);
284 if (!kv)
285 return NULL;
287 kv->value.csr_offset = csr_offset;
289 kv->offset = 0;
290 kv->valid = 1;
291 return kv;
294 struct csr1212_keyval *csr1212_new_directory(u_int8_t key)
296 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_DIRECTORY, key);
298 if (!kv)
299 return NULL;
301 kv->value.directory.len = 0;
302 kv->offset = 0;
303 kv->value.directory.dentries_head = NULL;
304 kv->value.directory.dentries_tail = NULL;
305 kv->valid = 1;
306 return kv;
309 int csr1212_associate_keyval(struct csr1212_keyval *kv,
310 struct csr1212_keyval *associate)
312 if (!kv || !associate)
313 return CSR1212_EINVAL;
315 if (kv->key.id == CSR1212_KV_ID_DESCRIPTOR ||
316 (associate->key.id != CSR1212_KV_ID_DESCRIPTOR &&
317 associate->key.id != CSR1212_KV_ID_DEPENDENT_INFO &&
318 associate->key.id != CSR1212_KV_ID_EXTENDED_KEY &&
319 associate->key.id != CSR1212_KV_ID_EXTENDED_DATA &&
320 associate->key.id < 0x30))
321 return CSR1212_EINVAL;
323 if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID &&
324 associate->key.id != CSR1212_KV_ID_EXTENDED_KEY)
325 return CSR1212_EINVAL;
327 if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
328 associate->key.id != CSR1212_KV_ID_EXTENDED_DATA)
329 return CSR1212_EINVAL;
331 if (associate->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
332 kv->key.id != CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID)
333 return CSR1212_EINVAL;
335 if (associate->key.id == CSR1212_KV_ID_EXTENDED_DATA &&
336 kv->key.id != CSR1212_KV_ID_EXTENDED_KEY)
337 return CSR1212_EINVAL;
339 if (kv->associate)
340 csr1212_release_keyval(kv->associate);
342 associate->refcnt++;
343 kv->associate = associate;
345 return CSR1212_SUCCESS;
348 int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
349 struct csr1212_keyval *kv)
351 struct csr1212_dentry *dentry;
353 if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
354 return CSR1212_EINVAL;
356 dentry = CSR1212_MALLOC(sizeof(*dentry));
357 if (!dentry)
358 return CSR1212_ENOMEM;
360 dentry->kv = kv;
362 kv->refcnt++;
364 dentry->next = NULL;
365 dentry->prev = dir->value.directory.dentries_tail;
367 if (!dir->value.directory.dentries_head)
368 dir->value.directory.dentries_head = dentry;
370 if (dir->value.directory.dentries_tail)
371 dir->value.directory.dentries_tail->next = dentry;
372 dir->value.directory.dentries_tail = dentry;
374 return CSR1212_SUCCESS;
377 struct csr1212_keyval *csr1212_new_extended_immediate(u_int32_t spec, u_int32_t key,
378 u_int32_t value)
380 struct csr1212_keyval *kvs, *kvk, *kvv;
382 kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
383 kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
384 kvv = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_DATA, value);
386 if (!kvs || !kvk || !kvv) {
387 if (kvs)
388 free_keyval(kvs);
389 if (kvk)
390 free_keyval(kvk);
391 if (kvv)
392 free_keyval(kvv);
393 return NULL;
396 /* Don't keep a local reference to the extended key or value. */
397 kvk->refcnt = 0;
398 kvv->refcnt = 0;
400 csr1212_associate_keyval(kvk, kvv);
401 csr1212_associate_keyval(kvs, kvk);
403 return kvs;
406 struct csr1212_keyval *csr1212_new_extended_leaf(u_int32_t spec, u_int32_t key,
407 const void *data, size_t data_len)
409 struct csr1212_keyval *kvs, *kvk, *kvv;
411 kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
412 kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
413 kvv = csr1212_new_leaf(CSR1212_KV_ID_EXTENDED_DATA, data, data_len);
415 if (!kvs || !kvk || !kvv) {
416 if (kvs)
417 free_keyval(kvs);
418 if (kvk)
419 free_keyval(kvk);
420 if (kvv)
421 free_keyval(kvv);
422 return NULL;
425 /* Don't keep a local reference to the extended key or value. */
426 kvk->refcnt = 0;
427 kvv->refcnt = 0;
429 csr1212_associate_keyval(kvk, kvv);
430 csr1212_associate_keyval(kvs, kvk);
432 return kvs;
435 struct csr1212_keyval *csr1212_new_descriptor_leaf(u_int8_t dtype, u_int32_t specifier_id,
436 const void *data, size_t data_len)
438 struct csr1212_keyval *kv;
440 kv = csr1212_new_leaf(CSR1212_KV_ID_DESCRIPTOR, NULL,
441 data_len + CSR1212_DESCRIPTOR_LEAF_OVERHEAD);
442 if (!kv)
443 return NULL;
445 CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, dtype);
446 CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, specifier_id);
448 if (data) {
449 memcpy(CSR1212_DESCRIPTOR_LEAF_DATA(kv), data, data_len);
452 return kv;
456 struct csr1212_keyval *csr1212_new_textual_descriptor_leaf(u_int8_t cwidth,
457 u_int16_t cset,
458 u_int16_t language,
459 const void *data,
460 size_t data_len)
462 struct csr1212_keyval *kv;
463 char *lstr;
465 kv = csr1212_new_descriptor_leaf(0, 0, NULL, data_len +
466 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD);
467 if (!kv)
468 return NULL;
470 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_WIDTH(kv, cwidth);
471 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_CHAR_SET(kv, cset);
472 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
474 lstr = (char*)CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(kv);
476 /* make sure last quadlet is zeroed out */
477 *((u_int32_t*)&(lstr[(data_len - 1) & ~0x3])) = 0;
479 /* don't copy the NUL terminator */
480 memcpy(lstr, data, data_len);
482 return kv;
485 static int csr1212_check_minimal_ascii(const char *s)
487 static const char minimal_ascii_table[] = {
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
489 0x00, 0x00, 0x0a, 0x00, 0x0C, 0x0D, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x20, 0x21, 0x22, 0x00, 0x00, 0x25, 0x26, 0x27,
493 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
494 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
495 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
496 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
497 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
498 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
499 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5f,
500 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
501 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
502 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
503 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
505 for (; *s; s++) {
506 if (minimal_ascii_table[*s & 0x7F] != *s)
507 return -1; /* failed */
509 /* String conforms to minimal-ascii, as specified by IEEE 1212,
510 * par. 7.4 */
511 return 0;
514 struct csr1212_keyval *csr1212_new_string_descriptor_leaf(const char *s)
516 /* Check if string conform to minimal_ascii format */
517 if (csr1212_check_minimal_ascii(s))
518 return NULL;
520 /* IEEE 1212, par. 7.5.4.1 Textual descriptors (minimal ASCII) */
521 return csr1212_new_textual_descriptor_leaf(0, 0, 0, s, strlen(s));
524 struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version,
525 u_int8_t palette_depth,
526 u_int8_t color_space,
527 u_int16_t language,
528 u_int16_t hscan,
529 u_int16_t vscan,
530 u_int32_t *palette,
531 u_int32_t *pixels)
533 static const int pd[4] = { 0, 4, 16, 256 };
534 static const int cs[16] = { 4, 2 };
535 struct csr1212_keyval *kv;
536 int palette_size = pd[palette_depth] * cs[color_space];
537 int pixel_size = (hscan * vscan + 3) & ~0x3;
539 if ((palette_depth && !palette) || !pixels)
540 return NULL;
542 kv = csr1212_new_descriptor_leaf(1, 0, NULL,
543 palette_size + pixel_size +
544 CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
545 if (!kv)
546 return NULL;
548 CSR1212_ICON_DESCRIPTOR_LEAF_SET_VERSION(kv, version);
549 CSR1212_ICON_DESCRIPTOR_LEAF_SET_PALETTE_DEPTH(kv, palette_depth);
550 CSR1212_ICON_DESCRIPTOR_LEAF_SET_COLOR_SPACE(kv, color_space);
551 CSR1212_ICON_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
552 CSR1212_ICON_DESCRIPTOR_LEAF_SET_HSCAN(kv, hscan);
553 CSR1212_ICON_DESCRIPTOR_LEAF_SET_VSCAN(kv, vscan);
555 if (palette_size)
556 memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PALETTE(kv), palette,
557 palette_size);
559 memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PIXELS(kv), pixels, pixel_size);
561 return kv;
564 struct csr1212_keyval *csr1212_new_modifiable_descriptor_leaf(u_int16_t max_size,
565 u_int64_t address)
567 struct csr1212_keyval *kv;
569 /* IEEE 1212, par. 7.5.4.3 Modifiable descriptors */
570 kv = csr1212_new_leaf(CSR1212_KV_ID_MODIFIABLE_DESCRIPTOR, NULL, sizeof(u_int64_t));
571 if(!kv)
572 return NULL;
574 CSR1212_MODIFIABLE_DESCRIPTOR_SET_MAX_SIZE(kv, max_size);
575 CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_HI(kv, address);
576 CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_LO(kv, address);
578 return kv;
581 static int csr1212_check_keyword(const char *s)
583 for (; *s; s++) {
585 if (('A' <= *s) && (*s <= 'Z'))
586 continue;
587 if (('0' <= *s) && (*s <= '9'))
588 continue;
589 if (*s == '-')
590 continue;
592 return -1; /* failed */
594 /* String conforms to keyword, as specified by IEEE 1212,
595 * par. 7.6.5 */
596 return CSR1212_SUCCESS;
599 struct csr1212_keyval *csr1212_new_keyword_leaf(int strc, const char *strv[])
601 struct csr1212_keyval *kv;
602 char *buffer;
603 int i, data_len = 0;
605 /* Check all keywords to see if they conform to restrictions:
606 * Only the following characters is allowed ['A'..'Z','0'..'9','-']
607 * Each word is zero-terminated.
608 * Also calculate the total length of the keywords.
610 for (i = 0; i < strc; i++) {
611 if (!strv[i] || csr1212_check_keyword(strv[i])) {
612 return NULL;
614 data_len += strlen(strv[i]) + 1; /* Add zero-termination char. */
617 /* IEEE 1212, par. 7.6.5 Keyword leaves */
618 kv = csr1212_new_leaf(CSR1212_KV_ID_KEYWORD, NULL, data_len);
619 if (!kv)
620 return NULL;
622 buffer = (char *)kv->value.leaf.data;
624 /* make sure last quadlet is zeroed out */
625 *((u_int32_t*)&(buffer[(data_len - 1) & ~0x3])) = 0;
627 /* Copy keyword(s) into leaf data buffer */
628 for (i = 0; i < strc; i++) {
629 int len = strlen(strv[i]) + 1;
630 memcpy(buffer, strv[i], len);
631 buffer += len;
633 return kv;
637 /* Destruction Routines */
639 void csr1212_detach_keyval_from_directory(struct csr1212_keyval *dir,
640 struct csr1212_keyval *kv)
642 struct csr1212_dentry *dentry;
644 if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
645 return;
647 dentry = csr1212_find_keyval(dir, kv);
649 if (!dentry)
650 return;
652 if (dentry->prev)
653 dentry->prev->next = dentry->next;
654 if (dentry->next)
655 dentry->next->prev = dentry->prev;
656 if (dir->value.directory.dentries_head == dentry)
657 dir->value.directory.dentries_head = dentry->next;
658 if (dir->value.directory.dentries_tail == dentry)
659 dir->value.directory.dentries_tail = dentry->prev;
661 CSR1212_FREE(dentry);
663 csr1212_release_keyval(kv);
667 void csr1212_disassociate_keyval(struct csr1212_keyval *kv)
669 if (kv->associate) {
670 csr1212_release_keyval(kv->associate);
673 kv->associate = NULL;
677 /* This function is used to free the memory taken by a keyval. If the given
678 * keyval is a directory type, then any keyvals contained in that directory
679 * will be destroyed as well if their respective refcnts are 0. By means of
680 * list manipulation, this routine will descend a directory structure in a
681 * non-recursive manner. */
682 void _csr1212_destroy_keyval(struct csr1212_keyval *kv)
684 struct csr1212_keyval *k, *a;
685 struct csr1212_dentry dentry;
686 struct csr1212_dentry *head, *tail;
688 dentry.kv = kv;
689 dentry.next = NULL;
690 dentry.prev = NULL;
692 head = &dentry;
693 tail = head;
695 while (head) {
696 k = head->kv;
698 while (k) {
699 k->refcnt--;
701 if (k->refcnt > 0)
702 break;
704 a = k->associate;
706 if (k->key.type == CSR1212_KV_TYPE_DIRECTORY) {
707 /* If the current entry is a directory, then move all
708 * the entries to the destruction list. */
709 if (k->value.directory.dentries_head) {
710 tail->next = k->value.directory.dentries_head;
711 k->value.directory.dentries_head->prev = tail;
712 tail = k->value.directory.dentries_tail;
715 free_keyval(k);
716 k = a;
719 head = head->next;
720 if (head) {
721 if (head->prev && head->prev != &dentry) {
722 CSR1212_FREE(head->prev);
724 head->prev = NULL;
725 } else if (tail != &dentry)
726 CSR1212_FREE(tail);
731 void csr1212_destroy_csr(struct csr1212_csr *csr)
733 struct csr1212_csr_rom_cache *c, *oc;
734 struct csr1212_cache_region *cr, *ocr;
736 csr1212_release_keyval(csr->root_kv);
738 c = csr->cache_head;
739 while (c) {
740 oc = c;
741 cr = c->filled_head;
742 while (cr) {
743 ocr = cr;
744 cr = cr->next;
745 CSR1212_FREE(ocr);
747 c = c->next;
748 CSR1212_FREE(oc);
751 CSR1212_FREE(csr);
756 /* CSR Image Creation */
758 static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
760 struct csr1212_csr_rom_cache *cache;
761 u_int64_t csr_addr;
763 if (!csr || !csr->ops->allocate_addr_range ||
764 !csr->ops->release_addr)
765 return CSR1212_ENOMEM;
767 /* ROM size must be a multiple of csr->max_rom */
768 romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
770 csr_addr = csr->ops->allocate_addr_range(romsize, csr->max_rom, csr->private);
771 if (csr_addr == ~0ULL) {
772 return CSR1212_ENOMEM;
774 if (csr_addr < CSR1212_REGISTER_SPACE_BASE) {
775 /* Invalid address returned from allocate_addr_range(). */
776 csr->ops->release_addr(csr_addr, csr->private);
777 return CSR1212_ENOMEM;
780 cache = csr1212_rom_cache_malloc(csr_addr - CSR1212_REGISTER_SPACE_BASE, romsize);
781 if (!cache) {
782 csr->ops->release_addr(csr_addr, csr->private);
783 return CSR1212_ENOMEM;
786 cache->ext_rom = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, CSR1212_KV_ID_EXTENDED_ROM);
787 if (!cache->ext_rom) {
788 csr->ops->release_addr(csr_addr, csr->private);
789 CSR1212_FREE(cache);
790 return CSR1212_ENOMEM;
793 if (csr1212_attach_keyval_to_directory(csr->root_kv, cache->ext_rom) != CSR1212_SUCCESS) {
794 csr1212_release_keyval(cache->ext_rom);
795 csr->ops->release_addr(csr_addr, csr->private);
796 CSR1212_FREE(cache);
797 return CSR1212_ENOMEM;
799 cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE;
800 cache->ext_rom->value.leaf.len = -1;
801 cache->ext_rom->value.leaf.data = cache->data;
803 /* Add cache to tail of cache list */
804 cache->prev = csr->cache_tail;
805 csr->cache_tail->next = cache;
806 csr->cache_tail = cache;
807 return CSR1212_SUCCESS;
810 static inline void csr1212_remove_cache(struct csr1212_csr *csr,
811 struct csr1212_csr_rom_cache *cache)
813 if (csr->cache_head == cache)
814 csr->cache_head = cache->next;
815 if (csr->cache_tail == cache)
816 csr->cache_tail = cache->prev;
818 if (cache->prev)
819 cache->prev->next = cache->next;
820 if (cache->next)
821 cache->next->prev = cache->prev;
823 if (cache->ext_rom) {
824 csr1212_detach_keyval_from_directory(csr->root_kv, cache->ext_rom);
825 csr1212_release_keyval(cache->ext_rom);
828 CSR1212_FREE(cache);
831 static int csr1212_generate_layout_subdir(struct csr1212_keyval *dir,
832 struct csr1212_keyval **layout_tail)
834 struct csr1212_dentry *dentry;
835 struct csr1212_keyval *dkv;
836 struct csr1212_keyval *last_extkey_spec = NULL;
837 struct csr1212_keyval *last_extkey = NULL;
838 int num_entries = 0;
840 for (dentry = dir->value.directory.dentries_head; dentry;
841 dentry = dentry->next) {
842 for (dkv = dentry->kv; dkv; dkv = dkv->associate) {
843 /* Special Case: Extended Key Specifier_ID */
844 if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
845 if (last_extkey_spec == NULL) {
846 last_extkey_spec = dkv;
847 } else if (dkv->value.immediate != last_extkey_spec->value.immediate) {
848 last_extkey_spec = dkv;
849 } else {
850 continue;
852 /* Special Case: Extended Key */
853 } else if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
854 if (last_extkey == NULL) {
855 last_extkey = dkv;
856 } else if (dkv->value.immediate != last_extkey->value.immediate) {
857 last_extkey = dkv;
858 } else {
859 continue;
863 num_entries += 1;
865 switch(dkv->key.type) {
866 default:
867 case CSR1212_KV_TYPE_IMMEDIATE:
868 case CSR1212_KV_TYPE_CSR_OFFSET:
869 break;
870 case CSR1212_KV_TYPE_LEAF:
871 case CSR1212_KV_TYPE_DIRECTORY:
872 /* Remove from list */
873 if (dkv->prev && (dkv->prev->next == dkv))
874 dkv->prev->next = dkv->next;
875 if (dkv->next && (dkv->next->prev == dkv))
876 dkv->next->prev = dkv->prev;
877 //if (dkv == *layout_tail)
878 // *layout_tail = dkv->prev;
880 /* Special case: Extended ROM leafs */
881 if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
882 dkv->value.leaf.len = -1;
883 /* Don't add Extended ROM leafs in the layout list,
884 * they are handled differently. */
885 break;
888 /* Add to tail of list */
889 dkv->next = NULL;
890 dkv->prev = *layout_tail;
891 (*layout_tail)->next = dkv;
892 *layout_tail = dkv;
893 break;
897 return num_entries;
900 size_t csr1212_generate_layout_order(struct csr1212_keyval *kv)
902 struct csr1212_keyval *ltail = kv;
903 size_t agg_size = 0;
905 while(kv) {
906 switch(kv->key.type) {
907 case CSR1212_KV_TYPE_LEAF:
908 /* Add 1 quadlet for crc/len field */
909 agg_size += kv->value.leaf.len + 1;
910 break;
912 case CSR1212_KV_TYPE_DIRECTORY:
913 kv->value.directory.len = csr1212_generate_layout_subdir(kv, &ltail);
914 /* Add 1 quadlet for crc/len field */
915 agg_size += kv->value.directory.len + 1;
916 break;
918 kv = kv->next;
920 return quads_to_bytes(agg_size);
923 struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *cache,
924 struct csr1212_keyval *start_kv,
925 int start_pos)
927 struct csr1212_keyval *kv = start_kv;
928 struct csr1212_keyval *okv = start_kv;
929 int pos = start_pos;
930 int kv_len = 0, okv_len = 0;
932 cache->layout_head = kv;
934 while(kv && pos < cache->size) {
935 /* Special case: Extended ROM leafs */
936 if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
937 kv->offset = cache->offset + pos;
940 switch(kv->key.type) {
941 case CSR1212_KV_TYPE_LEAF:
942 kv_len = kv->value.leaf.len;
943 break;
945 case CSR1212_KV_TYPE_DIRECTORY:
946 kv_len = kv->value.directory.len;
947 break;
949 default:
950 /* Should never get here */
951 break;
954 pos += quads_to_bytes(kv_len + 1);
956 if (pos <= cache->size) {
957 okv = kv;
958 okv_len = kv_len;
959 kv = kv->next;
963 cache->layout_tail = okv;
964 cache->len = (okv->offset - cache->offset) + quads_to_bytes(okv_len + 1);
966 return kv;
969 static void csr1212_generate_tree_subdir(struct csr1212_keyval *dir,
970 u_int32_t *data_buffer)
972 struct csr1212_dentry *dentry;
973 struct csr1212_keyval *last_extkey_spec = NULL;
974 struct csr1212_keyval *last_extkey = NULL;
975 int index = 0;
977 for (dentry = dir->value.directory.dentries_head; dentry; dentry = dentry->next) {
978 struct csr1212_keyval *a;
980 for (a = dentry->kv; a; a = a->associate) {
981 u_int32_t value = 0;
983 /* Special Case: Extended Key Specifier_ID */
984 if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
985 if (last_extkey_spec == NULL) {
986 last_extkey_spec = a;
987 } else if (a->value.immediate != last_extkey_spec->value.immediate) {
988 last_extkey_spec = a;
989 } else {
990 continue;
992 /* Special Case: Extended Key */
993 } else if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
994 if (last_extkey == NULL) {
995 last_extkey = a;
996 } else if (a->value.immediate != last_extkey->value.immediate) {
997 last_extkey = a;
998 } else {
999 continue;
1003 switch(a->key.type) {
1004 case CSR1212_KV_TYPE_IMMEDIATE:
1005 value = a->value.immediate;
1006 break;
1007 case CSR1212_KV_TYPE_CSR_OFFSET:
1008 value = a->value.csr_offset;
1009 break;
1010 case CSR1212_KV_TYPE_LEAF:
1011 value = a->offset;
1012 value -= dir->offset + quads_to_bytes(1+index);
1013 value = bytes_to_quads(value);
1014 break;
1015 case CSR1212_KV_TYPE_DIRECTORY:
1016 value = a->offset;
1017 value -= dir->offset + quads_to_bytes(1+index);
1018 value = bytes_to_quads(value);
1019 break;
1020 default:
1021 /* Should never get here */
1022 break; /* GDB breakpoint */
1025 value |= (a->key.id & CSR1212_KV_KEY_ID_MASK) << CSR1212_KV_KEY_SHIFT;
1026 value |= (a->key.type & CSR1212_KV_KEY_TYPE_MASK) <<
1027 (CSR1212_KV_KEY_SHIFT + CSR1212_KV_KEY_TYPE_SHIFT);
1028 data_buffer[index] = CSR1212_CPU_TO_BE32(value);
1029 index++;
1034 void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache)
1036 struct csr1212_keyval *kv, *nkv;
1037 struct csr1212_keyval_img *kvi;
1039 for (kv = cache->layout_head; kv != cache->layout_tail->next; kv = nkv) {
1040 kvi = (struct csr1212_keyval_img *)
1041 (cache->data + bytes_to_quads(kv->offset - cache->offset));
1042 switch(kv->key.type) {
1043 default:
1044 case CSR1212_KV_TYPE_IMMEDIATE:
1045 case CSR1212_KV_TYPE_CSR_OFFSET:
1046 /* Should never get here */
1047 break; /* GDB breakpoint */
1049 case CSR1212_KV_TYPE_LEAF:
1050 /* Don't copy over Extended ROM areas, they are
1051 * already filled out! */
1052 if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
1053 memcpy(kvi->data, kv->value.leaf.data,
1054 quads_to_bytes(kv->value.leaf.len));
1056 kvi->length = CSR1212_CPU_TO_BE16(kv->value.leaf.len);
1057 kvi->crc = csr1212_crc16(kvi->data, kv->value.leaf.len);
1058 break;
1060 case CSR1212_KV_TYPE_DIRECTORY:
1061 csr1212_generate_tree_subdir(kv, kvi->data);
1063 kvi->length = CSR1212_CPU_TO_BE16(kv->value.directory.len);
1064 kvi->crc = csr1212_crc16(kvi->data, kv->value.directory.len);
1065 break;
1068 nkv = kv->next;
1069 if (kv->prev)
1070 kv->prev->next = NULL;
1071 if (kv->next)
1072 kv->next->prev = NULL;
1073 kv->prev = NULL;
1074 kv->next = NULL;
1078 int csr1212_generate_csr_image(struct csr1212_csr *csr)
1080 struct csr1212_bus_info_block_img *bi;
1081 struct csr1212_csr_rom_cache *cache;
1082 struct csr1212_keyval *kv;
1083 size_t agg_size;
1084 int ret;
1085 int init_offset;
1087 if (!csr)
1088 return CSR1212_EINVAL;
1090 cache = csr->cache_head;
1092 bi = (struct csr1212_bus_info_block_img*)cache->data;
1094 bi->length = bytes_to_quads(csr->bus_info_len) - 1;
1095 bi->crc_length = bi->length;
1096 bi->crc = csr1212_crc16(bi->data, bi->crc_length);
1098 csr->root_kv->next = NULL;
1099 csr->root_kv->prev = NULL;
1101 agg_size = csr1212_generate_layout_order(csr->root_kv);
1103 init_offset = csr->bus_info_len;
1105 for (kv = csr->root_kv, cache = csr->cache_head; kv; cache = cache->next) {
1106 if (!cache) {
1107 /* Estimate approximate number of additional cache
1108 * regions needed (it assumes that the cache holding
1109 * the first 1K Config ROM space always exists). */
1110 int est_c = agg_size / (CSR1212_EXTENDED_ROM_SIZE -
1111 (2 * sizeof(u_int32_t))) + 1;
1113 /* Add additional cache regions, extras will be
1114 * removed later */
1115 for (; est_c; est_c--) {
1116 ret = csr1212_append_new_cache(csr, CSR1212_EXTENDED_ROM_SIZE);
1117 if (ret != CSR1212_SUCCESS)
1118 return ret;
1120 /* Need to re-layout for additional cache regions */
1121 agg_size = csr1212_generate_layout_order(csr->root_kv);
1122 kv = csr->root_kv;
1123 cache = csr->cache_head;
1124 init_offset = csr->bus_info_len;
1126 kv = csr1212_generate_positions(cache, kv, init_offset);
1127 agg_size -= cache->len;
1128 init_offset = sizeof(u_int32_t);
1131 /* Remove unused, excess cache regions */
1132 while (cache) {
1133 struct csr1212_csr_rom_cache *oc = cache;
1135 cache = cache->next;
1136 csr1212_remove_cache(csr, oc);
1139 /* Go through the list backward so that when done, the correct CRC
1140 * will be calculated for the Extended ROM areas. */
1141 for(cache = csr->cache_tail; cache; cache = cache->prev) {
1142 /* Only Extended ROM caches should have this set. */
1143 if (cache->ext_rom) {
1144 int leaf_size;
1146 /* Make sure the Extended ROM leaf is a multiple of
1147 * max_rom in size. */
1148 leaf_size = (cache->len + (csr->max_rom - 1)) &
1149 ~(csr->max_rom - 1);
1151 /* Zero out the unused ROM region */
1152 memset(cache->data + bytes_to_quads(cache->len), 0x00,
1153 leaf_size - cache->len);
1155 /* Subtract leaf header */
1156 leaf_size -= sizeof(u_int32_t);
1158 /* Update the Extended ROM leaf length */
1159 cache->ext_rom->value.leaf.len =
1160 bytes_to_quads(leaf_size);
1161 } else {
1162 /* Zero out the unused ROM region */
1163 memset(cache->data + bytes_to_quads(cache->len), 0x00,
1164 cache->size - cache->len);
1167 /* Copy the data into the cache buffer */
1168 csr1212_fill_cache(cache);
1170 if (cache != csr->cache_head) {
1171 /* Set the length and CRC of the extended ROM. */
1172 struct csr1212_keyval_img *kvi =
1173 (struct csr1212_keyval_img*)cache->data;
1175 kvi->length = CSR1212_CPU_TO_BE16(bytes_to_quads(cache->len) - 1);
1176 kvi->crc = csr1212_crc16(kvi->data,
1177 bytes_to_quads(cache->len) - 1);
1182 return CSR1212_SUCCESS;
1185 int csr1212_read(struct csr1212_csr *csr, u_int32_t offset, void *buffer, u_int32_t len)
1187 struct csr1212_csr_rom_cache *cache;
1189 for (cache = csr->cache_head; cache; cache = cache->next) {
1190 if (offset >= cache->offset &&
1191 (offset + len) <= (cache->offset + cache->size)) {
1192 memcpy(buffer,
1193 &cache->data[bytes_to_quads(offset - cache->offset)],
1194 len);
1195 return CSR1212_SUCCESS;
1198 return CSR1212_ENOENT;
1203 /* Parse a chunk of data as a Config ROM */
1205 static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
1207 struct csr1212_bus_info_block_img *bi;
1208 struct csr1212_cache_region *cr;
1209 int i;
1210 int ret;
1212 /* IEEE 1212 says that the entire bus info block should be readable in
1213 * a single transaction regardless of the max_rom value.
1214 * Unfortunately, many IEEE 1394 devices do not abide by that, so the
1215 * bus info block will be read 1 quadlet at a time. The rest of the
1216 * ConfigROM will be read according to the max_rom field. */
1217 for (i = 0; i < csr->bus_info_len; i += sizeof(csr1212_quad_t)) {
1218 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
1219 sizeof(csr1212_quad_t),
1220 &csr->cache_head->data[bytes_to_quads(i)],
1221 csr->private);
1222 if (ret != CSR1212_SUCCESS)
1223 return ret;
1226 bi = (struct csr1212_bus_info_block_img*)csr->cache_head->data;
1227 csr->crc_len = quads_to_bytes(bi->crc_length);
1229 /* IEEE 1212 recommends that crc_len be equal to bus_info_len, but that is not
1230 * always the case, so read the rest of the crc area 1 quadlet at a time. */
1231 for (i = csr->bus_info_len; i <= csr->crc_len; i += sizeof(csr1212_quad_t)) {
1232 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
1233 sizeof(csr1212_quad_t),
1234 &csr->cache_head->data[bytes_to_quads(i)],
1235 csr->private);
1236 if (ret != CSR1212_SUCCESS)
1237 return ret;
1240 if (bytes_to_quads(csr->bus_info_len - sizeof(csr1212_quad_t)) != bi->length)
1241 return CSR1212_EINVAL;
1243 #if 0
1244 /* Apparently there are too many differnt wrong implementations of the
1245 * CRC algorithm that verifying them is moot. */
1246 if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
1247 (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
1248 return CSR1212_EINVAL;
1249 #endif
1251 cr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1252 if (!cr)
1253 return CSR1212_ENOMEM;
1255 cr->next = NULL;
1256 cr->prev = NULL;
1257 cr->offset_start = 0;
1258 cr->offset_end = csr->crc_len + 4;
1260 csr->cache_head->filled_head = cr;
1261 csr->cache_head->filled_tail = cr;
1263 return CSR1212_SUCCESS;
1266 static int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
1267 csr1212_quad_t ki,
1268 u_int32_t kv_pos)
1270 int ret = CSR1212_SUCCESS;
1271 struct csr1212_keyval *k = NULL;
1272 u_int32_t offset;
1274 switch(CSR1212_KV_KEY_TYPE(ki)) {
1275 case CSR1212_KV_TYPE_IMMEDIATE:
1276 k = csr1212_new_immediate(CSR1212_KV_KEY_ID(ki),
1277 CSR1212_KV_VAL(ki));
1278 if (!k) {
1279 ret = CSR1212_ENOMEM;
1280 goto fail;
1283 k->refcnt = 0; /* Don't keep local reference when parsing. */
1284 break;
1286 case CSR1212_KV_TYPE_CSR_OFFSET:
1287 k = csr1212_new_csr_offset(CSR1212_KV_KEY_ID(ki),
1288 CSR1212_KV_VAL(ki));
1289 if (!k) {
1290 ret = CSR1212_ENOMEM;
1291 goto fail;
1293 k->refcnt = 0; /* Don't keep local reference when parsing. */
1294 break;
1296 default:
1297 /* Compute the offset from 0xffff f000 0000. */
1298 offset = quads_to_bytes(CSR1212_KV_VAL(ki)) + kv_pos;
1299 if (offset == kv_pos) {
1300 /* Uh-oh. Can't have a relative offset of 0 for Leaves
1301 * or Directories. The Config ROM image is most likely
1302 * messed up, so we'll just abort here. */
1303 ret = CSR1212_EIO;
1304 goto fail;
1307 k = csr1212_find_keyval_offset(dir, offset);
1309 if (k)
1310 break; /* Found it. */
1312 if (CSR1212_KV_KEY_TYPE(ki) == CSR1212_KV_TYPE_DIRECTORY) {
1313 k = csr1212_new_directory(CSR1212_KV_KEY_ID(ki));
1314 } else {
1315 k = csr1212_new_leaf(CSR1212_KV_KEY_ID(ki), NULL, 0);
1317 if (!k) {
1318 ret = CSR1212_ENOMEM;
1319 goto fail;
1321 k->refcnt = 0; /* Don't keep local reference when parsing. */
1322 k->valid = 0; /* Contents not read yet so it's not valid. */
1323 k->offset = offset;
1325 k->prev = dir;
1326 k->next = dir->next;
1327 dir->next->prev = k;
1328 dir->next = k;
1330 ret = csr1212_attach_keyval_to_directory(dir, k);
1332 fail:
1333 if (ret != CSR1212_SUCCESS) {
1334 if (k)
1335 free_keyval(k);
1337 return ret;
1341 int csr1212_parse_keyval(struct csr1212_keyval *kv,
1342 struct csr1212_csr_rom_cache *cache)
1344 struct csr1212_keyval_img *kvi;
1345 int i;
1346 int ret = CSR1212_SUCCESS;
1347 int kvi_len;
1349 kvi = (struct csr1212_keyval_img*)&cache->data[bytes_to_quads(kv->offset -
1350 cache->offset)];
1351 kvi_len = CSR1212_BE16_TO_CPU(kvi->length);
1353 #if 0
1354 /* Apparently there are too many differnt wrong implementations of the
1355 * CRC algorithm that verifying them is moot. */
1356 if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
1357 (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) {
1358 ret = CSR1212_EINVAL;
1359 goto fail;
1361 #endif
1363 switch(kv->key.type) {
1364 case CSR1212_KV_TYPE_DIRECTORY:
1365 for (i = 0; i < kvi_len; i++) {
1366 csr1212_quad_t ki = kvi->data[i];
1368 /* Some devices put null entries in their unit
1369 * directories. If we come across such an entry,
1370 * then skip it. */
1371 if (ki == 0x0)
1372 continue;
1373 ret = csr1212_parse_dir_entry(kv, ki,
1374 (kv->offset +
1375 quads_to_bytes(i + 1)));
1377 kv->value.directory.len = kvi_len;
1378 break;
1380 case CSR1212_KV_TYPE_LEAF:
1381 if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
1382 kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
1383 if (!kv->value.leaf.data)
1385 ret = CSR1212_ENOMEM;
1386 goto fail;
1389 kv->value.leaf.len = kvi_len;
1390 memcpy(kv->value.leaf.data, kvi->data, quads_to_bytes(kvi_len));
1392 break;
1395 kv->valid = 1;
1397 fail:
1398 return ret;
1402 int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
1404 struct csr1212_cache_region *cr, *ncr, *newcr = NULL;
1405 struct csr1212_keyval_img *kvi = NULL;
1406 struct csr1212_csr_rom_cache *cache;
1407 int cache_index;
1408 u_int64_t addr;
1409 u_int32_t *cache_ptr;
1410 u_int16_t kv_len = 0;
1412 if (!csr || !kv)
1413 return CSR1212_EINVAL;
1415 /* First find which cache the data should be in (or go in if not read
1416 * yet). */
1417 for (cache = csr->cache_head; cache; cache = cache->next) {
1418 if (kv->offset >= cache->offset &&
1419 kv->offset < (cache->offset + cache->size))
1420 break;
1423 if (!cache) {
1424 csr1212_quad_t q;
1425 u_int32_t cache_size;
1427 /* Only create a new cache for Extended ROM leaves. */
1428 if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
1429 return CSR1212_EINVAL;
1431 if (csr->ops->bus_read(csr,
1432 CSR1212_REGISTER_SPACE_BASE + kv->offset,
1433 sizeof(csr1212_quad_t), &q, csr->private)) {
1434 return CSR1212_EIO;
1437 kv->value.leaf.len = CSR1212_BE32_TO_CPU(q) >> 16;
1439 cache_size = (quads_to_bytes(kv->value.leaf.len + 1) +
1440 (csr->max_rom - 1)) & ~(csr->max_rom - 1);
1442 cache = csr1212_rom_cache_malloc(kv->offset, cache_size);
1443 if (!cache)
1444 return CSR1212_ENOMEM;
1446 kv->value.leaf.data = &cache->data[1];
1447 csr->cache_tail->next = cache;
1448 cache->prev = csr->cache_tail;
1449 cache->next = NULL;
1450 csr->cache_tail = cache;
1451 cache->filled_head =
1452 CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1453 if (!cache->filled_head) {
1454 return CSR1212_ENOMEM;
1457 cache->filled_head->offset_start = 0;
1458 cache->filled_head->offset_end = sizeof(csr1212_quad_t);
1459 cache->filled_tail = cache->filled_head;
1460 cache->filled_head->next = NULL;
1461 cache->filled_head->prev = NULL;
1462 cache->data[0] = q;
1464 /* Don't read the entire extended ROM now. Pieces of it will
1465 * be read when entries inside it are read. */
1466 return csr1212_parse_keyval(kv, cache);
1469 cache_index = kv->offset - cache->offset;
1471 /* Now seach read portions of the cache to see if it is there. */
1472 for (cr = cache->filled_head; cr; cr = cr->next) {
1473 if (cache_index < cr->offset_start) {
1474 newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1475 if (!newcr)
1476 return CSR1212_ENOMEM;
1478 newcr->offset_start = cache_index & ~(csr->max_rom - 1);
1479 newcr->offset_end = newcr->offset_start;
1480 newcr->next = cr;
1481 newcr->prev = cr->prev;
1482 cr->prev = newcr;
1483 cr = newcr;
1484 break;
1485 } else if ((cache_index >= cr->offset_start) &&
1486 (cache_index < cr->offset_end)) {
1487 kvi = (struct csr1212_keyval_img*)
1488 (&cache->data[bytes_to_quads(cache_index)]);
1489 kv_len = quads_to_bytes(CSR1212_BE16_TO_CPU(kvi->length) +
1491 break;
1492 } else if (cache_index == cr->offset_end)
1493 break;
1496 if (!cr) {
1497 cr = cache->filled_tail;
1498 newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1499 if (!newcr)
1500 return CSR1212_ENOMEM;
1502 newcr->offset_start = cache_index & ~(csr->max_rom - 1);
1503 newcr->offset_end = newcr->offset_start;
1504 newcr->prev = cr;
1505 newcr->next = cr->next;
1506 cr->next = newcr;
1507 cr = newcr;
1508 cache->filled_tail = newcr;
1511 while(!kvi || cr->offset_end < cache_index + kv_len) {
1512 cache_ptr = &cache->data[bytes_to_quads(cr->offset_end &
1513 ~(csr->max_rom - 1))];
1515 addr = (CSR1212_CSR_ARCH_REG_SPACE_BASE + cache->offset +
1516 cr->offset_end) & ~(csr->max_rom - 1);
1518 if (csr->ops->bus_read(csr, addr, csr->max_rom, cache_ptr,
1519 csr->private)) {
1520 if (csr->max_rom == 4)
1521 /* We've got problems! */
1522 return CSR1212_EIO;
1524 /* Apperently the max_rom value was a lie, set it to
1525 * do quadlet reads and try again. */
1526 csr->max_rom = 4;
1527 continue;
1530 cr->offset_end += csr->max_rom - (cr->offset_end &
1531 (csr->max_rom - 1));
1533 if (!kvi && (cr->offset_end > cache_index)) {
1534 kvi = (struct csr1212_keyval_img*)
1535 (&cache->data[bytes_to_quads(cache_index)]);
1536 kv_len = quads_to_bytes(CSR1212_BE16_TO_CPU(kvi->length) +
1540 if ((kv_len + (kv->offset - cache->offset)) > cache->size) {
1541 /* The Leaf or Directory claims its length extends
1542 * beyond the ConfigROM image region and thus beyond the
1543 * end of our cache region. Therefore, we abort now
1544 * rather than seg faulting later. */
1545 return CSR1212_EIO;
1548 ncr = cr->next;
1550 if (ncr && (cr->offset_end >= ncr->offset_start)) {
1551 /* consolidate region entries */
1552 ncr->offset_start = cr->offset_start;
1554 if (cr->prev)
1555 cr->prev->next = cr->next;
1556 ncr->prev = cr->prev;
1557 if (cache->filled_head == cr)
1558 cache->filled_head = ncr;
1559 CSR1212_FREE(cr);
1560 cr = ncr;
1564 return csr1212_parse_keyval(kv, cache);
1569 int csr1212_parse_csr(struct csr1212_csr *csr)
1571 static const int mr_map[] = { 4, 64, 1024, 0 };
1572 struct csr1212_dentry *dentry;
1573 int ret;
1575 if (!csr || !csr->ops->bus_read)
1576 return CSR1212_EINVAL;
1578 ret = csr1212_parse_bus_info_block(csr);
1579 if (ret != CSR1212_SUCCESS)
1580 return ret;
1582 if (!csr->ops->get_max_rom)
1583 csr->max_rom = mr_map[0]; /* default value */
1584 else
1585 csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data,
1586 csr->private)];
1588 csr->cache_head->layout_head = csr->root_kv;
1589 csr->cache_head->layout_tail = csr->root_kv;
1591 csr->root_kv->offset = (CSR1212_CONFIG_ROM_SPACE_BASE & 0xffff) +
1592 csr->bus_info_len;
1594 csr->root_kv->valid = 0;
1595 csr->root_kv->next = csr->root_kv;
1596 csr->root_kv->prev = csr->root_kv;
1597 csr1212_get_keyval(csr, csr->root_kv);
1599 /* Scan through the Root directory finding all extended ROM regions
1600 * and make cache regions for them */
1601 for (dentry = csr->root_kv->value.directory.dentries_head;
1602 dentry; dentry = dentry->next) {
1603 if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
1604 csr1212_get_keyval(csr, dentry->kv);
1606 if (ret != CSR1212_SUCCESS)
1607 return ret;
1611 return CSR1212_SUCCESS;