瀏覽代碼

[settings] Allow for arbitrarily-named settings

This provides a mechanism for using arbitrarily-named variables within
gPXE, using the existing syntax for settings.
tags/v0.9.8
Michael Brown 15 年之前
父節點
當前提交
3c06277bbb
共有 6 個檔案被更改,包括 297 行新增99 行删除
  1. 241
    55
      src/core/settings.c
  2. 16
    3
      src/include/gpxe/netdevice.h
  3. 24
    17
      src/include/gpxe/settings.h
  4. 0
    17
      src/interface/smbios/smbios_settings.c
  5. 14
    4
      src/net/netdev_settings.c
  6. 2
    3
      src/net/netdevice.c

+ 241
- 55
src/core/settings.c 查看文件

41
 
41
 
42
 /******************************************************************************
42
 /******************************************************************************
43
  *
43
  *
44
- * Registered settings blocks
44
+ * Generic settings blocks
45
  *
45
  *
46
  ******************************************************************************
46
  ******************************************************************************
47
  */
47
  */
48
 
48
 
49
 /**
49
 /**
50
- * Store value of simple setting
50
+ * A generic setting
51
+ *
52
+ */
53
+struct generic_setting {
54
+	/** List of generic settings */
55
+	struct list_head list;
56
+	/** Setting */
57
+	struct setting setting;
58
+	/** Size of setting name */
59
+	size_t name_len;
60
+	/** Size of setting data */
61
+	size_t data_len;
62
+};
63
+
64
+/**
65
+ * Get generic setting name
66
+ *
67
+ * @v generic		Generic setting
68
+ * @ret name		Generic setting name
69
+ */
70
+static inline void * generic_setting_name ( struct generic_setting *generic ) {
71
+	return ( ( ( void * ) generic ) + sizeof ( *generic ) );
72
+}
73
+
74
+/**
75
+ * Get generic setting data
76
+ *
77
+ * @v generic		Generic setting
78
+ * @ret data		Generic setting data
79
+ */
80
+static inline void * generic_setting_data ( struct generic_setting *generic ) {
81
+	return ( ( ( void * ) generic ) + sizeof ( *generic ) +
82
+		 generic->name_len );
83
+}
84
+
85
+/**
86
+ * Find generic setting
51
  *
87
  *
52
- * @v options		DHCP option block
88
+ * @v generics		Generic settings block
89
+ * @v setting		Setting to find
90
+ * @ret generic		Generic setting, or NULL
91
+ */
92
+static struct generic_setting *
93
+find_generic_setting ( struct generic_settings *generics,
94
+		       struct setting *setting ) {
95
+	struct generic_setting *generic;
96
+
97
+	list_for_each_entry ( generic, &generics->list, list ) {
98
+		if ( setting_cmp ( &generic->setting, setting ) == 0 )
99
+			return generic;
100
+	}
101
+	return NULL;
102
+}
103
+
104
+/**
105
+ * Store value of generic setting
106
+ *
107
+ * @v settings		Settings block
53
  * @v setting		Setting to store
108
  * @v setting		Setting to store
54
  * @v data		Setting data, or NULL to clear setting
109
  * @v data		Setting data, or NULL to clear setting
55
  * @v len		Length of setting data
110
  * @v len		Length of setting data
56
  * @ret rc		Return status code
111
  * @ret rc		Return status code
57
  */
112
  */
