Переглянути джерело

[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

+ 241
- 55
src/core/settings.c Переглянути файл

@@ -41,65 +41,194 @@ FILE_LICENCE ( GPL2_OR_LATER );
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 108
  * @v setting		Setting to store
54 109
  * @v data		Setting data, or NULL to clear setting
55 110
  * @v len		Length of setting data
56 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 160
  * @v setting		Setting to fetch
71 161
  * @v data		Buffer to fill with setting data
72 162
  * @v len		Length of buffer
73 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 218
 	.settings = {
91 219
 		.refcnt = NULL,
92 220
 		.name = "",
93 221
 		.siblings =
94
-		     LIST_HEAD_INIT ( simple_settings_root.settings.siblings ),
222
+		    LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
95 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 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 234
  * Find child named settings block
@@ -135,7 +264,7 @@ static struct settings * find_child_settings ( struct settings *parent,
135 264
 static struct settings * autovivify_child_settings ( struct settings *parent,
136 265
 						     const char *name ) {
137 266
 	struct {
138
-		struct simple_settings simple;
267
+		struct generic_settings generic;
139 268
 		char name[ strlen ( name ) + 1 /* NUL */ ];
140 269
 	} *new_child;
141 270
 	struct settings *settings;
@@ -144,7 +273,7 @@ static struct settings * autovivify_child_settings ( struct settings *parent,
144 273
 	if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
145 274
 		return settings;
146 275
 
147
-	/* Create new simple settings block */
276
+	/* Create new generic settings block */
148 277
 	new_child = zalloc ( sizeof ( *new_child ) );
149 278
 	if ( ! new_child ) {
150 279
 		DBGC ( parent, "Settings %p could not create child %s\n",
@@ -152,12 +281,31 @@ static struct settings * autovivify_child_settings ( struct settings *parent,
152 281
 		return NULL;
153 282
 	}
154 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 286
 	register_settings ( settings, parent );
158 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 310
  * Parse settings block name
163 311
  *
@@ -284,7 +432,8 @@ int register_settings ( struct settings *settings, struct settings *parent ) {
284 432
 	ref_get ( parent->refcnt );
285 433
 	settings->parent = parent;
286 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 438
 	/* Fix up settings priority */
290 439
 	reprioritise_settings ( settings );
@@ -302,12 +451,14 @@ int register_settings ( struct settings *settings, struct settings *parent ) {
302 451
  */
303 452
 void unregister_settings ( struct settings *settings ) {
304 453
 
454
+	DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
455
+	       settings, settings_name ( settings ) );
456
+
305 457
 	/* Remove from list of settings */
306 458
 	ref_put ( settings->refcnt );
307 459
 	ref_put ( settings->parent->refcnt );
308 460
 	settings->parent = NULL;
309 461
 	list_del ( &settings->siblings );
310
-	DBGC ( settings, "Settings %p unregistered\n", settings );
311 462
 
312 463
 	/* Apply potentially-updated settings */
313 464
 	apply_settings();
@@ -337,6 +488,10 @@ int store_setting ( struct settings *settings, struct setting *setting,
337 488
 	if ( ! settings )
338 489
 		settings = &settings_root;
339 490
 
491
+	/* Sanity check */
492
+	if ( ! settings->op->store )
493
+		return -ENOTSUP;
494
+
340 495
 	/* Store setting */
341 496
 	if ( ( rc = settings->op->store ( settings, setting,
342 497
 					  data, len ) ) != 0 )
@@ -384,6 +539,10 @@ int fetch_setting ( struct settings *settings, struct setting *setting,
384 539
 	if ( ! settings )
385 540
 		settings = &settings_root;
386 541
 
542
+	/* Sanity check */
543
+	if ( ! settings->op->fetch )
544
+		return -ENOTSUP;
545
+
387 546
 	/* Try this block first */
388 547
 	if ( ( ret = settings->op->fetch ( settings, setting,
389 548
 					   data, len ) ) >= 0 )
@@ -599,6 +758,16 @@ int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
599 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 772
  * Compare two settings
604 773
  *
@@ -662,6 +831,26 @@ static struct setting * find_setting ( const char *name ) {
662 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 855
  * Find setting type
667 856
  *
@@ -685,31 +874,35 @@ static struct setting_type * find_setting_type ( const char *name ) {
685 874
  * @v get_child		Function to find or create child settings block
686 875
  * @v settings		Settings block to fill in
687 876
  * @v setting		Setting to fill in
877
+ * @v tmp_name		Buffer for copy of setting name
688 878
  * @ret rc		Return status code
689 879
  *
690 880
  * Interprets a name of the form
691 881
  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
692 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 887
 static int
695 888
 parse_setting_name ( const char *name,
696 889
 		     struct settings * ( * get_child ) ( struct settings *,
697 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 893
 	char *settings_name;
701 894
 	char *setting_name;
702 895
 	char *type_name;
703 896
 	struct setting *named_setting;
704
-	char *tmp;
705 897
 
706 898
 	/* Set defaults */
707 899
 	*settings = &settings_root;
708 900
 	memset ( setting, 0, sizeof ( *setting ) );
709
-	setting->type = &setting_type_hex;
901
+	setting->name = "";
902
+	setting->type = &setting_type_string;
710 903
 
711 904
 	/* Split name into "[settings_name/]setting_name[:type_name]" */
712
-	memcpy ( tmp_name, name, sizeof ( tmp_name ) );
905
+	strcpy ( tmp_name, name );
713 906
 	if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
714 907
 		*(setting_name++) = 0;
715 908
 		settings_name = tmp_name;
@@ -730,25 +923,16 @@ parse_setting_name ( const char *name,
730 923
 		}
731 924
 	}
732 925
 
733
-	/* Identify tag number */
926
+	/* Identify setting */
734 927
 	if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
928
+		/* Matches a defined named setting; use that setting */
735 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 932
 		setting->tag |= (*settings)->tag_magic;
933
+	} else {
934
+		/* Use the arbitrary name */
935
+		setting->name = setting_name;
752 936
 	}
753 937
 
754 938
 	/* Identify setting type, if specified */
@@ -774,10 +958,11 @@ parse_setting_name ( const char *name,
774 958
 int storef_named_setting ( const char *name, const char *value ) {
775 959
 	struct settings *settings;
776 960
 	struct setting setting;
961
+	char tmp_name[ strlen ( name ) + 1 ];
777 962
 	int rc;
778 963
 
779 964
 	if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
780
-					 &settings, &setting ) ) != 0 )
965
+					 &settings, &setting, tmp_name )) != 0)
781 966
 		return rc;
782 967
 	return storef_setting ( settings, &setting, value );
783 968
 }
@@ -793,10 +978,11 @@ int storef_named_setting ( const char *name, const char *value ) {
793 978
 int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
794 979
 	struct settings *settings;
795 980
 	struct setting setting;
981
+	char tmp_name[ strlen ( name ) + 1 ];
796 982
 	int rc;
797 983
 
798 984
 	if ( ( rc = parse_setting_name ( name, find_child_settings,
799
-					 &settings, &setting ) ) != 0 )
985
+					 &settings, &setting, tmp_name )) != 0)
800 986
 		return rc;
801 987
 	return fetchf_setting ( settings, &setting, buf, len );
802 988
 }

+ 16
- 3
src/include/gpxe/netdevice.h Переглянути файл

@@ -269,7 +269,7 @@ struct net_device {
269 269
 	struct net_device_stats rx_stats;
270 270
 
271 271
 	/** Configuration settings applicable to this device */
272
-	struct simple_settings settings;
272
+	struct generic_settings settings;
273 273
 
274 274
 	/** Driver private data */
275 275
 	void *priv;
@@ -295,6 +295,7 @@ struct net_device {
295 295
 
296 296
 extern struct list_head net_devices;
297 297
 extern struct net_device_operations null_netdev_operations;
298
+extern struct settings_operations netdev_settings_operations;
298 299
 
299 300
 /**
300 301
  * Initialise a network device
@@ -385,6 +386,20 @@ netdev_settings ( struct net_device *netdev ) {
385 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 404
  * Mark network device as having link up
390 405
  *
@@ -440,8 +455,6 @@ extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
440 455
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
441 456
 		    uint16_t net_proto, const void *ll_source );
442 457
 
443
-extern struct settings_operations netdev_settings_operations;
444
-
445 458
 /**
446 459
  * Complete network transmission
447 460
  *

+ 24
- 17
src/include/gpxe/settings.h Переглянути файл

@@ -13,7 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
13 13
 #include <gpxe/tables.h>
14 14
 #include <gpxe/list.h>
15 15
 #include <gpxe/refcnt.h>
16
-#include <gpxe/dhcpopts.h>
17 16
 
18 17
 struct settings;
19 18
 struct in_addr;
@@ -69,6 +68,11 @@ struct settings_operations {
69 68
 	 */
70 69
 	int ( * fetch ) ( struct settings *settings, struct setting *setting,
71 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 78
 /** A settings block */
@@ -154,23 +158,24 @@ struct settings_applicator {
154 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 165
 	/** Settings block */
162 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 180
 extern int register_settings ( struct settings *settings,
176 181
 			       struct settings *parent );
@@ -201,6 +206,7 @@ extern unsigned long fetch_uintz_setting ( struct settings *settings,
201 206
 					   struct setting *setting );
202 207
 extern int fetch_uuid_setting ( struct settings *settings,
203 208
 				struct setting *setting, union uuid *uuid );
209
+extern void clear_settings ( struct settings *settings );
204 210
 extern int setting_cmp ( struct setting *a, struct setting *b );
205 211
 
206 212
 extern struct settings * find_settings ( const char *name );
@@ -263,15 +269,16 @@ static inline void settings_init ( struct settings *settings,
263 269
 /**
264 270
  * Initialise a settings block
265 271
  *
266
- * @v simple		Simple settings block
272
+ * @v generics		Generic settings block
267 273
  * @v refcnt		Containing object reference counter, or NULL
268 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 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,22 +63,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
63 63
 	  ( (_type) << 16 ) |					\
64 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 67
  * Fetch value of SMBIOS setting
84 68
  *
@@ -135,7 +119,6 @@ static int smbios_fetch ( struct settings *settings __unused,
135 119
 
136 120
 /** SMBIOS settings operations */
137 121
 static struct settings_operations smbios_settings_operations = {
138
-	.store = smbios_store,
139 122
 	.fetch = smbios_fetch,
140 123
 };
141 124
 

+ 14
- 4
src/net/netdev_settings.c Переглянути файл

@@ -56,9 +56,9 @@ static int netdev_store ( struct settings *settings, struct setting *setting,
56 56
 			return -EINVAL;
57 57
 		memcpy ( netdev->ll_addr, data, len );
58 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,13 +80,23 @@ static int netdev_fetch ( struct settings *settings, struct setting *setting,
80 80
 			len = netdev->ll_protocol->ll_addr_len;
81 81
 		memcpy ( data, netdev->ll_addr, len );
82 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 97
 /** Network device configuration settings operations */
89 98
 struct settings_operations netdev_settings_operations = {
90 99
 	.store = netdev_store,
91 100
 	.fetch = netdev_fetch,
101
+	.clear = netdev_clear,
92 102
 };

+ 2
- 3
src/net/netdevice.c Переглянути файл

@@ -282,6 +282,7 @@ static void free_netdev ( struct refcnt *refcnt ) {
282 282
 	
283 283
 	netdev_tx_flush ( netdev );
284 284
 	netdev_rx_flush ( netdev );
285
+	clear_settings ( netdev_settings ( netdev ) );
285 286
 	free ( netdev );
286 287
 }
287 288
 
@@ -303,9 +304,7 @@ struct net_device * alloc_netdev ( size_t priv_size ) {
303 304
 		netdev->refcnt.free = free_netdev;
304 305
 		INIT_LIST_HEAD ( &netdev->tx_queue );
305 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 308
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
310 309
 	}
311 310
 	return netdev;

Завантаження…
Відмінити
Зберегти