1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2020 Joyent, Inc. 14 */ 15 16 #ifndef _SYS_DDI_UFM_H 17 #define _SYS_DDI_UFM_H 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #ifdef _KERNEL 24 #include <sys/cred.h> 25 #include <sys/dditypes.h> 26 #include <sys/nvpair.h> 27 #include <sys/param.h> 28 #else 29 #include <sys/nvpair.h> 30 #include <sys/param.h> 31 #include <sys/types.h> 32 #endif /* _KERNEL */ 33 34 #define DDI_UFM_DEV "/dev/ufm" 35 #define DDI_UFM_CURRENT_VERSION 1 36 #define DDI_UFM_VERSION_ONE 1 37 38 #define UFM_IOC ('u' << 24) | ('f' << 16) | ('m' << 8) 39 #define UFM_IOC_GETCAPS (UFM_IOC | 1) 40 #define UFM_IOC_REPORTSZ (UFM_IOC | 2) 41 #define UFM_IOC_REPORT (UFM_IOC | 3) 42 #define UFM_IOC_MAX UFM_IOC_REPORT 43 44 /* 45 * Bitfield enumerating the DDI UFM capabilities supported by this device 46 * instance. Currently there is only a single capability of being able to 47 * report UFM information. Future UFM versions may add additional capabilities 48 * such as the ability to obtain a raw dump the firmware image or ability to 49 * upgrade the firmware. When support for new capabilties are added to the DDI 50 * UFM subsystem, it should be reflected in this enum and the implementation of 51 * the UFM_IOC_GETCAPS should be extended appropriately. 52 */ 53 typedef enum { 54 DDI_UFM_CAP_REPORT = 1 << 0 55 } ddi_ufm_cap_t; 56 57 /* 58 * This struct defines the input/output data for the UFM_IOC_GETCAPS ioctl. 59 * Callers should specify the ufmg_version and ufmg_devpath fields. On success 60 * the ufmg_caps field will be filled in with a value indicating the supported 61 * UFM capabilities of the device specified in ufmg_devpath. 62 */ 63 typedef struct ufm_ioc_getcaps { 64 uint_t ufmg_version; /* DDI_UFM_VERSION */ 65 uint_t ufmg_caps; /* UFM Caps */ 66 char ufmg_devpath[MAXPATHLEN]; 67 } ufm_ioc_getcaps_t; 68 69 /* 70 * This struct defines the input/output data for the UFM_IOC_REPORTSZ ioctl. 71 * Callers should specify the ufbz_version and ufbz_devpath fields. On success 72 * the ufmg_size field will be filled in with the amount of space (in bytes) 73 * required to hold the UFM data for this device instance. This should be used 74 * to allocate a sufficiently size buffer for the UFM_IOC_REPORT ioctl. 75 */ 76 typedef struct ufm_ioc_bufsz { 77 uint_t ufbz_version; /* DDI_UFM_VERSION */ 78 size_t ufbz_size; /* sz of buf to be returned by ioctl */ 79 char ufbz_devpath[MAXPATHLEN]; 80 } ufm_ioc_bufsz_t; 81 82 #ifdef _KERNEL 83 typedef struct ufm_ioc_bufsz32 { 84 uint_t ufbz_version; 85 size32_t ufbz_size; 86 char ufbz_devpath[MAXPATHLEN]; 87 } ufm_ioc_bufsz32_t; 88 #endif /* _KERNEL */ 89 90 /* 91 * This struct defines the input/output data for the UFM_IOC_REPORT ioctl. 92 * Callers should specify the ufmr_version, ufmr_bufsz and ufmr_devpath fields. 93 * On success, the ufmr_buf field will point to a packed nvlist containing the 94 * UFM data for the specified device instance. The value of ufmr_bufsz will be 95 * updated to reflect the actual size of data copied out. 96 */ 97 typedef struct ufm_ioc_report { 98 uint_t ufmr_version; /* DDI_UFM_VERSION */ 99 size_t ufmr_bufsz; /* size of caller-supplied buffer */ 100 caddr_t ufmr_buf; /* buf to hold packed output nvl */ 101 char ufmr_devpath[MAXPATHLEN]; 102 } ufm_ioc_report_t; 103 104 #ifdef _KERNEL 105 typedef struct ufm_ioc_report32 { 106 uint_t ufmr_version; 107 size32_t ufmr_bufsz; 108 caddr32_t ufmr_buf; 109 char ufmr_devpath[MAXPATHLEN]; 110 } ufm_ioc_report32_t; 111 #endif /* _KERNEL */ 112 113 /* 114 * The UFM_IOC_REPORT ioctl return UFM image and slot data in the form of a 115 * packed nvlist. The nvlist contains and array of nvlists (one-per-image). 116 * Each image nvlist contains will contain a string nvpair containing a 117 * description of the image and an optional nvlist nvpair containing 118 * miscellaneous image information. 119 */ 120 #define DDI_UFM_NV_IMAGES "ufm-images" 121 #define DDI_UFM_NV_IMAGE_DESC "ufm-image-description" 122 #define DDI_UFM_NV_IMAGE_MISC "ufm-image-misc" 123 124 /* 125 * Each image nvlist also contains an array of nvlists representing the slots. 126 */ 127 #define DDI_UFM_NV_IMAGE_SLOTS "ufm-image-slots" 128 129 /* 130 * Each slot nvlist as a string nvpair describing the firmware image version 131 * and an uint32 nvpair describing the slot attributes (see ddi_ufm_attr_t 132 * above). An option nvlist nvpar may be present containing additional 133 * miscellaneous slot data. 134 */ 135 #define DDI_UFM_NV_SLOT_VERSION "ufm-slot-version" 136 137 typedef enum { 138 DDI_UFM_ATTR_READABLE = 1 << 0, 139 DDI_UFM_ATTR_WRITEABLE = 1 << 1, 140 DDI_UFM_ATTR_ACTIVE = 1 << 2, 141 DDI_UFM_ATTR_EMPTY = 1 << 3 142 } ddi_ufm_attr_t; 143 144 #define DDI_UFM_ATTR_MAX DDI_UFM_ATTR_READABLE | \ 145 DDI_UFM_ATTR_WRITEABLE | \ 146 DDI_UFM_ATTR_ACTIVE | \ 147 DDI_UFM_ATTR_EMPTY 148 149 #define DDI_UFM_NV_SLOT_ATTR "ufm-slot-attributes" 150 151 #define DDI_UFM_NV_SLOT_MISC "ufm-slot-misc" 152 153 #ifdef _KERNEL 154 /* opaque structures */ 155 typedef struct ddi_ufm_handle ddi_ufm_handle_t; 156 typedef struct ddi_ufm_image ddi_ufm_image_t; 157 typedef struct ddi_ufm_slot ddi_ufm_slot_t; 158 159 /* 160 * DDI UFM Operations vector 161 */ 162 typedef struct ddi_ufm_ops { 163 int (*ddi_ufm_op_nimages)(ddi_ufm_handle_t *, void *, uint_t *); 164 int (*ddi_ufm_op_fill_image)(ddi_ufm_handle_t *, void *, uint_t, 165 ddi_ufm_image_t *); 166 int (*ddi_ufm_op_fill_slot)(ddi_ufm_handle_t *, void *, uint_t, uint_t, 167 ddi_ufm_slot_t *); 168 int (*ddi_ufm_op_getcaps)(ddi_ufm_handle_t *, void *, ddi_ufm_cap_t *); 169 } ddi_ufm_ops_t; 170 171 /* 172 * During a device driver's attach(9E) entry point, a device driver should 173 * register with the UFM subsystem by filling out a UFM operations vector 174 * (see above) and then calling ddi_ufm_init(9F). The driver may pass in a 175 * value, usually a pointer to its soft state pointer, which it will then 176 * receive when its subsequent entry points are called. 177 */ 178 int ddi_ufm_init(dev_info_t *, uint_t version, ddi_ufm_ops_t *, 179 ddi_ufm_handle_t **, void *); 180 181 /* 182 * Device drivers should call ddi_ufm_update(9F) after driver initialization is 183 * complete and after calling ddi_ufm_init(9F), in order to indicate to the 184 * UFM subsystem that the driver is in a state where it is ready to receive 185 * calls to its UFM entry points. 186 * 187 * Additionally, whenever the driver detects a change in the state of a UFM, it 188 * should call ddi_ufm_update(9F). This will cause the UFM subsystem to 189 * invalidate any cached state regarding this driver's UFM(s) 190 */ 191 void ddi_ufm_update(ddi_ufm_handle_t *); 192 193 /* 194 * A device driver should call ddi_ufm_fini(9F) during its detach(9E) entry 195 * point. Upon return, the driver is gaurunteed that no further DDI UFM entry 196 * points will be called and thus any related state can be safely torn down. 197 * 198 * After return, the UFM handle is no longer valid and should not be used in 199 * any future ddi_ufm_* calls. 200 */ 201 void ddi_ufm_fini(ddi_ufm_handle_t *); 202 203 /* 204 * These interfaces should only be called within the context of a 205 * ddi_ufm_op_fill_image callback. 206 */ 207 void ddi_ufm_image_set_desc(ddi_ufm_image_t *, const char *); 208 void ddi_ufm_image_set_nslots(ddi_ufm_image_t *, uint_t); 209 void ddi_ufm_image_set_misc(ddi_ufm_image_t *, nvlist_t *); 210 211 /* 212 * These interfaces should only be called within the context of a 213 * ddi_ufm_op_fill_slot callback. 214 */ 215 void ddi_ufm_slot_set_version(ddi_ufm_slot_t *, const char *); 216 void ddi_ufm_slot_set_attrs(ddi_ufm_slot_t *, ddi_ufm_attr_t); 217 void ddi_ufm_slot_set_misc(ddi_ufm_slot_t *, nvlist_t *); 218 #endif /* _KERNEL */ 219 220 #ifdef __cplusplus 221 } 222 #endif 223 224 #endif /* _SYS_DDI_UFM_H */