iPXE
Functions
nvsvpd.c File Reference

Non-Volatile Storage using Vital Product Data. More...

#include <stdio.h>
#include <errno.h>
#include <ipxe/nvs.h>
#include <ipxe/pci.h>
#include <ipxe/pcivpd.h>
#include <ipxe/nvo.h>
#include <ipxe/nvsvpd.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int nvs_vpd_read (struct nvs_device *nvs, unsigned int field, void *data, size_t len)
 Read from VPD field.
static int nvs_vpd_write (struct nvs_device *nvs, unsigned int field, const void *data, size_t len)
 Write to VPD field.
static int nvs_vpd_resize (struct nvs_device *nvs, unsigned int field, size_t len)
 Resize VPD field.
int nvs_vpd_init (struct nvs_vpd_device *nvsvpd, struct pci_device *pci)
 Initialise NVS VPD device.
static int nvs_vpd_nvo_resize (struct nvo_block *nvo, size_t len)
 Resize non-volatile option storage within NVS VPD device.
void nvs_vpd_nvo_init (struct nvs_vpd_device *nvsvpd, unsigned int field, struct nvo_block *nvo, struct refcnt *refcnt)
 Initialise non-volatile option storage within NVS VPD device.

Detailed Description

Non-Volatile Storage using Vital Product Data.

Definition in file nvsvpd.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int nvs_vpd_read ( struct nvs_device nvs,
unsigned int  field,
void *  data,
size_t  len 
) [static]

Read from VPD field.

Parameters:
nvsNVS device
fieldVPD field descriptor
dataData buffer
lenLength of data buffer
Return values:
rcReturn status code

Definition at line 49 of file nvsvpd.c.

References address, container_of, DBGC, ENXIO, max_len, pci_vpd::pci, PCI_ARGS, PCI_FMT, PCI_VPD_FIELD_ARGS, PCI_VPD_FIELD_FMT, pci_vpd_find(), pci_vpd_read(), rc, strerror(), and nvs_vpd_device::vpd.

Referenced by nvs_vpd_init().

                                                   {
        struct nvs_vpd_device *nvsvpd =
                container_of ( nvs, struct nvs_vpd_device, nvs );
        struct pci_device *pci = nvsvpd->vpd.pci;
        unsigned int address;
        size_t max_len;
        int rc;

        /* Allow reading non-existent field */
        if ( len == 0 )
                return 0;

        /* Locate VPD field */
        if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
                                   &max_len ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS VPD could not locate field "
                       PCI_VPD_FIELD_FMT ": %s\n", PCI_ARGS ( pci ),
                       PCI_VPD_FIELD_ARGS ( field ), strerror ( rc ) );
                return rc;
        }

        /* Sanity check */
        if ( len > max_len ) {
                DBGC ( pci, PCI_FMT " NVS VPD cannot read %#02zx bytes "
                       "beyond field " PCI_VPD_FIELD_FMT " at [%04x,%04zx)\n",
                       PCI_ARGS ( pci ), len, PCI_VPD_FIELD_ARGS ( field ),
                       address, ( address + max_len ) );
                return -ENXIO;
        }

        /* Read from VPD field */
        if ( ( rc = pci_vpd_read ( &nvsvpd->vpd, address, data, len ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS VPD could not read field "
                       PCI_VPD_FIELD_FMT " at [%04x,%04zx): %s\n",
                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
                       address, ( address + len ), strerror ( rc ) );
                return rc;
        }

        return 0;
}
static int nvs_vpd_write ( struct nvs_device nvs,
unsigned int  field,
const void *  data,
size_t  len 
) [static]

Write to VPD field.

Parameters:
nvsNVS device
fieldVPD field descriptor
dataData buffer
lenLength of data buffer
Return values:
rcReturn status code

Definition at line 101 of file nvsvpd.c.

References address, container_of, DBGC, ENXIO, max_len, pci_vpd::pci, PCI_ARGS, PCI_FMT, PCI_VPD_FIELD_ARGS, PCI_VPD_FIELD_FMT, pci_vpd_find(), pci_vpd_write(), rc, strerror(), and nvs_vpd_device::vpd.

Referenced by nvs_vpd_init().

                                                          {
        struct nvs_vpd_device *nvsvpd =
                container_of ( nvs, struct nvs_vpd_device, nvs );
        struct pci_device *pci = nvsvpd->vpd.pci;
        unsigned int address;
        size_t max_len;
        int rc;

        /* Locate VPD field */
        if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
                                   &max_len ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS VPD could not locate field "
                       PCI_VPD_FIELD_FMT ": %s\n", PCI_ARGS ( pci ),
                       PCI_VPD_FIELD_ARGS ( field ), strerror ( rc ) );
                return rc;
        }

        /* Sanity check */
        if ( len > max_len ) {
                DBGC ( pci, PCI_FMT " NVS VPD cannot write %#02zx bytes "
                       "beyond field " PCI_VPD_FIELD_FMT " at [%04x,%04zx)\n",
                       PCI_ARGS ( pci ), len, PCI_VPD_FIELD_ARGS ( field ),
                       address, ( address + max_len ) );
                return -ENXIO;
        }

        /* Write field */
        if ( ( rc = pci_vpd_write ( &nvsvpd->vpd, address, data,
                                    len ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS VPD could not write field "
                       PCI_VPD_FIELD_FMT " at [%04x,%04zx): %s\n",
                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
                       address, ( address + len ), strerror ( rc ) );
                return rc;
        }

        return 0;
}
static int nvs_vpd_resize ( struct nvs_device nvs,
unsigned int  field,
size_t  len 
) [static]

