#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <gpxe/uaccess.h>
#include <gpxe/smbios.h>
Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static size_t | find_strings_terminator (size_t offset) |
| Find SMBIOS strings terminator. | |
| int | find_smbios_structure (unsigned int type, struct smbios_structure *structure) |
| Find specific structure type within SMBIOS. | |
| int | read_smbios_structure (struct smbios_structure *structure, void *data, size_t len) |
| Copy SMBIOS structure. | |
| int | read_smbios_string (struct smbios_structure *structure, unsigned int index, void *data, size_t len) |
| Find indexed string within SMBIOS structure. | |
Variables | |
| static struct smbios | smbios |
| SMBIOS entry point descriptor. | |
Definition in file smbios.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
Find SMBIOS strings terminator.
| offset | Offset to start of strings |
| offset | Offset to strings terminator, or 0 if not found |
Definition at line 45 of file smbios.c.
References smbios::address, copy_from_user(), and smbios::len.
Referenced by find_smbios_structure().
00045 { 00046 size_t max_offset = ( smbios.len - 2 ); 00047 uint16_t nulnul; 00048 00049 for ( ; offset <= max_offset ; offset++ ) { 00050 copy_from_user ( &nulnul, smbios.address, offset, 2 ); 00051 if ( nulnul == 0 ) 00052 return ( offset + 1 ); 00053 } 00054 return 0; 00055 }
| int find_smbios_structure | ( | unsigned int | type, | |
| struct smbios_structure * | structure | |||
| ) |
Find specific structure type within SMBIOS.
| type | Structure type to search for | |
| structure | SMBIOS structure descriptor to fill in |
| rc | Return status code |
Definition at line 64 of file smbios.c.
References smbios::address, assert, copy_from_user(), smbios::count, DBG, ENOENT, find_smbios(), find_strings_terminator(), smbios_structure::header, smbios_header::len, smbios::len, smbios_structure::offset, offset, smbios_structure::strings_len, smbios_header::type, and UNULL.
Referenced by smbios_fetch().
00065 { 00066 unsigned int count = 0; 00067 size_t offset = 0; 00068 size_t strings_offset; 00069 size_t terminator_offset; 00070 int rc; 00071 00072 /* Find SMBIOS */ 00073 if ( ( smbios.address == UNULL ) && 00074 ( ( rc = find_smbios ( &smbios ) ) != 0 ) ) 00075 return rc; 00076 assert ( smbios.address != UNULL ); 00077 00078 /* Scan through list of structures */ 00079 while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len ) 00080 && ( count < smbios.count ) ) { 00081 00082 /* Read next SMBIOS structure header */ 00083 copy_from_user ( &structure->header, smbios.address, offset, 00084 sizeof ( structure->header ) ); 00085 00086 /* Determine start and extent of strings block */ 00087 strings_offset = ( offset + structure->header.len ); 00088 if ( strings_offset > smbios.len ) { 00089 DBG ( "SMBIOS structure at offset %zx with length " 00090 "%x extends beyond SMBIOS\n", offset, 00091 structure->header.len ); 00092 return -ENOENT; 00093 } 00094 terminator_offset = find_strings_terminator ( strings_offset ); 00095 if ( ! terminator_offset ) { 00096 DBG ( "SMBIOS structure at offset %zx has " 00097 "unterminated strings section\n", offset ); 00098 return -ENOENT; 00099 } 00100 structure->strings_len = ( terminator_offset - strings_offset); 00101 00102 DBG ( "SMBIOS structure at offset %zx has type %d, length %x, " 00103 "strings length %zx\n", offset, structure->header.type, 00104 structure->header.len, structure->strings_len ); 00105 00106 /* If this is the structure we want, return */ 00107 if ( structure->header.type == type ) { 00108 structure->offset = offset; 00109 return 0; 00110 } 00111 00112 /* Move to next SMBIOS structure */ 00113 offset = ( terminator_offset + 1 ); 00114 count++; 00115 } 00116 00117 DBG ( "SMBIOS structure type %d not found\n", type ); 00118 return -ENOENT; 00119 }
| int read_smbios_structure | ( | struct smbios_structure * | structure, | |
| void * | data, | |||
| size_t | len | |||
| ) |
Copy SMBIOS structure.
| structure | SMBIOS structure descriptor | |
| data | Buffer to hold SMBIOS structure | |
| len | Length of buffer |
| rc | Return status code |
Definition at line 129 of file smbios.c.
References smbios::address, assert, copy_from_user(), smbios_structure::header, smbios_header::len, smbios_structure::offset, and UNULL.
Referenced by smbios_fetch().
00130 { 00131 00132 assert ( smbios.address != UNULL ); 00133 00134 if ( len > structure->header.len ) 00135 len = structure->header.len; 00136 copy_from_user ( data, smbios.address, structure->offset, len ); 00137 return 0; 00138 }
| int read_smbios_string | ( | struct smbios_structure * | structure, | |
| unsigned int | index, | |||
| void * | data, | |||
| size_t | len | |||
| ) |
Find indexed string within SMBIOS structure.
| structure | SMBIOS structure descriptor | |
| index | String index | |
| data | Buffer for string | |
| len | Length of string buffer |
| rc | Length of string, or negative error |
Definition at line 149 of file smbios.c.
References smbios::address, assert, copy_from_user(), DBG, ENOENT, smbios_structure::header, smbios_header::len, offset, smbios_structure::offset, smbios_structure::strings_len, strlen_user(), and UNULL.
Referenced by smbios_fetch().
00150 { 00151 size_t strings_start = ( structure->offset + structure->header.len ); 00152 size_t strings_end = ( strings_start + structure->strings_len ); 00153 size_t offset; 00154 size_t string_len; 00155 00156 assert ( smbios.address != UNULL ); 00157 00158 /* String numbers start at 1 (0 is used to indicate "no string") */ 00159 if ( ! index ) 00160 return -ENOENT; 00161 00162 for ( offset = strings_start ; offset < strings_end ; 00163 offset += ( string_len + 1 ) ) { 00164 /* Get string length. This is known safe, since the 00165 * smbios_strings struct is constructed so as to 00166 * always end on a string boundary. 00167 */ 00168 string_len = strlen_user ( smbios.address, offset ); 00169 if ( --index == 0 ) { 00170 /* Copy string, truncating as necessary. */ 00171 if ( len > string_len ) 00172 len = string_len; 00173 copy_from_user ( data, smbios.address, offset, len ); 00174 return string_len; 00175 } 00176 } 00177 00178 DBG ( "SMBIOS string index %d not found\n", index ); 00179 return -ENOENT; 00180 }
1.5.7.1