xref: /illumos-gate/usr/src/man/man4d/ufm.4d (revision bbf215553c7233fbab8a0afdf1fac74c44781867)
1*bbf21555SRichard Lowe.\"
2*bbf21555SRichard Lowe.\" This file and its contents are supplied under the terms of the
3*bbf21555SRichard Lowe.\" Common Development and Distribution License ("CDDL"), version 1.0.
4*bbf21555SRichard Lowe.\" You may only use this file in accordance with the terms of version
5*bbf21555SRichard Lowe.\" 1.0 of the CDDL.
6*bbf21555SRichard Lowe.\"
7*bbf21555SRichard Lowe.\" A full copy of the text of the CDDL should have accompanied this
8*bbf21555SRichard Lowe.\" source.  A copy of the CDDL is also available via the Internet at
9*bbf21555SRichard Lowe.\" http://www.illumos.org/license/CDDL.
10*bbf21555SRichard Lowe.\"
11*bbf21555SRichard Lowe.\"
12*bbf21555SRichard Lowe.\" Copyright 2019 Joyent, Inc.
13*bbf21555SRichard Lowe.\" Copyright 2020 Oxide Computer Company
14*bbf21555SRichard Lowe.\"
15*bbf21555SRichard Lowe.Dd May 23, 2021
16*bbf21555SRichard Lowe.Dt UFM 4D
17*bbf21555SRichard Lowe.Os
18*bbf21555SRichard Lowe.Sh NAME
19*bbf21555SRichard Lowe.Nm ufm
20*bbf21555SRichard Lowe.Nd Upgradeable Firmware Module driver
21*bbf21555SRichard Lowe.Sh SYNOPSIS
22*bbf21555SRichard Lowe.Pa /dev/ufm
23*bbf21555SRichard Lowe.Lp
24*bbf21555SRichard Lowe.In sys/ddi_ufm.h
25*bbf21555SRichard Lowe.Sh DESCRIPTION
26*bbf21555SRichard LoweThe
27*bbf21555SRichard Lowe.Nm
28*bbf21555SRichard Lowedevice is a character special file that provides access to
29*bbf21555SRichard LoweUpgradeable Firmware Image information, as described in
30*bbf21555SRichard Lowe.Xr ddi_ufm 9E
31*bbf21555SRichard Lowevia a private ioctl interface.
32*bbf21555SRichard Lowe.Pp
33*bbf21555SRichard LoweThe UFM interfaces described below are used in the implementation of the
34*bbf21555SRichard Lowesystem through tools such as
35*bbf21555SRichard Lowe.Xr fwflash 8
36*bbf21555SRichard Loweor as part of the fault management architecture.
37*bbf21555SRichard Lowe.Sh FILES
38*bbf21555SRichard Lowe.Bl -tag -width Pa
39*bbf21555SRichard Lowe.It Pa /kernel/drv/amd64/ufm
40*bbf21555SRichard Lowe64-bit AMD64 ELF kernel driver
41*bbf21555SRichard Lowe.It Pa /kernel/drv/sparcv9/ufm
42*bbf21555SRichard Lowe64-bit SPARC ELF kernel driver
43*bbf21555SRichard Lowe.El
44*bbf21555SRichard Lowe.Sh IOCTLS
45*bbf21555SRichard LoweThe
46*bbf21555SRichard Lowe.Nm
47*bbf21555SRichard Lowedriver implements a versioned ioctl interface for accessing UFM facilities.
48*bbf21555SRichard LoweThe ioctl interfaces are defined in sys/ddi_ufm.h.
49*bbf21555SRichard LoweThe following ioctl cmds are supported by DDI_UFM_VERSION_ONE:
50*bbf21555SRichard Lowe.Bl -tag -width Dv
51*bbf21555SRichard Lowe.It Dv UFM_IOC_GETCAPS
52*bbf21555SRichard LoweThe
53*bbf21555SRichard Lowe.Dv UFM_IOC_GETCAPS
54*bbf21555SRichard Loweioctl is used to retrieve the set of DDI UFM capabilities supported by this
55*bbf21555SRichard Lowedevice instance.
56*bbf21555SRichard Lowe.Pp
57*bbf21555SRichard LoweThe ddi_ufm_cap_t type defines a bitfield enumerating the full set of DDI UFM
58*bbf21555SRichard Lowecapabilities.
59*bbf21555SRichard Lowe.Bd -literal
60*bbf21555SRichard Lowetypedef enum {
61*bbf21555SRichard Lowe	DDI_UFM_CAP_REPORT	= 1 << 0,
62*bbf21555SRichard Lowe	DDI_UFM_CAP_READIMG	= 1 << 1
63*bbf21555SRichard Lowe} ddi_ufm_cap_t;
64*bbf21555SRichard Lowe.Ed
65*bbf21555SRichard Lowe.Pp
66*bbf21555SRichard LoweThe capabilities mean:
67*bbf21555SRichard Lowe.Bl -tag -width Dv
68*bbf21555SRichard Lowe.It Dv DDI_UFM_CAP_REPORT
69*bbf21555SRichard LoweIndicates that the device is capable of reporting UFM information and
70*bbf21555SRichard Lowesupports the
71*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
72*bbf21555SRichard Loweand
73*bbf21555SRichard Lowe.Dv UFM_IOC_REPORTSZ
74*bbf21555SRichard Loweioctls.
75*bbf21555SRichard Lowe.It Dv DDI_UFM_CAP_READIMG
76*bbf21555SRichard LoweIndicates that the device is capable of retrieving a firmware image from
77*bbf21555SRichard Lowea slot and transferring it back to the caller.
78*bbf21555SRichard LoweThe
79*bbf21555SRichard Lowe.Dv UFM_IOC_READIMG
80*bbf21555SRichard Loweioctl is supported.
81*bbf21555SRichard Lowe.El
82*bbf21555SRichard Lowe.Pp
83*bbf21555SRichard LoweThe
84*bbf21555SRichard Lowe.Vt ufm_ioc_getcaps_t
85*bbf21555SRichard Lowestructure defines the input/output data for the
86*bbf21555SRichard Lowe.Dv UFM_IOC_GETCAPS
87*bbf21555SRichard Loweioctl.
88*bbf21555SRichard LoweCallers should specify the
89*bbf21555SRichard Lowe.Fa ufmg_version
90*bbf21555SRichard Loweand
91*bbf21555SRichard Lowe.Fa ufmg_devpath
92*bbf21555SRichard Lowefields.
93*bbf21555SRichard LoweOn success the
94*bbf21555SRichard Lowe.Fa ufmg_caps
95*bbf21555SRichard Lowefield will be filled in with a value indicating the
96*bbf21555SRichard Lowesupported UFM capabilities of the device specified in
97*bbf21555SRichard Lowe.Fa ufmg_devpath .
98*bbf21555SRichard Lowe.Bd -literal
99*bbf21555SRichard Lowetypedef struct ufm_ioc_getcaps {
100*bbf21555SRichard Lowe	uint_t		ufmg_version;	/* DDI_UFM_VERSION_ONE */
101*bbf21555SRichard Lowe	uint_t		ufmg_caps;	/* UFM Caps */
102*bbf21555SRichard Lowe	char		ufmg_devpath[MAXPATHLEN];
103*bbf21555SRichard Lowe} ufm_ioc_getcaps_t;
104*bbf21555SRichard Lowe.Ed
105*bbf21555SRichard Lowe.It Dv UFM_IOC_REPORTSZ
106*bbf21555SRichard LoweThe
107*bbf21555SRichard Lowe.Dv UFM_IOC_REPORTSZ
108*bbf21555SRichard Loweioctl is used to retrieve the amount of space
109*bbf21555SRichard Lowe(in bytes) required to hold the UFM data for this device instance.
110*bbf21555SRichard LoweThis should be used to allocate a sufficiently sized buffer for the
111*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
112*bbf21555SRichard Loweioctl.
113*bbf21555SRichard Lowe.Pp
114*bbf21555SRichard LoweThe
115*bbf21555SRichard Lowe.Vt ufm_ioc_bufsz_t
116*bbf21555SRichard Lowestructure defines the input/output data for the
117*bbf21555SRichard Lowe.Dv UFM_IOC_REPORTSZ
118*bbf21555SRichard Loweioctl.
119*bbf21555SRichard LoweCallers should specify the
120*bbf21555SRichard Lowe.Fa ufbz_version
121*bbf21555SRichard Loweand
122*bbf21555SRichard Lowe.Fa ufbz_devpath
123*bbf21555SRichard Lowefields.
124*bbf21555SRichard LoweOn success the
125*bbf21555SRichard Lowe.Fa ufbz_size
126*bbf21555SRichard Lowefield will be filled in with the required buffer size.
127*bbf21555SRichard Lowe.Bd -literal
128*bbf21555SRichard Lowetypedef struct ufm_ioc_bufsz {
129*bbf21555SRichard Lowe	uint_t		ufbz_version;	/* DDI_UFM_VERSION_ONE */
130*bbf21555SRichard Lowe	size_t		ufbz_size;	/* sz of buf to be returned by ioctl */
131*bbf21555SRichard Lowe	char		ufbz_devpath[MAXPATHLEN];
132*bbf21555SRichard Lowe} ufm_ioc_bufsz_t;
133*bbf21555SRichard Lowe.Ed
134*bbf21555SRichard Lowe.It Dv UFM_IOC_REPORT
135*bbf21555SRichard LoweThe
136*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
137*bbf21555SRichard Loweioctl returns UFM image and slot data in the form of a packed nvlist.
138*bbf21555SRichard LoweThe
139*bbf21555SRichard Lowe.Vt ufm_ioc_report_t
140*bbf21555SRichard Lowestructure defines the input/output data for the
141*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
142*bbf21555SRichard Loweioctl.
143*bbf21555SRichard LoweCallers should specify the ufmr_version, ufmr_bufsz and ufmr_devpath fields.
144*bbf21555SRichard LoweOn success, the ufmr_buf field will point to a packed nvlist containing the UFM
145*bbf21555SRichard Lowedata for the specified device instance.
146*bbf21555SRichard LoweThis data can be unpacked and decoded into an nvlist using
147*bbf21555SRichard Lowe.Xr nvlist_unpack 3NVPAIR .
148*bbf21555SRichard Lowe.Bd -literal
149*bbf21555SRichard Lowetypedef struct ufm_ioc_report {
150*bbf21555SRichard Lowe	uint_t		ufmr_version;	/* DDI_UFM_VERSIONONE */
151*bbf21555SRichard Lowe	size_t		ufmr_bufsz;	/* size of caller-supplied buffer */
152*bbf21555SRichard Lowe	caddr_t		ufmr_buf;	/* buf to hold packed output nvl */
153*bbf21555SRichard Lowe	char		ufmr_devpath[MAXPATHLEN];
154*bbf21555SRichard Lowe} ufm_ioc_report_t;
155*bbf21555SRichard Lowe.Ed
156*bbf21555SRichard Lowe.Pp
157*bbf21555SRichard LoweDue to the asynchronous nature of the system, it's possible for a device to
158*bbf21555SRichard Loweundergo a configuration change in between a
159*bbf21555SRichard Lowe.Dv UFM_IOC_REPORTSZ
160*bbf21555SRichard Loweioctl and a subsequent
161*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
162*bbf21555SRichard Loweioctl that would alter the size of the buffer
163*bbf21555SRichard Lowerequired to hold the UFM data.
164*bbf21555SRichard Lowe.Pp
165*bbf21555SRichard LoweIf the size of buffer supplied in the
166*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
167*bbf21555SRichard Loweioctl is greater than is required to hold the UFM data, then
168*bbf21555SRichard Lowethe ioctl will succeed and the ufmr_bufsz field will be updated to reflect the
169*bbf21555SRichard Loweactual size of the returned UFM data.
170*bbf21555SRichard LoweIf the size of buffer supplied in the
171*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
172*bbf21555SRichard Loweioctl is less than what is required to hold the UFM data,
173*bbf21555SRichard Lowethe ioctl will fail with errno set to
174*bbf21555SRichard Lowe.Er EOVERFLOW .
175*bbf21555SRichard Lowe.It Dv UFM_IOC_READIMG
176*bbf21555SRichard LoweThe
177*bbf21555SRichard Lowe.Dv UFM_IOC_READIMG
178*bbf21555SRichard Loweioctl retrieves a firmware image and slot from a device.
179*bbf21555SRichard LoweThe
180*bbf21555SRichard Lowe.Vt ufm_ioc_readimg_t
181*bbf21555SRichard Lowestructure defines the input and output data for the ioctl.
182*bbf21555SRichard LoweDevices may have their own alignment and size constraints which may be
183*bbf21555SRichard Loweenforced upon issuing this ioctl.
184*bbf21555SRichard LoweThe structure has the following form:
185*bbf21555SRichard Lowe.Bd -literal
186*bbf21555SRichard Lowetypedef struct ufm_ioc_readimg {
187*bbf21555SRichard Lowe	uint_t		ufri_version;
188*bbf21555SRichard Lowe	uint_t		ufri_imageno;
189*bbf21555SRichard Lowe	uint_t		ufri_slotno;
190*bbf21555SRichard Lowe	uint64_t	ufri_offset;
191*bbf21555SRichard Lowe	uint64_t	ufri_len;
192*bbf21555SRichard Lowe	uint64_t	ufri_nread;
193*bbf21555SRichard Lowe	void		*ufri_buf;
194*bbf21555SRichard Lowe	char		ufri_devpath[MAXPATHLEN];
195*bbf21555SRichard Lowe} ufm_ioc_readimg_t;
196*bbf21555SRichard Lowe.Ed
197*bbf21555SRichard Lowe.Pp
198*bbf21555SRichard LoweThe
199*bbf21555SRichard Lowe.Ft ufri_imageno
200*bbf21555SRichard Loweand
201*bbf21555SRichard Lowe.Ft ufri_slotno
202*bbf21555SRichard Lowevalues are used to indicate the image and slot to read.
203*bbf21555SRichard LoweThese indexes correspond to the same indices that are returned in the
204*bbf21555SRichard Lowenvlist from the
205*bbf21555SRichard Lowe.Dv UFM_IOC_REPORT
206*bbf21555SRichard Loweioctl.
207*bbf21555SRichard LoweThe
208*bbf21555SRichard Lowe.Ft ufri_offset
209*bbf21555SRichard Loweand
210*bbf21555SRichard Lowe.Ft ufri_len
211*bbf21555SRichard Lowemembers are used to indicate how many bytes to read from the image and
212*bbf21555SRichard Lowewhere in the image to begin.
213*bbf21555SRichard LoweThe
214*bbf21555SRichard Lowe.Fa ufri_buf
215*bbf21555SRichard Lowemember must be set to a valid pointer.
216*bbf21555SRichard LoweData read from the device will be placed in that pointer.
217*bbf21555SRichard LoweThe pointer must be at least
218*bbf21555SRichard Lowe.Fa ufri_len
219*bbf21555SRichard Lowebytes long.
220*bbf21555SRichard LoweUpon successful completion, the
221*bbf21555SRichard Lowe.Fa ufri_nread
222*bbf21555SRichard Lowemember will be filled in with the number of bytes that have been placed
223*bbf21555SRichard Lowein
224*bbf21555SRichard Lowe.Fa ufri_buf .
225*bbf21555SRichard LoweFinally, the
226*bbf21555SRichard Lowe.Fa ufri_version
227*bbf21555SRichard Loweand
228*bbf21555SRichard Lowe.Fa ufri_devpath
229*bbf21555SRichard Lowefields must be filled in with the version number,
230*bbf21555SRichard Lowe.Dv DDI_UFM_VERSION_ONE ,
231*bbf21555SRichard Loweand the corresponding /devices path.
232*bbf21555SRichard Lowe.El
233*bbf21555SRichard Lowe.Sh EXAMPLES
234*bbf21555SRichard LoweThis example demonstrates how to use the
235*bbf21555SRichard Lowe.Dv UFM_IOC_GETCAPS
236*bbf21555SRichard Loweioctl to determine the UFM capabilities of a given device instance.
237*bbf21555SRichard Lowe.Bd -literal
238*bbf21555SRichard Lowe#include <stdio.h>
239*bbf21555SRichard Lowe#include <stdlib.h>
240*bbf21555SRichard Lowe#include <errno.h>
241*bbf21555SRichard Lowe#include <fcntl.h>
242*bbf21555SRichard Lowe#include <string.h>
243*bbf21555SRichard Lowe#include <unistd.h>
244*bbf21555SRichard Lowe#include <sys/ddi_ufm.h>
245*bbf21555SRichard Lowe#include <sys/types.h>
246*bbf21555SRichard Lowe
247*bbf21555SRichard Lowestatic const char devname[] = "/pci@ce,0/pci8086,2030@0/pci15d9,808@0";
248*bbf21555SRichard Lowe
249*bbf21555SRichard Loweint
250*bbf21555SRichard Lowemain(int argc, char **argv)
251*bbf21555SRichard Lowe{
252*bbf21555SRichard Lowe        int fd;
253*bbf21555SRichard Lowe        ufm_ioc_getcaps_t ioc = { 0 };
254*bbf21555SRichard Lowe
255*bbf21555SRichard Lowe        if ((fd = open(DDI_UFM_DEV, O_RDWR)) < 0) {
256*bbf21555SRichard Lowe                (void) fprintf(stderr, "failed to open %s (%s)\n", DDI_UFM_DEV,
257*bbf21555SRichard Lowe                    strerror(errno));
258*bbf21555SRichard Lowe                return (1);
259*bbf21555SRichard Lowe        }
260*bbf21555SRichard Lowe
261*bbf21555SRichard Lowe        ioc.ufmg_version = DDI_UFM_CURRENT_VERSION;
262*bbf21555SRichard Lowe        (void) strcpy(ioc.ufmg_devpath, devname);
263*bbf21555SRichard Lowe
264*bbf21555SRichard Lowe        if (ioctl(fd, UFM_IOC_GETCAPS, &ioc) < 0) {
265*bbf21555SRichard Lowe                (void) fprintf(stderr, "getcaps ioctl failed (%s)\n",
266*bbf21555SRichard Lowe                    strerror(errno));
267*bbf21555SRichard Lowe                (void) close(fd);
268*bbf21555SRichard Lowe                return (1);
269*bbf21555SRichard Lowe        }
270*bbf21555SRichard Lowe        if ((ioc.ufmg_caps & DDI_UFM_CAP_REPORT) == 0) {
271*bbf21555SRichard Lowe                (void) printf("Driver does not support DDI_UFM_CAP_REPORT\n");
272*bbf21555SRichard Lowe        } else {
273*bbf21555SRichard Lowe                (void) printf("Driver supports DDI_UFM_CAP_REPORT\n");
274*bbf21555SRichard Lowe        }
275*bbf21555SRichard Lowe        (void) close(fd);
276*bbf21555SRichard Lowe        return (0);
277*bbf21555SRichard Lowe}
278*bbf21555SRichard Lowe.Ed
279*bbf21555SRichard Lowe.Sh ERRORS
280*bbf21555SRichard LoweOn failure to open or perform ioctls to the
281*bbf21555SRichard Lowe.Nm
282*bbf21555SRichard Lowedriver,
283*bbf21555SRichard Lowe.Va errno
284*bbf21555SRichard Lowewill be set to indicate the type of error.
285*bbf21555SRichard LoweA subset of the more common errors are detailed below.
286*bbf21555SRichard LoweFor a full list of error numbers, see
287*bbf21555SRichard Lowe.Xr Intro 2
288*bbf21555SRichard Lowe.Bl -tag -width Er
289*bbf21555SRichard Lowe.It Er EAGAIN
290*bbf21555SRichard LoweThe device driver is not currently ready to accept calls to it's DDI UFM entry
291*bbf21555SRichard Lowepoints.
292*bbf21555SRichard LoweThis may be because the driver is not fully initialized or because the driver
293*bbf21555SRichard Loweis in the process of detaching.
294*bbf21555SRichard Lowe.It Er EFAULT
295*bbf21555SRichard LoweThe ufm driver encountered a failure while copying data either from or to the
296*bbf21555SRichard Loweaddress space of the calling process.
297*bbf21555SRichard Lowe.It Er EINVAL
298*bbf21555SRichard LoweThe offset or length of an image would have resulted in a read outside
299*bbf21555SRichard Loweof the image's valid range or with improper alignment.
300*bbf21555SRichard Lowe.It Er EIO
301*bbf21555SRichard LoweA failure occurred while executing a DDI UFM entry point.
302*bbf21555SRichard Lowe.It Er ENOTSUP
303*bbf21555SRichard LoweEither the requested ioctl is not supported by the target device, the device
304*bbf21555SRichard Lowedoes not exist or the device does not support the UFM interfaces.
305*bbf21555SRichard Lowe.El
306*bbf21555SRichard Lowe.Sh INTERFACE STABILITY
307*bbf21555SRichard Lowe.Sy Evolving
308*bbf21555SRichard Lowe.Sh SEE ALSO
309*bbf21555SRichard Lowe.Xr ddi_ufm 9E ,
310*bbf21555SRichard Lowe.Xr ddi_ufm 9F ,
311*bbf21555SRichard Lowe.Xr ddi_ufm_image 9F ,
312*bbf21555SRichard Lowe.Xr ddi_ufm_slot 9F
313