1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * CCS static data binary parser library
5 * Copyright 2019--2020 Intel Corporation
8 #include <linux/device.h>
9 #include <linux/errno.h>
10 #include <linux/limits.h>
12 #include <linux/slab.h>
14 #include "ccs-data-defs.h"
16 struct bin_container
{
23 static void *bin_alloc(struct bin_container
*bin
, size_t len
)
29 if (bin
->end
- bin
->now
< len
)
38 static void bin_reserve(struct bin_container
*bin
, size_t len
)
40 bin
->size
+= ALIGN(len
, 8);
43 static int bin_backing_alloc(struct bin_container
*bin
)
45 bin
->base
= bin
->now
= kvzalloc(bin
->size
, GFP_KERNEL
);
49 bin
->end
= bin
->base
+ bin
->size
;
54 #define is_contained(var, endp) \
55 (sizeof(*var) <= (endp) - (void *)(var))
56 #define has_headroom(ptr, headroom, endp) \
57 ((headroom) <= (endp) - (void *)(ptr))
58 #define is_contained_with_headroom(var, headroom, endp) \
59 (sizeof(*var) + (headroom) <= (endp) - (void *)(var))
62 ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier
*__len
,
63 size_t *__hlen
, size_t *__plen
,
68 if (!is_contained(__len
, endp
))
71 switch (__len
->length
>> CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) {
72 case CCS_DATA_LENGTH_SPECIFIER_1
:
73 hlen
= sizeof(*__len
);
74 plen
= __len
->length
&
75 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) - 1);
77 case CCS_DATA_LENGTH_SPECIFIER_2
: {
78 struct __ccs_data_length_specifier2
*__len2
= (void *)__len
;
80 if (!is_contained(__len2
, endp
))
83 hlen
= sizeof(*__len2
);
86 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) - 1))
87 << 8) + __len2
->length
[1];
90 case CCS_DATA_LENGTH_SPECIFIER_3
: {
91 struct __ccs_data_length_specifier3
*__len3
= (void *)__len
;
93 if (!is_contained(__len3
, endp
))
96 hlen
= sizeof(*__len3
);
99 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) - 1))
100 << 16) + (__len3
->length
[0] << 8) + __len3
->length
[1];
107 if (!has_headroom(__len
, hlen
+ plen
, endp
))
117 ccs_data_parse_format_version(const struct __ccs_data_block
*block
)
119 return block
->id
>> CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT
;
122 static u8
ccs_data_parse_block_id(const struct __ccs_data_block
*block
,
128 return block
->id
& ((1 << CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT
) - 1);
131 static int ccs_data_parse_version(struct bin_container
*bin
,
132 struct ccs_data_container
*ccsdata
,
133 const void *payload
, const void *endp
)
135 const struct __ccs_data_block_version
*v
= payload
;
136 struct ccs_data_block_version
*vv
;
142 bin_reserve(bin
, sizeof(*ccsdata
->version
));
146 ccsdata
->version
= bin_alloc(bin
, sizeof(*ccsdata
->version
));
147 if (!ccsdata
->version
)
150 vv
= ccsdata
->version
;
151 vv
->version_major
= ((u16
)v
->static_data_version_major
[0] << 8) +
152 v
->static_data_version_major
[1];
153 vv
->version_minor
= ((u16
)v
->static_data_version_minor
[0] << 8) +
154 v
->static_data_version_minor
[1];
155 vv
->date_year
= ((u16
)v
->year
[0] << 8) + v
->year
[1];
156 vv
->date_month
= v
->month
;
157 vv
->date_day
= v
->day
;
162 static void print_ccs_data_version(struct device
*dev
,
163 struct ccs_data_block_version
*v
)
166 "static data version %4.4x.%4.4x, date %4.4u-%2.2u-%2.2u\n",
167 v
->version_major
, v
->version_minor
,
168 v
->date_year
, v
->date_month
, v
->date_day
);
171 static int ccs_data_block_parse_header(const struct __ccs_data_block
*block
,
172 bool is_first
, unsigned int *__block_id
,
173 const void **payload
,
174 const struct __ccs_data_block
**next_block
,
175 const void *endp
, struct device
*dev
,
182 if (!is_contained(block
, endp
))
185 rval
= ccs_data_parse_length_specifier(&block
->length
, &hlen
, &plen
,
190 block_id
= ccs_data_parse_block_id(block
, is_first
);
194 "Block ID 0x%2.2x, header length %zu, payload length %zu\n",
195 block_id
, hlen
, plen
);
197 if (!has_headroom(&block
->length
, hlen
+ plen
, endp
))
201 *__block_id
= block_id
;
204 *payload
= (void *)&block
->length
+ hlen
;
207 *next_block
= (void *)&block
->length
+ hlen
+ plen
;
212 static int ccs_data_parse_regs(struct bin_container
*bin
,
213 struct ccs_reg
**__regs
,
214 size_t *__num_regs
, const void *payload
,
215 const void *endp
, struct device
*dev
)
217 struct ccs_reg
*regs_base
= NULL
, *regs
= NULL
;
221 if (bin
->base
&& __regs
) {
222 regs
= regs_base
= bin_alloc(bin
, sizeof(*regs
) * *__num_regs
);
227 while (payload
< endp
&& num_regs
< INT_MAX
) {
228 const struct __ccs_data_block_regs
*r
= payload
;
232 if (!is_contained(r
, endp
))
235 switch (r
->reg_len
>> CCS_DATA_BLOCK_REGS_SEL_SHIFT
) {
236 case CCS_DATA_BLOCK_REGS_SEL_REGS
:
237 addr
+= r
->reg_len
& CCS_DATA_BLOCK_REGS_ADDR_MASK
;
238 len
= ((r
->reg_len
& CCS_DATA_BLOCK_REGS_LEN_MASK
)
239 >> CCS_DATA_BLOCK_REGS_LEN_SHIFT
) + 1;
241 if (!is_contained_with_headroom(r
, len
, endp
))
246 case CCS_DATA_BLOCK_REGS_SEL_REGS2
: {
247 const struct __ccs_data_block_regs2
*r2
= payload
;
249 if (!is_contained(r2
, endp
))
252 addr
+= ((u16
)(r2
->reg_len
&
253 CCS_DATA_BLOCK_REGS_2_ADDR_MASK
) << 8)
255 len
= ((r2
->reg_len
& CCS_DATA_BLOCK_REGS_2_LEN_MASK
)
256 >> CCS_DATA_BLOCK_REGS_2_LEN_SHIFT
) + 1;
258 if (!is_contained_with_headroom(r2
, len
, endp
))
264 case CCS_DATA_BLOCK_REGS_SEL_REGS3
: {
265 const struct __ccs_data_block_regs3
*r3
= payload
;
267 if (!is_contained(r3
, endp
))
270 addr
= ((u16
)r3
->addr
[0] << 8) + r3
->addr
[1];
271 len
= (r3
->reg_len
& CCS_DATA_BLOCK_REGS_3_LEN_MASK
) + 1;
273 if (!is_contained_with_headroom(r3
, len
, endp
))
286 bin_reserve(bin
, len
);
293 regs
->value
= bin_alloc(bin
, len
);
297 memcpy(regs
->value
, data
, len
);
302 payload
= data
+ len
;
306 bin_reserve(bin
, sizeof(*regs
) * num_regs
);
309 *__num_regs
= num_regs
;
311 if (bin
->base
&& __regs
) {
321 static int ccs_data_parse_reg_rules(struct bin_container
*bin
,
322 struct ccs_reg
**__regs
,
325 const void *endp
, struct device
*dev
)
330 return ccs_data_parse_regs(bin
, NULL
, NULL
, payload
, endp
, dev
);
332 rval
= ccs_data_parse_regs(bin
, NULL
, __num_regs
, payload
, endp
, dev
);
336 return ccs_data_parse_regs(bin
, __regs
, __num_regs
, payload
, endp
,
340 static void assign_ffd_entry(struct ccs_frame_format_desc
*desc
,
341 const struct __ccs_data_block_ffd_entry
*ent
)
343 desc
->pixelcode
= ent
->pixelcode
;
344 desc
->value
= ((u16
)ent
->value
[0] << 8) + ent
->value
[1];
347 static int ccs_data_parse_ffd(struct bin_container
*bin
,
348 struct ccs_frame_format_descs
**ffd
,
350 const void *endp
, struct device
*dev
)
352 const struct __ccs_data_block_ffd
*__ffd
= payload
;
353 const struct __ccs_data_block_ffd_entry
*__entry
;
356 if (!is_contained(__ffd
, endp
))
359 if ((void *)__ffd
+ sizeof(*__ffd
) +
360 ((u32
)__ffd
->num_column_descs
+
361 (u32
)__ffd
->num_row_descs
) *
362 sizeof(struct __ccs_data_block_ffd_entry
) != endp
)
366 bin_reserve(bin
, sizeof(**ffd
));
367 bin_reserve(bin
, __ffd
->num_column_descs
*
368 sizeof(struct ccs_frame_format_desc
));
369 bin_reserve(bin
, __ffd
->num_row_descs
*
370 sizeof(struct ccs_frame_format_desc
));
375 *ffd
= bin_alloc(bin
, sizeof(**ffd
));
379 (*ffd
)->num_column_descs
= __ffd
->num_column_descs
;
380 (*ffd
)->num_row_descs
= __ffd
->num_row_descs
;
381 __entry
= (void *)(__ffd
+ 1);
383 (*ffd
)->column_descs
= bin_alloc(bin
, __ffd
->num_column_descs
*
384 sizeof(*(*ffd
)->column_descs
));
385 if (!(*ffd
)->column_descs
)
388 for (i
= 0; i
< __ffd
->num_column_descs
; i
++, __entry
++)
389 assign_ffd_entry(&(*ffd
)->column_descs
[i
], __entry
);
391 (*ffd
)->row_descs
= bin_alloc(bin
, __ffd
->num_row_descs
*
392 sizeof(*(*ffd
)->row_descs
));
393 if (!(*ffd
)->row_descs
)
396 for (i
= 0; i
< __ffd
->num_row_descs
; i
++, __entry
++)
397 assign_ffd_entry(&(*ffd
)->row_descs
[i
], __entry
);
405 static int ccs_data_parse_pdaf_readout(struct bin_container
*bin
,
406 struct ccs_pdaf_readout
**pdaf_readout
,
408 const void *endp
, struct device
*dev
)
410 const struct __ccs_data_block_pdaf_readout
*__pdaf
= payload
;
412 if (!is_contained(__pdaf
, endp
))
416 bin_reserve(bin
, sizeof(**pdaf_readout
));
418 *pdaf_readout
= bin_alloc(bin
, sizeof(**pdaf_readout
));
422 (*pdaf_readout
)->pdaf_readout_info_order
=
423 __pdaf
->pdaf_readout_info_order
;
426 return ccs_data_parse_ffd(bin
, !bin
->base
? NULL
: &(*pdaf_readout
)->ffd
,
427 __pdaf
+ 1, endp
, dev
);
430 static int ccs_data_parse_rules(struct bin_container
*bin
,
431 struct ccs_rule
**__rules
,
432 size_t *__num_rules
, const void *payload
,
433 const void *endp
, struct device
*dev
)
435 struct ccs_rule
*rules_base
= NULL
, *rules
= NULL
, *next_rule
= NULL
;
436 size_t num_rules
= 0;
437 const void *__next_rule
= payload
;
441 rules_base
= next_rule
=
442 bin_alloc(bin
, sizeof(*rules
) * *__num_rules
);
447 while (__next_rule
< endp
) {
448 size_t rule_hlen
, rule_plen
, rule_plen2
;
449 const u8
*__rule_type
;
450 const void *rule_payload
;
452 /* Size of a single rule */
453 rval
= ccs_data_parse_length_specifier(__next_rule
, &rule_hlen
,
459 __rule_type
= __next_rule
+ rule_hlen
;
461 if (!is_contained(__rule_type
, endp
))
464 rule_payload
= __rule_type
+ 1;
465 rule_plen2
= rule_plen
- sizeof(*__rule_type
);
467 if (*__rule_type
== CCS_DATA_BLOCK_RULE_ID_IF
) {
468 const struct __ccs_data_block_rule_if
*__if_rules
=
470 const size_t __num_if_rules
=
471 rule_plen2
/ sizeof(*__if_rules
);
472 struct ccs_if_rule
*if_rule
;
474 if (!has_headroom(__if_rules
,
475 sizeof(*__if_rules
) * __num_if_rules
,
476 rule_payload
+ rule_plen2
))
479 /* Also check there is no extra data */
480 if (__if_rules
+ __num_if_rules
!=
481 rule_payload
+ rule_plen2
)
498 if_rule
= bin_alloc(bin
,
504 for (i
= 0; i
< __num_if_rules
; i
++) {
506 ((u16
)__if_rules
[i
].addr
[0]
508 __if_rules
[i
].addr
[1];
509 if_rule
[i
].value
= __if_rules
[i
].value
;
510 if_rule
[i
].mask
= __if_rules
[i
].mask
;
513 rules
->if_rules
= if_rule
;
514 rules
->num_if_rules
= __num_if_rules
;
517 /* Check there was an if rule before any other rules */
518 if (bin
->base
&& !rules
)
521 switch (*__rule_type
) {
522 case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS
:
523 rval
= ccs_data_parse_reg_rules(bin
,
525 &rules
->read_only_regs
: NULL
,
527 &rules
->num_read_only_regs
: NULL
,
529 rule_payload
+ rule_plen2
,
534 case CCS_DATA_BLOCK_RULE_ID_FFD
:
535 rval
= ccs_data_parse_ffd(bin
, rules
?
536 &rules
->frame_format
: NULL
,
538 rule_payload
+ rule_plen2
,
543 case CCS_DATA_BLOCK_RULE_ID_MSR
:
544 rval
= ccs_data_parse_reg_rules(bin
,
546 &rules
->manufacturer_regs
: NULL
,
548 &rules
->num_manufacturer_regs
: NULL
,
550 rule_payload
+ rule_plen2
,
555 case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT
:
556 rval
= ccs_data_parse_pdaf_readout(bin
,
558 &rules
->pdaf_readout
: NULL
,
560 rule_payload
+ rule_plen2
,
567 "Don't know how to handle rule type %u!\n",
572 __next_rule
= __next_rule
+ rule_hlen
+ rule_plen
;
576 bin_reserve(bin
, sizeof(*rules
) * num_rules
);
577 *__num_rules
= num_rules
;
582 *__rules
= rules_base
;
588 static int ccs_data_parse_pdaf(struct bin_container
*bin
, struct ccs_pdaf_pix_loc
**pdaf
,
589 const void *payload
, const void *endp
,
592 const struct __ccs_data_block_pdaf_pix_loc
*__pdaf
= payload
;
593 const struct __ccs_data_block_pdaf_pix_loc_block_desc_group
*__bdesc_group
;
594 const struct __ccs_data_block_pdaf_pix_loc_pixel_desc
*__pixel_desc
;
596 u16 num_block_desc_groups
;
597 u8 max_block_type_id
= 0;
598 const u8
*__num_pixel_descs
;
600 if (!is_contained(__pdaf
, endp
))
604 *pdaf
= bin_alloc(bin
, sizeof(**pdaf
));
608 bin_reserve(bin
, sizeof(**pdaf
));
611 num_block_desc_groups
=
612 ((u16
)__pdaf
->num_block_desc_groups
[0] << 8) +
613 __pdaf
->num_block_desc_groups
[1];
616 (*pdaf
)->main_offset_x
=
617 ((u16
)__pdaf
->main_offset_x
[0] << 8) +
618 __pdaf
->main_offset_x
[1];
619 (*pdaf
)->main_offset_y
=
620 ((u16
)__pdaf
->main_offset_y
[0] << 8) +
621 __pdaf
->main_offset_y
[1];
622 (*pdaf
)->global_pdaf_type
= __pdaf
->global_pdaf_type
;
623 (*pdaf
)->block_width
= __pdaf
->block_width
;
624 (*pdaf
)->block_height
= __pdaf
->block_height
;
625 (*pdaf
)->num_block_desc_groups
= num_block_desc_groups
;
628 __bdesc_group
= (const void *)(__pdaf
+ 1);
631 (*pdaf
)->block_desc_groups
=
633 sizeof(struct ccs_pdaf_pix_loc_block_desc_group
) *
634 num_block_desc_groups
);
635 if (!(*pdaf
)->block_desc_groups
)
638 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_block_desc_group
) *
639 num_block_desc_groups
);
642 for (i
= 0; i
< num_block_desc_groups
; i
++) {
643 const struct __ccs_data_block_pdaf_pix_loc_block_desc
*__bdesc
;
647 if (!is_contained(__bdesc_group
, endp
))
651 ((u16
)__bdesc_group
->num_block_descs
[0] << 8) +
652 __bdesc_group
->num_block_descs
[1];
655 (*pdaf
)->block_desc_groups
[i
].repeat_y
=
656 __bdesc_group
->repeat_y
;
657 (*pdaf
)->block_desc_groups
[i
].num_block_descs
=
661 __bdesc
= (const void *)(__bdesc_group
+ 1);
664 (*pdaf
)->block_desc_groups
[i
].block_descs
=
666 sizeof(struct ccs_pdaf_pix_loc_block_desc
) *
668 if (!(*pdaf
)->block_desc_groups
[i
].block_descs
)
671 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_block_desc
) *
675 for (j
= 0; j
< num_block_descs
; j
++, __bdesc
++) {
676 struct ccs_pdaf_pix_loc_block_desc
*bdesc
;
678 if (!is_contained(__bdesc
, endp
))
681 if (max_block_type_id
<= __bdesc
->block_type_id
)
682 max_block_type_id
= __bdesc
->block_type_id
+ 1;
687 bdesc
= &(*pdaf
)->block_desc_groups
[i
].block_descs
[j
];
689 bdesc
->repeat_x
= ((u16
)__bdesc
->repeat_x
[0] << 8)
690 + __bdesc
->repeat_x
[1];
692 if (__bdesc
->block_type_id
>= num_block_descs
)
695 bdesc
->block_type_id
= __bdesc
->block_type_id
;
698 __bdesc_group
= (const void *)__bdesc
;
701 __num_pixel_descs
= (const void *)__bdesc_group
;
704 (*pdaf
)->pixel_desc_groups
=
706 sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group
) *
708 if (!(*pdaf
)->pixel_desc_groups
)
710 (*pdaf
)->num_pixel_desc_grups
= max_block_type_id
;
712 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group
) *
716 for (i
= 0; i
< max_block_type_id
; i
++) {
717 struct ccs_pdaf_pix_loc_pixel_desc_group
*pdgroup
= NULL
;
720 if (!is_contained(__num_pixel_descs
, endp
))
724 pdgroup
= &(*pdaf
)->pixel_desc_groups
[i
];
727 sizeof(struct ccs_pdaf_pix_loc_pixel_desc
) *
731 pdgroup
->num_descs
= *__num_pixel_descs
;
733 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_pixel_desc
) *
737 __pixel_desc
= (const void *)(__num_pixel_descs
+ 1);
739 for (j
= 0; j
< *__num_pixel_descs
; j
++, __pixel_desc
++) {
740 struct ccs_pdaf_pix_loc_pixel_desc
*pdesc
;
742 if (!is_contained(__pixel_desc
, endp
))
751 pdesc
= &pdgroup
->descs
[j
];
752 pdesc
->pixel_type
= __pixel_desc
->pixel_type
;
753 pdesc
->small_offset_x
= __pixel_desc
->small_offset_x
;
754 pdesc
->small_offset_y
= __pixel_desc
->small_offset_y
;
757 __num_pixel_descs
= (const void *)(__pixel_desc
+ 1);
763 static int ccs_data_parse_license(struct bin_container
*bin
,
765 size_t *__license_length
,
766 const void *payload
, const void *endp
)
768 size_t size
= endp
- payload
;
772 bin_reserve(bin
, size
);
776 license
= bin_alloc(bin
, size
);
780 memcpy(license
, payload
, size
);
782 *__license
= license
;
783 *__license_length
= size
;
788 static int ccs_data_parse_end(bool *end
, const void *payload
, const void *endp
,
791 const struct __ccs_data_block_end
*__end
= payload
;
793 if (__end
+ 1 != endp
) {
794 dev_dbg(dev
, "Invalid end block length %u\n",
795 (unsigned int)(endp
- payload
));
804 static int __ccs_data_parse(struct bin_container
*bin
,
805 struct ccs_data_container
*ccsdata
,
806 const void *data
, size_t len
, struct device
*dev
,
809 const struct __ccs_data_block
*block
= data
;
810 const struct __ccs_data_block
*endp
= data
+ len
;
811 unsigned int version
;
812 bool is_first
= true;
815 version
= ccs_data_parse_format_version(block
);
816 if (version
!= CCS_STATIC_DATA_VERSION
) {
817 dev_dbg(dev
, "Don't know how to handle version %u\n", version
);
822 dev_dbg(dev
, "Parsing CCS static data version %u\n", version
);
825 *ccsdata
= (struct ccs_data_container
){ 0 };
827 while (block
< endp
) {
828 const struct __ccs_data_block
*next_block
;
829 unsigned int block_id
;
832 rval
= ccs_data_block_parse_header(block
, is_first
, &block_id
,
833 &payload
, &next_block
, endp
,
835 bin
->base
? false : verbose
);
841 case CCS_DATA_BLOCK_ID_DUMMY
:
843 case CCS_DATA_BLOCK_ID_DATA_VERSION
:
844 rval
= ccs_data_parse_version(bin
, ccsdata
, payload
,
849 case CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS
:
850 rval
= ccs_data_parse_regs(
851 bin
, &ccsdata
->sensor_read_only_regs
,
852 &ccsdata
->num_sensor_read_only_regs
, payload
,
857 case CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS
:
858 rval
= ccs_data_parse_regs(
859 bin
, &ccsdata
->sensor_manufacturer_regs
,
860 &ccsdata
->num_sensor_manufacturer_regs
, payload
,
865 case CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS
:
866 rval
= ccs_data_parse_regs(
867 bin
, &ccsdata
->module_read_only_regs
,
868 &ccsdata
->num_module_read_only_regs
, payload
,
873 case CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS
:
874 rval
= ccs_data_parse_regs(
875 bin
, &ccsdata
->module_manufacturer_regs
,
876 &ccsdata
->num_module_manufacturer_regs
, payload
,
881 case CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION
:
882 rval
= ccs_data_parse_pdaf(bin
, &ccsdata
->sensor_pdaf
,
883 payload
, next_block
, dev
);
887 case CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION
:
888 rval
= ccs_data_parse_pdaf(bin
, &ccsdata
->module_pdaf
,
889 payload
, next_block
, dev
);
893 case CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK
:
894 rval
= ccs_data_parse_rules(
895 bin
, &ccsdata
->sensor_rules
,
896 &ccsdata
->num_sensor_rules
, payload
, next_block
,
901 case CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK
:
902 rval
= ccs_data_parse_rules(
903 bin
, &ccsdata
->module_rules
,
904 &ccsdata
->num_module_rules
, payload
, next_block
,
909 case CCS_DATA_BLOCK_ID_LICENSE
:
910 rval
= ccs_data_parse_license(bin
, &ccsdata
->license
,
911 &ccsdata
->license_length
,
912 payload
, next_block
);
916 case CCS_DATA_BLOCK_ID_END
:
917 rval
= ccs_data_parse_end(&ccsdata
->end
, payload
,
923 dev_dbg(dev
, "WARNING: not handling block ID 0x%2.2x\n",
935 * ccs_data_parse - Parse a CCS static data file into a usable in-memory
937 * @ccsdata: CCS static data in-memory data structure
938 * @data: CCS static data binary
939 * @len: Length of @data
940 * @dev: Device the data is related to (used for printing debug messages)
941 * @verbose: Whether to be verbose or not
943 int ccs_data_parse(struct ccs_data_container
*ccsdata
, const void *data
,
944 size_t len
, struct device
*dev
, bool verbose
)
946 struct bin_container bin
= { 0 };
949 rval
= __ccs_data_parse(&bin
, ccsdata
, data
, len
, dev
, verbose
);
953 rval
= bin_backing_alloc(&bin
);
957 rval
= __ccs_data_parse(&bin
, ccsdata
, data
, len
, dev
, false);
961 if (verbose
&& ccsdata
->version
)
962 print_ccs_data_version(dev
, ccsdata
->version
);
964 if (bin
.now
!= bin
.end
) {
966 dev_dbg(dev
, "parsing mismatch; base %p; now %p; end %p\n",
967 bin
.base
, bin
.now
, bin
.end
);
971 ccsdata
->backing
= bin
.base
;