iPXE
nvsvpd.c File Reference

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

#include <stdio.h>
#include <string.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()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ nvs_vpd_read()

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 50 of file nvsvpd.c.

51 {
52 struct nvs_vpd_device *nvsvpd =
54 struct pci_device *pci = nvsvpd->vpd.pci;
55 unsigned int address;
56 size_t max_len;
57 int rc;
58
59 /* Allow reading non-existent field */
60 if ( len == 0 )
61 return 0;
62
63 /* Locate VPD field */
64 if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
65 &max_len ) ) != 0 ) {
66 DBGC ( pci, PCI_FMT " NVS VPD could not locate field "
67 PCI_VPD_FIELD_FMT ": %s\n", PCI_ARGS ( pci ),
68 PCI_VPD_FIELD_ARGS ( field ), strerror ( rc ) );
69 return rc;
70 }
71
72 /* Sanity check */
73 if ( len > max_len ) {
74 DBGC ( pci, PCI_FMT " NVS VPD cannot read %#02zx bytes "
75 "beyond field " PCI_VPD_FIELD_FMT " at [%04x,%04zx)\n",
76 PCI_ARGS ( pci ), len, PCI_VPD_FIELD_ARGS ( field ),
77 address, ( address + max_len ) );
78 return -ENXIO;
79 }
80
81 /* Read from VPD field */
82 if ( ( rc = pci_vpd_read ( &nvsvpd->vpd, address, data, len ) ) != 0 ) {
83 DBGC ( pci, PCI_FMT " NVS VPD could not read field "
84 PCI_VPD_FIELD_FMT " at [%04x,%04zx): %s\n",
85 PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
86 address, ( address + len ), strerror ( rc ) );
87 return rc;
88 }
89
90 return 0;
91}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint64_t address
Base address.
Definition ena.h:13
#define DBGC(...)
Definition compiler.h:505
#define ENXIO
No such device or address.
Definition errno.h:600
#define PCI_FMT
PCI device debug message format.
Definition pci.h:312
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:315
int pci_vpd_read(struct pci_vpd *vpd, unsigned int address, void *buf, size_t len)
Read PCI VPD.
Definition pcivpd.c:183
int pci_vpd_find(struct pci_vpd *vpd, unsigned int field, unsigned int *address, size_t *len)
Locate PCI VPD field.
Definition pcivpd.c:353
#define PCI_VPD_FIELD_ARGS(field)
PCI VPD field debug message arguments.
Definition pcivpd.h:73
#define PCI_VPD_FIELD_FMT
PCI VPD field debug message format.
Definition pcivpd.h:70
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An NVS VPD device.
Definition nvsvpd.h:20
struct pci_vpd vpd
PCI VPD device.
Definition nvsvpd.h:24
struct nvs_device nvs
NVS device.
Definition nvsvpd.h:22
A PCI device.
Definition pci.h:211
struct pci_device * pci
PCI device.
Definition pcivpd.h:132

References address, container_of, data, DBGC, ENXIO, len, nvs_vpd_device::nvs, 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().

◆ nvs_vpd_write()

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 102 of file nvsvpd.c.

103 {
104 struct nvs_vpd_device *nvsvpd =
105 container_of ( nvs, struct nvs_vpd_device, nvs );
106 struct pci_device *pci = nvsvpd->vpd.pci;
107 unsigned int address;
108 size_t max_len;
109 int rc;
110
111 /* Locate VPD field */
112 if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
113 &max_len ) ) != 0 ) {
114 DBGC ( pci, PCI_FMT " NVS VPD could not locate field "
115 PCI_VPD_FIELD_FMT ": %s\n", PCI_ARGS ( pci ),
116 PCI_VPD_FIELD_ARGS ( field ), strerror ( rc ) );
117 return rc;
118 }
119
120 /* Sanity check */
121 if ( len > max_len ) {
122 DBGC ( pci, PCI_FMT " NVS VPD cannot write %#02zx bytes "
123 "beyond field " PCI_VPD_FIELD_FMT " at [%04x,%04zx)\n",
124 PCI_ARGS ( pci ), len, PCI_VPD_FIELD_ARGS ( field ),
125 address, ( address + max_len ) );
126 return -ENXIO;
127 }
128
129 /* Write field */
130 if ( ( rc = pci_vpd_write ( &nvsvpd->vpd, address, data,
131 len ) ) != 0 ) {
132 DBGC ( pci, PCI_FMT " NVS VPD could not write field "
133 PCI_VPD_FIELD_FMT " at [%04x,%04zx): %s\n",
134 PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
135 address, ( address + len ), strerror ( rc ) );
136 return rc;
137 }
138
139 return 0;
140}
int pci_vpd_write(struct pci_vpd *vpd, unsigned int address, const void *buf, size_t len)
Write PCI VPD.
Definition pcivpd.c:225

