|
@@ -68,3 +68,46 @@ int nvs_read ( struct nvs_device *nvs, unsigned int address,
|
68
|
68
|
|
69
|
69
|
return 0;
|
70
|
70
|
}
|
|
71
|
+
|
|
72
|
+/**
|
|
73
|
+ * Write to non-volatile storage device
|
|
74
|
+ *
|
|
75
|
+ * @v nvs NVS device
|
|
76
|
+ * @v address Address to which to write
|
|
77
|
+ * @v data Data buffer
|
|
78
|
+ * @v len Length of data buffer
|
|
79
|
+ * @ret rc Return status code
|
|
80
|
+ */
|
|
81
|
+int nvs_write ( struct nvs_device *nvs, unsigned int address,
|
|
82
|
+ const void *data, size_t len ) {
|
|
83
|
+ size_t frag_len;
|
|
84
|
+ int rc;
|
|
85
|
+
|
|
86
|
+ /* We don't even attempt to handle buffer lengths that aren't
|
|
87
|
+ * an integral number of words.
|
|
88
|
+ */
|
|
89
|
+ assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 );
|
|
90
|
+
|
|
91
|
+ while ( len ) {
|
|
92
|
+
|
|
93
|
+ /* Calculate space remaining up to next block boundary */
|
|
94
|
+ frag_len = ( ( nvs->block_size -
|
|
95
|
+ ( address & ( nvs->block_size - 1 ) ) )
|
|
96
|
+ << nvs->word_len_log2 );
|
|
97
|
+
|
|
98
|
+ /* Limit to space remaining in buffer */
|
|
99
|
+ if ( frag_len > len )
|
|
100
|
+ frag_len = len;
|
|
101
|
+
|
|
102
|
+ /* Read this portion of the buffer from the device */
|
|
103
|
+ if ( ( rc = nvs->write ( nvs, address, data, frag_len ) ) != 0)
|
|
104
|
+ return rc;
|
|
105
|
+
|
|
106
|
+ /* Update parameters */
|
|
107
|
+ data += frag_len;
|
|
108
|
+ address += ( frag_len >> nvs->word_len_log2 );
|
|
109
|
+ len -= frag_len;
|
|
110
|
+ }
|
|
111
|
+
|
|
112
|
+ return 0;
|
|
113
|
+}
|