Browse Source

Added nvo_save()

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
ab4e1dba3f
2 changed files with 64 additions and 30 deletions
  1. 58
    30
      src/core/nvo.c
  2. 6
    0
      src/include/gpxe/nvo.h

+ 58
- 30
src/core/nvo.c View File

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
  * @v nvo		Non-volatile options block
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
  * @v nvo		Non-volatile options block
51
  * @v nvo		Non-volatile options block
52
  * @ret rc		Return status code
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
 	void *data = nvo->options->data;
55
 	void *data = nvo->options->data;
56
+	struct nvo_fragment *fragment;
57
 	int rc;
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
 		if ( ( rc = nvs_read ( nvo->nvs, fragment->address,
61
 		if ( ( rc = nvs_read ( nvo->nvs, fragment->address,
61
 				       data, fragment->len ) ) != 0 ) {
62
 				       data, fragment->len ) ) != 0 ) {
62
 			DBG ( "NVO %p could not read %zd bytes at %#04x\n",
63
 			DBG ( "NVO %p could not read %zd bytes at %#04x\n",
69
 	return 0;
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
  * Parse stored options
103
  * Parse stored options
74
  *
104
  *
75
  * @v nvo		Non-volatile options block
105
  * @v nvo		Non-volatile options block
76
- * @v total_len		Total length of options data
77
  *
106
  *
78
  * Verifies that the options data is valid, and configures the DHCP
107
  * Verifies that the options data is valid, and configures the DHCP
79
  * options block.  If the data is not valid, it is replaced with an
108
  * options block.  If the data is not valid, it is replaced with an
80
  * empty options block.
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
 	struct dhcp_option_block *options = nvo->options;
112
 	struct dhcp_option_block *options = nvo->options;
84
 	struct dhcp_option *option;
113
 	struct dhcp_option *option;
85
-	uint8_t sum;
86
-	unsigned int i;
87
 
114
 
88
 	/* Steal one byte for the checksum */
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
 	/* Verify checksum over whole block */
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
 		DBG ( "NVO %p has bad checksum %02x; assuming empty\n",
120
 		DBG ( "NVO %p has bad checksum %02x; assuming empty\n",
97
-		      nvo, sum );
121
+		      nvo, nvo_checksum ( nvo ) );
98
 		goto empty;
122
 		goto empty;
99
 	}
123
 	}
100
 
124
 
134
  * @ret rc		Return status code
158
  * @ret rc		Return status code
135
  */
159
  */
136
 int nvo_register ( struct nvo_block *nvo ) {
160
 int nvo_register ( struct nvo_block *nvo ) {
137
-	size_t total_len;
161
+	struct nvo_fragment *fragment = nvo->fragments;
138
 	int rc;
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
 	/* Allocate memory for options and read in from NVS */
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
 	if ( ! nvo->options ) {
172
 	if ( ! nvo->options ) {
144
 		DBG ( "NVO %p could not allocate %zd bytes\n",
173
 		DBG ( "NVO %p could not allocate %zd bytes\n",
145
-		      nvo, total_len );
174
+		      nvo, nvo->total_len );
146
 		rc = -ENOMEM;
175
 		rc = -ENOMEM;
147
 		goto err;
176
 		goto err;
148
 	}
177
 	}
149
-
150
-	if ( ( rc = nvo_read ( nvo ) ) != 0 )
178
+	if ( ( rc = nvo_load ( nvo ) ) != 0 )
151
 		goto err;
179
 		goto err;
152
 
180
 
153
 	/* Verify and register options */
181
 	/* Verify and register options */
154
-	nvo_init_dhcp ( nvo, total_len );
182
+	nvo_init_dhcp ( nvo );
155
 	register_dhcp_options ( nvo->options );
183
 	register_dhcp_options ( nvo->options );
156
 
184
 
157
 	return 0;
185
 	return 0;

+ 6
- 0
src/include/gpxe/nvo.h View File

33
 	 * The list is terminated by a fragment with a length of zero.
33
 	 * The list is terminated by a fragment with a length of zero.
34
 	 */
34
 	 */
35
 	struct nvo_fragment *fragments;
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
 	/** DHCP options block */
41
 	/** DHCP options block */
37
 	struct dhcp_option_block *options;
42
 	struct dhcp_option_block *options;
38
 };
43
 };
39
 
44
 
40
 extern int nvo_register ( struct nvo_block *nvo );
45
 extern int nvo_register ( struct nvo_block *nvo );
46
+extern int nvo_save ( struct nvo_block *nvo );
41
 extern void nvo_unregister ( struct nvo_block *nvo );
47
 extern void nvo_unregister ( struct nvo_block *nvo );
42
 
48
 
43
 #endif /* _GPXE_NVO_H */
49
 #endif /* _GPXE_NVO_H */

Loading…
Cancel
Save