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