58
-int simple_settings_store ( struct settings *settings, struct setting *setting,
59
-			    const void *data, size_t len ) {
60
-	struct simple_settings *simple =
61
-		container_of ( settings, struct simple_settings, settings );
62
-	return dhcpopt_extensible_store ( &simple->dhcpopts, setting->tag,
63
-					  data, len );
113
+int generic_settings_store ( struct settings *settings,
114
+			     struct setting *setting,
115
+			     const void *data, size_t len ) {
116
+	struct generic_settings *generics =
117
+		container_of ( settings, struct generic_settings, settings );
118
+	struct generic_setting *old;
119
+	struct generic_setting *new = NULL;
120
+	size_t name_len;
121
+
122
+	/* Identify existing generic setting, if any */
123
+	old = find_generic_setting ( generics, setting );
124
+
125
+	/* Create new generic setting, if required */
126
+	if ( len ) {
127
+		/* Allocate new generic setting */
128
+		name_len = ( strlen ( setting->name ) + 1 );
129
+		new = zalloc ( sizeof ( *new ) + name_len + len );
130
+		if ( ! new )
131
+			return -ENOMEM;
132
+
133
+		/* Populate new generic setting */
134
+		new->name_len = name_len;
135
+		new->data_len = len;
136
+		memcpy ( &new->setting, setting, sizeof ( new->setting ) );
137
+		new->setting.name = generic_setting_name ( new );
138
+		memcpy ( generic_setting_name ( new ),
139
+			 setting->name, name_len );
140
+		memcpy ( generic_setting_data ( new ), data, len );
141
+	}
142
+
143
+	/* Delete existing generic setting, if any */
144
+	if ( old ) {
145
+		list_del ( &old->list );
146
+		free ( old );
147
+	}
148
+
149
+	/* Add new setting to list, if any */
150
+	if ( new )
151
+		list_add ( &new->list, &generics->list );
152
+
153
+	return 0;
64
 }
154
 }
65
 
155
 
66
 /**
156
 /**
67
- * Fetch value of simple setting
157
+ * Fetch value of generic setting
68
  *
158
  *
69
- * @v options		DHCP option block
159
+ * @v settings		Settings block
70
  * @v setting		Setting to fetch
160
  * @v setting		Setting to fetch
71
  * @v data		Buffer to fill with setting data
161
  * @v data		Buffer to fill with setting data
72
  * @v len		Length of buffer
162
  * @v len		Length of buffer
73
  * @ret len		Length of setting data, or negative error
163
  * @ret len		Length of setting data, or negative error
74
  */
164
  */
75
-int simple_settings_fetch ( struct settings *settings, struct setting *setting,
76
-			    void *data, size_t len ) {
77
-	struct simple_settings *simple =
78
-		container_of ( settings, struct simple_settings, settings );
79
-	return dhcpopt_fetch ( &simple->dhcpopts, setting->tag, data, len );
165
+int generic_settings_fetch ( struct settings *settings,
166
+			     struct setting *setting,
167
+			     void *data, size_t len ) {
168
+	struct generic_settings *generics =
169
+		container_of ( settings, struct generic_settings, settings );
170
+	struct generic_setting *generic;
171
+
172
+	/* Find generic setting */
173
+	generic = find_generic_setting ( generics, setting );
174
+	if ( ! generic )
175
+		return -ENOENT;
176
+
177
+	/* Copy out generic setting data */
178
+	if ( len > generic->data_len )
179
+		len = generic->data_len;
180
+	memcpy ( data, generic_setting_data ( generic ), len );
181
+	return generic->data_len;
182
+}
183
+
184
+/**
185
+ * Clear generic settings block
186
+ *
187
+ * @v settings		Settings block
188
+ */
189
+void generic_settings_clear ( struct settings *settings ) {
190
+	struct generic_settings *generics =
191
+		container_of ( settings, struct generic_settings, settings );
192
+	struct generic_setting *generic;
193
+	struct generic_setting *tmp;
194
+
195
+	list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
196
+		list_del ( &generic->list );
197
+		free ( generic );
198
+	}
199
+	assert ( list_empty ( &generics->list ) );
80
 }
200
 }
81
 
201
 
82
-/** Simple settings operations */
83
-struct settings_operations simple_settings_operations = {
84
-	.store = simple_settings_store,
85
-	.fetch = simple_settings_fetch,
202
+/** Generic settings operations */
203
+struct settings_operations generic_settings_operations = {
204
+	.store = generic_settings_store,
205
+	.fetch = generic_settings_fetch,
206
+	.clear = generic_settings_clear,
86
 };
207
 };
87
 
208
 
