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