diff options
author | Michael Brown <mcb30@etherboot.org> | 2006-12-04 22:06:54 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2006-12-04 22:06:54 +0000 |
commit | 052ef6dc5a4ed2444aeda90af7b97c0a92e98e54 (patch) | |
tree | fc797c253eae123786d32f7eec1136e3d8868392 /src/drivers/nvs/nvs.c | |
parent | ab4e1dba3fe44a94c5bc425d737571bdc7b21fda (diff) | |
download | ipxe-052ef6dc5a4ed2444aeda90af7b97c0a92e98e54.tar.gz |
Added nvs_write(). This shares a lot of code in common with nvs_read();
this can probably be optimised down quite a lot.
Diffstat (limited to 'src/drivers/nvs/nvs.c')
-rw-r--r-- | src/drivers/nvs/nvs.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/drivers/nvs/nvs.c b/src/drivers/nvs/nvs.c index 3f22a0ee7..a566cdfde 100644 --- a/src/drivers/nvs/nvs.c +++ b/src/drivers/nvs/nvs.c @@ -68,3 +68,46 @@ int nvs_read ( struct nvs_device *nvs, unsigned int address, return 0; } + +/** + * Write to non-volatile storage device + * + * @v nvs NVS device + * @v address Address to which to write + * @v data Data buffer + * @v len Length of data buffer + * @ret rc Return status code + */ +int nvs_write ( struct nvs_device *nvs, unsigned int address, + const void *data, size_t len ) { + size_t frag_len; + int rc; + + /* We don't even attempt to handle buffer lengths that aren't + * an integral number of words. + */ + assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 ); + + while ( len ) { + + /* Calculate space remaining up to next block boundary */ + frag_len = ( ( nvs->block_size - + ( address & ( nvs->block_size - 1 ) ) ) + << nvs->word_len_log2 ); + + /* Limit to space remaining in buffer */ + if ( frag_len > len ) + frag_len = len; + + /* Read this portion of the buffer from the device */ + if ( ( rc = nvs->write ( nvs, address, data, frag_len ) ) != 0) + return rc; + + /* Update parameters */ + data += frag_len; + address += ( frag_len >> nvs->word_len_log2 ); + len -= frag_len; + } + + return 0; +} |