1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _FWFLASH_H 27 #define _FWFLASH_H 28 29 /* 30 * fwflash.h 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <sys/queue.h> 38 #include <libdevinfo.h> 39 40 41 #define MSG_INFO 0 42 #define MSG_WARN 1 43 #define MSG_ERROR 2 44 int fwflash_debug; 45 46 #define FWFLASH_SUCCESS 0 47 #define FWFLASH_FAILURE 1 48 49 #define FWFLASH_FLASH_IMAGES 2 50 51 #define FWPLUGINDIR "/usr/lib/fwflash/identify" 52 #define FWVERIFYPLUGINDIR "/usr/lib/fwflash/verify" 53 54 /* 55 * we search for a variable (fwplugin_version, type uint32_t) 56 * which should equal FWPLUGIN_VERSION_1 57 */ 58 59 #define FWPLUGIN_VERSION_1 1 60 #define FWPLUGIN_VERSION_2 2 61 62 struct devicelist; 63 64 struct fw_plugin { 65 /* 66 * An opaque handle for dlopen()/dlclose() to use. 67 */ 68 void *handle; 69 70 /* 71 * fully-qualified filename in /usr/lib/fwflash/identify 72 * made up of [drivername].so 73 * 74 * eg /usr/lib/fwflash/identify/ses.so 75 * is the identification plugin for devices attached to 76 * the host using the ses(7D) driver. 77 */ 78 char *filename; 79 80 /* 81 * The driver name that this plugin will search for in 82 * the device tree snapshot using di_drv_first_node(3DEVINFO) 83 * and di_drv_next_node(3DEVINFO). 84 */ 85 char *drvname; /* "ses" or "tavor" or .... */ 86 87 /* 88 * Function entry point to support the command-line "-r" 89 * option - read image from device to persistent storage. 90 * 91 * Not all plugins and devices will support this operation. 92 */ 93 int (*fw_readfw)(struct devicelist *device, char *filename); 94 95 /* 96 * Function entry point to support the command-line "-f" 97 * option - writes from persistent storage to device 98 * 99 * All identification plugins must support this operation. 100 */ 101 int (*fw_writefw)(struct devicelist *device, char *filename); 102 103 /* 104 * Function entry point used to build the list of valid, flashable 105 * devices attached to the system using the loadable module drvname. 106 * (Not all devices attached using drvname will be valid for this 107 * plugin to report. 108 * 109 * start allows us to display flashable devices attached with 110 * different drivers and provide the user with a visual clue 111 * that these devices are different to others that are detected. 112 * 113 * All identification plugins must support this operation. 114 */ 115 int (*fw_identify)(int start); 116 117 /* 118 * Function entry point to support the command-line "-l" 119 * option - list/report flashable devices attached to the system. 120 * 121 * All identification plugins must support this operation. 122 */ 123 int (*fw_devinfo)(struct devicelist *thisdev); 124 125 /* 126 * Function entry point to allow the plugin to clean up its 127 * data structure use IF plugin_version == FWPLUGIN_VERSION_2. 128 * 129 * If this function is not defined in the plugin, that is not 130 * an error condition unless the plugin_version variable is 131 * defined. 132 */ 133 void (*fw_cleanup)(struct devicelist *thisdev); 134 }; 135 136 137 struct pluginlist { 138 /* 139 * fully qualified filename in /usr/lib/fwflash/identify 140 * made up of fwflash-[drivername].so 141 * 142 * eg /usr/lib/fwflash/identify/ses.so 143 * is the identification plugin for devices attached to 144 * the host using the ses(7D) driver. 145 */ 146 char *filename; 147 148 /* 149 * The driver name that this plugin will search for in 150 * the device tree snapshot using di_drv_first_node(3DEVINFO) 151 * and di_drv_next_node(3DEVINFO). 152 */ 153 char *drvname; 154 155 /* 156 * pointer to the actual plugin, so we can access its 157 * function entry points 158 */ 159 struct fw_plugin *plugin; 160 161 /* pointer to the next element in the list */ 162 TAILQ_ENTRY(pluginlist) nextplugin; 163 }; 164 165 struct vpr { 166 /* vendor ID, eg "HITACHI " */ 167 char *vid; 168 169 /* product ID, eg "DK32EJ36NSUN36G " */ 170 char *pid; 171 172 /* revision, eg "PQ08" */ 173 char *revid; 174 175 /* 176 * Additional, encapsulated identifying information. 177 * This pointer allows us to add details such as the 178 * IB hba sector size, which command set should be 179 * used or a part number. 180 */ 181 void *encap_ident; 182 }; 183 184 struct fwfile { 185 /* 186 * The fully qualified filename. No default location for 187 * the firmware image file is mandated. 188 */ 189 char *filename; 190 191 /* Pointer to the identification plugin required */ 192 struct fw_plugin *plugin; 193 194 /* pointer to the identification summary structure */ 195 struct vpr *ident; 196 }; 197 198 struct devicelist { 199 /* 200 * fully qualified pathname, with /devices/.... prefix 201 */ 202 char *access_devname; 203 204 /* 205 * Which drivername did we find this device attached with 206 * in our device tree walk? Eg, ses or tavor or sgen... 207 */ 208 char *drvname; 209 210 /* 211 * What class of device is this? For tavor-attached devices, 212 * we set this to "IB". For other devices, unless there is 213 * a common name to use, just make this the same as the 214 * drvname field. 215 */ 216 char *classname; 217 218 /* pointer to the VPR structure */ 219 struct vpr *ident; 220 221 /* 222 * In the original fwflash(1M), it was possible to select a 223 * device for flashing by using an index number called a 224 * dev_num. We retain that concept for pluggable fwflash, with 225 * the following change - whenever our identification plugin has 226 * finished and found at least one acceptable device, we bump the 227 * index number by 100. This provides the user with another key 228 * to distinguish the desired device from a potentially very large 229 * list of similar-looking devices. 230 */ 231 unsigned int index; 232 233 /* 234 * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only 235 * need one entry in this array since they really only have one 236 * address which we should track. IB devices can have 4 GUIDs 237 * (System Image, Node Image, Port 1 and Port 2). 238 */ 239 char *addresses[4]; 240 241 /* 242 * Pointer to the plugin needed to flash this device, and 243 * to use for printing appropriate device-specific information 244 * as required by the "-l" option to fwflash(1M). 245 */ 246 struct fw_plugin *plugin; 247 248 /* Next entry in the list */ 249 TAILQ_ENTRY(devicelist) nextdev; 250 }; 251 252 253 /* 254 * this type of plugin is for the firmware image vendor-specific 255 * verification functions, which we load from FWVERIFYPLUGINDIR 256 */ 257 258 struct vrfyplugin { 259 /* 260 * fully-qualified filename in /usr/lib/fwflash/verify, 261 * made up of [drivername]-[vendorname].so 262 * 263 * eg /usr/lib/fwflash/verify/ses-SUN.so 264 * is the verification plugin for ses-attached devices which 265 * have a vendorname of "SUN". 266 */ 267 char *filename; 268 269 /* 270 * The vendor name, such as "SUN" or "MELLANOX" 271 */ 272 char *vendor; 273 274 /* 275 * An opaque handle for dlopen()/dlclose() to use. 276 */ 277 void *handle; 278 279 /* 280 * Firmware image size in bytes, as reported by 281 * stat(). 282 */ 283 unsigned int imgsize; 284 285 /* 286 * Flashable devices frequently have different buffers 287 * to use for different image types. We track the buffer 288 * required for this particular image with this variable. 289 * 290 * Once the verifier has figured out what sort of image 291 * it's been passed, it will know what value to use for 292 * this variable. 293 */ 294 unsigned int flashbuf; 295 296 /* 297 * Points to the entire firmware image in memory. 298 * We do this so we can avoid multiple open()/close() 299 * operations, and to make it easier for checksum 300 * calculations. 301 */ 302 int *fwimage; 303 304 /* 305 * We also store the name of the firmware file that 306 * we point to with *fwimage. This is needed in cases 307 * where we need to key off the name of the file to 308 * determine whether a different buffer in the target 309 * device should be targeted. 310 * 311 * For example, our "standard" firmware image (file.fw) 312 * might require use of buffer id 0, but a boot image 313 * (boot.fw) might require use of buffer id 17. In each 314 * case, it is the verifier plugin that determines the 315 * specific bufferid that is needed by that firmware image. 316 */ 317 char *imgfile; 318 319 /* 320 * The verification function entry point. The code 321 * in fwflash.c calls this function to verify that 322 * the nominated firmware image file is valid for 323 * the selected devicenode. 324 * 325 * Note that if the verification fails, the image 326 * does _not_ get force-flashed to the device. 327 */ 328 int (*vendorvrfy)(struct devicelist *devicenode); 329 }; 330 331 /* Flags for argument parsing */ 332 #define FWFLASH_HELP_FLAG 0x01 333 #define FWFLASH_VER_FLAG 0x02 334 #define FWFLASH_YES_FLAG 0x04 335 #define FWFLASH_LIST_FLAG 0x08 336 #define FWFLASH_CLASS_FLAG 0x10 337 #define FWFLASH_DEVICE_FLAG 0x20 338 #define FWFLASH_FW_FLAG 0x40 339 #define FWFLASH_READ_FLAG 0x80 340 341 /* global variables for fwflash */ 342 TAILQ_HEAD(PLUGINLIST, pluginlist); 343 TAILQ_HEAD(DEVICELIST, devicelist); 344 struct PLUGINLIST *fw_pluginlist; 345 struct DEVICELIST *fw_devices; 346 347 struct vrfyplugin *verifier; 348 di_node_t rootnode; 349 struct fw_plugin *self; 350 351 /* 352 * utility defines and macros, since the firmware image we get 353 * from LSI is ARM-format and that means byte- and short-swapping 354 * on sparc 355 */ 356 357 #define HIGHBITS16 0xff00 358 #define HIGHBITS32 0xffff0000 359 #define HIGHBITS64 0xffffffff00000000ULL 360 #define LOWBITS16 0x00ff 361 #define LOWBITS32 0x0000ffff 362 #define LOWBITS64 0x00000000ffffffffULL 363 364 #if defined(_LITTLE_ENDIAN) 365 #define ARMSWAPBITS(bs) (bs) 366 #define MLXSWAPBITS16(bs) ntohs(bs) 367 #define MLXSWAPBITS32(bs) ntohl(bs) 368 #define MLXSWAPBITS64(bs) \ 369 (BE_64(((bs) & LOWBITS64)) | BE_64(((bs) & HIGHBITS64))) 370 #else 371 #define ARMSWAPBITS(bs) (LE_32(((bs) & LOWBITS32)) | LE_32(((bs) & HIGHBITS32))) 372 #define MLXSWAPBITS16(bs) (bs) 373 #define MLXSWAPBITS32(bs) (bs) 374 #define MLXSWAPBITS64(bs) (bs) 375 #endif 376 377 /* common functions for fwflash */ 378 void logmsg(int severity, const char *msg, ...); 379 380 #ifdef __cplusplus 381 } 382 #endif 383 384 #endif /* _FWFLASH_H */ 385