]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[smbios] Allow access to multiple instances of SMBIOS structures
authorMichael Brown <mcb30@ipxe.org>
Wed, 1 May 2013 19:42:57 +0000 (20:42 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 1 May 2013 21:11:04 +0000 (22:11 +0100)
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>
src/include/ipxe/smbios.h
src/interface/smbios/smbios.c
src/interface/smbios/smbios_settings.c

index 0765c4e4a3365cda290894312ab668718c724e07..aaba6cb12ac77b902374e2daefe5f04e0a1d3256 100644 (file)
@@ -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 );
index 2adaa53d98070f98fa3d3ae3ec8be6a8f44c6414..90907e18e45eddd98012437dd92bb81a670b8781 100644 (file)
@@ -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;
                }
index 17f9a48eecb1632ec227a938a499041b8c5bf0f1..d2975df442a716d965339e56f5b1f01d7e69a9f4 100644 (file)
@@ -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;
 
        {