References address, container_of, data, DBGC, ENXIO, len, nvs_vpd_device::nvs, 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().

◆ nvs_vpd_resize()

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 151 of file nvsvpd.c.

152 {
153 struct nvs_vpd_device *nvsvpd =
154 container_of ( nvs, struct nvs_vpd_device, nvs );
155 struct pci_device *pci = nvsvpd->vpd.pci;
156 unsigned int address;
157 int rc;
158
159 /* Resize field */
160 if ( ( rc = pci_vpd_resize ( &nvsvpd->vpd, field, len,
161 &address ) ) != 0 ) {
162 DBGC ( pci, PCI_FMT " NVS VPD could not resize field "
163 PCI_VPD_FIELD_FMT " to %#02zx bytes: %s\n",
164 PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
165 len, strerror ( rc ) );
166 return rc;
167 }
168
169 return 0;
170}
int pci_vpd_resize(struct pci_vpd *vpd, unsigned int field, size_t len, unsigned int *address)
Resize VPD field.
Definition pcivpd.c:411

References address, container_of, DBGC, len, nvs_vpd_device::nvs, 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().

◆ nvs_vpd_init()

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 179 of file nvsvpd.c.

179 {
180 int rc;
181
182 /* Initialise VPD device */
183 if ( ( rc = pci_vpd_init ( &nvsvpd->vpd, pci ) ) != 0 ) {
184 DBGC ( pci, PCI_FMT " NVS could not initialise "
185 "VPD: %s\n", PCI_ARGS ( pci ), strerror ( rc ) );
186 return rc;
187 }
188
189 /* Initialise NVS device */
190 nvsvpd->nvs.read = nvs_vpd_read;
191 nvsvpd->nvs.write = nvs_vpd_write;
192
193 return 0;
194}
static int nvs_vpd_write(struct nvs_device *nvs, unsigned int field, const void *data, size_t len)
Write to VPD field.
Definition nvsvpd.c:102
static int nvs_vpd_read(struct nvs_device *nvs, unsigned int field, void *data, size_t len)
Read from VPD field.
Definition nvsvpd.c:50
int pci_vpd_init(struct pci_vpd *vpd, struct pci_device *pci)
Initialise PCI Vital Product Data.
Definition pcivpd.c:48
int(* read)(struct nvs_device *nvs, unsigned int address, void *data, size_t len)
Read data from device.
Definition nvs.h:48
int(* write)(struct nvs_device *nvs, unsigned int address, const void *data, size_t len)
Write data to device.
Definition nvs.h:60

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().

◆ nvs_vpd_nvo_resize()

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 203 of file nvsvpd.c.

203 {
204 int rc;
205
206 /* Resize VPD field */
207 if ( ( rc = nvs_vpd_resize ( nvo->nvs, nvo->address, len ) ) != 0 )
208 return rc;
209
210 return 0;
211}
static int nvs_vpd_resize(struct nvs_device *nvs, unsigned int field, size_t len)
Resize VPD field.
Definition nvsvpd.c:151
unsigned int address
Address within NVS device.
Definition nvo.h:29
struct nvs_device * nvs
Underlying non-volatile storage device.
Definition nvo.h:27

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

Referenced by nvs_vpd_nvo_init().

◆ nvs_vpd_nvo_init()

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 221 of file nvsvpd.c.

222 {
223 struct pci_device *pci = nvsvpd->vpd.pci;
224 unsigned int address;
225 size_t len;
226 int rc;
227
228 /* Locate VPD field, if present */
229 if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
230 &len ) ) != 0 ) {
231 DBGC ( pci, PCI_FMT " NVS VPD field " PCI_VPD_FIELD_FMT
232 " not present; assuming empty\n",
233 PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ) );
234 len = 0;
235 }
236
237 /* Initialise non-volatile options block */
238 nvo_init ( nvo, &nvsvpd->nvs, field, len, nvs_vpd_nvo_resize, refcnt );
239}
void nvo_init(struct nvo_block *nvo, struct nvs_device *nvs, size_t address, size_t len, int(*resize)(struct nvo_block *nvo, size_t len), struct refcnt *refcnt)
Initialise non-volatile stored options.
Definition nvo.c:274
static int nvs_vpd_nvo_resize(struct nvo_block *nvo, size_t len)
Resize non-volatile option storage within NVS VPD device.
Definition nvsvpd.c:203
A reference counter.
Definition refcnt.h:27

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().