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