nvo.c File Reference

Non-volatile stored options. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <gpxe/dhcp.h>
#include <gpxe/nvs.h>
#include <gpxe/nvo.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static unsigned int nvo_checksum (struct nvo_block *nvo)
 Calculate checksum over non-volatile stored options.
static int nvo_load (struct nvo_block *nvo)
 Load non-volatile stored options from non-volatile storage device.
static int nvo_save (struct nvo_block *nvo)
 Save non-volatile stored options back to non-volatile storage device.
static void nvo_init_dhcpopts (struct nvo_block *nvo)
 Parse stored options.
static int nvo_store (struct settings *settings, struct setting *setting, const void *data, size_t len)
 Store value of NVO setting.
static int nvo_fetch (struct settings *settings, struct setting *setting, void *data, size_t len)
 Fetch value of NVO setting.
void nvo_init (struct nvo_block *nvo, struct nvs_device *nvs, struct nvo_fragment *fragments, struct refcnt *refcnt)
 Initialise non-volatile stored options.
int register_nvo (struct nvo_block *nvo, struct settings *parent)
 Register non-volatile stored options.
void unregister_nvo (struct nvo_block *nvo)
 Unregister non-volatile stored options.

Variables

static struct settings_operations nvo_settings_operations
 NVO settings operations.


Detailed Description

Non-volatile stored options.

Definition in file nvo.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static unsigned int nvo_checksum ( struct nvo_block nvo  )  [static]

Calculate checksum over non-volatile stored options.

Parameters:
nvo Non-volatile options block
Return values:
sum Checksum

Definition at line 41 of file nvo.c.

References nvo_block::data, and nvo_block::total_len.

Referenced by nvo_init_dhcpopts(), and nvo_save().

00041                                                            {
00042         uint8_t *data = nvo->data;
00043         uint8_t sum = 0;
00044         unsigned int i;
00045 
00046         for ( i = 0 ; i < nvo->total_len ; i++ ) {
00047                 sum += *(data++);
00048         }
00049         return sum;
00050 }

static int nvo_load ( struct nvo_block nvo  )  [static]

Load non-volatile stored options from non-volatile storage device.

Parameters:
nvo Non-volatile options block
Return values:
rc Return status code

Definition at line 58 of file nvo.c.

References nvo_fragment::address, nvo_block::data, DBGC, nvo_block::fragments, nvo_fragment::len, nvo_block::nvs, and nvs_read().

Referenced by register_nvo().

00058                                               {
00059         void *data = nvo->data;
00060         struct nvo_fragment *frag;
00061         int rc;
00062 
00063         /* Read data a fragment at a time */
00064         for ( frag = nvo->fragments ; frag->len ; frag++ ) {
00065                 if ( ( rc = nvs_read ( nvo->nvs, frag->address, data,
00066                                        frag->len ) ) != 0 ) {
00067                         DBGC ( nvo, "NVO %p could not read %zd bytes at "
00068                                "%#04x\n", nvo, frag->len, frag->address );
00069                         return rc;
00070                 }
00071                 data += frag->len;
00072         }
00073 
00074         DBGC ( nvo, "NVO %p loaded from non-volatile storage\n", nvo );
00075         return 0;
00076 }

static int nvo_save ( struct nvo_block nvo  )  [static]

Save non-volatile stored options back to non-volatile storage device.

Parameters:
nvo Non-volatile options block
Return values:
rc Return status code

Definition at line 84 of file nvo.c.

References nvo_fragment::address, nvo_block::data, DBGC, nvo_block::fragments, nvo_fragment::len, nvo_checksum(), nvo_block::nvs, and nvs_write().

Referenced by nvo_store().

00084                                               {
00085         void *data = nvo->data;
00086         uint8_t *checksum = data;
00087         struct nvo_fragment *frag;
00088         int rc;
00089 
00090         /* Recalculate checksum */
00091         *checksum -= nvo_checksum ( nvo );
00092 
00093         /* Write data a fragment at a time */
00094         for ( frag = nvo->fragments ; frag->len ; frag++ ) {
00095                 if ( ( rc = nvs_write ( nvo->nvs, frag->address, data,
00096                                         frag->len ) ) != 0 ) {
00097                         DBGC ( nvo, "NVO %p could not write %zd bytes at "
00098                                "%#04x\n", nvo, frag->len, frag->address );
00099                         return rc;
00100                 }
00101                 data += frag->len;
00102         }
00103 
00104         DBGC ( nvo, "NVO %p saved to non-volatile storage\n", nvo );
00105         return 0;
00106 }

static void nvo_init_dhcpopts ( struct nvo_block nvo  )  [static]

Parse stored options.

Parameters:
nvo Non-volatile options block
Verifies that the options data is valid, and configures the DHCP options block. If the data is not valid, it is replaced with an empty options block.

Definition at line 117 of file nvo.c.

References nvo_block::data, DBGC, dhcpopt_init(), nvo_block::dhcpopts, memset(), nvo_checksum(), and nvo_block::total_len.

Referenced by register_nvo().

00117                                                         {
00118         uint8_t *options_data;
00119         size_t options_len;
00120 
00121         /* Steal one byte for the checksum */
00122         options_data = ( nvo->data + 1 );
00123         options_len = ( nvo->total_len - 1 );
00124 
00125         /* If checksum fails, or options data starts with a zero,
00126          * assume the whole block is invalid.  This should capture the
00127          * case of random initial contents.
00128          */
00129         if ( ( nvo_checksum ( nvo ) != 0 ) || ( options_data[0] == 0 ) ) {
00130                 DBGC ( nvo, "NVO %p has checksum %02x and initial byte %02x; "
00131                        "assuming empty\n", nvo, nvo_checksum ( nvo ),
00132                        options_data[0] );
00133                 memset ( nvo->data, 0, nvo->total_len );
00134         }
00135 
00136         dhcpopt_init ( &nvo->dhcpopts, options_data, options_len );
00137 }

