Browse Source

[smbios] Allow access to multiple instances of SMBIOS structures

Extend the syntax for numerical SMBIOS settings from

  smbios/<type>.<offset>.<length>

to

  smbios/[<instance>.]<type>.<offset>.<length>

Where SMBIOS provides multiple structures with the same <type>, this
extended syntax allows for access to structures other than the first.
If <instance> is omitted then it will default to zero, giving access
to the first instance (and so matching existing behaviour).

The 16-bit SMBIOS handle (which is an alternative way to disambiguate
multiple instances of the same type of structure) can be accessed, if
required, using

  smbios/<instance>.<type>.2.2:uint16

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
8bc20c1aa0

+ 1
- 1
src/include/ipxe/smbios.h View File

@@ -162,7 +162,7 @@ struct smbios {
162 162
 #define SMBIOS_VERSION( major, minor ) ( ( (major) << 8 ) | (minor) )
163 163
 
164 164
 extern int find_smbios ( struct smbios *smbios );
165
-extern int find_smbios_structure ( unsigned int type,
165
+extern int find_smbios_structure ( unsigned int type, unsigned int instance,
166 166
 				   struct smbios_structure *structure );
167 167
 extern int read_smbios_structure ( struct smbios_structure *structure,
168 168
 				   void *data, size_t len );

+ 4
- 2
src/interface/smbios/smbios.c View File

@@ -59,10 +59,11 @@ static size_t find_strings_terminator ( size_t offset ) {
59 59
  * Find specific structure type within SMBIOS
60 60
  *
61 61
  * @v type		Structure type to search for
62
+ * @v instance		Instance of this type of structure
62 63
  * @v structure		SMBIOS structure descriptor to fill in
63 64
  * @ret rc		Return status code
64 65
  */
65
-int find_smbios_structure ( unsigned int type,
66
+int find_smbios_structure ( unsigned int type, unsigned int instance,
66 67
 			    struct smbios_structure *structure ) {
67 68
 	unsigned int count = 0;
68 69
 	size_t offset = 0;
@@ -105,7 +106,8 @@ int find_smbios_structure ( unsigned int type,
105 106
 		      structure->header.len, structure->strings_len );
106 107
 
107 108
 		/* If this is the structure we want, return */
108
-		if ( structure->header.type == type ) {
109
+		if ( ( structure->header.type == type ) &&
110
+		     ( instance-- == 0 ) ) {
109 111
 			structure->offset = offset;
110 112
 			return 0;
111 113
 		}

+ 5
- 2
src/interface/smbios/smbios_settings.c View File

@@ -81,18 +81,21 @@ static int smbios_fetch ( struct settings *settings __unused,
81 81
 			  struct setting *setting,
82 82
 			  void *data, size_t len ) {
83 83
 	struct smbios_structure structure;
84
+	unsigned int tag_instance;
84 85
 	unsigned int tag_type;
85 86
 	unsigned int tag_offset;
86 87
 	unsigned int tag_len;
87 88
 	int rc;
88 89
 
89
-	/* Split tag into type, offset and length */
90
+	/* Split tag into instance, type, offset and length */
91
+	tag_instance = ( ( setting->tag >> 24 ) & 0xff );
90 92
 	tag_type = ( ( setting->tag >> 16 ) & 0xff );
91 93
 	tag_offset = ( ( setting->tag >> 8 ) & 0xff );
92 94
 	tag_len = ( setting->tag & 0xff );
93 95
 
94 96
 	/* Find SMBIOS structure */
95
-	if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
97
+	if ( ( rc = find_smbios_structure ( tag_type, tag_instance,
98
+					    &structure ) ) != 0 )
96 99
 		return rc;
97 100
 
98 101
 	{

Loading…
Cancel
Save