diff options
| author | Michael Brown | 2013-05-01 21:42:57 +0200 |
|---|---|---|
| committer | Michael Brown | 2013-05-01 23:11:04 +0200 |
| commit | 8bc20c1aa09ec521476f4b35b0a09c21e2e1e5f3 (patch) | |
| tree | 2d931446de6536772b283a69d1ddbaaa34094465 /src | |
| parent | [smbios] Allow access to unreferenced SMBIOS strings (diff) | |
| download | ipxe-8bc20c1aa09ec521476f4b35b0a09c21e2e1e5f3.tar.gz ipxe-8bc20c1aa09ec521476f4b35b0a09c21e2e1e5f3.tar.xz ipxe-8bc20c1aa09ec521476f4b35b0a09c21e2e1e5f3.zip | |
[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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/ipxe/smbios.h | 2 | ||||
| -rw-r--r-- | src/interface/smbios/smbios.c | 6 | ||||
| -rw-r--r-- | src/interface/smbios/smbios_settings.c | 7 |
3 files changed, 10 insertions, 5 deletions
diff --git a/src/include/ipxe/smbios.h b/src/include/ipxe/smbios.h index 0765c4e4a..aaba6cb12 100644 --- a/src/include/ipxe/smbios.h +++ b/src/include/ipxe/smbios.h @@ -162,7 +162,7 @@ struct smbios { #define SMBIOS_VERSION( major, minor ) ( ( (major) << 8 ) | (minor) ) extern int find_smbios ( struct smbios *smbios ); -extern int find_smbios_structure ( unsigned int type, +extern int find_smbios_structure ( unsigned int type, unsigned int instance, struct smbios_structure *structure ); extern int read_smbios_structure ( struct smbios_structure *structure, void *data, size_t len ); diff --git a/src/interface/smbios/smbios.c b/src/interface/smbios/smbios.c index 2adaa53d9..90907e18e 100644 --- a/src/interface/smbios/smbios.c +++ b/src/interface/smbios/smbios.c @@ -59,10 +59,11 @@ static size_t find_strings_terminator ( size_t offset ) { * Find specific structure type within SMBIOS * * @v type Structure type to search for + * @v instance Instance of this type of structure * @v structure SMBIOS structure descriptor to fill in * @ret rc Return status code */ -int find_smbios_structure ( unsigned int type, +int find_smbios_structure ( unsigned int type, unsigned int instance, struct smbios_structure *structure ) { unsigned int count = 0; size_t offset = 0; @@ -105,7 +106,8 @@ int find_smbios_structure ( unsigned int type, structure->header.len, structure->strings_len ); /* If this is the structure we want, return */ - if ( structure->header.type == type ) { + if ( ( structure->header.type == type ) && + ( instance-- == 0 ) ) { structure->offset = offset; return 0; } diff --git a/src/interface/smbios/smbios_settings.c b/src/interface/smbios/smbios_settings.c index 17f9a48ee..d2975df44 100644 --- a/src/interface/smbios/smbios_settings.c +++ b/src/interface/smbios/smbios_settings.c @@ -81,18 +81,21 @@ static int smbios_fetch ( struct settings *settings __unused, struct setting *setting, void *data, size_t len ) { struct smbios_structure structure; + unsigned int tag_instance; unsigned int tag_type; unsigned int tag_offset; unsigned int tag_len; int rc; - /* Split tag into type, offset and length */ + /* Split tag into instance, type, offset and length */ + tag_instance = ( ( setting->tag >> 24 ) & 0xff ); tag_type = ( ( setting->tag >> 16 ) & 0xff ); tag_offset = ( ( setting->tag >> 8 ) & 0xff ); tag_len = ( setting->tag & 0xff ); /* Find SMBIOS structure */ - if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 ) + if ( ( rc = find_smbios_structure ( tag_type, tag_instance, + &structure ) ) != 0 ) return rc; { |
