Browse Source

[settings] Add the notion of a "tag magic" to numbered settings

Settings can be constructed using a dotted-decimal notation, to allow
for access to unnamed settings.  The default interpretation is as a
DHCP option number (with encapsulated options represented as
"<encapsulating option>.<encapsulated option>".

In several contexts (e.g. SMBIOS, Phantom CLP), it is useful to
interpret the dotted-decimal notation as referring to non-DHCP
options.  In this case, it becomes necessary for these contexts to
ignore standard DHCP options, otherwise we end up trying to, for
example, retrieve the boot filename from SMBIOS.

Allow settings blocks to specify a "tag magic".  When dotted-decimal
notation is used to construct a setting, the tag magic value of the
originating settings block will be ORed in to the tag number.
Store/fetch methods can then check for the magic number before
interpreting arbitrarily-numbered settings.
tags/v0.9.6
Michael Brown 16 years ago
parent
commit
0a6c66a830

+ 19
- 4
src/arch/i386/firmware/pcbios/smbios_settings.c View File

24
 #include <gpxe/uuid.h>
24
 #include <gpxe/uuid.h>
25
 #include <smbios.h>
25
 #include <smbios.h>
26
 
26
 
27
+/** SMBIOS settings tag magic number */
28
+#define SMBIOS_TAG_MAGIC 0x5B /* "SmBios" */
29
+
30
+/**
31
+ * Construct SMBIOS empty tag
32
+ *
33
+ * @ret tag		SMBIOS setting tag
34
+ */
35
+#define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
36
+
27
 /**
37
 /**
28
  * Construct SMBIOS raw-data tag
38
  * Construct SMBIOS raw-data tag
29
  *
39
  *
33
  * @ret tag		SMBIOS setting tag
43
  * @ret tag		SMBIOS setting tag
34
  */
44
  */
35
 #define SMBIOS_RAW_TAG( _type, _structure, _field )		\
45
 #define SMBIOS_RAW_TAG( _type, _structure, _field )		\
36
-	( ( (_type) << 16 ) |					\
46
+	( ( SMBIOS_TAG_MAGIC << 24 ) |				\
47
+	  ( (_type) << 16 ) |					\
37
 	  ( offsetof ( _structure, _field ) << 8 ) |		\
48
 	  ( offsetof ( _structure, _field ) << 8 ) |		\
38
 	  ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
49
 	  ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
39
 
50
 
46
  * @ret tag		SMBIOS setting tag
57
  * @ret tag		SMBIOS setting tag
47
  */
58
  */
48
 #define SMBIOS_STRING_TAG( _type, _structure, _field )		\
59
 #define SMBIOS_STRING_TAG( _type, _structure, _field )		\
49
-	( ( (_type) << 16 ) |					\
60
+	( ( SMBIOS_TAG_MAGIC << 24 ) |				\
61
+	  ( (_type) << 16 ) |					\
50
 	  ( offsetof ( _structure, _field ) << 8 ) )
62
 	  ( offsetof ( _structure, _field ) << 8 ) )
51
 
63
 
52
 /**
64
 /**
78
 			  struct setting *setting,
90
 			  struct setting *setting,
79
 			  void *data, size_t len ) {
91
 			  void *data, size_t len ) {
80
 	struct smbios_structure structure;
92
 	struct smbios_structure structure;
93
+	unsigned int tag_magic;
81
 	unsigned int tag_type;
94
 	unsigned int tag_type;
82
 	unsigned int tag_offset;
95
 	unsigned int tag_offset;
83
 	unsigned int tag_len;
96
 	unsigned int tag_len;
84
 	int rc;
97
 	int rc;
85
 
98
 
86
 	/* Split tag into type, offset and length */
99
 	/* Split tag into type, offset and length */
87
-	tag_type = ( setting->tag >> 16 );
100
+	tag_magic = ( setting->tag >> 24 );
101
+	tag_type = ( ( setting->tag >> 16 ) & 0xff );
88
 	tag_offset = ( ( setting->tag >> 8 ) & 0xff );
102
 	tag_offset = ( ( setting->tag >> 8 ) & 0xff );
89
 	tag_len = ( setting->tag & 0xff );
103
 	tag_len = ( setting->tag & 0xff );
90
-	if ( ! tag_type )
104
+	if ( tag_magic != SMBIOS_TAG_MAGIC )
91
 		return -ENOENT;
105
 		return -ENOENT;
92
 
106
 
93
 	/* Find SMBIOS structure */
107
 	/* Find SMBIOS structure */
127
 static struct settings smbios_settings = {
141
 static struct settings smbios_settings = {
128
 	.refcnt = NULL,
142
 	.refcnt = NULL,
129
 	.name = "smbios",
143
 	.name = "smbios",
144
+	.tag_magic = SMBIOS_EMPTY_TAG,
130
 	.siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
145
 	.siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
131
 	.children = LIST_HEAD_INIT ( smbios_settings.children ),
146
 	.children = LIST_HEAD_INIT ( smbios_settings.children ),
132
 	.op = &smbios_settings_operations,
147
 	.op = &smbios_settings_operations,

+ 1
- 1
src/core/nvo.c View File

203
 	nvo->nvs = nvs;
203
 	nvo->nvs = nvs;
204
 	nvo->fragments = fragments;
204
 	nvo->fragments = fragments;
205
 	settings_init ( &nvo->settings, &nvo_settings_operations, refcnt,
205
 	settings_init ( &nvo->settings, &nvo_settings_operations, refcnt,
206
-			"nvo" );
206
+			"nvo", 0 );
207
 }
207
 }
208
 
208
 
209
 /**
209
 /**

+ 1
- 0
src/core/settings.c View File

665
 			}
665
 			}
666
 			tmp++;
666
 			tmp++;
667
 		}
667
 		}
668
+		setting->tag |= (*settings)->tag_magic;
668
 	}
669
 	}
669
 
670
 
670
 	/* Identify setting type, if specified */
671
 	/* Identify setting type, if specified */

+ 24
- 16
src/drivers/net/phantom/phantom.c View File

1589
  *
1589
  *
1590
  */
1590
  */
1591
 
1591
 
1592
+/** Phantom CLP settings tag magic */
1593
+#define PHN_CLP_TAG_MAGIC 0xc19c1900UL
1594
+
1595
+/** Phantom CLP settings tag magic mask */
1596
+#define PHN_CLP_TAG_MAGIC_MASK 0xffffff00UL
1597
+
1592
 /** Phantom CLP data
1598
 /** Phantom CLP data
1593
  *
1599
  *
1594
  */
1600
  */
1790
 	/** gPXE setting */
1796
 	/** gPXE setting */
1791
 	struct setting *setting;
1797
 	struct setting *setting;
1792
 	/** Setting number */
1798
 	/** Setting number */
1793
-	unsigned int number;
1799
+	unsigned int clp_setting;
1794
 };
1800
 };
1795
 
1801
 
1796
 /** Phantom CLP settings */
1802
 /** Phantom CLP settings */
1802
  * Find Phantom CLP setting
1808
  * Find Phantom CLP setting
1803
  *
1809
  *
1804
  * @v setting		gPXE setting
1810
  * @v setting		gPXE setting
1805
- * @v clp_setting	Equivalent Phantom CLP setting, or NULL
1811
+ * @v clp_setting	Setting number, or 0 if not found
1806
  */
1812
  */
1807
-static struct phantom_clp_setting *
1808
-phantom_find_clp_setting ( struct phantom_nic *phantom,
1809
-			   struct setting *setting ) {
1813
+static unsigned int
1814
+phantom_clp_setting ( struct phantom_nic *phantom, struct setting *setting ) {
1810
 	struct phantom_clp_setting *clp_setting;
1815
 	struct phantom_clp_setting *clp_setting;
1811
 	unsigned int i;
1816
 	unsigned int i;
1812
 
1817
 
1818
+	/* Search the list of explicitly-defined settings */
1813
 	for ( i = 0 ; i < ( sizeof ( clp_settings ) /
1819
 	for ( i = 0 ; i < ( sizeof ( clp_settings ) /
1814
 			    sizeof ( clp_settings[0] ) ) ; i++ ) {
1820
 			    sizeof ( clp_settings[0] ) ) ; i++ ) {
1815
 		clp_setting = &clp_settings[i];
1821
 		clp_setting = &clp_settings[i];
1816
 		if ( setting_cmp ( setting, clp_setting->setting ) == 0 )
1822
 		if ( setting_cmp ( setting, clp_setting->setting ) == 0 )
1817
-			return clp_setting;
1823
+			return clp_setting->clp_setting;
1818
 	}
1824
 	}
1819
 
1825
 
1826
+	/* Allow for use of numbered settings */
1827
+	if ( ( setting->tag & PHN_CLP_TAG_MAGIC_MASK ) == PHN_CLP_TAG_MAGIC )
1828
+		return ( setting->tag & ~PHN_CLP_TAG_MAGIC_MASK );
1829
+
1820
 	DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n",
1830
 	DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n",
1821
 		phantom, setting->name );
1831
 		phantom, setting->name );
1822
 
1832
 
1823
-	return NULL;
1833
+	return 0;
1824
 }