static int nvo_store ( struct settings settings,
struct setting setting,
const void *  data,
size_t  len 
) [static]

Store value of NVO setting.

Parameters:
settings Settings block
setting Setting to store
data Setting data, or NULL to clear setting
len Length of setting data
Return values:
rc Return status code

Definition at line 148 of file nvo.c.

References container_of, DBGC, dhcpopt_store(), nvo_block::dhcpopts, nvo_save(), strerror(), and setting::tag.

00149                                                       {
00150         struct nvo_block *nvo =
00151                 container_of ( settings, struct nvo_block, settings );
00152         int rc;
00153 
00154         /* Update stored options */
00155         if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, setting->tag,
00156                                     data, len ) ) != 0 ) {
00157                 DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n",
00158                        nvo, len, strerror ( rc ) );
00159                 return rc;
00160         }
00161 
00162         /* Save updated options to NVS */
00163         if ( ( rc = nvo_save ( nvo ) ) != 0 )
00164                 return rc;
00165 
00166         return 0;
00167 }

static int nvo_fetch ( struct settings settings,
struct setting setting,
void *  data,
size_t  len 
) [static]

Fetch value of NVO setting.

Parameters:
settings Settings block
setting Setting to fetch
data Buffer to fill with setting data
len Length of buffer
Return values:
len Length of setting data, or negative error
The actual length of the setting will be returned even if the buffer was too small.

Definition at line 181 of file nvo.c.

References container_of, dhcpopt_fetch(), nvo_block::dhcpopts, and setting::tag.

00182                                                 {
00183         struct nvo_block *nvo =
00184                 container_of ( settings, struct nvo_block, settings );
00185 
00186         return dhcpopt_fetch ( &nvo->dhcpopts, setting->tag, data, len );
00187 }

void nvo_init ( struct nvo_block nvo,
struct nvs_device nvs,
struct nvo_fragment fragments,
struct refcnt refcnt 
)

Initialise non-volatile stored options.

Parameters:
nvo Non-volatile options block
nvs Underlying non-volatile storage device
fragments List of option-containing fragments
refcnt Containing object reference counter, or NULL

Definition at line 203 of file nvo.c.

References nvo_block::fragments, nvo_block::nvs, nvo_block::settings, and settings_init().

Referenced by falcon_probe_spi(), and rtl_init_eeprom().

00204                                                                         {
00205         nvo->nvs = nvs;
00206         nvo->fragments = fragments;
00207         settings_init ( &nvo->settings, &nvo_settings_operations, refcnt,
00208                         "nvo", 0 );
00209 }

int register_nvo ( struct nvo_block nvo,
struct settings parent 
)

Register non-volatile stored options.

Parameters:
nvo Non-volatile options block
parent Parent settings block, or NULL
Return values:
rc Return status code

Definition at line 218 of file nvo.c.

References nvo_block::data, DBGC, ENOMEM, nvo_block::fragments, free(), nvo_fragment::len, malloc(), NULL, nvo_init_dhcpopts(), nvo_load(), register_settings(), nvo_block::settings, and nvo_block::total_len.

Referenced by efab_probe(), and rtl_probe().

00218                                                                     {
00219         struct nvo_fragment *fragment = nvo->fragments;
00220         int rc;
00221 
00222         /* Calculate total length of all fragments */
00223         for ( fragment = nvo->fragments ; fragment->len ; fragment++ )
00224                 nvo->total_len += fragment->len;
00225 
00226         /* Allocate memory for options and read in from NVS */
00227         nvo->data = malloc ( nvo->total_len );
00228         if ( ! nvo->data ) {
00229                 DBGC ( nvo, "NVO %p could not allocate %zd bytes\n",
00230                        nvo, nvo->total_len );
00231                 rc = -ENOMEM;
00232                 goto err_malloc;
00233         }
00234         if ( ( rc = nvo_load ( nvo ) ) != 0 )
00235                 goto err_load;
00236 
00237         /* Verify and register options */
00238         nvo_init_dhcpopts ( nvo );
00239         if ( ( rc = register_settings ( &nvo->settings, parent ) ) != 0 )
00240                 goto err_register;
00241 
00242         DBGC ( nvo, "NVO %p registered\n", nvo );
00243         return 0;
00244         
00245  err_register:
00246  err_load:
00247         free ( nvo->data );
00248         nvo->data = NULL;
00249  err_malloc:
00250         return rc;
00251 }

void unregister_nvo ( struct nvo_block nvo  ) 

Unregister non-volatile stored options.

Parameters:
nvo Non-volatile options block

Definition at line 258 of file nvo.c.

References nvo_block::data, DBGC, free(), NULL, nvo_block::settings, and unregister_settings().

Referenced by efab_remove(), and rtl_remove().

00258                                               {
00259         unregister_settings ( &nvo->settings );
00260         free ( nvo->data );
00261         nvo->data = NULL;
00262         DBGC ( nvo, "NVO %p unregistered\n", nvo );
00263 }


Variable Documentation

Initial value:

 {
        .store = nvo_store,
        .fetch = nvo_fetch,
}
NVO settings operations.

Definition at line 190 of file nvo.c.


Generated on Tue Apr 6 20:01:14 2010 for gPXE by  doxygen 1.5.7.1