Home | History | Annotate | Download | only in common
      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(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 	 * 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(7D) 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(1M), 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(1M).
    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