1 /* $NetBSD: ieee1212.c,v 1.11 2008/04/28 20:23:58 martin Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: ieee1212.c,v 1.11 2008/04/28 20:23:58 martin Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
41 #include <dev/std/ieee1212reg.h>
42 #include <dev/std/ieee1212var.h>
44 static const char * const p1212_keytype_strings
[] = P1212_KEYTYPE_STRINGS
;
45 static const char * const p1212_keyvalue_strings
[] = P1212_KEYVALUE_STRINGS
;
47 static u_int16_t
p1212_calc_crc(u_int32_t
, u_int32_t
*, int, int);
48 static int p1212_parse_directory(struct p1212_dir
*, u_int32_t
*, u_int32_t
);
49 static struct p1212_leafdata
*p1212_parse_leaf(u_int32_t
*);
50 static int p1212_parse_textdir(struct p1212_com
*, u_int32_t
*);
51 static struct p1212_textdata
*p1212_parse_text_desc(u_int32_t
*);
52 static void p1212_print_node(struct p1212_key
*, void *);
53 static int p1212_validate_offset(u_int16_t
, u_int32_t
);
54 static int p1212_validate_immed(u_int16_t
, u_int32_t
);
55 static int p1212_validate_leaf(u_int16_t
, u_int32_t
);
56 static int p1212_validate_dir(u_int16_t
, u_int32_t
);
59 #define DPRINTF(x) if (p1212debug) printf x
60 #define DPRINTFN(n,x) if (p1212debug>(n)) printf x
68 * Routines to parse the ROM into a tree that's usable. Also verify integrity
69 * vs. the P1212 standard
73 * A buffer of u_int32_t's and a size in quads gets passed in. The output will
74 * return -1 on error, or 0 on success and possibly reset *size to a larger
77 * NOTE: Rom's are guaranteed per the ISO spec to be contiguous but only the
78 * first 1k is directly mapped. Anything past 1k is supposed to use a loop
79 * around the indirect registers to read in the rom. This code only assumes the
80 * buffer passed in represents a total rom regardless of end size. It is the
81 * callers responsibility to treat a size > 1024 as a special case.
85 p1212_iscomplete(u_int32_t
*t
, u_int32_t
*size
)
87 u_int16_t infolen
, crclen
, len
;
88 u_int32_t newlen
, offset
, test
;
89 int complete
, i
, numdirs
, type
, val
, *dirs
;
94 DPRINTF(("Invalid size for ROM: %d\n", (unsigned int)*size
));
98 infolen
= P1212_ROMFMT_GET_INFOLEN((ntohl(t
[0])));
100 DPRINTF(("ROM not initialized or minimal ROM: Info "
101 "length: %d\n", infolen
));
104 crclen
= P1212_ROMFMT_GET_CRCLEN((ntohl(t
[0])));
105 if (crclen
< infolen
) {
106 DPRINTF(("CRC len less than info len. CRC len: %d, "
107 "Info len: %d\n", crclen
, infolen
));
112 * Now loop through it to check if all the offsets referenced are
113 * within the image stored so far. If not, get those as well.
116 offset
= P1212_ROMFMT_GET_INFOLEN((ntohl(t
[0]))) + 1;
119 * Make sure at least the bus info block is in memory + the root dir
120 * header quad. Add 1 here since offset is an array offset and size is
121 * the total array size we want. If this is getting the root dir
122 * then add another since infolen doesn't end on the root dir entry but
126 if ((*size
== 1) || (*size
< (offset
+ 1))) {
127 *size
= (crclen
> infolen
) ? crclen
: infolen
;
128 if (crclen
== infolen
)
141 * Make sure the whole directory is in memory. If not, bail now
145 newlen
= P1212_DIRENT_GET_LEN((ntohl(t
[offset
])));
146 if ((offset
+ newlen
+ 1) > *size
) {
147 newlen
+= offset
+ 1;
152 DPRINTF(("Impossible directory length of 0!\n"));
157 * Starting with the first byte of the directory, read through
158 * and check the values found. On offsets and directories read
159 * them in if appropriate (always for offsets, if not in memory
160 * for leaf/directories).
166 for (i
= 0; i
< len
; i
++) {
167 type
= P1212_DIRENT_GET_KEYTYPE((ntohl(t
[offset
+i
])));
168 val
= P1212_DIRENT_GET_VALUE((ntohl(t
[offset
+i
])));
170 case P1212_KEYTYPE_Immediate
:
171 case P1212_KEYTYPE_Offset
:
173 case P1212_KEYTYPE_Leaf
:
176 * If a leaf is found, and it's beyond the
177 * current rom length and it's beyond the
178 * current newlen setting,
179 * then set newlen accordingly.
182 test
= offset
+ i
+ val
+ 1;
183 if ((test
> *size
) && (test
> newlen
)) {
189 * For leaf nodes just make sure the whole leaf
190 * length is in the buffer. There's no data
191 * inside of them that can refer to outside
192 * nodes. (Uless it's vendor specific and then
193 * you're on your own anyways).
198 P1212_DIRENT_GET_LEN((ntohl(t
[test
])));
201 if ((test
> *size
) && (test
> newlen
)) {
206 case P1212_KEYTYPE_Directory
:
208 /* Make sure the first quad is in memory. */
210 test
= offset
+ i
+ val
+ 1;
211 if ((test
> *size
) && (test
> newlen
)) {
217 * Can't just walk the ROM looking at type
218 * codes since these are only valid on
219 * directory entries. So save any directories
220 * we find into a queue and the bottom of the
221 * while loop will pop the last one off and
222 * walk that directory.
227 sizeof(int) * (numdirs
+ 1), M_DEVBUF
,
229 dirs
[numdirs
++] = test
;
232 panic("Impossible type code: 0x%04hx",
233 (unsigned short)type
);
241 free(dirs
, M_DEVBUF
);
245 offset
= dirs
[--numdirs
];
246 dirs
= realloc(dirs
, sizeof(int) * numdirs
, M_DEVBUF
,
259 p1212_parse(u_int32_t
*t
, u_int32_t size
, u_int32_t mask
)
262 u_int16_t crc
, romcrc
, crc1
;
263 u_int32_t next
, check
;
264 struct p1212_rom
*rom
;
269 if (p1212_iscomplete(t
, &check
) == -1) {
270 DPRINTF(("ROM is not complete\n"));
274 DPRINTF(("ROM is not complete (check != size)\n"));
278 /* Calculate both a good and known bad crc. */
280 /* CRC's are calculated from everything except the first quad. */
282 crc
= p1212_calc_crc(0, &t
[1], P1212_ROMFMT_GET_CRCLEN((ntohl(t
[0]))),
285 romcrc
= P1212_ROMFMT_GET_CRC((ntohl(t
[0])));
287 crc1
= p1212_calc_crc(0, &t
[1],
288 P1212_ROMFMT_GET_CRCLEN((ntohl(t
[0]))), 1);
289 if (crc1
!= romcrc
) {
290 DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated "
291 "CRC: 0x%04hx, CRC1: 0x%04hx\n",
292 (unsigned short)romcrc
, (unsigned short)crc
,
293 (unsigned short)crc1
));
298 /* Now, walk the ROM. */
300 /* Get the initial offset for the root dir. */
302 rom
= malloc(sizeof(struct p1212_rom
), M_DEVBUF
, M_WAITOK
);
303 rom
->len
= P1212_ROMFMT_GET_INFOLEN((ntohl(t
[0])));
306 if ((rom
->len
< 1) || (rom
->len
> size
)) {
307 DPRINTF(("Invalid ROM info length: %d\n", rom
->len
));
312 /* Exclude the quad which covers the bus name. */
316 rom
->data
= malloc(sizeof(u_int32_t
) * rom
->len
, M_DEVBUF
,
318 /* Add 2 to account for info/crc and bus name skipped. */
319 for (i
= 0; i
< rom
->len
; i
++)
320 rom
->data
[i
] = t
[i
+ 2];
323 /* The name field is always 4 bytes and always the 2nd field. */
324 strncpy(rom
->name
, (char *)&t
[1], 4);
328 * Fill out the root directory. All these values are hardcoded so the
329 * parse/print/match routines have a standard layout to work against.
332 rom
->root
= malloc(sizeof(*rom
->root
), M_DEVBUF
, M_WAITOK
|M_ZERO
);
333 rom
->root
->com
.key
.key_type
= P1212_KEYTYPE_Directory
;
334 rom
->root
->com
.key
.key_value
= 0;
335 rom
->root
->com
.key
.key
= (u_int8_t
)P1212_KEYTYPE_Directory
;
336 rom
->root
->com
.key
.val
= 0;
337 TAILQ_INIT(&rom
->root
->data_root
);
338 TAILQ_INIT(&rom
->root
->subdir_root
);
340 if (p1212_parse_directory(rom
->root
, &t
[next
], mask
)) {
341 DPRINTF(("Parse error in ROM. Bailing\n"));
349 p1212_parse_directory(struct p1212_dir
*root
, u_int32_t
*addr
, u_int32_t mask
)
351 struct p1212_dir
*dir
, *sdir
;
352 struct p1212_data
*data
;
353 struct p1212_com
*com
;
355 u_int16_t crclen
, crc
, crc1
, romcrc
;
358 int i
, module_vendor_flag
, module_sw_flag
, node_sw_flag
, unit_sw_flag
;
359 int node_capabilities_flag
, offset
, unit_location_flag
, unitdir_cnt
;
365 module_vendor_flag
= 0;
368 node_capabilities_flag
= 0;
374 crclen
= P1212_DIRENT_GET_LEN((ntohl(t
[offset
])));
375 romcrc
= P1212_DIRENT_GET_CRC((ntohl(t
[offset
])));
377 crc
= p1212_calc_crc(0, &t
[offset
+ 1], crclen
, 0);
379 crc1
= p1212_calc_crc(0, &t
[offset
+ 1], crclen
, 1);
380 if (crc1
!= romcrc
) {
381 DPRINTF(("Invalid ROM: CRC: 0x%04hx, "
383 "0x%04hx, CRC1: 0x%04hx\n",
384 (unsigned short)romcrc
,
386 (unsigned short)crc1
));
392 unit_location_flag
= 0;
395 if ((dir
->parent
== NULL
) && dir
->com
.key
.val
) {
396 DPRINTF(("Invalid root dir. key.val is 0x%0x and not"
397 " 0x0\n", dir
->com
.key
.val
));
401 for (i
= offset
; i
< (offset
+ crclen
); i
++) {
403 type
= P1212_DIRENT_GET_KEYTYPE(desc
);
404 val
= P1212_DIRENT_GET_KEYVALUE(desc
);
407 * Sanity check for valid types/locations/etc.
409 * See pages 79-100 of
410 * ISO/IEC 13213:1194(ANSI/IEEE Std 1212, 1994 edition)
413 * XXX: These all really should be broken out into
414 * subroutines as it's grown large and complicated
419 case P1212_KEYVALUE_Unit_Spec_Id
:
420 case P1212_KEYVALUE_Unit_Sw_Version
:
421 case P1212_KEYVALUE_Unit_Dependent_Info
:
422 case P1212_KEYVALUE_Unit_Location
:
423 case P1212_KEYVALUE_Unit_Poll_Mask
:
424 if (dir
->parent
== NULL
) {
425 DPRINTF(("Invalid ROM: %s is not "
426 "valid in the root directory.\n",
427 p1212_keyvalue_strings
[val
]));
432 if (dir
->com
.key
.val
==
433 P1212_KEYVALUE_Unit_Directory
) {
434 DPRINTF(("Invalid ROM: %s is "
435 "not valid in a unit directory.\n",
436 p1212_keyvalue_strings
[val
]));
443 case P1212_KEYTYPE_Immediate
:
444 if (p1212_validate_immed(val
, mask
)) {
445 DPRINTF(("Invalid ROM: Can't have an "
446 "immediate type with %s value. Key"
447 " used at location 0x%0x in ROM\n",
448 p1212_keyvalue_strings
[val
],
449 (unsigned int)(&t
[i
]-&addr
[0])));
453 case P1212_KEYTYPE_Offset
:
454 if (p1212_validate_offset(val
, mask
)) {
455 DPRINTF(("Invalid ROM: Can't have "
456 "an offset type with key %s."
457 " Used at location 0x%0x in ROM\n",
458 p1212_keyvalue_strings
[val
],
459 (unsigned int)(&t
[i
]-&addr
[0])));
463 case P1212_KEYTYPE_Leaf
:
464 if (p1212_validate_leaf(val
, mask
)) {
465 DPRINTF(("Invalid ROM: Can't have a "
466 "leaf type with %s value. Key "
467 "used at location 0x%0x in ROM\n",
468 p1212_keyvalue_strings
[val
],
469 (unsigned int)(&t
[i
]-&addr
[0])));
473 case P1212_KEYTYPE_Directory
:
474 if (p1212_validate_dir(val
, mask
)) {
475 DPRINTF(("Invalid ROM: Can't have a "
476 "directory type with %s value. Key"
477 " used at location 0x%0x in ROM\n",
478 p1212_keyvalue_strings
[val
],
479 (unsigned int)(&t
[i
]-&addr
[0])));
484 panic("Impossible type code: 0x%04hx",
485 (unsigned short)type
);
489 /* Note flags for required fields. */
491 if (val
== P1212_KEYVALUE_Module_Vendor_Id
) {
492 module_vendor_flag
= 1;
495 if (val
== P1212_KEYVALUE_Node_Capabilities
) {
496 node_capabilities_flag
= 1;
499 if (val
== P1212_KEYVALUE_Unit_Sw_Version
)
502 if (val
== P1212_KEYVALUE_Unit_Location
)
503 unit_location_flag
= 1;
506 * This is just easier to spell out. You can't have
507 * a module sw version if you include a node sw version
508 * and vice-versa. Both aren't allowed if you have unit
512 if (val
== P1212_KEYVALUE_Module_Sw_Version
) {
514 DPRINTF(("Can't have a module software"
515 " version along with a node "
516 "software version entry\n"));
520 DPRINTF(("Can't have unit directories "
521 "with module software version "
528 if (val
== P1212_KEYVALUE_Node_Sw_Version
) {
529 if (module_sw_flag
) {
530 DPRINTF(("Can't have a node software "
531 "version along with a module "
532 "software version entry\n"));
536 DPRINTF(("Can't have unit directories "
537 "with node software version "
544 if (val
== P1212_KEYVALUE_Unit_Directory
) {
545 if (module_sw_flag
|| node_sw_flag
) {
546 DPRINTF(("Can't have unit directories "
547 "with either module or node "
548 "software version defined.\n"));
555 * Text descriptors are special. They describe the
556 * last entry they follow. So they need to be included
557 * with it's struct and there's nothing in the spec
558 * preventing one from putting text descriptors after
559 * directory descriptors. Also they can be a single
560 * value or a list of them in a directory format so
561 * account for either. Finally if they're in a
562 * directory those can be the only types in a
566 if (val
== P1212_KEYVALUE_Textual_Descriptor
) {
568 size
= sizeof(struct p1212_textdata
*);
569 leafoff
= P1212_DIRENT_GET_VALUE(desc
);
573 DPRINTF(("Can't have a text descriptor"
574 " as the first entry in a "
579 if (com
->textcnt
!= 0) {
580 DPRINTF(("Text descriptors can't "
581 "follow each other in a "
586 if (type
== P1212_KEYTYPE_Leaf
) {
588 malloc(size
, M_DEVBUF
, M_WAITOK
);
590 p1212_parse_text_desc(&t
[leafoff
]);
591 if (com
->text
[0] == NULL
) {
592 DPRINTF(("Got an error parsing"
593 " text descriptor at "
595 &t
[leafoff
]-&addr
[0]));
596 free(com
->text
, M_DEVBUF
);
601 i
= p1212_parse_textdir(com
,
608 if ((type
!= P1212_KEYTYPE_Directory
) &&
609 (val
!= P1212_KEYVALUE_Textual_Descriptor
)) {
610 data
= malloc(sizeof(struct p1212_data
),
611 M_DEVBUF
, M_WAITOK
|M_ZERO
);
612 data
->com
.key
.key_type
= type
;
613 data
->com
.key
.key_value
= val
;
615 P1212_DIRENT_GET_KEY((ntohl(t
[i
])));
617 P1212_DIRENT_GET_VALUE((ntohl(t
[i
])));
621 * Don't try and read the offset. It may be
622 * a register or something special. Generally
623 * these are node specific so let the upper
624 * level code figure it out.
627 if ((type
== P1212_KEYTYPE_Immediate
) ||
628 (type
== P1212_KEYTYPE_Offset
))
629 data
->val
= data
->com
.key
.val
;
631 data
->leafdata
= NULL
;
632 TAILQ_INSERT_TAIL(&dir
->data_root
, data
, data
);
634 if (type
== P1212_KEYTYPE_Leaf
) {
635 leafoff
= i
+ data
->com
.key
.val
;
637 p1212_parse_leaf(&t
[leafoff
]);
638 if (data
->leafdata
== NULL
) {
639 DPRINTF(("Error parsing leaf\n"));
644 if (type
== P1212_KEYTYPE_Directory
) {
646 sdir
= malloc(sizeof(struct p1212_dir
),
647 M_DEVBUF
, M_WAITOK
|M_ZERO
);
649 sdir
->com
.key
.key_type
= type
;
650 sdir
->com
.key
.key_value
= val
;
652 P1212_DIRENT_GET_KEY((ntohl(t
[i
])));
654 P1212_DIRENT_GET_VALUE((ntohl(t
[i
])));
656 sdir
->match
= sdir
->com
.key
.val
+ i
;
657 TAILQ_INIT(&sdir
->data_root
);
658 TAILQ_INIT(&sdir
->subdir_root
);
659 TAILQ_INSERT_TAIL(&dir
->subdir_root
, sdir
,dir
);
663 /* More validity checks. */
665 if (dir
->parent
== NULL
) {
666 if (module_vendor_flag
== 0) {
667 DPRINTF(("Missing module vendor entry in root "
671 if (node_capabilities_flag
== 0) {
672 DPRINTF(("Missing node capabilities entry in "
673 "root directory.\n"));
677 if ((unitdir_cnt
> 1) && (unit_location_flag
== 0)) {
678 DPRINTF(("Must have a unit location in each "
679 "unit directory when more than one unit "
680 "directory exists.\n"));
686 * Ok, done with this directory and it's sanity checked. Now
687 * loop through and either find an unparsed subdir or one
688 * farther back up the chain.
691 if (!TAILQ_EMPTY(&dir
->subdir_root
)) {
692 sdir
= TAILQ_FIRST(&dir
->subdir_root
);
695 sdir
= TAILQ_NEXT(dir
, dir
);
699 } while ((sdir
== NULL
) && (dir
!= NULL
));
704 DPRINTF(("Invalid subdir..Has no offset\n"));
713 static struct p1212_leafdata
*
714 p1212_parse_leaf(u_int32_t
*t
)
716 u_int16_t crclen
, crc
, crc1
, romcrc
;
717 struct p1212_leafdata
*leafdata
;
720 crclen
= P1212_DIRENT_GET_LEN((ntohl(t
[0])));
721 romcrc
= P1212_DIRENT_GET_CRC((ntohl(t
[0])));
722 crc
= p1212_calc_crc(0, &t
[1], crclen
, 0);
723 crc1
= p1212_calc_crc(0,&t
[1], crclen
, 1);
724 if ((crc
!= romcrc
) && (crc1
!= romcrc
)) {
725 DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated CRC: "
726 "0x%04hx, CRC1: 0x%04hx\n", (unsigned short)romcrc
,
727 (unsigned short)crc
, (unsigned short)crc1
));
733 * Most of these are vendor specific so don't bother trying to map them
734 * out. Anything which needs them later on can extract them.
737 leafdata
= malloc(sizeof(struct p1212_leafdata
), M_DEVBUF
, M_WAITOK
);
738 leafdata
->data
= malloc((sizeof(u_int32_t
) * crclen
), M_DEVBUF
,
740 leafdata
->len
= crclen
;
741 for (i
= 0; i
< crclen
; i
++)
742 leafdata
->data
[i
] = ntohl(t
[i
]);
747 p1212_parse_textdir(struct p1212_com
*com
, u_int32_t
*addr
)
749 u_int32_t
*t
, entry
, new;
750 u_int16_t crclen
, crc
, crc1
, romcrc
;
755 * A bit more complicated. A directory for a text descriptor can
756 * contain text descriptor leaf nodes only.
760 size
= sizeof(struct p1212_text
*);
763 crclen
= P1212_DIRENT_GET_LEN((ntohl(t
[0])));
764 romcrc
= P1212_DIRENT_GET_CRC((ntohl(t
[0])));
765 crc
= p1212_calc_crc(0, &t
[1], crclen
, 0);
766 crc1
= p1212_calc_crc(0,&t
[1], crclen
, 1);
767 if ((crc
!= romcrc
) && (crc1
!= romcrc
)) {
768 DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated CRC: "
769 "0x%04hx, CRC1: 0x%04hx\n", (unsigned short)romcrc
,
770 (unsigned short)crc
, (unsigned short)crc1
));
774 for (i
= 0; i
< crclen
; i
++) {
777 type
= P1212_DIRENT_GET_KEYTYPE(entry
);
778 val
= P1212_DIRENT_GET_KEYVALUE(entry
);
779 if ((type
!= P1212_KEYTYPE_Leaf
) ||
780 (val
!= P1212_KEYVALUE_Textual_Descriptor
)) {
781 DPRINTF(("Text descriptor directories can only "
782 "contain text descriptors. Type: %s, value: %s "
783 "isn't valid at offset 0x%0x\n",
784 p1212_keytype_strings
[type
],
785 p1212_keyvalue_strings
[val
], &t
[i
]-&addr
[0]));
789 new = P1212_DIRENT_GET_VALUE(entry
);
790 com
->text
= realloc(com
->text
, size
* (com
->textcnt
+ 1),
792 if ((com
->text
[i
] = p1212_parse_text_desc(&t
[i
+new])) == NULL
) {
793 DPRINTF(("Got an error parsing text descriptor.\n"));
794 if (com
->textcnt
== 0)
795 free(com
->text
, M_DEVBUF
);
803 static struct p1212_textdata
*
804 p1212_parse_text_desc(u_int32_t
*addr
)
807 u_int16_t crclen
, crc
, crc1
, romcrc
;
808 struct p1212_textdata
*text
;
813 crclen
= P1212_DIRENT_GET_LEN((ntohl(t
[0])));
814 romcrc
= P1212_DIRENT_GET_CRC((ntohl(t
[0])));
816 if (crclen
< P1212_TEXT_Min_Leaf_Length
) {
817 DPRINTF(("Invalid ROM: text descriptor too short\n"));
821 crc
= p1212_calc_crc(0, &t
[1], crclen
, 0);
823 crc1
= p1212_calc_crc(0, &t
[1], crclen
, 1);
824 if (crc1
!= romcrc
) {
825 DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated CRC: "
826 "0x%04hx, CRC1: 0x%04hx\n", (unsigned short)romcrc
,
827 (unsigned short)crc
, (unsigned short)crc1
));
833 text
= malloc(sizeof(struct p1212_textdata
), M_DEVBUF
, M_WAITOK
);
834 text
->spec_type
= P1212_TEXT_GET_Spec_Type((ntohl(t
[0])));
835 text
->spec_id
= P1212_TEXT_GET_Spec_Id((ntohl(t
[0])));
836 text
->lang_id
= ntohl(t
[1]);
841 size
= (crclen
* sizeof(u_int32_t
));
843 text
->text
= malloc(size
+ 1, M_DEVBUF
, M_WAITOK
|M_ZERO
);
845 memcpy(text
->text
, &t
[0], size
);
851 p1212_find(struct p1212_dir
*root
, int type
, int value
, int flags
)
853 struct p1212_key
**retkeys
;
854 struct p1212_dir
*dir
, *sdir
, *parent
;
855 struct p1212_data
*data
;
861 if ((type
< P1212_KEYTYPE_Immediate
) ||
862 (type
> P1212_KEYTYPE_Directory
)) {
864 printf("p1212_find: invalid type - %d\n", type
);
870 (value
> (sizeof(p1212_keyvalue_strings
) / sizeof(char *)))) {
872 printf("p1212_find: invalid value - %d\n", value
);
877 if (flags
& ~(P1212_FIND_SEARCHALL
| P1212_FIND_RETURNALL
)) {
879 printf("p1212_find: invalid flags - %d\n", flags
);
885 * Part of this is copied from p1212_walk to do depth first traversal
886 * without using recursion. Using the walk API would have made things
887 * more complicated in trying to build up the return struct otherwise.
893 parent
= root
->parent
;
897 if (type
== P1212_KEYTYPE_Directory
) {
898 TAILQ_FOREACH(sdir
, &dir
->subdir_root
, dir
) {
899 if ((sdir
->com
.key
.key_value
== value
) ||
902 retkeys
= realloc(retkeys
,
903 sizeof(struct p1212_key
*) *
904 (numkeys
+ 1), M_DEVBUF
, M_WAITOK
);
905 retkeys
[numkeys
- 1] = &sdir
->com
.key
;
906 retkeys
[numkeys
] = NULL
;
907 if ((flags
& P1212_FIND_RETURNALL
)
909 root
->parent
= parent
;
915 TAILQ_FOREACH(data
, &dir
->data_root
, data
) {
916 if (((data
->com
.key
.key_type
== type
) &&
917 (data
->com
.key
.key_value
== value
)) ||
918 ((data
->com
.key
.key_type
== type
) &&
921 retkeys
= realloc(retkeys
,
922 sizeof(struct p1212_key
*) *
923 (numkeys
+ 1), M_DEVBUF
, M_WAITOK
);
924 retkeys
[numkeys
- 1] = &data
->com
.key
;
925 retkeys
[numkeys
] = NULL
;
926 if ((flags
& P1212_FIND_RETURNALL
)
928 root
->parent
= parent
;
934 if (flags
& P1212_FIND_SEARCHALL
) {
936 sdir
= TAILQ_NEXT(dir
, dir
);
940 } while ((sdir
== NULL
) && (dir
!= NULL
));
945 root
->parent
= parent
;
950 p1212_walk(struct p1212_dir
*root
, void *arg
,
951 void (*func
)(struct p1212_key
*, void *))
953 struct p1212_data
*data
;
954 struct p1212_dir
*sdir
, *dir
, *parent
;
961 printf("p1212_walk: Passed in NULL function\n");
967 printf("p1212_walk: Called with NULL root\n");
972 /* Allow walking from any point. Just mark the starting point. */
973 parent
= root
->parent
;
977 * Depth first traversal that doesn't use recursion.
979 * Call the function first for the directory node and then loop through
980 * all the data nodes and call the function for them.
982 * Finally, figure out the next possible directory node if one is
983 * available or bail out.
987 func((struct p1212_key
*) dir
, arg
);
988 TAILQ_FOREACH(data
, &dir
->data_root
, data
)
989 func((struct p1212_key
*) data
, arg
);
990 if (!TAILQ_EMPTY(&dir
->subdir_root
)) {
991 sdir
= TAILQ_FIRST(&dir
->subdir_root
);
994 sdir
= TAILQ_NEXT(dir
, dir
);
998 } while ((sdir
== NULL
) && dir
);
1003 root
->parent
= parent
;
1007 p1212_print(struct p1212_dir
*dir
)
1013 p1212_walk(dir
, &indent
, p1212_print_node
);
1018 p1212_print_node(struct p1212_key
*key
, void *arg
)
1021 struct p1212_data
*data
;
1022 struct p1212_dir
*sdir
, *dir
;
1027 if (key
->key_type
== P1212_KEYTYPE_Directory
) {
1028 dir
= (struct p1212_dir
*) key
;
1031 data
= (struct p1212_data
*) key
;
1035 /* Recompute the indent level on each directory. */
1039 while (sdir
!= NULL
) {
1041 sdir
= sdir
->parent
;
1045 if (dir
&& dir
->parent
)
1048 /* Set the indent string up. 4 spaces per level. */
1049 for (i
= 0; i
< (*indent
* 4); i
++)
1053 printf("Directory: ");
1057 if (key
->key_value
>=
1058 (sizeof(p1212_keyvalue_strings
) / sizeof(char *)))
1059 printf("Unknown type 0x%04hx\n",
1060 (unsigned short)key
->key_value
);
1063 p1212_keyvalue_strings
[key
->key_value
]);
1065 if (dir
->com
.textcnt
) {
1066 for (i
= 0; i
< dir
->com
.textcnt
; i
++) {
1067 for (j
= 0; j
< (*indent
* 4); j
++)
1069 printf("Text descriptor: %s\n",
1070 dir
->com
.text
[i
]->text
);
1078 if (key
->key_value
>=
1079 (sizeof(p1212_keyvalue_strings
) / sizeof(char *)))
1080 printf("Unknown type 0x%04hx: ",
1081 (unsigned short)key
->key_value
);
1084 p1212_keyvalue_strings
[key
->key_value
]);
1086 printf("0x%08x\n", key
->val
);
1088 if ((data
->com
.key
.key_type
== P1212_KEYTYPE_Leaf
) &&
1089 (data
->leafdata
== NULL
))
1090 panic("Invalid data node in configrom tree");
1093 if (data
->leafdata
) {
1094 for (i
= 0; i
< data
->leafdata
->len
; i
++) {
1095 for (j
= 0; j
< (*indent
* 4); j
++)
1097 printf ("Leaf data: 0x%08x\n",
1098 data
->leafdata
->data
[i
]);
1101 if (data
->com
.textcnt
)
1102 for (i
= 0; i
< data
->com
.textcnt
; i
++) {
1103 for (j
= 0; j
< (*indent
* 4); j
++)
1105 printf("Text descriptor: %s\n",
1106 data
->com
.text
[i
]->text
);
1115 p1212_free(struct p1212_rom
*rom
)
1117 struct p1212_dir
*sdir
, *dir
;
1118 struct p1212_data
*data
;
1123 /* Avoid recursing. Find the bottom most node and work back. */
1125 if (!TAILQ_EMPTY(&dir
->subdir_root
)) {
1126 sdir
= TAILQ_FIRST(&dir
->subdir_root
);
1127 if (TAILQ_EMPTY(&sdir
->subdir_root
)) {
1128 TAILQ_REMOVE(&dir
->subdir_root
, sdir
, dir
);
1137 TAILQ_REMOVE(&dir
->parent
->subdir_root
, dir
,
1141 while ((data
= TAILQ_FIRST(&dir
->data_root
))) {
1142 if (data
->leafdata
) {
1143 if (data
->leafdata
->data
)
1144 free(data
->leafdata
->data
, M_DEVBUF
);
1145 free(data
->leafdata
, M_DEVBUF
);
1147 TAILQ_REMOVE(&dir
->data_root
, data
, data
);
1148 if (data
->com
.textcnt
) {
1149 for (i
= 0; i
< data
->com
.textcnt
; i
++)
1150 free(data
->com
.text
[i
], M_DEVBUF
);
1151 free(data
->com
.text
, M_DEVBUF
);
1153 free(data
, M_DEVBUF
);
1160 if (sdir
->com
.textcnt
) {
1161 for (i
= 0; i
< sdir
->com
.textcnt
; i
++)
1162 free(sdir
->com
.text
[i
], M_DEVBUF
);
1163 free(sdir
->com
.text
, M_DEVBUF
);
1165 free(sdir
, M_DEVBUF
);
1168 free(rom
->data
, M_DEVBUF
);
1169 free(rom
, M_DEVBUF
);
1173 * A fairly well published reference implementation of the CRC routine had
1174 * a typo in it and some devices may be using it rather than the correct one
1175 * in calculating their ROM CRC's. To compensate an interface for generating
1176 * either is provided.
1178 * len is the number of u_int32_t entries, not bytes.
1182 p1212_calc_crc(u_int32_t crc
, u_int32_t
*data
, int len
, int broke
)
1188 for (i
= 0; i
< len
; i
++) {
1189 for (shift
= 28; shift
> 0; shift
-= 4) {
1190 sum
= ((crc
>> 12) ^ (ntohl(data
[i
]) >> shift
)) &
1192 crc
= (crc
<< 4) ^ (sum
<< 12) ^ (sum
<< 5) ^ sum
;
1196 /* The broken implementation doesn't do the last shift. */
1198 sum
= ((crc
>> 12) ^ ntohl(data
[i
])) & 0x0000000f;
1199 crc
= (crc
<< 4) ^ (sum
<< 12) ^ (sum
<< 5) ^ sum
;
1202 return (u_int16_t
)crc
;
1206 * This is almost identical to the standard autoconf *match idea except it
1207 * can match and attach multiple children in one pass.
1211 p1212_match_units(device_t sc
, struct p1212_dir
*dir
,
1212 int (*print
)(void *, const char *))
1214 struct p1212_dir
**udirs
;
1215 device_t
*devret
, *dev
;
1219 * Setup typical return val. Always allocate one extra pointer for a
1220 * NULL guard end pointer.
1224 devret
= malloc(sizeof(device_t
) * 2, M_DEVBUF
, M_WAITOK
);
1227 udirs
= (struct p1212_dir
**)p1212_find(dir
, P1212_KEYTYPE_Directory
,
1228 P1212_KEYVALUE_Unit_Directory
,
1229 P1212_FIND_SEARCHALL
|P1212_FIND_RETURNALL
);
1233 dev
= config_found_ia(sc
, "fwnode", udirs
, print
);
1234 if (dev
&& numdev
) {
1235 devret
= realloc(devret
,
1237 (numdev
+ 2), M_DEVBUF
, M_WAITOK
);
1238 devret
[numdev
++] = dev
;
1239 devret
[numdev
] = NULL
;
1248 free(devret
, M_DEVBUF
);
1255 * Make these their own functions as they have slightly complicated rules.
1259 * Under normal circumstances only the 2 extent types can be offset
1260 * types. However some spec's which use p1212 like SBP2 for
1261 * firewire/1394 will define a dependent info type as an offset value.
1262 * Allow the upper level code to flag this and pass it down during
1263 * parsing. The same thing applies to immediate types.
1267 p1212_validate_offset(u_int16_t val
, u_int32_t mask
)
1269 if ((val
== P1212_KEYVALUE_Node_Units_Extent
) ||
1270 (val
== P1212_KEYVALUE_Node_Memory_Extent
) ||
1271 ((mask
& P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE
) &&
1272 ((val
== P1212_KEYVALUE_Unit_Dependent_Info
) ||
1273 (val
== P1212_KEYVALUE_Node_Dependent_Info
) ||
1274 (val
== P1212_KEYVALUE_Module_Dependent_Info
))))
1280 p1212_validate_immed(u_int16_t val
, u_int32_t mask
)
1283 case P1212_KEYVALUE_Textual_Descriptor
:
1284 case P1212_KEYVALUE_Bus_Dependent_Info
:
1285 case P1212_KEYVALUE_Module_Dependent_Info
:
1286 case P1212_KEYVALUE_Node_Unique_Id
:
1287 case P1212_KEYVALUE_Node_Dependent_Info
:
1288 case P1212_KEYVALUE_Unit_Directory
:
1289 case P1212_KEYVALUE_Unit_Dependent_Info
:
1290 case P1212_KEYVALUE_Unit_Location
:
1291 if ((mask
& P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE
) &&
1292 ((val
== P1212_KEYVALUE_Module_Dependent_Info
) ||
1293 (val
== P1212_KEYVALUE_Node_Dependent_Info
) ||
1294 (val
== P1212_KEYVALUE_Unit_Dependent_Info
)))
1305 p1212_validate_leaf(u_int16_t val
, u_int32_t mask
)
1308 case P1212_KEYVALUE_Textual_Descriptor
:
1309 case P1212_KEYVALUE_Bus_Dependent_Info
:
1310 case P1212_KEYVALUE_Module_Dependent_Info
:
1311 case P1212_KEYVALUE_Node_Unique_Id
:
1312 case P1212_KEYVALUE_Node_Dependent_Info
:
1313 case P1212_KEYVALUE_Unit_Dependent_Info
:
1314 case P1212_KEYVALUE_Unit_Location
:
1324 p1212_validate_dir(u_int16_t val
, u_int32_t mask
)
1327 case P1212_KEYVALUE_Textual_Descriptor
:
1328 case P1212_KEYVALUE_Bus_Dependent_Info
:
1329 case P1212_KEYVALUE_Module_Dependent_Info
:
1330 case P1212_KEYVALUE_Node_Dependent_Info
:
1331 case P1212_KEYVALUE_Unit_Directory
:
1332 case P1212_KEYVALUE_Unit_Dependent_Info
:
1335 if ((mask
& P1212_ALLOW_VENDOR_DIRECTORY_TYPE
) &&
1336 (val
== P1212_KEYVALUE_Module_Vendor_Id
))