UFM(4D) | Devices | UFM(4D) |
ufm
— Upgradeable
Firmware Module driver
/dev/ufm
#include <sys/ddi_ufm.h>
The ufm
device is a character special file
that provides access to Upgradeable Firmware Image information, as described
in ddi_ufm(9E) via a private ioctl
interface.
The UFM interfaces described below are used in the implementation of the system through tools such as fwflash(8) or as part of the fault management architecture.
The ufm
driver implements a versioned
ioctl interface for accessing UFM facilities. The ioctl interfaces are
defined in sys/ddi_ufm.h. The following ioctl cmds are supported by
DDI_UFM_VERSION_ONE:
UFM_IOC_GETCAPS
UFM_IOC_GETCAPS
ioctl is used to retrieve the
set of DDI UFM capabilities supported by this device instance.
The ddi_ufm_cap_t type defines a bitfield enumerating the full set of DDI UFM capabilities.
typedef enum { DDI_UFM_CAP_REPORT = 1 << 0, DDI_UFM_CAP_READIMG = 1 << 1 } ddi_ufm_cap_t;
The capabilities mean:
DDI_UFM_CAP_REPORT
UFM_IOC_REPORT
and
UFM_IOC_REPORTSZ
ioctls.DDI_UFM_CAP_READIMG
UFM_IOC_READIMG
ioctl is supported.The ufm_ioc_getcaps_t structure defines
the input/output data for the UFM_IOC_GETCAPS
ioctl. Callers should specify the ufmg_version and
ufmg_devpath fields. On success the
ufmg_caps field will be filled in with a value
indicating the supported UFM capabilities of the device specified in
ufmg_devpath.
typedef struct ufm_ioc_getcaps { uint_t ufmg_version; /* DDI_UFM_VERSION_ONE */ uint_t ufmg_caps; /* UFM Caps */ char ufmg_devpath[MAXPATHLEN]; } ufm_ioc_getcaps_t;
UFM_IOC_REPORTSZ
UFM_IOC_REPORTSZ
ioctl is used to retrieve the
amount of space (in bytes) required to hold the UFM data for this device
instance. This should be used to allocate a sufficiently sized buffer for
the UFM_IOC_REPORT
ioctl.
The ufm_ioc_bufsz_t structure defines
the input/output data for the UFM_IOC_REPORTSZ
ioctl. Callers should specify the ufbz_version and
ufbz_devpath fields. On success the
ufbz_size field will be filled in with the
required buffer size.
typedef struct ufm_ioc_bufsz { uint_t ufbz_version; /* DDI_UFM_VERSION_ONE */ size_t ufbz_size; /* sz of buf to be returned by ioctl */ char ufbz_devpath[MAXPATHLEN]; } ufm_ioc_bufsz_t;
UFM_IOC_REPORT
UFM_IOC_REPORT
ioctl returns UFM image and
slot data in the form of a packed nvlist. The
ufm_ioc_report_t structure defines the input/output
data for the UFM_IOC_REPORT
ioctl. Callers should
specify the ufmr_version, ufmr_bufsz and ufmr_devpath fields. On success,
the ufmr_buf field will point to a packed nvlist containing the UFM data
for the specified device instance. This data can be unpacked and decoded
into an nvlist using
nvlist_unpack(3NVPAIR).
typedef struct ufm_ioc_report { uint_t ufmr_version; /* DDI_UFM_VERSIONONE */ size_t ufmr_bufsz; /* size of caller-supplied buffer */ caddr_t ufmr_buf; /* buf to hold packed output nvl */ char ufmr_devpath[MAXPATHLEN]; } ufm_ioc_report_t;
Due to the asynchronous nature of the system, it's possible
for a device to undergo a configuration change in between a
UFM_IOC_REPORTSZ
ioctl and a subsequent
UFM_IOC_REPORT
ioctl that would alter the size
of the buffer required to hold the UFM data.
If the size of buffer supplied in the
UFM_IOC_REPORT
ioctl is greater than is required
to hold the UFM data, then the ioctl will succeed and the ufmr_bufsz
field will be updated to reflect the actual size of the returned UFM
data. If the size of buffer supplied in the
UFM_IOC_REPORT
ioctl is less than what is
required to hold the UFM data, the ioctl will fail with errno set to
EOVERFLOW
.
UFM_IOC_READIMG
UFM_IOC_READIMG
ioctl retrieves a firmware
image and slot from a device. The ufm_ioc_readimg_t
structure defines the input and output data for the ioctl. Devices may
have their own alignment and size constraints which may be enforced upon
issuing this ioctl. The structure has the following form:
typedef struct ufm_ioc_readimg { uint_t ufri_version; uint_t ufri_imageno; uint_t ufri_slotno; uint64_t ufri_offset; uint64_t ufri_len; uint64_t ufri_nread; void *ufri_buf; char ufri_devpath[MAXPATHLEN]; } ufm_ioc_readimg_t;
The ufri_imageno and
ufri_slotno values are used to indicate the image
and slot to read. These indexes correspond to the same indices that are
returned in the nvlist from the UFM_IOC_REPORT
ioctl. The ufri_offset and
ufri_len members are used to indicate how many
bytes to read from the image and where in the image to begin. The
ufri_buf member must be set to a valid pointer.
Data read from the device will be placed in that pointer. The pointer
must be at least ufri_len bytes long. Upon
successful completion, the ufri_nread member will
be filled in with the number of bytes that have been placed in
ufri_buf. Finally, the
ufri_version and
ufri_devpath fields must be filled in with the
version number, DDI_UFM_VERSION_ONE
, and the
corresponding /devices path.
This example demonstrates how to use the
UFM_IOC_GETCAPS
ioctl to determine the UFM
capabilities of a given device instance.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <sys/ddi_ufm.h> #include <sys/types.h> static const char devname[] = "/pci@ce,0/pci8086,2030@0/pci15d9,808@0"; int main(int argc, char **argv) { int fd; ufm_ioc_getcaps_t ioc = { 0 }; if ((fd = open(DDI_UFM_DEV, O_RDWR)) < 0) { (void) fprintf(stderr, "failed to open %s (%s)0, DDI_UFM_DEV, strerror(errno)); return (1); } ioc.ufmg_version = DDI_UFM_CURRENT_VERSION; (void) strcpy(ioc.ufmg_devpath, devname); if (ioctl(fd, UFM_IOC_GETCAPS, &ioc) < 0) { (void) fprintf(stderr, "getcaps ioctl failed (%s)0, strerror(errno)); (void) close(fd); return (1); } if ((ioc.ufmg_caps & DDI_UFM_CAP_REPORT) == 0) { (void) printf("Driver does not support DDI_UFM_CAP_REPORT0); } else { (void) printf("Driver supports DDI_UFM_CAP_REPORT0); } (void) close(fd); return (0); }
On failure to open or perform ioctls to the
ufm
driver, errno will be set
to indicate the type of error. A subset of the more common errors are
detailed below. For a full list of error numbers, see
Intro(2)
EAGAIN
EFAULT
EINVAL
EIO
ENOTSUP
ddi_ufm(9E), ddi_ufm(9F), ddi_ufm_image(9F), ddi_ufm_slot(9F)
May 23, 2021 | OmniOS |