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