88
-/** Root simple settings block */
89
-struct simple_settings simple_settings_root = {
209
+/******************************************************************************
210
+ *
211
+ * Registered settings blocks
212
+ *
213
+ ******************************************************************************
214
+ */
215
+
216
+/** Root generic settings block */
217
+struct generic_settings generic_settings_root = {
90
 	.settings = {
218
 	.settings = {
91
 		.refcnt = NULL,
219
 		.refcnt = NULL,
92
 		.name = "",
220
 		.name = "",
93
 		.siblings =
221
 		.siblings =
94
-		     LIST_HEAD_INIT ( simple_settings_root.settings.siblings ),
222
+		    LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
95
 		.children =
223
 		.children =
96
-		     LIST_HEAD_INIT ( simple_settings_root.settings.children ),
97
-		.op = &simple_settings_operations,
224
+		    LIST_HEAD_INIT ( generic_settings_root.settings.children ),
225
+		.op = &generic_settings_operations,
98
 	},
226
 	},
227
+	.list = LIST_HEAD_INIT ( generic_settings_root.list ),
99
 };
228
 };
100
 
229
 
101
 /** Root settings block */
230
 /** Root settings block */
102
-#define settings_root simple_settings_root.settings
231
+#define settings_root generic_settings_root.settings
103
 
232
 
104
 /**
233
 /**
105
  * Find child named settings block
234
  * Find child named settings block
135
 static struct settings * autovivify_child_settings ( struct settings *parent,
264
 static struct settings * autovivify_child_settings ( struct settings *parent,
136
 						     const char *name ) {
265
 						     const char *name ) {
137
 	struct {
266
 	struct {
138
-		struct simple_settings simple;
267
+		struct generic_settings generic;
139
 		char name[ strlen ( name ) + 1 /* NUL */ ];
268
 		char name[ strlen ( name ) + 1 /* NUL */ ];
140
 	} *new_child;
269
 	} *new_child;
141
 	struct settings *settings;
270
 	struct settings *settings;
144
 	if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
273
 	if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
145
 		return settings;
274
 		return settings;
146
 
275
 
147
-	/* Create new simple settings block */
276
+	/* Create new generic settings block */
148
 	new_child = zalloc ( sizeof ( *new_child ) );
277
 	new_child = zalloc ( sizeof ( *new_child ) );
149
 	if ( ! new_child ) {
278
 	if ( ! new_child ) {
150
 		DBGC ( parent, "Settings %p could not create child %s\n",
279
 		DBGC ( parent, "Settings %p could not create child %s\n",
152
 		return NULL;
281
 		return NULL;
153
 	}
282
 	}
154
 	memcpy ( new_child->name, name, sizeof ( new_child->name ) );
283
 	memcpy ( new_child->name, name, sizeof ( new_child->name ) );
155
-	simple_settings_init ( &new_child->simple, NULL, new_child->name );
156
-	settings = &new_child->simple.settings;
284
+	generic_settings_init ( &new_child->generic, NULL, new_child->name );
285
+	settings = &new_child->generic.settings;
157
 	register_settings ( settings, parent );
286
 	register_settings ( settings, parent );
158
 	return settings;
287
 	return settings;
159
 }
288
 }
160
 
289
 
290
+/**
291
+ * Return settings block name (for debug only)
292
+ *
293
+ * @v settings		Settings block
294
+ * @ret name		Settings block name
295
+ */
296
+static const char * settings_name ( struct settings *settings ) {
297
+	static char buf[64];
298
+	char tmp[ sizeof ( buf ) ];
299
+	int count;
300
+
301
+	for ( count = 0 ; settings ; settings = settings->parent ) {
302
+		memcpy ( tmp, buf, sizeof ( tmp ) );
303
+		snprintf ( buf, sizeof ( buf ), "%s%c%s", settings->name,
304
+			   ( count++ ? '.' : '\0' ), tmp );
305
+	}
306
+	return ( buf + 1 );
307
+}
308
+
161
 /**
309
 /**
162
  * Parse settings block name
310
  * Parse settings block name
163
  *
311
  *
284
 	ref_get ( parent->refcnt );
432
 	ref_get ( parent->refcnt );
285
 	settings->parent = parent;
433
 	settings->parent = parent;
286
 	list_add_tail ( &settings->siblings, &parent->children );
434
 	list_add_tail ( &settings->siblings, &parent->children );
287
-	DBGC ( settings, "Settings %p registered\n", settings );
435
+	DBGC ( settings, "Settings %p (\"%s\") registered\n",
436
+	       settings, settings_name ( settings ) );
288
 
437
 
289
 	/* Fix up settings priority */
