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