瀏覽代碼

Added nvo_save()

tags/v0.9.3
Michael Brown 17 年之前
父節點
當前提交
ab4e1dba3f
共有 2 個檔案被更改,包括 64 行新增30 行删除
  1. 58
    30
      src/core/nvo.c
  2. 6
    0
      src/include/gpxe/nvo.h

+ 58
- 30
src/core/nvo.c 查看文件

@@ -29,34 +29,35 @@
29 29
  */
30 30
 
31 31
 /**
32
- * Calculate total length of non-volatile stored options
32
+ * Calculate checksum over non-volatile stored options
33 33
  *
34 34
  * @v nvo		Non-volatile options block
35
- * @ret total_len	Total length of all fragments
35
+ * @ret sum		Checksum
36 36
  */
37
-static size_t nvo_total_len ( struct nvo_block *nvo ) {
38
-	struct nvo_fragment *fragment = nvo->fragments;
39
-	size_t total_len = 0;
37
+static unsigned int nvo_checksum ( struct nvo_block *nvo ) {
38
+	uint8_t *data = nvo->options->data;
39
+	uint8_t sum = 0;
40
+	unsigned int i;
40 41
 
41
-	for ( ; fragment->len ; fragment++ ) {
42
-		total_len += fragment->len;
42
+	for ( i = 0 ; i < nvo->total_len ; i++ ) {
43
+		sum += *(data++);
43 44
 	}
44
-
45
-	return total_len;
45
+	return sum;
46 46
 }
47 47
 
48 48
 /**
49
- * Read non-volatile stored options from non-volatile storage device
49
+ * Load non-volatile stored options from non-volatile storage device
50 50
  *
51 51
  * @v nvo		Non-volatile options block
52 52
  * @ret rc		Return status code
53 53
  */
54
-static int nvo_read ( struct nvo_block *nvo ) {
55
-	struct nvo_fragment *fragment = nvo->fragments;
54
+static int nvo_load ( struct nvo_block *nvo ) {
56 55
 	void *data = nvo->options->data;
56
+	struct nvo_fragment *fragment;
57 57
 	int rc;
58 58
 
59
-	for ( ; fragment->len ; fragment++ ) {
59
+	/* Read data a fragment at a time */
60
+	for ( fragment = nvo->fragments ; fragment->len ; fragment++ ) {
60 61
 		if ( ( rc = nvs_read ( nvo->nvs, fragment->address,
61 62
 				       data, fragment->len ) ) != 0 ) {
62 63
 			DBG ( "NVO %p could not read %zd bytes at %#04x\n",
@@ -69,32 +70,55 @@ static int nvo_read ( struct nvo_block *nvo ) {
69 70
 	return 0;
70 71
 }
71 72
 
73
+/**
74
+ * Save non-volatile stored options back to non-volatile storage device
75
+ *
76
+ * @v nvo		Non-volatile options block
77
+ * @ret rc		Return status code
78
+ */
79
+int nvo_save ( struct nvo_block *nvo ) {
80
+	void *data = nvo->options->data;
81
+	uint8_t *checksum = ( data + nvo->total_len - 1 );
82
+	struct nvo_fragment *fragment;
83
+	int rc;
84
+
85
+	/* Recalculate checksum */
86
+	checksum -= nvo_checksum ( nvo );
87
+
88
+	/* Write data a fragment at a time */
89
+	for ( fragment = nvo->fragments ; fragment->len ; fragment++ ) {
90
+		if ( ( rc = nvs_write ( nvo->nvs, fragment->address,
91
+					data, fragment->len ) ) != 0 ) {
92
+			DBG ( "NVO %p could not write %zd bytes at %#04x\n",
93
+			      nvo, fragment->len, fragment->address );
94
+			return rc;
95
+		}
96
+		data += fragment->len;
97
+	}
98
+	
99
+	return 0;
100
+}
101
+
72 102
 /**
73 103
  * Parse stored options
74 104
  *
75 105
  * @v nvo		Non-volatile options block
76
- * @v total_len		Total length of options data
77 106
  *
78 107
  * Verifies that the options data is valid, and configures the DHCP
79 108
  * options block.  If the data is not valid, it is replaced with an
80 109
  * empty options block.
81 110
  */
82
-static void nvo_init_dhcp ( struct nvo_block *nvo, size_t total_len ) {
111
+static void nvo_init_dhcp ( struct nvo_block *nvo ) {
83 112
 	struct dhcp_option_block *options = nvo->options;
84 113
 	struct dhcp_option *option;
85
-	uint8_t sum;
86
-	unsigned int i;
87 114
 
88 115
 	/* Steal one byte for the checksum */
89
-	options->max_len = ( total_len - 1 );
116
+	options->max_len = ( nvo->total_len - 1 );
90 117
 
91 118
 	/* Verify checksum over whole block */
92
-	for ( sum = 0, i = 0 ; i < total_len ; i++ ) {
93
-		sum += * ( ( uint8_t * ) ( options->data + i ) );
94
-	}
95
-	if ( sum != 0 ) {
119
+	if ( nvo_checksum ( nvo ) != 0 ) {
96 120
 		DBG ( "NVO %p has bad checksum %02x; assuming empty\n",
97
-		      nvo, sum );
121
+		      nvo, nvo_checksum ( nvo ) );
98 122
 		goto empty;
99 123
 	}
100 124
 
@@ -134,24 +158,28 @@ static void nvo_init_dhcp ( struct nvo_block *nvo, size_t total_len ) {
134 158
  * @ret rc		Return status code
135 159
  */
136 160
 int nvo_register ( struct nvo_block *nvo ) {
137
-	size_t total_len;
161
+	struct nvo_fragment *fragment = nvo->fragments;
138 162
 	int rc;
139 163
 
164
+	/* Calculate total length of all fragments */
165
+	nvo->total_len = 0;
166
+	for ( fragment = nvo->fragments ; fragment->len ; fragment++ ) {
167
+		nvo->total_len += fragment->len;
168
+	}
169
+
140 170
 	/* Allocate memory for options and read in from NVS */
141
-	total_len = nvo_total_len ( nvo );
142
-	nvo->options = alloc_dhcp_options ( total_len );
171
+	nvo->options = alloc_dhcp_options ( nvo->total_len );
143 172
 	if ( ! nvo->options ) {
144 173
 		DBG ( "NVO %p could not allocate %zd bytes\n",
145
-		      nvo, total_len );
174
+		      nvo, nvo->total_len );
146 175
 		rc = -ENOMEM;
147 176
 		goto err;
148 177
 	}
149
-
150
-	if ( ( rc = nvo_read ( nvo ) ) != 0 )
178
+	if ( ( rc = nvo_load ( nvo ) ) != 0 )
151 179
 		goto err;
152 180
 
153 181
 	/* Verify and register options */
154
-	nvo_init_dhcp ( nvo, total_len );
182
+	nvo_init_dhcp ( nvo );
155 183
 	register_dhcp_options ( nvo->options );
156 184
 
157 185
 	return 0;

+ 6
- 0
src/include/gpxe/nvo.h 查看文件

@@ -33,11 +33,17 @@ struct nvo_block {
33 33
 	 * The list is terminated by a fragment with a length of zero.
34 34
 	 */
35 35
 	struct nvo_fragment *fragments;
36
+	/** Total length of all fragments
37
+	 *
38
+	 * This field is filled in by nvo_register().
39
+	 */
40
+	size_t total_len;
36 41
 	/** DHCP options block */
37 42
 	struct dhcp_option_block *options;
38 43
 };
39 44
 
40 45
 extern int nvo_register ( struct nvo_block *nvo );
46
+extern int nvo_save ( struct nvo_block *nvo );
41 47
 extern void nvo_unregister ( struct nvo_block *nvo );
42 48
 
43 49
 #endif /* _GPXE_NVO_H */

Loading…
取消
儲存