438
 	/* Fix up settings priority */
290
 	reprioritise_settings ( settings );
439
 	reprioritise_settings ( settings );
302
  */
451
  */
303
 void unregister_settings ( struct settings *settings ) {
452
 void unregister_settings ( struct settings *settings ) {
304
 
453
 
454
+	DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
455
+	       settings, settings_name ( settings ) );
456
+
305
 	/* Remove from list of settings */
457
 	/* Remove from list of settings */
306
 	ref_put ( settings->refcnt );
458
 	ref_put ( settings->refcnt );
307
 	ref_put ( settings->parent->refcnt );
459
 	ref_put ( settings->parent->refcnt );
308
 	settings->parent = NULL;
460
 	settings->parent = NULL;
309
 	list_del ( &settings->siblings );
461
 	list_del ( &settings->siblings );
310
-	DBGC ( settings, "Settings %p unregistered\n", settings );
311
 
462
 
312
 	/* Apply potentially-updated settings */
463
 	/* Apply potentially-updated settings */
313
 	apply_settings();
464
 	apply_settings();
337
 	if ( ! settings )
488
 	if ( ! settings )
338
 		settings = &settings_root;
489
 		settings = &settings_root;
339
 
490
 
491
+	/* Sanity check */
492
+	if ( ! settings->op->store )
493
+		return -ENOTSUP;
494
+
340
 	/* Store setting */
495
 	/* Store setting */
341
 	if ( ( rc = settings->op->store ( settings, setting,
496
 	if ( ( rc = settings->op->store ( settings, setting,
342
 					  data, len ) ) != 0 )
497
 					  data, len ) ) != 0 )
384
 	if ( ! settings )
539
 	if ( ! settings )
385
 		settings = &settings_root;
540
 		settings = &settings_root;
386
 
541
 
542
+	/* Sanity check */
543
+	if ( ! settings->op->fetch )
544
+		return -ENOTSUP;
545
+
387
 	/* Try this block first */
546
 	/* Try this block first */
388
 	if ( ( ret = settings->op->fetch ( settings, setting,
547
 	if ( ( ret = settings->op->fetch ( settings, setting,
389
 					   data, len ) ) >= 0 )
548
 					   data, len ) ) >= 0 )
599
 	return len;
758
 	return len;
600
 }
759
 }
601
 
760
 
761
+/**
762
+ * Clear settings block
763
+ *
764
+ * @v settings		Settings block
765
+ */
766
+void clear_settings ( struct settings *settings ) {
767
+	if ( settings->op->clear )
768
+		settings->op->clear ( settings );
769
+}
770
+
602
 /**
771
 /**
603
  * Compare two settings
772
  * Compare two settings
604
  *
773
  *
662
 	return NULL;
831
 	return NULL;
663
 }
832
 }
664
 
833
 
834
+/**
835
+ * Parse setting name as tag number
836
+ *
837
+ * @v name		Name
838
+ * @ret tag		Tag number, or 0 if not a valid number
839
+ */
840
+static unsigned int parse_setting_tag ( const char *name ) {
841
+	char *tmp = ( ( char * ) name );
842
+	unsigned int tag = 0;
843
+
844
+	while ( 1 ) {
845
+		tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
846
+		if ( *tmp == 0 )
847
+			return tag;
848
+		if ( *tmp != '.' )
849
+			return 0;
850
+		tmp++;
851
+	}
852
+}
853
+
665
 /**
854
 /**
666
  * Find setting type
855
  * Find setting type
667
  *
856
  *
685
  * @v get_child		Function to find or create child settings block
874
  * @v get_child		Function to find or create child settings block
686
  * @v settings		Settings block to fill in
875
  * @v settings		Settings block to fill in
687
  * @v setting		Setting to fill in
876
  * @v setting		Setting to fill in
877
+ * @v tmp_name		Buffer for copy of setting name
688
  * @ret rc		Return status code
878
  * @ret rc		Return status code
689
  *
879
  *
690
  * Interprets a name of the form
880
  * Interprets a name of the form
691
  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
881
  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
692
  * fields.
882
  * fields.
883
+ *
884
+ * The @c tmp_name buffer must be large enough to hold a copy of the
885
+ * setting name.
693
  */