Resize VPD field.

Parameters:
nvsNVS device
fieldVPD field descriptor
dataData buffer
lenLength of data buffer
Return values:
rcReturn status code

Definition at line 150 of file nvsvpd.c.

References address, container_of, DBGC, pci_vpd::pci, PCI_ARGS, PCI_FMT, PCI_VPD_FIELD_ARGS, PCI_VPD_FIELD_FMT, pci_vpd_resize(), rc, strerror(), and nvs_vpd_device::vpd.

Referenced by nvs_vpd_nvo_resize().

                                         {
        struct nvs_vpd_device *nvsvpd =
                container_of ( nvs, struct nvs_vpd_device, nvs );
        struct pci_device *pci = nvsvpd->vpd.pci;
        unsigned int address;
        int rc;

        /* Resize field */
        if ( ( rc = pci_vpd_resize ( &nvsvpd->vpd, field, len,
                                     &address ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS VPD could not resize field "
                       PCI_VPD_FIELD_FMT " to %#02zx bytes: %s\n",
                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
                       len, strerror ( rc ) );
                return rc;
        }

        return 0;
}
int nvs_vpd_init ( struct nvs_vpd_device nvsvpd,
struct pci_device pci 
)

Initialise NVS VPD device.

Parameters:
nvsvpdNVS VPD device
pciPCI device
Return values:
rcReturn status code

Definition at line 178 of file nvsvpd.c.

References DBGC, nvs_vpd_device::nvs, nvs_vpd_read(), nvs_vpd_write(), PCI_ARGS, PCI_FMT, pci_vpd_init(), rc, nvs_device::read, strerror(), nvs_vpd_device::vpd, and nvs_device::write.

Referenced by hermon_probe().

                                                                           {
        int rc;

        /* Initialise VPD device */
        if ( ( rc = pci_vpd_init ( &nvsvpd->vpd, pci ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS could not initialise "
                       "VPD: %s\n", PCI_ARGS ( pci ), strerror ( rc ) );
                return rc;
        }

        /* Initialise NVS device */
        nvsvpd->nvs.read = nvs_vpd_read;
        nvsvpd->nvs.write = nvs_vpd_write;

        return 0;
}
static int nvs_vpd_nvo_resize ( struct nvo_block nvo,
size_t  len 
) [static]

Resize non-volatile option storage within NVS VPD device.

Parameters:
nvoNon-volatile options block
lenNew length
Return values:
rcReturn status code

Definition at line 202 of file nvsvpd.c.

References nvo_block::address, nvo_block::nvs, nvs_vpd_resize(), and rc.

Referenced by nvs_vpd_nvo_init().

                                                                    {
        int rc;

        /* Resize VPD field */
        if ( ( rc = nvs_vpd_resize ( nvo->nvs, nvo->address, len ) ) != 0 )
                return rc;

        return 0;
}
void nvs_vpd_nvo_init ( struct nvs_vpd_device nvsvpd,
unsigned int  field,
struct nvo_block nvo,
struct refcnt refcnt 
)

Initialise non-volatile option storage within NVS VPD device.

Parameters:
nvsvpdNVS VPD device
fieldVPD field descriptor
nvoNon-volatile options block
refcntContaining object reference counter, or NULL

Definition at line 220 of file nvsvpd.c.

References address, DBGC, len, nvo_init(), nvs_vpd_device::nvs, nvs_vpd_nvo_resize(), pci_vpd::pci, PCI_ARGS, PCI_FMT, PCI_VPD_FIELD_ARGS, PCI_VPD_FIELD_FMT, pci_vpd_find(), rc, and nvs_vpd_device::vpd.

Referenced by hermon_probe().

                                                                       {
        struct pci_device *pci = nvsvpd->vpd.pci;
        unsigned int address;
        size_t len;
        int rc;

        /* Locate VPD field, if present */
        if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
                                   &len ) ) != 0 ) {
                DBGC ( pci, PCI_FMT " NVS VPD field " PCI_VPD_FIELD_FMT
                       " not present; assuming empty\n",
                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ) );
                len = 0;
        }

        /* Initialise non-volatile options block */
        nvo_init ( nvo, &nvsvpd->nvs, field, len, nvs_vpd_nvo_resize, refcnt );
}