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

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

@@ -203,7 +203,7 @@ void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs,
203 203
 	nvo->nvs = nvs;
204 204
 	nvo->fragments = fragments;
205 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,6 +665,7 @@ static int parse_setting_name ( const char *name, struct settings **settings,
665 665
 			}
666 666
 			tmp++;
667 667
 		}
668
+		setting->tag |= (*settings)->tag_magic;
668 669
 	}
669 670
 
670 671
 	/* Identify setting type, if specified */

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

@@ -1589,6 +1589,12 @@ static struct net_device_operations phantom_operations = {
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 1598
 /** Phantom CLP data
1593 1599
  *
1594 1600
  */
@@ -1790,7 +1796,7 @@ struct phantom_clp_setting {
1790 1796
 	/** gPXE setting */
1791 1797
 	struct setting *setting;
1792 1798
 	/** Setting number */
1793
-	unsigned int number;
1799
+	unsigned int clp_setting;
1794 1800
 };
1795 1801
 
1796 1802
 /** Phantom CLP settings */
@@ -1802,25 +1808,29 @@ static struct phantom_clp_setting clp_settings[] = {
1802 1808
  * Find Phantom CLP setting
1803 1809
  *
1804 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 1815
 	struct phantom_clp_setting *clp_setting;
1811 1816
 	unsigned int i;
1812 1817
 
1818
+	/* Search the list of explicitly-defined settings */
1813 1819
 	for ( i = 0 ; i < ( sizeof ( clp_settings ) /
1814 1820
 			    sizeof ( clp_settings[0] ) ) ; i++ ) {
1815 1821
 		clp_setting = &clp_settings[i];
1816 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 1830
 	DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n",
1821 1831
 		phantom, setting->name );
1822 1832
 
1823
-	return NULL;
1833
+	return 0;
1824 1834
 }
1825 1835
 
1826 1836
 /**
@@ -1838,18 +1848,17 @@ static int phantom_store_setting ( struct settings *settings,
1838 1848
 	struct phantom_nic_port *phantom_port =
1839 1849
 		container_of ( settings, struct phantom_nic_port, settings );
1840 1850
 	struct phantom_nic *phantom = phantom_port->phantom;
1841
-	struct phantom_clp_setting *clp_setting;
1851
+	unsigned int clp_setting;
1842 1852
 	int rc;
1843 1853
 
1844 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 1856
 	if ( ! clp_setting )
1847 1857
 		return -ENOTSUP;
1848 1858
 
1849 1859
 	/* Store setting */
1850 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 1862
 		DBGC ( phantom, "Phantom %p could not store setting \"%s\": "
1854 1863
 		       "%s\n", phantom, setting->name, strerror ( rc ) );
1855 1864
 		return rc;
@@ -1873,19 +1882,18 @@ static int phantom_fetch_setting ( struct settings *settings,
1873 1882
 	struct phantom_nic_port *phantom_port =
1874 1883
 		container_of ( settings, struct phantom_nic_port, settings );
1875 1884
 	struct phantom_nic *phantom = phantom_port->phantom;
1876
-	struct phantom_clp_setting *clp_setting;
1885
+	unsigned int clp_setting;
1877 1886
 	int read_len;
1878 1887
 	int rc;
1879 1888
 
1880 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 1891
 	if ( ! clp_setting )
1883 1892
 		return -ENOTSUP;
1884 1893
 
1885 1894
 	/* Fetch setting */
1886 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 1897
 		rc = read_len;
1890 1898
 		DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": "
1891 1899
 		       "%s\n", phantom, setting->name, strerror ( rc ) );
@@ -2269,7 +2277,7 @@ static int phantom_probe ( struct pci_device *pci,
2269 2277
 		phantom_port->port = i;
2270 2278
 		settings_init ( &phantom_port->settings,
2271 2279
 				&phantom_settings_operations,
2272
-				&netdev->refcnt, "clp" );
2280
+				&netdev->refcnt, "clp", PHN_CLP_TAG_MAGIC );
2273 2281
 	}
2274 2282
 
2275 2283
 	/* BUG5945 - need to hack PCI config space on P3 B1 silicon.

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

@@ -72,6 +72,14 @@ struct settings {
72 72
 	struct refcnt *refcnt;
73 73
 	/** Name */
74 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 83
 	/** Parent settings block */
76 84
 	struct settings *parent;
77 85
 	/** Sibling settings blocks */
@@ -225,16 +233,19 @@ extern struct setting mac_setting __setting;
225 233
  * @v op		Settings block operations
226 234
  * @v refcnt		Containing object reference counter, or NULL
227 235
  * @v name		Settings block name
236
+ * @v tag_magic		Tag magic
228 237
  */
229 238
 static inline void settings_init ( struct settings *settings,
230 239
 				   struct settings_operations *op,
231 240
 				   struct refcnt *refcnt,
232
-				   const char *name ) {
241
+				   const char *name,
242
+				   unsigned int tag_magic ) {
233 243
 	INIT_LIST_HEAD ( &settings->siblings );
234 244
 	INIT_LIST_HEAD ( &settings->children );
235 245
 	settings->op = op;
236 246
 	settings->refcnt = refcnt;
237 247
 	settings->name = name;
248
+	settings->tag_magic = tag_magic;
238 249
 }
239 250
 
240 251
 /**
@@ -248,7 +259,7 @@ static inline void simple_settings_init ( struct simple_settings *simple,
248 259
 					  struct refcnt *refcnt,
249 260
 					  const char *name ) {
250 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,7 +268,7 @@ struct net_device * alloc_netdev ( size_t priv_size ) {
268 268
 		INIT_LIST_HEAD ( &netdev->rx_queue );
269 269
 		settings_init ( netdev_settings ( netdev ),
270 270
 				&netdev_settings_operations, &netdev->refcnt,
271
-				netdev->name );
271
+				netdev->name, 0 );
272 272
 		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
273 273
 	}
274 274
 	return netdev;

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

@@ -256,7 +256,7 @@ static struct dhcp_settings * dhcpset_create ( const struct dhcphdr *dhcphdr,
256 256
 		dhcppkt_init ( &dhcpset->dhcppkt, data, len );
257 257
 		settings_init ( &dhcpset->settings,
258 258
 				&dhcpset_settings_operations, &dhcpset->refcnt,
259
-				DHCP_SETTINGS_NAME );
259
+				DHCP_SETTINGS_NAME, 0 );
260 260
 	}
261 261
 	return dhcpset;
262 262
 }

Loading…
Cancel
Save