1834
 }
1825
 
1835
 
1826
 /**
1836
 /**
1838
 	struct phantom_nic_port *phantom_port =
1848
 	struct phantom_nic_port *phantom_port =
1839
 		container_of ( settings, struct phantom_nic_port, settings );
1849
 		container_of ( settings, struct phantom_nic_port, settings );
1840
 	struct phantom_nic *phantom = phantom_port->phantom;
1850
 	struct phantom_nic *phantom = phantom_port->phantom;
1841
-	struct phantom_clp_setting *clp_setting;
1851
+	unsigned int clp_setting;
1842
 	int rc;
1852
 	int rc;
1843
 
1853
 
1844
 	/* Find Phantom setting equivalent to gPXE setting */
1854
 	/* Find Phantom setting equivalent to gPXE setting */
1845
-	clp_setting = phantom_find_clp_setting ( phantom, setting );
1855
+	clp_setting = phantom_clp_setting ( phantom, setting );
1846
 	if ( ! clp_setting )
1856
 	if ( ! clp_setting )
1847
 		return -ENOTSUP;
1857
 		return -ENOTSUP;
1848
 
1858
 
1849
 	/* Store setting */
1859
 	/* Store setting */
1850
 	if ( ( rc = phantom_clp_store ( phantom, phantom_port->port,
1860
 	if ( ( rc = phantom_clp_store ( phantom, phantom_port->port,
1851
-					clp_setting->number,
1852
-					data, len ) ) != 0 ) {
1861
+					clp_setting, data, len ) ) != 0 ) {
1853
 		DBGC ( phantom, "Phantom %p could not store setting \"%s\": "
1862
 		DBGC ( phantom, "Phantom %p could not store setting \"%s\": "
1854
 		       "%s\n", phantom, setting->name, strerror ( rc ) );
1863
 		       "%s\n", phantom, setting->name, strerror ( rc ) );
1855
 		return rc;
1864
 		return rc;
1873
 	struct phantom_nic_port *phantom_port =
1882
 	struct phantom_nic_port *phantom_port =
1874
 		container_of ( settings, struct phantom_nic_port, settings );
1883
 		container_of ( settings, struct phantom_nic_port, settings );
1875
 	struct phantom_nic *phantom = phantom_port->phantom;
1884
 	struct phantom_nic *phantom = phantom_port->phantom;
1876
-	struct phantom_clp_setting *clp_setting;
1885
+	unsigned int clp_setting;
1877
 	int read_len;
1886
 	int read_len;
1878
 	int rc;
1887
 	int rc;
1879
 
1888
 
1880
 	/* Find Phantom setting equivalent to gPXE setting */
1889
 	/* Find Phantom setting equivalent to gPXE setting */
1881
-	clp_setting = phantom_find_clp_setting ( phantom, setting );
1890
+	clp_setting = phantom_clp_setting ( phantom, setting );
1882
 	if ( ! clp_setting )
1891
 	if ( ! clp_setting )
1883
 		return -ENOTSUP;
1892
 		return -ENOTSUP;
1884
 
1893
 
1885
 	/* Fetch setting */
1894
 	/* Fetch setting */
1886
 	if ( ( read_len = phantom_clp_fetch ( phantom, phantom_port->port,
1895
 	if ( ( read_len = phantom_clp_fetch ( phantom, phantom_port->port,
1887
-					      clp_setting->number,
1888
-					      data, len ) ) < 0 ) {
1896
+					      clp_setting, data, len ) ) < 0 ){
1889
 		rc = read_len;
1897
 		rc = read_len;
1890
 		DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": "
1898
 		DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": "
1891
 		       "%s\n", phantom, setting->name, strerror ( rc ) );
1899
 		       "%s\n", phantom, setting->name, strerror ( rc ) );
2269
 		phantom_port->port = i;
2277
 		phantom_port->port = i;
2270
 		settings_init ( &phantom_port->settings,
2278
 		settings_init ( &phantom_port->settings,
2271
 				&phantom_settings_operations,
2279
 				&phantom_settings_operations,
2272
-				&netdev->refcnt, "clp" );
2280
+				&netdev->refcnt, "clp", PHN_CLP_TAG_MAGIC );
2273
 	}
2281
 	}
