nvs.c File Reference

Non-volatile storage. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <gpxe/nvs.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
int nvs_read (struct nvs_device *nvs, unsigned int address, void *data, size_t len)
 Read from non-volatile storage device.
static int nvs_verify (struct nvs_device *nvs, unsigned int address, const void *data, size_t len)
 Verify content of non-volatile storage device.
int nvs_write (struct nvs_device *nvs, unsigned int address, const void *data, size_t len)
 Write to non-volatile storage device.


Detailed Description

Non-volatile storage.

Definition in file nvs.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

int nvs_read ( struct nvs_device nvs,
unsigned int  address,
void *  data,
size_t  len 
)

Read from non-volatile storage device.

Parameters:
nvs NVS device
address Address from which to read
data Data buffer
len Length of data buffer
Return values:
rc Return status code

Definition at line 42 of file nvs.c.

References assert, nvs_device::block_size, nvs_device::read, and nvs_device::word_len_log2.

Referenced by a3c90x_internal_ReadEepromContents(), falcon_probe_nvram(), ifec_pci_probe(), natsemi_probe(), nvo_load(), nvs_verify(), rtl818x_probe(), and rtl_probe().

00043                                         {
00044         size_t frag_len;
00045         int rc;
00046 
00047         /* We don't even attempt to handle buffer lengths that aren't
00048          * an integral number of words.
00049          */
00050         assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 );
00051 
00052         while ( len ) {
00053 
00054                 /* Calculate space remaining up to next block boundary */
00055                 frag_len = ( ( nvs->block_size -
00056                                ( address & ( nvs->block_size - 1 ) ) )
00057                              << nvs->word_len_log2 );
00058 
00059                 /* Limit to space remaining in buffer */
00060                 if ( frag_len > len )
00061                         frag_len = len;
00062 
00063                 /* Read this portion of the buffer from the device */
00064                 if ( ( rc = nvs->read ( nvs, address, data, frag_len ) ) != 0 )
00065                         return rc;
00066 
00067                 /* Update parameters */
00068                 data += frag_len;
00069                 address += ( frag_len >> nvs->word_len_log2 );
00070                 len -= frag_len;
00071         }
00072 
00073         return 0;
00074 }

static int nvs_verify ( struct nvs_device nvs,
unsigned int  address,
const void *  data,
size_t  len 
) [static]

Verify content of non-volatile storage device.

Parameters:
nvs NVS device
address Address from which to read
data Data to compare against
len Length of data buffer
Return values:
rc Return status code

Definition at line 85 of file nvs.c.

References DBG, EIO, memcmp(), and nvs_read().

Referenced by nvs_write().

00086                                                        {
00087         uint8_t read_data[len];
00088         int rc;
00089 
00090         /* Read data into temporary buffer */
00091         if ( ( rc = nvs_read ( nvs, address, read_data, len ) ) != 0 )
00092                 return rc;
00093 
00094         /* Compare data */
00095         if ( memcmp ( data, read_data, len ) != 0 ) {
00096                 DBG ( "NVS %p verification failed at %#04x+%zd\n",
00097                       nvs, address, len );
00098                 return -EIO;
00099         }
00100 
00101         return 0;
00102 }

int nvs_write ( struct nvs_device nvs,
unsigned int  address,
const void *  data,
size_t  len 
)

Write to non-volatile storage device.

Parameters:
nvs NVS device
address Address to which to write
data Data buffer
len Length of data buffer
Return values:
rc Return status code

Definition at line 113 of file nvs.c.

References assert, nvs_device::block_size, nvs_verify(), nvs_device::word_len_log2, and nvs_device::write.

Referenced by nvo_save().

00114                                                {
00115         size_t frag_len;
00116         int rc;
00117 
00118         /* We don't even attempt to handle buffer lengths that aren't
00119          * an integral number of words.
00120          */
00121         assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 );
00122 
00123         while ( len ) {
00124 
00125                 /* Calculate space remaining up to next block boundary */
00126                 frag_len = ( ( nvs->block_size -
00127                                ( address & ( nvs->block_size - 1 ) ) )
00128                              << nvs->word_len_log2 );
00129 
00130                 /* Limit to space remaining in buffer */
00131                 if ( frag_len > len )
00132                         frag_len = len;
00133 
00134                 /* Write this portion of the buffer to the device */
00135                 if ( ( rc = nvs->write ( nvs, address, data, frag_len ) ) != 0)
00136                         return rc;
00137 
00138                 /* Read back and verify data */
00139                 if ( ( rc = nvs_verify ( nvs, address, data, frag_len ) ) != 0)
00140                         return rc;
00141 
00142                 /* Update parameters */
00143                 data += frag_len;
00144                 address += ( frag_len >> nvs->word_len_log2 );
00145                 len -= frag_len;
00146         }
00147 
00148         return 0;
00149 }


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