886
  */
694
 static int
887
 static int
695
 parse_setting_name ( const char *name,
888
 parse_setting_name ( const char *name,
696
 		     struct settings * ( * get_child ) ( struct settings *,
889
 		     struct settings * ( * get_child ) ( struct settings *,
697
 							 const char * ),
890
 							 const char * ),
698
-		     struct settings **settings, struct setting *setting ) {
699
-	char tmp_name[ strlen ( name ) + 1 ];
891
+		     struct settings **settings, struct setting *setting,
892
+		     char *tmp_name ) {
700
 	char *settings_name;
893
 	char *settings_name;
701
 	char *setting_name;
894
 	char *setting_name;
702
 	char *type_name;
895
 	char *type_name;
703
 	struct setting *named_setting;
896
 	struct setting *named_setting;
704
-	char *tmp;
705
 
897
 
706
 	/* Set defaults */
898
 	/* Set defaults */
707
 	*settings = &settings_root;
899
 	*settings = &settings_root;
708
 	memset ( setting, 0, sizeof ( *setting ) );
900
 	memset ( setting, 0, sizeof ( *setting ) );
709
-	setting->type = &setting_type_hex;
901
+	setting->name = "";
902
+	setting->type = &setting_type_string;
710
 
903
 
711
 	/* Split name into "[settings_name/]setting_name[:type_name]" */
904
 	/* Split name into "[settings_name/]setting_name[:type_name]" */
712
-	memcpy ( tmp_name, name, sizeof ( tmp_name ) );
905
+	strcpy ( tmp_name, name );
713
 	if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
906
 	if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
714
 		*(setting_name++) = 0;
907
 		*(setting_name++) = 0;
715
 		settings_name = tmp_name;
908
 		settings_name = tmp_name;
730
 		}
923
 		}
731
 	}
924
 	}
732
 
925
 
733
-	/* Identify tag number */
926
+	/* Identify setting */
734
 	if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
927
 	if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
928
+		/* Matches a defined named setting; use that setting */
735
 		memcpy ( setting, named_setting, sizeof ( *setting ) );
929
 		memcpy ( setting, named_setting, sizeof ( *setting ) );
736
-	} else {
737
-		/* Unrecognised name: try to interpret as a tag number */
738
-		tmp = setting_name;
739
-		while ( 1 ) {
740
-			setting->tag = ( ( setting->tag << 8 ) |
741
-					 strtoul ( tmp, &tmp, 0 ) );
742
-			if ( *tmp == 0 )
743
-				break;
744
-			if ( *tmp != '.' ) {
745
-				DBG ( "Invalid setting \"%s\" in \"%s\"\n",
746
-				      setting_name, name );
747
-				return -ENOENT;
748
-			}
749
-			tmp++;
750
-		}
930
+	} else if ( ( setting->tag = parse_setting_tag ( setting_name ) ) !=0){
931
+		/* Is a valid numeric tag; use the tag */
751
 		setting->tag |= (*settings)->tag_magic;
932
 		setting->tag |= (*settings)->tag_magic;
933
+	} else {
934
+		/* Use the arbitrary name */
935
+		setting->name = setting_name;
752
 	}
936
 	}
753
 
937
 
754
 	/* Identify setting type, if specified */
938
 	/* Identify setting type, if specified */
