Lines Matching +full:bool +full:- +full:property
1 // SPDX-License-Identifier: GPL-2.0
3 * Thunderbolt XDomain property support
40 bool is_root);
52 static bool tb_property_entry_valid(const struct tb_property_entry *entry,
55 switch (entry->type) {
59 if (entry->length > block_len)
61 if (entry->value + entry->length > block_len)
66 if (entry->length != 1)
74 static bool tb_property_key_valid(const char *key)
82 struct tb_property *property;
84 property = kzalloc(sizeof(*property), GFP_KERNEL);
85 if (!property)
88 strcpy(property->key, key);
89 property->type = type;
90 INIT_LIST_HEAD(&property->list);
92 return property;
99 struct tb_property *property;
108 property = tb_property_alloc(key, entry->type);
109 if (!property)
112 property->length = entry->length;
114 switch (property->type) {
116 dir = __tb_property_parse_dir(block, block_len, entry->value,
117 entry->length, false);
119 kfree(property);
122 property->value.dir = dir;
126 property->value.data = kcalloc(property->length, sizeof(u32),
128 if (!property->value.data) {
129 kfree(property);
132 parse_dwdata(property->value.data, block + entry->value,
133 entry->length);
137 property->value.text = kcalloc(property->length, sizeof(u32),
139 if (!property->value.text) {
140 kfree(property);
143 parse_dwdata(property->value.text, block + entry->value,
144 entry->length);
146 property->value.text[property->length * 4 - 1] = '\0';
150 property->value.immediate = entry->value;
154 property->type = TB_PROPERTY_TYPE_UNKNOWN;
158 return property;
162 size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root)
177 dir->uuid = kmemdup(&block[dir_offset], sizeof(*dir->uuid),
179 if (!dir->uuid) {
184 content_len = dir_len - 4; /* Length includes UUID */
190 INIT_LIST_HEAD(&dir->properties);
193 struct tb_property *property;
195 property = tb_property_parse(block, block_len, &entries[i]);
196 if (!property) {
201 list_add_tail(&property->list, &dir->properties);
208 * tb_property_parse_dir() - Parses properties from given property block
209 * @block: Property block to parse
210 * @block_len: Number of dword elements in the property block
228 if (rootdir->magic != TB_PROPERTY_ROOTDIR_MAGIC)
230 if (rootdir->length > block_len)
233 return __tb_property_parse_dir(block, block_len, 0, rootdir->length,
238 * tb_property_create_dir() - Creates new property directory
241 * Creates new, empty property directory. If @uuid is %NULL then the
254 INIT_LIST_HEAD(&dir->properties);
256 dir->uuid = kmemdup(uuid, sizeof(*dir->uuid), GFP_KERNEL);
257 if (!dir->uuid) {
267 static void tb_property_free(struct tb_property *property)
269 switch (property->type) {
271 tb_property_free_dir(property->value.dir);
275 kfree(property->value.data);
279 kfree(property->value.text);
286 kfree(property);
290 * tb_property_free_dir() - Release memory allocated for property directory
299 struct tb_property *property, *tmp;
304 list_for_each_entry_safe(property, tmp, &dir->properties, list) {
305 list_del(&property->list);
306 tb_property_free(property);
308 kfree(dir->uuid);
314 bool recurse, size_t *data_len)
316 const struct tb_property *property;
319 if (dir->uuid)
320 len += sizeof(*dir->uuid) / 4;
324 list_for_each_entry(property, &dir->properties, list) {
327 switch (property->type) {
331 property->value.dir, recurse, data_len);
341 *data_len += property->length;
356 const struct tb_property *property;
362 * The structure of property block looks like following. Leaf
366 * +----------+ <-- start_offset
367 * | header | <-- root directory header
368 * +----------+ ---
369 * | entry 0 | -^--------------------.
370 * +----------+ | |
371 * | entry 1 | -|--------------------|--.
372 * +----------+ | | |
373 * | entry 2 | -|-----------------. | |
374 * +----------+ | | | |
378 * +----------+ | | | |
380 * +----------+ <-- data_offset | | |
381 * | data 0 | <------------------|--' |
382 * +----------+ | |
383 * | data 1 | <------------------|-----'
384 * +----------+ |
386 * +----------+ <-- dir_end <------'
387 * | UUID | <-- directory UUID (child directory)
388 * +----------+
390 * +----------+
392 * +----------+
396 * +----------+
398 * +----------+
400 * +----------+
411 return -EINVAL;
413 return -EINVAL;
416 if (dir->uuid) {
420 memcpy(pe->uuid, dir->uuid, sizeof(pe->uuid));
421 entry = pe->entries;
426 re->magic = TB_PROPERTY_ROOTDIR_MAGIC;
427 re->length = dir_len - sizeof(*re) / 4;
428 entry = re->entries;
431 list_for_each_entry(property, &dir->properties, list) {
434 format_dwdata(entry, property->key, 2);
435 entry->type = property->type;
437 switch (property->type) {
439 child = property->value.dir;
444 entry->length = tb_property_dir_length(child, false,
446 entry->value = dir_end;
451 format_dwdata(&block[data_offset], property->value.data,
452 property->length);
453 entry->length = property->length;
454 entry->value = data_offset;
455 data_offset += entry->length;
459 format_dwdata(&block[data_offset], property->value.text,
460 property->length);
461 entry->length = property->length;
462 entry->value = data_offset;
463 data_offset += entry->length;
467 entry->length = property->length;
468 entry->value = property->value.immediate;
482 * tb_property_format_dir() - Formats directory to the packed XDomain format
484 * @block: Property block where the packed data is placed
485 * @block_len: Length of the property block
511 * tb_property_copy_dir() - Take a deep copy of directory
520 struct tb_property *property, *p = NULL;
526 d = tb_property_create_dir(dir->uuid);
530 list_for_each_entry(property, &dir->properties, list) {
533 p = tb_property_alloc(property->key, property->type);
537 p->length = property->length;
539 switch (property->type) {
541 p->value.dir = tb_property_copy_dir(property->value.dir);
542 if (!p->value.dir)
547 p->value.data = kmemdup(property->value.data,
548 property->length * 4,
550 if (!p->value.data)
555 p->value.text = kzalloc(p->length * 4, GFP_KERNEL);
556 if (!p->value.text)
558 strcpy(p->value.text, property->value.text);
562 p->value.immediate = property->value.immediate;
569 list_add_tail(&p->list, &d->properties);
582 * tb_property_add_immediate() - Add immediate property to directory
583 * @parent: Directory to add the property
584 * @key: Key for the property
585 * @value: Immediate value to store with the property
592 struct tb_property *property;
595 return -EINVAL;
597 property = tb_property_alloc(key, TB_PROPERTY_TYPE_VALUE);
598 if (!property)
599 return -ENOMEM;
601 property->length = 1;
602 property->value.immediate = value;
604 list_add_tail(&property->list, &parent->properties);
610 * tb_property_add_data() - Adds arbitrary data property to directory
611 * @parent: Directory to add the property
612 * @key: Key for the property
625 struct tb_property *property;
628 return -EINVAL;
630 property = tb_property_alloc(key, TB_PROPERTY_TYPE_DATA);
631 if (!property)
632 return -ENOMEM;
634 property->length = size / 4;
635 property->value.data = kzalloc(size, GFP_KERNEL);
636 if (!property->value.data) {
637 kfree(property);
638 return -ENOMEM;
641 memcpy(property->value.data, buf, buflen);
643 list_add_tail(&property->list, &parent->properties);
649 * tb_property_add_text() - Adds string property to directory
650 * @parent: Directory to add the property
651 * @key: Key for the property
663 struct tb_property *property;
666 return -EINVAL;
668 property = tb_property_alloc(key, TB_PROPERTY_TYPE_TEXT);
669 if (!property)
670 return -ENOMEM;
672 property->length = size / 4;
673 property->value.text = kzalloc(size, GFP_KERNEL);
674 if (!property->value.text) {
675 kfree(property);
676 return -ENOMEM;
679 strcpy(property->value.text, text);
681 list_add_tail(&property->list, &parent->properties);
687 * tb_property_add_dir() - Adds a directory to the parent directory
688 * @parent: Directory to add the property
689 * @key: Key for the property
697 struct tb_property *property;
700 return -EINVAL;
702 property = tb_property_alloc(key, TB_PROPERTY_TYPE_DIRECTORY);
703 if (!property)
704 return -ENOMEM;
706 property->value.dir = dir;
708 list_add_tail(&property->list, &parent->properties);
714 * tb_property_remove() - Removes property from a parent directory
715 * @property: Property to remove
717 * Note memory for @property is released as well so it is not allowed to
720 void tb_property_remove(struct tb_property *property)
722 list_del(&property->list);
723 kfree(property);
728 * tb_property_find() - Find a property from a directory
729 * @dir: Directory where the property is searched
731 * @type: Type of the property
733 * Finds and returns property from the given directory. Does not
734 * recurse into sub-directories.
736 * Return: Pointer to &struct tb_property, %NULL if the property was not found.
741 struct tb_property *property;
743 list_for_each_entry(property, &dir->properties, list) {
744 if (property->type == type && !strcmp(property->key, key))
745 return property;
753 * tb_property_get_next() - Get next property from directory
755 * @prev: Previous property in the directory (%NULL returns the first)
757 * Return: Pointer to &struct tb_property, %NULL if property was not found.
763 if (list_is_last(&prev->list, &dir->properties))
767 return list_first_entry_or_null(&dir->properties, struct tb_property,