1 /*
2 * csr1212.c -- IEEE 1212 Control and Status Register support for Linux
3 *
4 * Copyright (C) 2003 Francois Retief <fgretief@sun.ac.za>
5 * Steve Kinneberg <kinnebergsteve@acmsystems.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
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.
17 *
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.
28 */
29
30
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.
35 */
36
37 #ifndef __KERNEL__
38 #include <string.h>
39 #endif
40
41 #include "csr1212.h"
42
43
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 */
78 };
79 #undef __I
80 #undef __C
81 #undef __D
82 #undef __L
83
84
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))
87
88 static inline void free_keyval(struct csr1212_keyval *kv)
89 {
90 if (kv->key.type == CSR1212_KV_TYPE_LEAF)
91 CSR1212_FREE(kv->value.leaf.data);
92
93 CSR1212_FREE(kv);
94 }
95
96 static u_int16_t csr1212_crc16(const u_int32_t *buffer, size_t length)
97 {
98 int shift;
99 u_int32_t data;
100 u_int16_t sum, crc = 0;
101
102 for (; length; length--) {
103 data = CSR1212_BE32_TO_CPU(*buffer);
104 buffer++;
105 for (shift = 28; shift >= 0; shift -= 4 ) {
106 sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
107 crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
108 }
109 crc &= 0xffff;
110 }
111
112 return CSR1212_CPU_TO_BE16(crc);
113 }
114
115 #if 0
116 /* Microsoft computes the CRC with the bytes in reverse order. Therefore we
117 * have a special version of the CRC algorithm to account for their buggy
118 * software. */
119 static u_int16_t csr1212_msft_crc16(const u_int32_t *buffer, size_t length)
120 {
121 int shift;
122 u_int32_t data;
123 u_int16_t sum, crc = 0;
124
125 for (; length; length--) {
126 data = CSR1212_LE32_TO_CPU(*buffer);
127 buffer++;
128 for (shift = 28; shift >= 0; shift -= 4 ) {
129 sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
130 crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
131 }
132 crc &= 0xffff;
133 }
134
135 return CSR1212_CPU_TO_BE16(crc);
136 }
137 #endif
138
139 static inline struct csr1212_dentry *csr1212_find_keyval(struct csr1212_keyval *dir,
140 struct csr1212_keyval *kv)
141 {
142 struct csr1212_dentry *pos;
143
144 for (pos = dir->value.directory.dentries_head;
145 pos != NULL; pos = pos->next) {
146 if (pos->kv == kv)
147 return pos;
148 }
149 return NULL;
150 }
151
152
153 static inline struct csr1212_keyval *csr1212_find_keyval_offset(struct csr1212_keyval *kv_list,
154 u_int32_t offset)
155 {
156 struct csr1212_keyval *kv;
157
158 for (kv = kv_list; kv != NULL; kv = kv->next) {
159 if (kv->offset == offset)
160 return kv;
161 }
162 return NULL;
163 }
164
165
166 /* Creation Routines */
167 struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
168 size_t bus_info_size, void *private)
169 {
170 struct csr1212_csr *csr;
171
172 csr = CSR1212_MALLOC(sizeof(*csr));
173 if (!csr)
174 return NULL;
175
176 csr->cache_head =
177 csr1212_rom_cache_malloc(CSR1212_CONFIG_ROM_SPACE_OFFSET,
178 CSR1212_CONFIG_ROM_SPACE_SIZE);
179 if (!csr->cache_head) {
180 CSR1212_FREE(csr);
181 return NULL;
182 }
183
184 /* The keyval key id is not used for the root node, but a valid key id
185 * that can be used for a directory needs to be passed to
186 * csr1212_new_directory(). */
187 csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR);
188 if (!csr->root_kv) {
189 CSR1212_FREE(csr->cache_head);
190 CSR1212_FREE(csr);
191 return NULL;
192 }
193
194 csr->bus_info_data = csr->cache_head->data;
195 csr->bus_info_len = bus_info_size;
196 csr->crc_len = bus_info_size;
197 csr->ops = ops;
198 csr->private = private;
199 csr->cache_tail = csr->cache_head;
200
201 return csr;
202 }
203
204
205
206 void csr1212_init_local_csr(struct csr1212_csr *csr,
207 const u_int32_t *bus_info_data, int max_rom)
208 {
209 static const int mr_map[] = { 4, 64, 1024, 0 };
210
211 csr->max_rom = mr_map[max_rom];
212 memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
213 }
214
215
216 static struct csr1212_keyval *csr1212_new_keyval(u_int8_t type, u_int8_t key)
217 {
218 struct csr1212_keyval *kv;
219
220 if (key < 0x30 && ((csr1212_key_id_type_map[key] & (1 << type)) == 0))
221 return NULL;
222
223 kv = CSR1212_MALLOC(sizeof(*kv));
224 if (!kv)
225 return NULL;
226
227 kv->key.type = type;
228 kv->key.id = key;
229
230 kv->associate = NULL;
231 kv->refcnt = 1;
232
233 kv->next = NULL;
234 kv->prev = NULL;
235 kv->offset = 0;
236 kv->valid = 0;
237 return kv;
238 }
239
240 struct csr1212_keyval *csr1212_new_immediate(u_int8_t key, u_int32_t value)
241 {
242 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key);
243
244 if (!kv)
245 return NULL;
246
247 kv->value.immediate = value;
248 kv->valid = 1;
249 return kv;
250 }
251
252 struct csr1212_keyval *csr1212_new_leaf(u_int8_t key, const void *data, size_t data_len)
253 {
254 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, key);
255
256 if (!kv)
257 return NULL;
258
259 if (data_len > 0) {
260 kv->value.leaf.data = CSR1212_MALLOC(data_len);
261 if (!kv->value.leaf.data) {
262 CSR1212_FREE(kv);
263 return NULL;
264 }
265
266 if (data)
267 memcpy(kv->value.leaf.data, data, data_len);
268 } else {
269 kv->value.leaf.data = NULL;
270 }
271
272 kv->value.leaf.len = bytes_to_quads(data_len);
273 kv->offset = 0;
274 kv->valid = 1;
275
276 return kv;
277 }
278
279 struct csr1212_keyval *csr1212_new_csr_offset(u_int8_t key, u_int32_t csr_offset)
280 {
281 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_CSR_OFFSET, key);
282
283 if (!kv)
284 return NULL;
285
286 kv->value.csr_offset = csr_offset;
287
288 kv->offset = 0;
289 kv->valid = 1;
290 return kv;
291 }
292
293 struct csr1212_keyval *csr1212_new_directory(u_int8_t key)
294 {
295 struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_DIRECTORY, key);
296
297 if (!kv)
298 return NULL;
299
300 kv->value.directory.len = 0;
301 kv->offset = 0;
302 kv->value.directory.dentries_head = NULL;
303 kv->value.directory.dentries_tail = NULL;
304 kv->valid = 1;
305 return kv;
306 }
307
308 int csr1212_associate_keyval(struct csr1212_keyval *kv,
309 struct csr1212_keyval *associate)
310 {
311 if (!kv || !associate)
312 return CSR1212_EINVAL;
313
314 if (kv->key.id == CSR1212_KV_ID_DESCRIPTOR ||
315 (associate->key.id != CSR1212_KV_ID_DESCRIPTOR &&
316 associate->key.id != CSR1212_KV_ID_DEPENDENT_INFO &&
317 associate->key.id != CSR1212_KV_ID_EXTENDED_KEY &&
318 associate->key.id != CSR1212_KV_ID_EXTENDED_DATA &&
319 associate->key.id < 0x30))
320 return CSR1212_EINVAL;
321
322 if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID &&
323 associate->key.id != CSR1212_KV_ID_EXTENDED_KEY)
324 return CSR1212_EINVAL;
325
326 if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
327 associate->key.id != CSR1212_KV_ID_EXTENDED_DATA)
328 return CSR1212_EINVAL;
329
330 if (associate->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
331 kv->key.id != CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID)
332 return CSR1212_EINVAL;
333
334 if (associate->key.id == CSR1212_KV_ID_EXTENDED_DATA &&
335 kv->key.id != CSR1212_KV_ID_EXTENDED_KEY)
336 return CSR1212_EINVAL;
337
338 if (kv->associate)
339 csr1212_release_keyval(kv->associate);
340
341 associate->refcnt++;
342 kv->associate = associate;
343
344 return CSR1212_SUCCESS;
345 }
346
347 int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
348 struct csr1212_keyval *kv)
349 {
350 struct csr1212_dentry *dentry;
351
352 if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
353 return CSR1212_EINVAL;
354
355 dentry = CSR1212_MALLOC(sizeof(*dentry));
356 if (!dentry)
357 return CSR1212_ENOMEM;
358
359 dentry->kv = kv;
360
361 kv->refcnt++;
362
363 dentry->next = NULL;
364 dentry->prev = dir->value.directory.dentries_tail;
365
366 if (!dir->value.directory.dentries_head)
367 dir->value.directory.dentries_head = dentry;
368
369 if (dir->value.directory.dentries_tail)
370 dir->value.directory.dentries_tail->next = dentry;
371 dir->value.directory.dentries_tail = dentry;
372
373 return CSR1212_SUCCESS;
374 }
375
376 struct csr1212_keyval *csr1212_new_extended_immediate(u_int32_t spec, u_int32_t key,
377 u_int32_t value)
378 {
379 struct csr1212_keyval *kvs, *kvk, *kvv;
380
381 kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
382 kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
383 kvv = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_DATA, value);
384
385 if (!kvs || !kvk || !kvv) {
386 if (kvs)
387 free_keyval(kvs);
388 if (kvk)
389 free_keyval(kvk);
390 if (kvv)
391 free_keyval(kvv);
392 return NULL;
393 }
394
395 /* Don't keep a local reference to the extended key or value. */
396 kvk->refcnt = 0;
397 kvv->refcnt = 0;
398
399 csr1212_associate_keyval(kvk, kvv);
400 csr1212_associate_keyval(kvs, kvk);
401
402 return kvs;
403 }
404
405 struct csr1212_keyval *csr1212_new_extended_leaf(u_int32_t spec, u_int32_t key,
406 const void *data, size_t data_len)
407 {
408 struct csr1212_keyval *kvs, *kvk, *kvv;
409
410 kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
411 kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
412 kvv = csr1212_new_leaf(CSR1212_KV_ID_EXTENDED_DATA, data, data_len);
413
414 if (!kvs || !kvk || !kvv) {
415 if (kvs)
416 free_keyval(kvs);
417 if (kvk)
418 free_keyval(kvk);
419 if (kvv)
420 free_keyval(kvv);
421 return NULL;
422 }
423
424 /* Don't keep a local reference to the extended key or value. */
425 kvk->refcnt = 0;
426 kvv->refcnt = 0;
427
428 csr1212_associate_keyval(kvk, kvv);
429 csr1212_associate_keyval(kvs, kvk);
430
431 return kvs;
432 }
433
434 struct csr1212_keyval *csr1212_new_descriptor_leaf(u_int8_t dtype, u_int32_t specifier_id,
435 const void *data, size_t data_len)
436 {
437 struct csr1212_keyval *kv;
438
439 kv = csr1212_new_leaf(CSR1212_KV_ID_DESCRIPTOR, NULL,
440 data_len + CSR1212_DESCRIPTOR_LEAF_OVERHEAD);
441 if (!kv)
442 return NULL;
443
444 CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, dtype);
445 CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, specifier_id);
446
447 if (data) {
448 memcpy(CSR1212_DESCRIPTOR_LEAF_DATA(kv), data, data_len);
449 }
450
451 return kv;
452 }
453
454
455 struct csr1212_keyval *csr1212_new_textual_descriptor_leaf(u_int8_t cwidth,
456 u_int16_t cset,
457 u_int16_t language,
458 const void *data,
459 size_t data_len)
460 {
461 struct csr1212_keyval *kv;
462 char *lstr;
463
464 kv = csr1212_new_descriptor_leaf(0, 0, NULL, data_len +
465 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD);
466 if (!kv)
467 return NULL;
468
469 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_WIDTH(kv, cwidth);
470 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_CHAR_SET(kv, cset);
471 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
472
473 lstr = (char*)CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(kv);
474
475 /* make sure last quadlet is zeroed out */
476 *((u_int32_t*)&(lstr[(data_len - 1) & ~0x3])) = 0;
477
478 /* don't copy the NUL terminator */
479 memcpy(lstr, data, data_len);
480
481 return kv;
482 }
483
484 static int csr1212_check_minimal_ascii(const char *s)
485 {
486 static const char minimal_ascii_table[] = {
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
488 0x00, 0x00, 0x0a, 0x00, 0x0C, 0x0D, 0x00, 0x00,
489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x20, 0x21, 0x22, 0x00, 0x00, 0x25, 0x26, 0x27,
492 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
493 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
494 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
495 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
496 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
497 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
498 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5f,
499 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
500 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
501 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
502 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
503 };
504 for (; *s; s++) {
505 if (minimal_ascii_table[*s & 0x7F] != *s)
506 return -1; /* failed */
507 }
508 /* String conforms to minimal-ascii, as specified by IEEE 1212,
509 * par. 7.4 */
510 return 0;
511 }
512
513 struct csr1212_keyval *csr1212_new_string_descriptor_leaf(const char *s)
514 {
515 /* Check if string conform to minimal_ascii format */
516 if (csr1212_check_minimal_ascii(s))
517 return NULL;
518
519 /* IEEE 1212, par. 7.5.4.1 Textual descriptors (minimal ASCII) */
520 return csr1212_new_textual_descriptor_leaf(0, 0, 0, s, strlen(s));
521 }
522
523 struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version,
524 u_int8_t palette_depth,
525 u_int8_t color_space,
526 u_int16_t language,
527 u_int16_t hscan,
528 u_int16_t vscan,
529 u_int32_t *palette,
530 u_int32_t *pixels)
531 {
532 static const int pd[4] = { 0, 4, 16, 256 };
533 static const int cs[16] = { 4, 2 };
534 struct csr1212_keyval *kv;
535 int palette_size = pd[palette_depth] * cs[color_space];
536 int pixel_size = (hscan * vscan + 3) & ~0x3;
537
538 if ((palette_depth && !palette) || !pixels)
539 return NULL;
540
541 kv = csr1212_new_descriptor_leaf(1, 0, NULL,
542 palette_size + pixel_size +
543 CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
544 if (!kv)
545 return NULL;
546
547 CSR1212_ICON_DESCRIPTOR_LEAF_SET_VERSION(kv, version);
548 CSR1212_ICON_DESCRIPTOR_LEAF_SET_PALETTE_DEPTH(kv, palette_depth);
549 CSR1212_ICON_DESCRIPTOR_LEAF_SET_COLOR_SPACE(kv, color_space);
550 CSR1212_ICON_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
551 CSR1212_ICON_DESCRIPTOR_LEAF_SET_HSCAN(kv, hscan);
552 CSR1212_ICON_DESCRIPTOR_LEAF_SET_VSCAN(kv, vscan);
553
554 if (palette_size)
555 memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PALETTE(kv), palette,
556 palette_size);
557
558 memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PIXELS(kv), pixels, pixel_size);
559
560 return kv;
561 }
562
563 struct csr1212_keyval *csr1212_new_modifiable_descriptor_leaf(u_int16_t max_size,
564 u_int64_t address)
565 {
566 struct csr1212_keyval *kv;
567
568 /* IEEE 1212, par. 7.5.4.3 Modifiable descriptors */
569 kv = csr1212_new_leaf(CSR1212_KV_ID_MODIFIABLE_DESCRIPTOR, NULL, sizeof(u_int64_t));
570 if(!kv)
571 return NULL;
572
573 CSR1212_MODIFIABLE_DESCRIPTOR_SET_MAX_SIZE(kv, max_size);
574 CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_HI(kv, address);
575 CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_LO(kv, address);
576
577 return kv;
578 }
579
580 static int csr1212_check_keyword(const char *s)
581 {
582 for (; *s; s++) {
583
584 if (('A' <= *s) && (*s <= 'Z'))
585 continue;
586 if (('' <= *s) && (*s <= '9'))
587 continue;
588 if (*s == '-')
589 continue;
590
591 return -1; /* failed */
592 }
593 /* String conforms to keyword, as specified by IEEE 1212,
594 * par. 7.6.5 */
595 return CSR1212_SUCCESS;
596 }
597
598 struct csr1212_keyval *csr1212_new_keyword_leaf(int strc, const char *strv[])
599 {
600 struct csr1212_keyval *kv;
601 char *buffer;
602 int i, data_len = 0;
603
604 /* Check all keywords to see if they conform to restrictions:
605 * Only the following characters is allowed ['A'..'Z',''..'9','-']
606 * Each word is zero-terminated.
607 * Also calculate the total length of the keywords.
608 */
609 for (i = 0; i < strc; i++) {
610 if (!strv[i] || csr1212_check_keyword(strv[i])) {
611 return NULL;
612 }
613 data_len += strlen(strv[i]) + 1; /* Add zero-termination char. */
614 }
615
616 /* IEEE 1212, par. 7.6.5 Keyword leaves */
617 kv = csr1212_new_leaf(CSR1212_KV_ID_KEYWORD, NULL, data_len);
618 if (!kv)
619 return NULL;
620
621 buffer = (char *)kv->value.leaf.data;
622
623 /* make sure last quadlet is zeroed out */
624 *((u_int32_t*)&(buffer[(data_len - 1) & ~0x3])) = 0;
625
626 /* Copy keyword(s) into leaf data buffer */
627 for (i = 0; i < strc; i++) {
628 int len = strlen(strv[i]) + 1;
629 memcpy(buffer, strv[i], len);
630 buffer += len;
631 }
632 return kv;
633 }
634
635
636 /* Destruction Routines */
637
638 void csr1212_detach_keyval_from_directory(struct csr1212_keyval *dir,
639 struct csr1212_keyval *kv)
640 {
641 struct csr1212_dentry *dentry;
642
643 if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
644 return;
645
646 dentry = csr1212_find_keyval(dir, kv);
647
648 if (!dentry)
649 return;
650
651 if (dentry->prev)
652 dentry->prev->next = dentry->next;
653 if (dentry->next)
654 dentry->next->prev = dentry->prev;
655 if (dir->value.directory.dentries_head == dentry)
656 dir->value.directory.dentries_head = dentry->next;
657 if (dir->value.directory.dentries_tail == dentry)
658 dir->value.directory.dentries_tail = dentry->prev;
659
660 CSR1212_FREE(dentry);
661
662 csr1212_release_keyval(kv);
663 }
664
665
666 void csr1212_disassociate_keyval(struct csr1212_keyval *kv)
667 {
668 if (kv->associate) {
669 csr1212_release_keyval(kv->associate);
670 }
671
672 kv->associate = NULL;
673 }
674
675
676 /* This function is used to free the memory taken by a keyval. If the given
677 * keyval is a directory type, then any keyvals contained in that directory
678 * will be destroyed as well if their respective refcnts are 0. By means of
679 * list manipulation, this routine will descend a directory structure in a
680 * non-recursive manner. */
681 void _csr1212_destroy_keyval(struct csr1212_keyval *kv)
682 {
683 struct csr1212_keyval *k, *a;
684 struct csr1212_dentry dentry;
685 struct csr1212_dentry *head, *tail;
686
687 dentry.kv = kv;
688 dentry.next = NULL;
689 dentry.prev = NULL;
690
691 head = &dentry;
692 tail = head;
693
694 while (head) {
695 k = head->kv;
696
697 while (k) {
698 k->refcnt--;
699
700 if (k->refcnt > 0)
701 break;
702
703 a = k->associate;
704
705 if (k->key.type == CSR1212_KV_TYPE_DIRECTORY) {
706 /* If the current entry is a directory, then move all
707 * the entries to the destruction list. */
708 if (k->value.directory.dentries_head) {
709 tail->next = k->value.directory.dentries_head;
710 k->value.directory.dentries_head->prev = tail;
711 tail = k->value.directory.dentries_tail;
712 }
713 }
714 free_keyval(k);
715 k = a;
716 }
717
718 head = head->next;
719 if (head) {
720 if (head->prev && head->prev != &dentry) {
721 CSR1212_FREE(head->prev);
722 }
723 head->prev = NULL;
724 } else if (tail != &dentry)
725 CSR1212_FREE(tail);
726 }
727 }
728
729
730 void csr1212_destroy_csr(struct csr1212_csr *csr)
731 {
732 struct csr1212_csr_rom_cache *c, *oc;
733 struct csr1212_cache_region *cr, *ocr;
734
735 csr1212_release_keyval(csr->root_kv);
736
737 c = csr->cache_head;
738 while (c) {
739 oc = c;
740 cr = c->filled_head;
741 while (cr) {
742 ocr = cr;
743 cr = cr->next;
744 CSR1212_FREE(ocr);
745 }
746 c = c->next;
747 CSR1212_FREE(oc);
748 }
749
750 CSR1212_FREE(csr);
751 }
752
753
754
755 /* CSR Image Creation */
756
757 static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
758 {
759 struct csr1212_csr_rom_cache *cache;
760 u_int64_t csr_addr;
761
762 if (!csr || !csr->ops->allocate_addr_range ||
763 !csr->ops->release_addr)
764 return CSR1212_ENOMEM;
765
766 /* ROM size must be a multiple of csr->max_rom */
767 romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
768
769 csr_addr = csr->ops->allocate_addr_range(romsize, csr->max_rom, csr->private);
770 if (csr_addr == ~0ULL) {
771 return CSR1212_ENOMEM;
772 }
773 if (csr_addr < CSR1212_REGISTER_SPACE_BASE) {
774 /* Invalid address returned from allocate_addr_range(). */
775 csr->ops->release_addr(csr_addr, csr->private);
776 return CSR1212_ENOMEM;
777 }
778
779 cache = csr1212_rom_cache_malloc(csr_addr - CSR1212_REGISTER_SPACE_BASE, romsize);
780 if (!cache) {
781 csr->ops->release_addr(csr_addr, csr->private);
782 return CSR1212_ENOMEM;
783 }
784
785 cache->ext_rom = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, CSR1212_KV_ID_EXTENDED_ROM);
786 if (!cache->ext_rom) {
787 csr->ops->release_addr(csr_addr, csr->private);
788 CSR1212_FREE(cache);
789 return CSR1212_ENOMEM;
790 }
791
792 if (csr1212_attach_keyval_to_directory(csr->root_kv, cache->ext_rom) != CSR1212_SUCCESS) {
793 csr1212_release_keyval(cache->ext_rom);
794 csr->ops->release_addr(csr_addr, csr->private);
795 CSR1212_FREE(cache);
796 return CSR1212_ENOMEM;
797 }
798 cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE;
799 cache->ext_rom->value.leaf.len = 0;
800
801 /* Add cache to tail of cache list */
802 cache->prev = csr->cache_tail;
803 csr->cache_tail->next = cache;
804 csr->cache_tail = cache;
805 return CSR1212_SUCCESS;
806 }
807
808 static inline void csr1212_remove_cache(struct csr1212_csr *csr,
809 struct csr1212_csr_rom_cache *cache)
810 {
811 if (csr->cache_head == cache)
812 csr->cache_head = cache->next;
813 if (csr->cache_tail == cache)
814 csr->cache_tail = cache->prev;
815
816 if (cache->prev)
817 cache->prev->next = cache->next;
818 if (cache->next)
819 cache->next->prev = cache->prev;
820
821 if (cache->ext_rom) {
822 csr1212_detach_keyval_from_directory(csr->root_kv, cache->ext_rom);
823 csr1212_release_keyval(cache->ext_rom);
824 }
825
826 CSR1212_FREE(cache);
827 }
828
829 static int csr1212_generate_layout_subdir(struct csr1212_keyval *dir,
830 struct csr1212_keyval **layout_tail)
831 {
832 struct csr1212_dentry *dentry;
833 struct csr1212_keyval *dkv;
834 struct csr1212_keyval *last_extkey_spec = NULL;
835 struct csr1212_keyval *last_extkey = NULL;
836 int num_entries = 0;
837
838 for (dentry = dir->value.directory.dentries_head; dentry;
839 dentry = dentry->next) {
840 for (dkv = dentry->kv; dkv; dkv = dkv->associate) {
841 /* Special Case: Extended Key Specifier_ID */
842 if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
843 if (last_extkey_spec == NULL) {
844 last_extkey_spec = dkv;
845 } else if (dkv->value.immediate != last_extkey_spec->value.immediate) {
846 last_extkey_spec = dkv;
847 } else {
848 continue;
849 }
850 /* Special Case: Extended Key */
851 } else if (dkv->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
852 if (last_extkey == NULL) {
853 last_extkey = dkv;
854 } else if (dkv->value.immediate != last_extkey->value.immediate) {
855 last_extkey = dkv;
856 } else {
857 continue;
858 }
859 }
860
861 num_entries += 1;
862
863 switch(dkv->key.type) {
864 default:
865 case CSR1212_KV_TYPE_IMMEDIATE:
866 case CSR1212_KV_TYPE_CSR_OFFSET:
867 continue;
868 case CSR1212_KV_TYPE_LEAF:
869 case CSR1212_KV_TYPE_DIRECTORY:
870 /* Remove from list */
871 if (dkv->prev)
872 dkv->prev->next = dkv->next;
873 if (dkv->next)
874 dkv->next->prev = dkv->prev;
875 if (dkv == *layout_tail)
876 *layout_tail = dkv->prev;
877
878 /* Special case: Extended ROM leafs */
879 if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
880 dkv->value.leaf.len = 0; /* initialize to zero */
881 /* Don't add Extended ROM leafs in the layout list,
882 * they are handled differently. */
883 break;
884 }
885
886 /* Add to tail of list */
887 dkv->next = NULL;
888 dkv->prev = *layout_tail;
889 (*layout_tail)->next = dkv;
890 *layout_tail = dkv;
891 break;
892 }
893 }
894 }
895 return num_entries;
896 }
897
898 size_t csr1212_generate_layout_order(struct csr1212_keyval *kv)
899 {
900 struct csr1212_keyval *ltail = kv;
901 size_t agg_size = 0;
902
903 while(kv) {
904 switch(kv->key.type) {
905 case CSR1212_KV_TYPE_LEAF:
906 /* Add 1 quadlet for crc/len field */
907 agg_size += kv->value.leaf.len + 1;
908 break;
909
910 case CSR1212_KV_TYPE_DIRECTORY:
911 kv->value.directory.len = csr1212_generate_layout_subdir(kv, <ail);
912 /* Add 1 quadlet for crc/len field */
913 agg_size += kv->value.directory.len + 1;
914 break;
915 }
916 kv = kv->next;
917 }
918 return quads_to_bytes(agg_size);
919 }
920
921 struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *cache,
922 struct csr1212_keyval *start_kv,
923 int start_pos)
924 {
925 struct csr1212_keyval *kv = start_kv;
926 struct csr1212_keyval *okv = start_kv;
927 int pos = start_pos;
928 int kv_len = 0, okv_len = 0;
929
930 cache->layout_head = kv;
931
932 while(kv && pos < cache->size) {
933 kv->offset = cache->offset + pos;
934
935 switch(kv->key.type) {
936 case CSR1212_KV_TYPE_LEAF:
937 kv_len = kv->value.leaf.len;
938 break;
939
940 case CSR1212_KV_TYPE_DIRECTORY:
941 kv_len = kv->value.directory.len;
942 break;
943
944 default:
945 /* Should never get here */
946 break;
947 }
948
949 pos += quads_to_bytes(kv_len + 1);
950
951 if (pos <= cache->size) {
952 okv = kv;
953 okv_len = kv_len;
954 kv = kv->next;
955 }
956 }
957
958 cache->layout_tail = okv;
959 cache->len = (okv->offset - cache->offset) + quads_to_bytes(okv_len + 1);
960
961 return kv;
962 }
963
964 static void csr1212_generate_tree_subdir(struct csr1212_keyval *dir,
965 u_int32_t *data_buffer)
966 {
967 struct csr1212_dentry *dentry;
968 struct csr1212_keyval *last_extkey_spec = NULL;
969 struct csr1212_keyval *last_extkey = NULL;
970 int index = 0;
971
972 for (dentry = dir->value.directory.dentries_head; dentry; dentry = dentry->next) {
973 struct csr1212_keyval *a;
974
975 for (a = dentry->kv; a; a = a->associate) {
976 u_int32_t value = 0;
977
978 /* Special Case: Extended Key Specifier_ID */
979 if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) {
980 if (last_extkey_spec == NULL) {
981 last_extkey_spec = a;
982 } else if (a->value.immediate != last_extkey_spec->value.immediate) {
983 last_extkey_spec = a;
984 } else {
985 continue;
986 }
987 /* Special Case: Extended Key */
988 } else if (a->key.id == CSR1212_KV_ID_EXTENDED_KEY) {
989 if (last_extkey == NULL) {
990 last_extkey = a;
991 } else if (a->value.immediate != last_extkey->value.immediate) {
992 last_extkey = a;
993 } else {
994 continue;
995 }
996 }
997
998 switch(a->key.type) {
999 case CSR1212_KV_TYPE_IMMEDIATE:
1000 value = a->value.immediate;
1001 break;
1002 case CSR1212_KV_TYPE_CSR_OFFSET:
1003 value = a->value.csr_offset;
1004 break;
1005 case CSR1212_KV_TYPE_LEAF:
1006 value = a->offset;
1007 value -= dir->offset + quads_to_bytes(1+index);
1008 value = bytes_to_quads(value);
1009 break;
1010 case CSR1212_KV_TYPE_DIRECTORY:
1011 value = a->offset;
1012 value -= dir->offset + quads_to_bytes(1+index);
1013 value = bytes_to_quads(value);
1014 break;
1015 default:
1016 /* Should never get here */
1017 break; /* GDB breakpoint */
1018 }
1019
1020 value |= (a->key.id & CSR1212_KV_KEY_ID_MASK) << CSR1212_KV_KEY_SHIFT;
1021 value |= (a->key.type & CSR1212_KV_KEY_TYPE_MASK) <<
1022 (CSR1212_KV_KEY_SHIFT + CSR1212_KV_KEY_TYPE_SHIFT);
1023 data_buffer[index] = CSR1212_CPU_TO_BE32(value);
1024 index++;
1025 }
1026 }
1027 }
1028
1029 void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache)
1030 {
1031 struct csr1212_keyval *kv, *nkv;
1032 struct csr1212_keyval_img *kvi;
1033
1034 for (kv = cache->layout_head; kv != cache->layout_tail->next; kv = nkv) {
1035 kvi = (struct csr1212_keyval_img *)
1036 (cache->data + bytes_to_quads(kv->offset - cache->offset));
1037 switch(kv->key.type) {
1038 default:
1039 case CSR1212_KV_TYPE_IMMEDIATE:
1040 case CSR1212_KV_TYPE_CSR_OFFSET:
1041 /* Should never get here */
1042 break; /* GDB breakpoint */
1043
1044 case CSR1212_KV_TYPE_LEAF:
1045 /* Don't copy over Extended ROM areas, they are
1046 * already filled out! */
1047 if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
1048 memcpy(kvi->data, kv->value.leaf.data,
1049 quads_to_bytes(kv->value.leaf.len));
1050
1051 kvi->length = CSR1212_CPU_TO_BE16(kv->value.leaf.len);
1052 kvi->crc = csr1212_crc16(kvi->data, kv->value.leaf.len);
1053 break;
1054
1055 case CSR1212_KV_TYPE_DIRECTORY:
1056 csr1212_generate_tree_subdir(kv, kvi->data);
1057
1058 kvi->length = CSR1212_CPU_TO_BE16(kv->value.directory.len);
1059 kvi->crc = csr1212_crc16(kvi->data, kv->value.directory.len);
1060 break;
1061 }
1062
1063 nkv = kv->next;
1064 if (kv->prev)
1065 kv->prev->next = NULL;
1066 if (kv->next)
1067 kv->next->prev = NULL;
1068 kv->prev = NULL;
1069 kv->next = NULL;
1070 }
1071 }
1072
1073 int csr1212_generate_csr_image(struct csr1212_csr *csr)
1074 {
1075 struct csr1212_bus_info_block_img *bi;
1076 struct csr1212_csr_rom_cache *cache;
1077 struct csr1212_keyval *kv;
1078 size_t agg_size;
1079 int ret;
1080 int init_offset;
1081
1082 if (!csr)
1083 return CSR1212_EINVAL;
1084
1085 cache = csr->cache_head;
1086
1087 bi = (struct csr1212_bus_info_block_img*)cache->data;
1088
1089 bi->length = bytes_to_quads(csr->bus_info_len) - 1;
1090 bi->crc_length = bi->length;
1091 bi->crc = csr1212_crc16(bi->data, bi->crc_length);
1092
1093 agg_size = csr1212_generate_layout_order(csr->root_kv);
1094
1095 init_offset = csr->bus_info_len;
1096
1097 for (kv = csr->root_kv, cache = csr->cache_head; kv; cache = cache->next) {
1098 if (!cache) {
1099 /* Estimate approximate number of additional cache
1100 * regions needed (it assumes that the cache holding
1101 * the first 1K Config ROM space always exists). */
1102 int est_c = agg_size / (CSR1212_EXTENDED_ROM_SIZE -
1103 (2 * sizeof(u_int32_t))) + 1;
1104
1105 /* Add additional cache regions, extras will be
1106 * removed later */
1107 for (; est_c; est_c--) {
1108 ret = csr1212_append_new_cache(csr, CSR1212_EXTENDED_ROM_SIZE);
1109 if (ret != CSR1212_SUCCESS)
1110 return ret;
1111 }
1112 /* Need to re-layout for additional cache regions */
1113 agg_size = csr1212_generate_layout_order(csr->root_kv);
1114 kv = csr->root_kv;
1115 cache = csr->cache_head;
1116 init_offset = csr->bus_info_len;
1117 }
1118 kv = csr1212_generate_positions(cache, kv, init_offset);
1119 agg_size -= cache->len;
1120 init_offset = sizeof(u_int32_t);
1121 }
1122
1123 /* Remove unused, excess cache regions */
1124 while (cache) {
1125 struct csr1212_csr_rom_cache *oc = cache;
1126
1127 cache = cache->next;
1128 csr1212_remove_cache(csr, oc);
1129 }
1130
1131 /* Go through the list backward so that when done, the correct CRC
1132 * will be calculated for the Extended ROM areas. */
1133 for(cache = csr->cache_tail; cache; cache = cache->prev) {
1134 /* Only Extended ROM caches should have this set. */
1135 if (cache->ext_rom) {
1136 int leaf_size;
1137
1138 /* Make sure the Extended ROM leaf is a multiple of
1139 * max_rom in size. */
1140 leaf_size = (cache->len + (csr->max_rom - 1)) &
1141 ~(csr->max_rom - 1);
1142
1143 /* Zero out the unused ROM region */
1144 memset(cache->data + bytes_to_quads(cache->len), 0x00,
1145 leaf_size - cache->len);
1146
1147 /* Subtract leaf header */
1148 leaf_size -= sizeof(u_int32_t);
1149
1150 /* Update the Extended ROM leaf length */
1151 cache->ext_rom->value.leaf.len =
1152 bytes_to_quads(leaf_size);
1153 } else {
1154 /* Zero out the unused ROM region */
1155 memset(cache->data + bytes_to_quads(cache->len), 0x00,
1156 cache->size - cache->len);
1157 }
1158
1159 /* Copy the data into the cache buffer */
1160 csr1212_fill_cache(cache);
1161 }
1162
1163 return CSR1212_SUCCESS;
1164 }
1165
1166 int csr1212_read(struct csr1212_csr *csr, u_int32_t offset, void *buffer, u_int32_t len)
1167 {
1168 struct csr1212_csr_rom_cache *cache;
1169
1170 for (cache = csr->cache_head; cache; cache = cache->next) {
1171 if (offset >= cache->offset &&
1172 (offset + len) <= (cache->offset + cache->size)) {
1173 memcpy(buffer,
1174 &cache->data[bytes_to_quads(offset - cache->offset)],
1175 len);
1176 return CSR1212_SUCCESS;
1177 } else if (((offset < cache->offset) &&
1178 ((offset + len) >= cache->offset)) ||
1179 ((offset >= cache->offset) &&
1180 ((offset + len) > (cache->offset + cache->size)))) {
1181 return CSR1212_EINVAL;
1182 }
1183 }
1184 return CSR1212_ENOENT;
1185 }
1186
1187
1188
1189 /* Parse a chunk of data as a Config ROM */
1190
1191 static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
1192 {
1193 struct csr1212_bus_info_block_img *bi;
1194 struct csr1212_cache_region *cr;
1195 int i;
1196 int ret;
1197
1198 /* IEEE 1212 says that the entire bus info block should be readable in
1199 * a single transaction regardless of the max_rom value.
1200 * Unfortunately, many IEEE 1394 devices do not abide by that, so the
1201 * bus info block will be read 1 quadlet at a time. The rest of the
1202 * ConfigROM will be read according to the max_rom field. */
1203 for (i = 0; i < csr->bus_info_len; i += sizeof(csr1212_quad_t)) {
1204 ret = csr->ops->bus_read(csr, CSR1212_CONFIG_ROM_SPACE_BASE + i,
1205 sizeof(csr1212_quad_t),
1206 &csr->cache_head->data[bytes_to_quads(i)],
1207 csr->private);
1208 if (ret != CSR1212_SUCCESS)
1209 return ret;
1210 }
1211
1212 bi = (struct csr1212_bus_info_block_img*)csr->cache_head->data;
1213 csr->crc_len = quads_to_bytes(bi->crc_length);
1214
1215 /* IEEE 1212 recommends that crc_len be equal to bus_info_len, but that is not
1216 * always the case, so read the rest of the crc area 1 quadlet at a time. */
1217 for (i = csr->bus_info_len; i <= csr->crc_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;
1224 }
1225
1226 if (bytes_to_quads(csr->bus_info_len - sizeof(csr1212_quad_t)) != bi->length)
1227 return CSR1212_EINVAL;
1228
1229 #if 0
1230 /* Apparently there are too many differnt wrong implementations of the
1231 * CRC algorithm that verifying them is moot. */
1232 if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
1233 (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
1234 return CSR1212_EINVAL;
1235 #endif
1236
1237 cr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1238 if (!cr)
1239 return CSR1212_ENOMEM;
1240
1241 cr->next = NULL;
1242 cr->prev = NULL;
1243 cr->offset_start = 0;
1244 cr->offset_end = csr->crc_len + 4;
1245
1246 csr->cache_head->filled_head = cr;
1247 csr->cache_head->filled_tail = cr;
1248
1249 return CSR1212_SUCCESS;
1250 }
1251
1252 static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
1253 csr1212_quad_t ki,
1254 u_int32_t kv_pos,
1255 struct csr1212_csr_rom_cache *cache)
1256 {
1257 int ret = CSR1212_SUCCESS;
1258 struct csr1212_keyval *k = NULL;
1259 u_int32_t offset;
1260
1261 switch(CSR1212_KV_KEY_TYPE(ki)) {
1262 case CSR1212_KV_TYPE_IMMEDIATE:
1263 k = csr1212_new_immediate(CSR1212_KV_KEY_ID(ki),
1264 CSR1212_KV_VAL(ki));
1265 if (!k) {
1266 ret = CSR1212_ENOMEM;
1267 goto fail;
1268 }
1269
1270 k->refcnt = 0; /* Don't keep local reference when parsing. */
1271 break;
1272
1273 case CSR1212_KV_TYPE_CSR_OFFSET:
1274 k = csr1212_new_csr_offset(CSR1212_KV_KEY_ID(ki),
1275 CSR1212_KV_VAL(ki));
1276 if (!k) {
1277 ret = CSR1212_ENOMEM;
1278 goto fail;
1279 }
1280 k->refcnt = 0; /* Don't keep local reference when parsing. */
1281 break;
1282
1283 default:
1284 /* Compute the offset from 0xffff f000 0000. */
1285 offset = quads_to_bytes(CSR1212_KV_VAL(ki)) + kv_pos;
1286 if (offset == kv_pos) {
1287 /* Uh-oh. Can't have a relative offset of 0 for Leaves
1288 * or Directories. The Config ROM image is most likely
1289 * messed up, so we'll just abort here. */
1290 ret = CSR1212_EIO;
1291 goto fail;
1292 }
1293
1294 k = csr1212_find_keyval_offset(cache->layout_head, offset);
1295
1296 if (k)
1297 break; /* Found it. */
1298
1299 if (CSR1212_KV_KEY_TYPE(ki) == CSR1212_KV_TYPE_DIRECTORY) {
1300 k = csr1212_new_directory(CSR1212_KV_KEY_ID(ki));
1301 } else {
1302 k = csr1212_new_leaf(CSR1212_KV_KEY_ID(ki), NULL, 0);
1303 }
1304 if (!k) {
1305 ret = CSR1212_ENOMEM;
1306 goto fail;
1307 }
1308 k->refcnt = 0; /* Don't keep local reference when parsing. */
1309 k->valid = 0; /* Contents not read yet so it's not valid. */
1310 k->offset = offset;
1311
1312 k->prev = cache->layout_tail;
1313 k->next = NULL;
1314 if (cache->layout_tail)
1315 cache->layout_tail->next = k;
1316 cache->layout_tail = k;
1317 }
1318 ret = csr1212_attach_keyval_to_directory(dir, k);
1319
1320 fail:
1321 if (ret != CSR1212_SUCCESS) {
1322 if (k)
1323 free_keyval(k);
1324 }
1325 return ret;
1326 }
1327
1328 int csr1212_parse_keyval(struct csr1212_keyval *kv,
1329 struct csr1212_csr_rom_cache *cache)
1330 {
1331 struct csr1212_keyval_img *kvi;
1332 int i;
1333 int ret = CSR1212_SUCCESS;
1334 int kvi_len;
1335
1336 kvi = (struct csr1212_keyval_img*)&cache->data[bytes_to_quads(kv->offset -
1337 cache->offset)];
1338 kvi_len = CSR1212_BE16_TO_CPU(kvi->length);
1339
1340 #if 0
1341 /* Apparently there are too many differnt wrong implementations of the
1342 * CRC algorithm that verifying them is moot. */
1343 if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
1344 (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) {
1345 ret = CSR1212_EINVAL;
1346 goto fail;
1347 }
1348 #endif
1349
1350 switch(kv->key.type) {
1351 case CSR1212_KV_TYPE_DIRECTORY:
1352 for (i = 0; i < kvi_len; i++) {
1353 csr1212_quad_t ki = kvi->data[i];
1354
1355 /* Some devices put null entries in their unit
1356 * directories. If we come across such and entry,
1357 * then skip it. */
1358 if (ki == 0x0)
1359 continue;
1360 ret = csr1212_parse_dir_entry(kv, ki,
1361 (kv->offset +
1362 quads_to_bytes(i + 1)),
1363 cache);
1364 }
1365 kv->value.directory.len = kvi_len;
1366 break;
1367
1368 case CSR1212_KV_TYPE_LEAF:
1369 if (kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
1370 kv->value.leaf.data = cache->data;
1371 } else {
1372 kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
1373 if (!kv->value.leaf.data)
1374 {
1375 ret = CSR1212_ENOMEM;
1376 goto fail;
1377 }
1378
1379 kv->value.leaf.len = kvi_len;
1380 memcpy(kv->value.leaf.data, kvi->data, quads_to_bytes(kvi_len));
1381 }
1382 break;
1383 }
1384
1385 kv->valid = 1;
1386
1387 fail:
1388 return ret;
1389 }
1390
1391
1392 int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
1393 {
1394 struct csr1212_cache_region *cr, *ncr, *newcr = NULL;
1395 struct csr1212_keyval_img *kvi = NULL;
1396 struct csr1212_csr_rom_cache *cache;
1397 int cache_index;
1398 u_int64_t addr;
1399 u_int32_t *cache_ptr;
1400 u_int16_t kv_len = 0;
1401
1402
1403 if (!csr || !kv)
1404 return CSR1212_EINVAL;
1405
1406 /* First find which cache the data should be in (or go in if not read
1407 * yet). */
1408 for (cache = csr->cache_head; cache; cache = cache->next) {
1409 if (kv->offset >= cache->offset &&
1410 kv->offset < (cache->offset + cache->size))
1411 break;
1412 }
1413
1414 if (!cache) {
1415 csr1212_quad_t q;
1416 struct csr1212_csr_rom_cache *nc;
1417
1418 /* Only create a new cache for Extended ROM leaves. */
1419 if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
1420 return CSR1212_EINVAL;
1421
1422 if (csr->ops->bus_read(csr,
1423 CSR1212_REGISTER_SPACE_BASE + kv->offset,
1424 sizeof(csr1212_quad_t), &q, csr->private)) {
1425 return CSR1212_EIO;
1426 }
1427
1428 kv->value.leaf.len = quads_to_bytes(CSR1212_BE32_TO_CPU(q)>>16);
1429
1430 nc = csr1212_rom_cache_malloc(kv->offset, kv->value.leaf.len);
1431 cache->next = nc;
1432 nc->prev = cache;
1433 csr->cache_tail = nc;
1434 cache->filled_head =
1435 CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1436 if (!cache->filled_head) {
1437 return CSR1212_ENOMEM;
1438 }
1439
1440 cache->filled_head->offset_start = 0;
1441 cache->filled_head->offset_end = sizeof(csr1212_quad_t);
1442 cache->filled_tail = cache->filled_head;
1443 cache->filled_head->next = NULL;
1444 cache->filled_head->prev = NULL;
1445 cache->data[0] = q;
1446 }
1447
1448 cache_index = kv->offset - cache->offset;
1449
1450 /* Now seach read portions of the cache to see if it is there. */
1451 for (cr = cache->filled_head; cr; cr = cr->next) {
1452 if (cache_index < cr->offset_start) {
1453 newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1454 if (!newcr)
1455 return CSR1212_ENOMEM;
1456
1457 newcr->offset_start = cache_index & ~(csr->max_rom - 1);
1458 newcr->offset_end = newcr->offset_start;
1459 newcr->next = cr;
1460 newcr->prev = cr->prev;
1461 cr->prev = newcr;
1462 cr = newcr;
1463 break;
1464 } else if ((cache_index >= cr->offset_start) &&
1465 (cache_index < cr->offset_end)) {
1466 kvi = (struct csr1212_keyval_img*)
1467 (&cache->data[bytes_to_quads(cache_index)]);
1468 kv_len = quads_to_bytes(CSR1212_BE16_TO_CPU(kvi->length) +
1469 1);
1470 break;
1471 } else if (cache_index == cr->offset_end)
1472 break;
1473 }
1474
1475 if (!cr) {
1476 cr = cache->filled_tail;
1477 newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
1478 if (!newcr)
1479 return CSR1212_ENOMEM;
1480
1481 newcr->offset_start = cache_index & ~(csr->max_rom - 1);
1482 newcr->offset_end = newcr->offset_start;
1483 newcr->prev = cr;
1484 newcr->next = cr->next;
1485 cr->next = newcr;
1486 cr = newcr;
1487 cache->filled_tail = newcr;
1488 }
1489
1490 while(!kvi || cr->offset_end < cache_index + kv_len) {
1491 cache_ptr = &cache->data[bytes_to_quads(cr->offset_end &
1492 ~(csr->max_rom - 1))];
1493
1494 addr = (CSR1212_CSR_ARCH_REG_SPACE_BASE + cache->offset +
1495 cr->offset_end) & ~(csr->max_rom - 1);
1496
1497 if (csr->ops->bus_read(csr, addr, csr->max_rom, cache_ptr,
1498 csr->private)) {
1499 if (csr->max_rom == 4)
1500 /* We've got problems! */
1501 return CSR1212_EIO;
1502
1503 /* Apperently the max_rom value was a lie, set it to
1504 * do quadlet reads and try again. */
1505 csr->max_rom = 4;
1506 continue;
1507 }
1508
1509 cr->offset_end += csr->max_rom - (cr->offset_end &
1510 (csr->max_rom - 1));
1511
1512 if (!kvi && (cr->offset_end > cache_index)) {
1513 kvi = (struct csr1212_keyval_img*)
1514 (&cache->data[bytes_to_quads(cache_index)]);
1515 kv_len = quads_to_bytes(CSR1212_BE16_TO_CPU(kvi->length) +
1516 1);
1517 }
1518
1519 if ((kv_len + (kv->offset - cache->offset)) > cache->size) {
1520 /* The Leaf or Directory claims its length extends
1521 * beyond the ConfigROM image region and thus beyond the
1522 * end of our cache region. Therefore, we abort now
1523 * rather than seg faulting later. */
1524 return CSR1212_EIO;
1525 }
1526
1527 ncr = cr->next;
1528
1529 if (ncr && (cr->offset_end >= ncr->offset_start)) {
1530 /* consolidate region entries */
1531 ncr->offset_start = cr->offset_start;
1532
1533 if (cr->prev)
1534 cr->prev->next = cr->next;
1535 ncr->prev = cr->prev;
1536 if (cache->filled_head == cr)
1537 cache->filled_head = ncr;
1538 CSR1212_FREE(cr);
1539 cr = ncr;
1540 }
1541 }
1542
1543 return csr1212_parse_keyval(kv, cache);
1544 }
1545
1546
1547
1548 int csr1212_parse_csr(struct csr1212_csr *csr)
1549 {
1550 static const int mr_map[] = { 4, 64, 1024, 0 };
1551 int ret;
1552
1553 if (!csr || !csr->ops->bus_read)
1554 return CSR1212_EINVAL;
1555
1556 ret = csr1212_parse_bus_info_block(csr);
1557 if (ret != CSR1212_SUCCESS)
1558 return ret;
1559
1560 if (!csr->ops->get_max_rom)
1561 csr->max_rom = mr_map[0]; /* default value */
1562 else
1563 csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data,
1564 csr->private)];
1565
1566 csr->cache_head->layout_head = csr->root_kv;
1567 csr->cache_head->layout_tail = csr->root_kv;
1568
1569 csr->root_kv->offset = (CSR1212_CONFIG_ROM_SPACE_BASE & 0xffff) +
1570 csr->bus_info_len;
1571
1572 csr->root_kv->valid = 0;
1573 csr1212_get_keyval(csr, csr->root_kv);
1574
1575 return CSR1212_SUCCESS;
1576 }
1577
|
This page was automatically generated by the
LXR engine.
|