// SPDX-License-Identifier: GPL-2.0+ /* * A hack to create a platform device from a DMI entry. This will * allow autoloading of the IPMI drive based on SMBIOS entries.
*/
if (ipmi_platform_add(name, ipmi_dmi_nr, &p))
ipmi_dmi_nr++;
}
/* * Look up the slave address for a given interface. This is here * because ACPI doesn't have a slave address while SMBIOS does, but we * prefer using ACPI so the ACPI code can use the IPMI namespace. * This function allows an ACPI-specified IPMI device to look up the * slave address from the DMI table.
*/ int ipmi_dmi_get_slave_addr(enum si_type si_type, unsignedint space, unsignedlong base_addr)
{ struct ipmi_dmi_info *info = ipmi_dmi_infos;
while (info) { if (info->si_type == si_type &&
info->space == space &&
info->addr == base_addr) return info->slave_addr;
info = info->next;
}
staticvoid __init dmi_decode_ipmi(conststruct dmi_header *dm)
{ const u8 *data = (const u8 *) dm; int space = IPMI_IO_ADDR_SPACE; unsignedlong base_addr;
u8 len = dm->length;
u8 slave_addr; int irq = 0, offset = 0; int type;
if (len < DMI_IPMI_MIN_LENGTH) return;
type = data[DMI_IPMI_TYPE];
slave_addr = data[DMI_IPMI_SLAVEADDR];
memcpy(&base_addr, data + DMI_IPMI_ADDR, sizeof(unsignedlong)); if (!base_addr) {
pr_err("Base address is zero, assuming no IPMI interface\n"); return;
} if (len >= DMI_IPMI_VER2_LENGTH) { if (type == IPMI_DMI_TYPE_SSIF) {
space = 0; /* Match I2C interface 0. */
base_addr = data[DMI_IPMI_ADDR] >> 1; if (base_addr == 0) { /* * Some broken systems put the I2C address in * the slave address field. We try to * accommodate them here.
*/
base_addr = data[DMI_IPMI_SLAVEADDR] >> 1;
slave_addr = 0;
}
} else { if (base_addr & 1) { /* I/O */
base_addr &= DMI_IPMI_IO_MASK;
} else { /* Memory */
space = IPMI_MEM_ADDR_SPACE;
}
/* * If bit 4 of byte 0x10 is set, then the lsb * for the address is odd.
*/
base_addr |= (data[DMI_IPMI_ACCESS] >> 4) & 1;
irq = data[DMI_IPMI_IRQ];
/* * The top two bits of byte 0x10 hold the * register spacing.
*/ switch ((data[DMI_IPMI_ACCESS] >> 6) & 3) { case 0: /* Byte boundaries */
offset = 1; break; case 1: /* 32-bit boundaries */
offset = 4; break; case 2: /* 16-byte boundaries */
offset = 16; break; default:
pr_err("Invalid offset: 0\n"); return;
}
}
} else { /* Old DMI spec. */ /* * Note that technically, the lower bit of the base * address should be 1 if the address is I/O and 0 if * the address is in memory. So many systems get that * wrong (and all that I have seen are I/O) so we just * ignore that bit and assume I/O. Systems that use * memory should use the newer spec, anyway.
*/
base_addr = base_addr & DMI_IPMI_IO_MASK;
offset = 1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.