[smbios] Remove userptr_t from SMBIOS structure parsing

Simplify the SMBIOS structure parsing code by assuming that all
structure content is fully accessible via pointer dereferences.

In particular, this allows the convoluted find_smbios_structure() and
read_smbios_structure() to be combined into a single function
smbios_structure() that just returns a direct pointer to the SMBIOS
structure, with smbios_string() similarly now returning a direct
pointer to the relevant string.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-04-23 09:53:38 +01:00
parent 0b3fc48fef
commit 0bf0f8716a
7 changed files with 257 additions and 314 deletions
+34 -59
View File
@@ -64,92 +64,67 @@ static struct profiler smsc95xx_out_profiler __profiler =
*/
static int smsc95xx_vm3_fetch_mac ( struct smscusb_device *smscusb ) {
struct net_device *netdev = smscusb->netdev;
struct smbios_structure structure;
struct smbios_system_information system;
struct {
char manufacturer[ 10 /* "Honeywell" + NUL */ ];
char product[ 4 /* "VM3" + NUL */ ];
char mac[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
} strings;
const struct smbios_header *structure;
const struct smbios_system_information *system;
const char *manufacturer;
const char *product;
const char *mac;
int len;
int rc;
/* Find system information */
if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0,
&structure ) ) != 0 ) {
structure = smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0 );
if ( ! structure ) {
DBGC ( smscusb, "SMSC95XX %p could not find system "
"information: %s\n", smscusb, strerror ( rc ) );
return rc;
"information\n", smscusb );
return -ENOENT;
}
/* Read system information */
if ( ( rc = read_smbios_structure ( &structure, &system,
sizeof ( system ) ) ) != 0 ) {
DBGC ( smscusb, "SMSC95XX %p could not read system "
"information: %s\n", smscusb, strerror ( rc ) );
return rc;
}
/* NUL-terminate all strings to be fetched */
memset ( &strings, 0, sizeof ( strings ) );
system = container_of ( structure, struct smbios_system_information,
header );
/* Fetch system manufacturer name */
len = read_smbios_string ( &structure, system.manufacturer,
strings.manufacturer,
( sizeof ( strings.manufacturer ) - 1 ) );
if ( len < 0 ) {
rc = len;
manufacturer = smbios_string ( structure, system->manufacturer );
if ( ! manufacturer ) {
DBGC ( smscusb, "SMSC95XX %p could not read manufacturer "
"name: %s\n", smscusb, strerror ( rc ) );
return rc;
"name\n", smscusb );
return -ENOENT;
}
/* Fetch system product name */
len = read_smbios_string ( &structure, system.product, strings.product,
( sizeof ( strings.product ) - 1 ) );
if ( len < 0 ) {
rc = len;
DBGC ( smscusb, "SMSC95XX %p could not read product name: "
"%s\n", smscusb, strerror ( rc ) );
return rc;
product = smbios_string ( structure, system->product );
if ( ! product ) {
DBGC ( smscusb, "SMSC95XX %p could not read product name\n",
smscusb );
return -ENOENT;
}
/* Ignore non-VM3 devices */
if ( ( strcmp ( strings.manufacturer, "Honeywell" ) != 0 ) ||
( strcmp ( strings.product, "VM3" ) != 0 ) )
if ( ( strcmp ( manufacturer, "Honeywell" ) != 0 ) ||
( strcmp ( product, "VM3" ) != 0 ) )
return -ENOTTY;
/* Find OEM strings */
if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0,
&structure ) ) != 0 ) {
DBGC ( smscusb, "SMSC95XX %p could not find OEM strings: %s\n",
smscusb, strerror ( rc ) );
return rc;
structure = smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0 );
if ( ! structure ) {
DBGC ( smscusb, "SMSC95XX %p could not find OEM strings\n",
smscusb );
return -ENOENT;
}
/* Fetch MAC address */
len = read_smbios_string ( &structure, SMSC95XX_VM3_OEM_STRING_MAC,
strings.mac, ( sizeof ( strings.mac ) - 1 ));
if ( len < 0 ) {
rc = len;
DBGC ( smscusb, "SMSC95XX %p could not read OEM string: %s\n",
smscusb, strerror ( rc ) );
return rc;
}
/* Sanity check */
if ( len != ( ( int ) ( sizeof ( strings.mac ) - 1 ) ) ) {
DBGC ( smscusb, "SMSC95XX %p invalid MAC address \"%s\"\n",
smscusb, strings.mac );
return -EINVAL;
mac = smbios_string ( structure, SMSC95XX_VM3_OEM_STRING_MAC );
if ( ! mac ) {
DBGC ( smscusb, "SMSC95XX %p could not read OEM string\n",
smscusb );
return -ENOENT;
}
/* Decode MAC address */
len = base16_decode ( strings.mac, netdev->hw_addr, ETH_ALEN );
len = base16_decode ( mac, netdev->hw_addr, ETH_ALEN );
if ( len < 0 ) {
rc = len;
DBGC ( smscusb, "SMSC95XX %p invalid MAC address \"%s\"\n",
smscusb, strings.mac );
smscusb, mac );
return rc;
}