2274
 
2282
 
2275
 	/* BUG5945 - need to hack PCI config space on P3 B1 silicon.
2283
 	/* BUG5945 - need to hack PCI config space on P3 B1 silicon.

+ 13
- 2
src/include/gpxe/settings.h View File

72
 	struct refcnt *refcnt;
72
 	struct refcnt *refcnt;
73
 	/** Name */
73
 	/** Name */
74
 	const char *name;
74
 	const char *name;
75
+	/** Tag magic
76
+	 *
77
+	 * This value will be ORed in to any numerical tags
78
+	 * constructed by parse_setting_name(), and can be used to
79
+	 * avoid e.g. attempting to retrieve the subnet mask from
80
+	 * SMBIOS, or the system UUID from DHCP.
81
+	 */
82
+	unsigned int tag_magic;
75
 	/** Parent settings block */
83
 	/** Parent settings block */
76
 	struct settings *parent;
84
 	struct settings *parent;
77
 	/** Sibling settings blocks */
85
 	/** Sibling settings blocks */
225
  * @v op		Settings block operations
233
  * @v op		Settings block operations
226
  * @v refcnt		Containing object reference counter, or NULL
234
  * @v refcnt		Containing object reference counter, or NULL
227
  * @v name		Settings block name
235
  * @v name		Settings block name
