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