Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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, &ltail);
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.