1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2023 Solidigm All Rights Reserved 3 */ 4 5 #include "spdk/queue.h" 6 #include "spdk/json.h" 7 #include "spdk/jsonrpc.h" 8 9 #include "ftl_core.h" 10 #include "ftl_property.h" 11 12 struct ftl_properties { 13 LIST_HEAD(, ftl_property) list; 14 }; 15 16 /** 17 * @brief FTL property descriptor 18 */ 19 struct ftl_property { 20 /** Name of the property */ 21 const char *name; 22 23 /* Pointer to the value of property */ 24 void *value; 25 26 /* The value size of the property */ 27 size_t size; 28 29 /* The function to dump the value of property into the specified JSON RPC request */ 30 ftl_property_dump_fn dump; 31 32 /** Link to put the property to the list */ 33 LIST_ENTRY(ftl_property) entry; 34 }; 35 36 static struct ftl_property * 37 get_property_item(struct ftl_properties *properties, const char *name) 38 { 39 struct ftl_property *entry; 40 41 LIST_FOREACH(entry, &properties->list, entry) { 42 /* TODO think about strncmp */ 43 if (0 == strcmp(entry->name, name)) { 44 return entry; 45 } 46 } 47 48 return NULL; 49 } 50 51 void 52 ftl_property_register(struct spdk_ftl_dev *dev, const char *name, void *value, size_t size, 53 ftl_property_dump_fn dump) 54 { 55 struct ftl_properties *properties = dev->properties; 56 57 if (get_property_item(properties, name)) { 58 FTL_ERRLOG(dev, "FTL property registration ERROR, already exist, name %s\n", name); 59 ftl_abort(); 60 } else { 61 struct ftl_property *prop = calloc(1, sizeof(*prop)); 62 if (NULL == prop) { 63 FTL_ERRLOG(dev, "FTL property registration ERROR, out of memory, name %s\n", name); 64 ftl_abort(); 65 } 66 67 prop->name = name; 68 prop->value = value; 69 prop->size = size; 70 prop->dump = dump; 71 LIST_INSERT_HEAD(&properties->list, prop, entry); 72 } 73 } 74 75 int 76 ftl_properties_init(struct spdk_ftl_dev *dev) 77 { 78 dev->properties = calloc(1, sizeof(*dev->properties)); 79 if (!dev->properties) { 80 return -ENOMEM; 81 } 82 83 LIST_INIT(&dev->properties->list); 84 return 0; 85 } 86 87 void 88 ftl_properties_deinit(struct spdk_ftl_dev *dev) 89 { 90 struct ftl_properties *properties = dev->properties; 91 struct ftl_property *prop; 92 93 if (!properties) { 94 return; 95 } 96 97 while (!LIST_EMPTY(&properties->list)) { 98 prop = LIST_FIRST(&properties->list); 99 LIST_REMOVE(prop, entry); 100 free(prop); 101 } 102 103 free(dev->properties); 104 } 105 106 void 107 ftl_property_dump(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request) 108 { 109 struct ftl_properties *properties = dev->properties; 110 struct ftl_property *prop; 111 struct spdk_json_write_ctx *w; 112 113 w = spdk_jsonrpc_begin_result(request); 114 spdk_json_write_object_begin(w); 115 spdk_json_write_named_string(w, "name", dev->conf.name); 116 117 spdk_json_write_named_object_begin(w, "properties"); 118 LIST_FOREACH(prop, &properties->list, entry) { 119 prop->dump(prop, w); 120 } 121 spdk_json_write_object_end(w); 122 123 spdk_json_write_object_end(w); 124 spdk_jsonrpc_end_result(request, w); 125 } 126 127 void 128 ftl_property_dump_bool(const struct ftl_property *property, 129 struct spdk_json_write_ctx *w) 130 { 131 bool *value = property->value; 132 133 assert(property->size == sizeof(*value)); 134 spdk_json_write_named_bool(w, property->name, *value); 135 } 136 137 void 138 ftl_property_dump_uint64(const struct ftl_property *property, 139 struct spdk_json_write_ctx *w) 140 { 141 uint64_t *value = property->value; 142 143 assert(property->size == sizeof(*value)); 144 spdk_json_write_named_uint64(w, property->name, *value); 145 } 146 147 void 148 ftl_property_dump_uint32(const struct ftl_property *property, 149 struct spdk_json_write_ctx *w) 150 { 151 uint32_t *value = property->value; 152 153 assert(property->size == sizeof(*value)); 154 spdk_json_write_named_uint32(w, property->name, *value); 155 } 156