774
 int storef_named_setting ( const char *name, const char *value ) {
958
 int storef_named_setting ( const char *name, const char *value ) {
775
 	struct settings *settings;
959
 	struct settings *settings;
776
 	struct setting setting;
960
 	struct setting setting;
961
+	char tmp_name[ strlen ( name ) + 1 ];
777
 	int rc;
962
 	int rc;
778
 
963
 
779
 	if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
964
 	if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
780
-					 &settings, &setting ) ) != 0 )
965
+					 &settings, &setting, tmp_name )) != 0)
781
 		return rc;
966
 		return rc;
782
 	return storef_setting ( settings, &setting, value );
967
 	return storef_setting ( settings, &setting, value );
783
 }
968
 }
793
 int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
978
 int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
794
 	struct settings *settings;
979
 	struct settings *settings;
795
 	struct setting setting;
980
 	struct setting setting;
981
+	char tmp_name[ strlen ( name ) + 1 ];
796
 	int rc;
982
 	int rc;
797
 
983
 
798
 	if ( ( rc = parse_setting_name ( name, find_child_settings,
984
 	if ( ( rc = parse_setting_name ( name, find_child_settings,
799
-					 &settings, &setting ) ) != 0 )
985
+					 &settings, &setting, tmp_name )) != 0)
800
 		return rc;
986
 		return rc;
801
 	return fetchf_setting ( settings, &setting, buf, len );
987
 	return fetchf_setting ( settings, &setting, buf, len );
802
 }
988
 }

+ 16
- 3
src/include/gpxe/netdevice.h 查看文件

269
 	struct net_device_stats rx_stats;
269
 	struct net_device_stats rx_stats;
270
 
270
 
271
 	/** Configuration settings applicable to this device */
271
 	/** Configuration settings applicable to this device */
272
-	struct simple_settings settings;
272
+	struct generic_settings settings;
273
 
273
 
274
 	/** Driver private data */
274
 	/** Driver private data */
275
 	void *priv;
275
 	void *priv;
295
 
295
 
296
 extern struct list_head net_devices;
296
 extern struct list_head net_devices;
297
 extern struct net_device_operations null_netdev_operations;
297
 extern struct net_device_operations null_netdev_operations;
298
+extern struct settings_operations netdev_settings_operations;
298
 
299
 
299
 /**
300
 /**
300
  * Initialise a network device
301
  * Initialise a network device
385
 	return &netdev->settings.settings;
386
 	return &netdev->settings.settings;
386
 }
387
 }
387
 
388
 
389
+/**
390
+ * Initialise a per-netdevice configuration settings block
391
+ *
392
+ * @v generics		Generic settings block
393
+ * @v refcnt		Containing object reference counter, or NULL
394
+ * @v name		Settings block name
395
+ */
396
+static inline __attribute__ (( always_inline )) void
397
+netdev_settings_init ( struct net_device *netdev ) {
398
+	generic_settings_init ( &netdev->settings,
399
+				&netdev->refcnt, netdev->name );
400
+	netdev->settings.settings.op = &netdev_settings_operations;
401
+}
402
+
388
 /**
403
 /**
389
  * Mark network device as having link up
404
  * Mark network device as having link up
390
  *
405
  *
440
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
455
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
441
 		    uint16_t net_proto, const void *ll_source );
456
 		    uint16_t net_proto, const void *ll_source );
442
 
457
 
443
-extern struct settings_operations netdev_settings_operations;
444
-
445
 /**
458
 /**
446
  * Complete network transmission
459
  * Complete network transmission
447
  *
460
  *

+ 24
- 17
src/include/gpxe/settings.h 查看文件

13
 #include <gpxe/tables.h>
13
 #include <gpxe/tables.h>
14
 #include <gpxe/list.h>
14
 #include <gpxe/list.h>
15
 #include <gpxe/refcnt.h>
15
 #include <gpxe/refcnt.h>
16
-#include <gpxe/dhcpopts.h>
17
 
16
 
18
 struct settings;
17
 struct settings;
19
 struct in_addr;
18
 struct in_addr;
69
 	 */
68
 	 */
70
 	int ( * fetch ) ( struct settings *settings, struct setting *setting,
69
 	int ( * fetch ) ( struct settings *settings, struct setting *setting,
71
 			  void *data, size_t len );
70
 			  void *data, size_t len );