236
+ * @v tag_magic		Tag magic
228
  */
237
  */
229
 static inline void settings_init ( struct settings *settings,
238
 static inline void settings_init ( struct settings *settings,
230
 				   struct settings_operations *op,
239
 				   struct settings_operations *op,
231
 				   struct refcnt *refcnt,
240
 				   struct refcnt *refcnt,
232
-				   const char *name ) {
241
+				   const char *name,
242
+				   unsigned int tag_magic ) {
233
 	INIT_LIST_HEAD ( &settings->siblings );
243
 	INIT_LIST_HEAD ( &settings->siblings );
234
 	INIT_LIST_HEAD ( &settings->children );
244
 	INIT_LIST_HEAD ( &settings->children );
235
 	settings->op = op;
245
 	settings->op = op;
236
 	settings->refcnt = refcnt;
246
 	settings->refcnt = refcnt;
237
 	settings->name = name;
247
 	settings->name = name;
248
+	settings->tag_magic = tag_magic;
238
 }
249
 }
239
 
250
 
240
 /**
251
 /**
248
 					  struct refcnt *refcnt,
259
 					  struct refcnt *refcnt,
249
 					  const char *name ) {
260
 					  const char *name ) {
250
 	settings_init ( &simple->settings, &simple_settings_operations,
261
 	settings_init ( &simple->settings, &simple_settings_operations,
251
-			refcnt, name );
262
+			refcnt, name, 0 );
252
 }
263
 }
253
 
264
 
254
 /**
265
 /**

+ 1
- 1
src/net/netdevice.c View File

268
 		INIT_LIST_HEAD ( &netdev->rx_queue );
268
 		INIT_LIST_HEAD ( &netdev->rx_queue );
269
 		settings_init ( netdev_settings ( netdev ),
269
 		settings_init ( netdev_settings ( netdev ),
270
 				&netdev_settings_operations, &netdev->refcnt,
270
 				&netdev_settings_operations, &netdev->refcnt,
271
-				netdev->name );
271
+				netdev->name, 0 );
272
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
272
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
273
 	}
273
 	}
274
 	return netdev;
274
 	return netdev;

+ 1
- 1
src/net/udp/dhcp.c View File

256
 		dhcppkt_init ( &dhcpset->dhcppkt, data, len );
256
 		dhcppkt_init ( &dhcpset->dhcppkt, data, len );
257
 		settings_init ( &dhcpset->settings,
257
 		settings_init ( &dhcpset->settings,
258
 				&dhcpset_settings_operations, &dhcpset->refcnt,
258
 				&dhcpset_settings_operations, &dhcpset->refcnt,
259
-				DHCP_SETTINGS_NAME );
259
+				DHCP_SETTINGS_NAME, 0 );
260
 	}
260
 	}
261
 	return dhcpset;
261
 	return dhcpset;
262
 }
262
 }

Loading…
Cancel
Save