1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _BHND_NVRAM_BHND_NVRAM_STOREVAR_H_ 33 #define _BHND_NVRAM_BHND_NVRAM_STOREVAR_H_ 34 35 #include <sys/types.h> 36 37 #ifndef _KERNEL 38 #include <pthread.h> 39 #endif 40 41 #include "bhnd_nvram_plist.h" 42 43 #include "bhnd_nvram_store.h" 44 45 /** Index is only generated if minimum variable count is met */ 46 #define BHND_NV_IDX_VAR_THRESHOLD 15 47 48 #define BHND_NVSTORE_ROOT_PATH "/" 49 #define BHND_NVSTORE_ROOT_PATH_LEN sizeof(BHND_NVSTORE_ROOT_PATH) 50 51 #define BHND_NVSTORE_GET_FLAG(_value, _flag) \ 52 (((_value) & BHND_NVSTORE_ ## _flag) != 0) 53 #define BHND_NVSTORE_GET_BITS(_value, _field) \ 54 ((_value) & BHND_NVSTORE_ ## _field ## _MASK) 55 56 /* Forward declarations */ 57 typedef struct bhnd_nvstore_name_info bhnd_nvstore_name_info; 58 typedef struct bhnd_nvstore_index bhnd_nvstore_index; 59 typedef struct bhnd_nvstore_path bhnd_nvstore_path; 60 61 typedef struct bhnd_nvstore_alias bhnd_nvstore_alias; 62 63 typedef struct bhnd_nvstore_alias_list bhnd_nvstore_alias_list; 64 typedef struct bhnd_nvstore_update_list bhnd_nvstore_update_list; 65 typedef struct bhnd_nvstore_path_list bhnd_nvstore_path_list; 66 67 LIST_HEAD(bhnd_nvstore_alias_list, bhnd_nvstore_alias); 68 LIST_HEAD(bhnd_nvstore_update_list, bhnd_nvstore_update); 69 LIST_HEAD(bhnd_nvstore_path_list, bhnd_nvstore_path); 70 71 /** 72 * NVRAM store variable entry types. 73 */ 74 typedef enum { 75 BHND_NVSTORE_VAR = 0, /**< simple variable (var=...) */ 76 BHND_NVSTORE_ALIAS_DECL = 1, /**< alias declaration ('devpath0=pci/1/1') */ 77 } bhnd_nvstore_var_type; 78 79 /** 80 * NVRAM path descriptor types. 81 */ 82 typedef enum { 83 BHND_NVSTORE_PATH_STRING = 0, /**< path is a string value */ 84 BHND_NVSTORE_PATH_ALIAS = 1 /**< path is an alias reference */ 85 } bhnd_nvstore_path_type; 86 87 /** 88 * NVRAM variable namespaces. 89 */ 90 typedef enum { 91 BHND_NVSTORE_NAME_INTERNAL = 1, /**< internal namespace. permits 92 use of reserved devpath and 93 alias name prefixes. */ 94 BHND_NVSTORE_NAME_EXTERNAL = 2, /**< external namespace. forbids 95 use of name prefixes used 96 for device path handling */ 97 } bhnd_nvstore_name_type; 98 99 bhnd_nvstore_path *bhnd_nvstore_path_new(const char *path_str, 100 size_t path_len); 101 void bhnd_nvstore_path_free(struct bhnd_nvstore_path *path); 102 103 bhnd_nvstore_index *bhnd_nvstore_index_new(size_t capacity); 104 void bhnd_nvstore_index_free(bhnd_nvstore_index *index); 105 int bhnd_nvstore_index_append(struct bhnd_nvram_store *sc, 106 bhnd_nvstore_index *index, 107 void *cookiep); 108 int bhnd_nvstore_index_prepare( 109 struct bhnd_nvram_store *sc, 110 bhnd_nvstore_index *index); 111 void *bhnd_nvstore_index_lookup(struct bhnd_nvram_store *sc, 112 bhnd_nvstore_index *index, const char *name); 113 114 bhnd_nvstore_path *bhnd_nvstore_get_root_path( 115 struct bhnd_nvram_store *sc); 116 bool bhnd_nvstore_is_root_path(struct bhnd_nvram_store *sc, 117 bhnd_nvstore_path *path); 118 119 void *bhnd_nvstore_path_data_next( 120 struct bhnd_nvram_store *sc, 121 bhnd_nvstore_path *path, void **indexp); 122 void *bhnd_nvstore_path_data_lookup( 123 struct bhnd_nvram_store *sc, 124 bhnd_nvstore_path *path, const char *name); 125 bhnd_nvram_prop *bhnd_nvstore_path_get_update( 126 struct bhnd_nvram_store *sc, 127 bhnd_nvstore_path *path, const char *name); 128 int bhnd_nvstore_path_register_update( 129 struct bhnd_nvram_store *sc, 130 bhnd_nvstore_path *path, const char *name, 131 bhnd_nvram_val *value); 132 133 bhnd_nvstore_alias *bhnd_nvstore_find_alias(struct bhnd_nvram_store *sc, 134 const char *path); 135 bhnd_nvstore_alias *bhnd_nvstore_get_alias(struct bhnd_nvram_store *sc, 136 u_long alias_val); 137 138 bhnd_nvstore_path *bhnd_nvstore_get_path(struct bhnd_nvram_store *sc, 139 const char *path, size_t path_len); 140 bhnd_nvstore_path *bhnd_nvstore_resolve_path_alias( 141 struct bhnd_nvram_store *sc, u_long aval); 142 143 bhnd_nvstore_path *bhnd_nvstore_var_get_path(struct bhnd_nvram_store *sc, 144 bhnd_nvstore_name_info *info); 145 int bhnd_nvstore_var_register_path( 146 struct bhnd_nvram_store *sc, 147 bhnd_nvstore_name_info *info, void *cookiep); 148 149 int bhnd_nvstore_register_path(struct bhnd_nvram_store *sc, 150 const char *path, size_t path_len); 151 int bhnd_nvstore_register_alias( 152 struct bhnd_nvram_store *sc, 153 const bhnd_nvstore_name_info *info, void *cookiep); 154 155 const char *bhnd_nvstore_parse_relpath(const char *parent, 156 const char *child); 157 int bhnd_nvstore_parse_name_info(const char *name, 158 bhnd_nvstore_name_type name_type, 159 uint32_t data_caps, bhnd_nvstore_name_info *info); 160 161 /** 162 * NVRAM variable name descriptor. 163 * 164 * For NVRAM data instances supporting BHND_NVRAM_DATA_CAP_DEVPATHS, the 165 * NVRAM-vended variable name will be in one of four formats: 166 * 167 * - Simple Variable: 168 * 'variable' 169 * - Device Variable: 170 * 'pci/1/1/variable' 171 * - Device Alias Variable: 172 * '0:variable' 173 * - Device Path Alias Definition: 174 * 'devpath0=pci/1/1/variable' 175 * 176 * Device Paths: 177 * 178 * The device path format is device class-specific; the known supported device 179 * classes are: 180 * - sb: BCMA/SIBA SoC core device path. 181 * - pci: PCI device path (and PCIe on some earlier devices). 182 * - pcie: PCIe device path. 183 * - usb: USB device path. 184 * 185 * The device path format is loosely defined as '[class]/[domain]/[bus]/[slot]', 186 * with missing values either assumed to be zero, a value specific to the 187 * device class, or irrelevant to the device class in question. 188 * 189 * Examples: 190 * sb/1 BCMA/SIBA backplane 0, core 1. 191 * pc/1/1 PCMCIA bus 1, slot 1 192 * pci/1/1 PCI/PCIe domain 0, bus 1, device 1 193 * pcie/1/1 PCIe domain 0, bus 1, device 1 194 * usb/0xbd17 USB PID 0xbd17 (VID defaults to Broadcom 0x0a5c) 195 * 196 * Device Path Aliases: 197 * 198 * Device path aliases reduce duplication of device paths in the flash encoding 199 * of NVRAM data; a single devpath[alias]=[devpath] variable entry is defined, 200 * and then later variables may reference the device path via its alias: 201 * devpath1=usb/0xbd17 202 * 1:mcs5gpo0=0x1100 203 * 204 * Alias values are always positive, base 10 integers. 205 */ 206 struct bhnd_nvstore_name_info { 207 const char *name; /**< variable name */ 208 bhnd_nvstore_var_type type; /**< variable type */ 209 bhnd_nvstore_path_type path_type; /**< path type */ 210 211 /** Path information */ 212 union { 213 /* BHND_NVSTORE_PATH_STRING */ 214 struct { 215 const char *value; /**< device path */ 216 size_t value_len; /**< device path length */ 217 } str; 218 219 /** BHND_NVSTORE_PATH_ALIAS */ 220 struct { 221 u_long value; /**< device alias */ 222 } alias; 223 } path; 224 }; 225 226 /** 227 * NVRAM variable index. 228 * 229 * Provides effecient name-based lookup by maintaining an array of cached 230 * cookiep values, sorted lexicographically by relative variable name. 231 */ 232 struct bhnd_nvstore_index { 233 size_t count; /**< entry count */ 234 size_t capacity; /**< entry capacity */ 235 void *cookiep[]; /**< cookiep values */ 236 }; 237 238 /** 239 * NVRAM device path. 240 */ 241 struct bhnd_nvstore_path { 242 char *path_str; /**< canonical path string */ 243 size_t num_vars; /**< per-path count of committed 244 (non-pending) variables */ 245 bhnd_nvstore_index *index; /**< per-path index, or NULL if 246 this is a root path for 247 which the data source 248 may be queried directly. */ 249 bhnd_nvram_plist *pending; /**< pending changes */ 250 251 LIST_ENTRY(bhnd_nvstore_path) np_link; 252 }; 253 254 /** 255 * NVRAM device path alias. 256 */ 257 struct bhnd_nvstore_alias { 258 bhnd_nvstore_path *path; /**< borrowed path reference */ 259 void *cookiep; /**< NVRAM variable's cookiep value */ 260 u_long alias; /**< alias value */ 261 262 LIST_ENTRY(bhnd_nvstore_alias) na_link; 263 }; 264 265 /** bhnd nvram store instance state */ 266 struct bhnd_nvram_store { 267 #ifdef _KERNEL 268 struct mtx mtx; 269 #else 270 pthread_mutex_t mtx; 271 #endif 272 struct bhnd_nvram_data *data; /**< backing data */ 273 uint32_t data_caps; /**< data capability flags */ 274 bhnd_nvram_plist *data_opts; /**< data serialization options */ 275 276 bhnd_nvstore_alias_list aliases[4]; /**< path alias hash table */ 277 size_t num_aliases; /**< alias count */ 278 279 bhnd_nvstore_path *root_path; /**< root path instance */ 280 bhnd_nvstore_path_list paths[4]; /**< path hash table */ 281 size_t num_paths; /**< path count */ 282 }; 283 284 #ifdef _KERNEL 285 286 #define BHND_NVSTORE_LOCK_INIT(sc) \ 287 mtx_init(&(sc)->mtx, "BHND NVRAM store lock", NULL, MTX_DEF) 288 #define BHND_NVSTORE_LOCK(sc) mtx_lock(&(sc)->mtx) 289 #define BHND_NVSTORE_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 290 #define BHND_NVSTORE_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what) 291 #define BHND_NVSTORE_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx) 292 293 #else /* !_KERNEL */ 294 295 #define BHND_NVSTORE_LOCK_INIT(sc) do { \ 296 int error = pthread_mutex_init(&(sc)->mtx, NULL); \ 297 if (error) \ 298 BHND_NV_PANIC("pthread_mutex_init() failed: %d", \ 299 error); \ 300 } while(0) 301 302 #define BHND_NVSTORE_LOCK(sc) pthread_mutex_lock(&(sc)->mtx) 303 #define BHND_NVSTORE_UNLOCK(sc) pthread_mutex_unlock(&(sc)->mtx) 304 #define BHND_NVSTORE_LOCK_DESTROY(sc) pthread_mutex_destroy(&(sc)->mtx) 305 #define BHND_NVSTORE_LOCK_ASSERT(sc, what) 306 307 #endif /* _KERNEL */ 308 309 #endif /* _BHND_NVRAM_BHND_NVRAM_STOREVAR_H_ */ 310