71
+	/** Clear settings block
72
+	 *
73
+	 * @v settings		Settings block
74
+	 */
75
+	void ( * clear ) ( struct settings *settings );
72
 };
76
 };
73
 
77
 
74
 /** A settings block */
78
 /** A settings block */
154
 #define __settings_applicator __table_entry ( SETTINGS_APPLICATORS, 01 )
158
 #define __settings_applicator __table_entry ( SETTINGS_APPLICATORS, 01 )
155
 
159
 
156
 /**
160
 /**
157
- * A simple settings block
161
+ * A generic settings block
158
  *
162
  *
159
  */
163
  */
160
-struct simple_settings {
164
+struct generic_settings {
161
 	/** Settings block */
165
 	/** Settings block */
162
 	struct settings settings;
166
 	struct settings settings;
163
-	/** DHCP options */
164
-	struct dhcp_options dhcpopts;
167
+	/** List of generic settings */
168
+	struct list_head list;
165
 };
169
 };
166
 
170
 
167
-extern struct settings_operations simple_settings_operations;
168
-extern int simple_settings_store ( struct settings *settings,
169
-				   struct setting *setting,
170
-				   const void *data, size_t len );
171
-extern int simple_settings_fetch ( struct settings *settings,
172
-				   struct setting *setting,
173
-				   void *data, size_t len );
171
+extern struct settings_operations generic_settings_operations;
172
+extern int generic_settings_store ( struct settings *settings,
173
+				    struct setting *setting,
174
+				    const void *data, size_t len );
175
+extern int generic_settings_fetch ( struct settings *settings,
176
+				    struct setting *setting,
177
+				    void *data, size_t len );
178
+extern void generic_settings_clear ( struct settings *settings );
174
 
179
 
175
 extern int register_settings ( struct settings *settings,
180
 extern int register_settings ( struct settings *settings,
176
 			       struct settings *parent );
181
 			       struct settings *parent );
201
 					   struct setting *setting );
206
 					   struct setting *setting );
202
 extern int fetch_uuid_setting ( struct settings *settings,
207
 extern int fetch_uuid_setting ( struct settings *settings,
203
 				struct setting *setting, union uuid *uuid );
208
 				struct setting *setting, union uuid *uuid );
209
+extern void clear_settings ( struct settings *settings );
204
 extern int setting_cmp ( struct setting *a, struct setting *b );
210
 extern int setting_cmp ( struct setting *a, struct setting *b );
205
 
211
 
206
 extern struct settings * find_settings ( const char *name );
212
 extern struct settings * find_settings ( const char *name );
263
 /**
269
 /**
264
  * Initialise a settings block
270
  * Initialise a settings block
265
  *
271
  *
266
- * @v simple		Simple settings block
272
+ * @v generics		Generic settings block
267
  * @v refcnt		Containing object reference counter, or NULL
273
  * @v refcnt		Containing object reference counter, or NULL
268
  * @v name		Settings block name
274
  * @v name		Settings block name
269
  */
275
  */
270
-static inline void simple_settings_init ( struct simple_settings *simple,
271
-					  struct refcnt *refcnt,
272
-					  const char *name ) {
273
-	settings_init ( &simple->settings, &simple_settings_operations,
276
+static inline void generic_settings_init ( struct generic_settings *generics,
277
+					   struct refcnt *refcnt,
278
+					   const char *name ) {
279
+	settings_init ( &generics->settings, &generic_settings_operations,
274
 			refcnt, name, 0 );
280
 			refcnt, name, 0 );
281
+	INIT_LIST_HEAD ( &generics->list );
275
 }
282
 }
276
 
283
 
