ipmi_smbios: Deduplicate smbios entry point discovery logic
Sponsored by: Ampere Computing LLC Submitted by: Klara Inc. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D28743
This commit is contained in:
@@ -286,3 +286,4 @@ static driver_t ipmi_isa_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DRIVER_MODULE(ipmi_isa, isa, ipmi_isa_driver, ipmi_devclass, 0, 0);
|
DRIVER_MODULE(ipmi_isa, isa, ipmi_isa_driver, ipmi_devclass, 0, 0);
|
||||||
|
MODULE_DEPEND(ipmi_isa, smbios, 1, 1, 1);
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ static driver_t ipmi_pci_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DRIVER_MODULE(ipmi_pci, pci, ipmi_pci_driver, ipmi_devclass, 0, 0);
|
DRIVER_MODULE(ipmi_pci, pci, ipmi_pci_driver, ipmi_devclass, 0, 0);
|
||||||
|
MODULE_DEPEND(ipmi_pci, smbios, 1, 1, 1);
|
||||||
|
|
||||||
/* Native IPMI on PCI driver. */
|
/* Native IPMI on PCI driver. */
|
||||||
|
|
||||||
|
|||||||
+16
-30
@@ -88,7 +88,7 @@ MTX_SYSINIT(ipmi_info, &ipmi_info_mtx, "ipmi info", MTX_DEF);
|
|||||||
|
|
||||||
static void ipmi_smbios_probe(struct ipmi_get_info *);
|
static void ipmi_smbios_probe(struct ipmi_get_info *);
|
||||||
static int smbios_cksum(struct smbios_eps *);
|
static int smbios_cksum(struct smbios_eps *);
|
||||||
static void smbios_walk_table(uint8_t *, int, smbios_callback_t,
|
static void smbios_walk_table(uint8_t *, vm_size_t, smbios_callback_t,
|
||||||
void *);
|
void *);
|
||||||
static void smbios_ipmi_info(struct smbios_structure_header *, void *);
|
static void smbios_ipmi_info(struct smbios_structure_header *, void *);
|
||||||
|
|
||||||
@@ -147,11 +147,12 @@ smbios_ipmi_info(struct smbios_structure_header *h, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
|
smbios_walk_table(uint8_t *table, vm_size_t size, smbios_callback_t cb, void *arg)
|
||||||
{
|
{
|
||||||
struct smbios_structure_header *s;
|
struct smbios_structure_header *s;
|
||||||
|
uint8_t *p;
|
||||||
|
|
||||||
while (entries--) {
|
for (p = table; p < table + size;) {
|
||||||
s = (struct smbios_structure_header *)p;
|
s = (struct smbios_structure_header *)p;
|
||||||
cb(s, arg);
|
cb(s, arg);
|
||||||
|
|
||||||
@@ -160,8 +161,11 @@ smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
|
|||||||
* formatted area of this structure.
|
* formatted area of this structure.
|
||||||
*/
|
*/
|
||||||
p += s->length;
|
p += s->length;
|
||||||
while (!(p[0] == 0 && p[1] == 0))
|
while (!(p[0] == 0 && p[1] == 0)) {
|
||||||
p++;
|
p++;
|
||||||
|
if (p >= table + size)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip over the double-nul to the start of the next
|
* Skip over the double-nul to the start of the next
|
||||||
@@ -179,41 +183,23 @@ smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
|
|||||||
static void
|
static void
|
||||||
ipmi_smbios_probe(struct ipmi_get_info *info)
|
ipmi_smbios_probe(struct ipmi_get_info *info)
|
||||||
{
|
{
|
||||||
struct smbios_eps *header;
|
|
||||||
void *table;
|
void *table;
|
||||||
u_int32_t addr;
|
vm_paddr_t table_paddr;
|
||||||
|
vm_size_t table_size;
|
||||||
|
int err;
|
||||||
|
|
||||||
bzero(info, sizeof(struct ipmi_get_info));
|
bzero(info, sizeof(struct ipmi_get_info));
|
||||||
|
|
||||||
/* Find the SMBIOS table header. */
|
err = smbios_get_structure_table(&table_paddr, &table_size);
|
||||||
addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
|
if (err != 0)
|
||||||
SMBIOS_STEP, SMBIOS_OFF);
|
|
||||||
if (addr == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
table = pmap_mapbios(table_paddr, table_size);
|
||||||
* Map the header. We first map a fixed size to get the actual
|
|
||||||
* length and then map it a second time with the actual length so
|
|
||||||
* we can verify the checksum.
|
|
||||||
*/
|
|
||||||
header = pmap_mapbios(addr, sizeof(struct smbios_eps));
|
|
||||||
table = pmap_mapbios(addr, header->length);
|
|
||||||
pmap_unmapbios((vm_offset_t)header, sizeof(struct smbios_eps));
|
|
||||||
header = table;
|
|
||||||
if (smbios_cksum(header) != 0) {
|
|
||||||
pmap_unmapbios((vm_offset_t)header, header->length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now map the actual table and walk it looking for an IPMI entry. */
|
smbios_walk_table(table, table_size, smbios_ipmi_info, info);
|
||||||
table = pmap_mapbios(header->structure_table_address,
|
|
||||||
header->structure_table_length);
|
|
||||||
smbios_walk_table(table, header->number_structures, smbios_ipmi_info,
|
|
||||||
info);
|
|
||||||
|
|
||||||
/* Unmap everything. */
|
/* Unmap everything. */
|
||||||
pmap_unmapbios((vm_offset_t)table, header->structure_table_length);
|
pmap_unmapbios((vm_offset_t)table, table_size);
|
||||||
pmap_unmapbios((vm_offset_t)header, header->length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -131,3 +131,4 @@ static driver_t ipmi_smbus_driver = {
|
|||||||
|
|
||||||
DRIVER_MODULE(ipmi_smbus, smbus, ipmi_smbus_driver, ipmi_devclass, 0, 0);
|
DRIVER_MODULE(ipmi_smbus, smbus, ipmi_smbus_driver, ipmi_devclass, 0, 0);
|
||||||
MODULE_DEPEND(ipmi_smbus, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
MODULE_DEPEND(ipmi_smbus, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
|
||||||
|
MODULE_DEPEND(ipmi_smbus, smbios, 1, 1, 1);
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#endif
|
#endif
|
||||||
#include <dev/smbios/smbios.h>
|
#include <dev/smbios/smbios.h>
|
||||||
|
|
||||||
|
static struct smbios_softc *smbios;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System Management BIOS Reference Specification, v2.4 Final
|
* System Management BIOS Reference Specification, v2.4 Final
|
||||||
* http://www.dmtf.org/standards/published_documents/DSP0134.pdf
|
* http://www.dmtf.org/standards/published_documents/DSP0134.pdf
|
||||||
@@ -179,6 +181,7 @@ smbios_attach (device_t dev)
|
|||||||
bcd2bin(sc->eps->BCD_revision & 0x0f));
|
bcd2bin(sc->eps->BCD_revision & 0x0f));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
smbios = sc;
|
||||||
return (0);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
if (sc->res)
|
if (sc->res)
|
||||||
@@ -191,6 +194,7 @@ smbios_detach (device_t dev)
|
|||||||
{
|
{
|
||||||
struct smbios_softc *sc;
|
struct smbios_softc *sc;
|
||||||
|
|
||||||
|
smbios = NULL;
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
|
|
||||||
if (sc->res)
|
if (sc->res)
|
||||||
@@ -199,6 +203,23 @@ smbios_detach (device_t dev)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
smbios_get_structure_table(vm_paddr_t *table, vm_size_t *size)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (smbios == NULL)
|
||||||
|
return (ENXIO);
|
||||||
|
if (smbios->eps_64bit) {
|
||||||
|
*table = smbios->eps3->structure_table_address;
|
||||||
|
*size = smbios->eps3->structure_table_max_size;
|
||||||
|
} else {
|
||||||
|
*table = smbios->eps->structure_table_address;
|
||||||
|
*size = smbios->eps->structure_table_length;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
smbios_modevent (mod, what, arg)
|
smbios_modevent (mod, what, arg)
|
||||||
module_t mod;
|
module_t mod;
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
#ifndef _SMBIOS_H_
|
#ifndef _SMBIOS_H_
|
||||||
#define _SMBIOS_H_
|
#define _SMBIOS_H_
|
||||||
|
|
||||||
|
int smbios_get_structure_table(vm_paddr_t *table, vm_size_t *size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System Management BIOS
|
* System Management BIOS
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user