277
 /**
284
 /**

+ 0
- 17
src/interface/smbios/smbios_settings.c 查看文件

63
 	  ( (_type) << 16 ) |					\
63
 	  ( (_type) << 16 ) |					\
64
 	  ( offsetof ( _structure, _field ) << 8 ) )
64
 	  ( offsetof ( _structure, _field ) << 8 ) )
65
 
65
 
66
-/**
67
- * Store value of SMBIOS setting
68
- *
69
- * @v settings		Settings block
70
- * @v setting		Setting to store
71
- * @v data		Setting data, or NULL to clear setting
72
- * @v len		Length of setting data
73
- * @ret rc		Return status code
74
- */
75
-static int smbios_store ( struct settings *settings __unused,
76
-			  struct setting *setting __unused,
77
-			  const void *data __unused, size_t len __unused ) {
78
-	/* Cannot write data into SMBIOS */
79
-	return -ENOTSUP;
80
-}
81
-
82
 /**
66
 /**
83
  * Fetch value of SMBIOS setting
67
  * Fetch value of SMBIOS setting
84
  *
68
  *
135
 
119
 
136
 /** SMBIOS settings operations */
120
 /** SMBIOS settings operations */
137
 static struct settings_operations smbios_settings_operations = {
121
 static struct settings_operations smbios_settings_operations = {
138
-	.store = smbios_store,
139
 	.fetch = smbios_fetch,
122
 	.fetch = smbios_fetch,
140
 };
123
 };
141
 
124
 

+ 14
- 4
src/net/netdev_settings.c 查看文件

56
 			return -EINVAL;
56
 			return -EINVAL;
57
 		memcpy ( netdev->ll_addr, data, len );
57
 		memcpy ( netdev->ll_addr, data, len );
58
 		return 0;
58
 		return 0;
59
-	} else {
60
-		return simple_settings_store ( settings, setting, data, len );
61
 	}
59
 	}
60
+
61
+	return generic_settings_store ( settings, setting, data, len );
62
 }
62
 }
63
 
63
 
64
 /**
64
 /**
80
 			len = netdev->ll_protocol->ll_addr_len;
80
 			len = netdev->ll_protocol->ll_addr_len;
81
 		memcpy ( data, netdev->ll_addr, len );
81
 		memcpy ( data, netdev->ll_addr, len );
82
 		return netdev->ll_protocol->ll_addr_len;
82
 		return netdev->ll_protocol->ll_addr_len;
83
-	} else {
84
-		return simple_settings_fetch ( settings, setting, data, len );
85
 	}
83
 	}
84
+
85
+	return generic_settings_fetch ( settings, setting, data, len );
86
+}
87
+
88
+/**
89
+ * Clear network device settings
90
+ *
91
+ * @v settings		Settings block
92
+ */
93
+static void netdev_clear ( struct settings *settings ) {
94
+	generic_settings_clear ( settings );
86
 }
95
 }
87
 
96
 
88
 /** Network device configuration settings operations */
97
 /** Network device configuration settings operations */
89
 struct settings_operations netdev_settings_operations = {
98
 struct settings_operations netdev_settings_operations = {
90
 	.store = netdev_store,
99
 	.store = netdev_store,
91
 	.fetch = netdev_fetch,
100
 	.fetch = netdev_fetch,
101
+	.clear = netdev_clear,
92
 };
102
 };

+ 2
- 3
src/net/netdevice.c 查看文件

282
 	
282
 	
283
 	netdev_tx_flush ( netdev );
283
 	netdev_tx_flush ( netdev );
284
 	netdev_rx_flush ( netdev );
284
 	netdev_rx_flush ( netdev );
285
+	clear_settings ( netdev_settings ( netdev ) );
285
 	free ( netdev );
286
 	free ( netdev );
286
 }
287
 }
287
 
288
 
303
 		netdev->refcnt.free = free_netdev;
304
 		netdev->refcnt.free = free_netdev;
304
 		INIT_LIST_HEAD ( &netdev->tx_queue );
305
 		INIT_LIST_HEAD ( &netdev->tx_queue );
305
 		INIT_LIST_HEAD ( &netdev->rx_queue );
306
 		INIT_LIST_HEAD ( &netdev->rx_queue );
306
-		settings_init ( netdev_settings ( netdev ),
307
-				&netdev_settings_operations, &netdev->refcnt,
308
-				netdev->name, 0 );
307
+		netdev_settings_init ( netdev );
309
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
308
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
310
 	}
309
 	}
311
 	return netdev;
310
 	return netdev;

Loading…
取消
儲存