Add support to the ipmi, isa attachment to attempt to read ipmi
config info. from device.hints. Some machines have ipmi controllers that do not have attachment info in either PCI, SMBIOS or ACPI. This idea was hacked together by me and then done properly by jhb. Submitted by: jhb Reviewed by: jhb (man page) Approved by: re (Ken Smith) MFC after: 1 week
This commit is contained in:
parent
871f1ddd46
commit
72d7331539
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 30, 2006
|
||||
.Dd July 10, 2007
|
||||
.Dt IPMI 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -33,6 +33,42 @@
|
||||
.Nd "OpenIPMI compatible IPMI interface driver"
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device ipmi"
|
||||
.Pp
|
||||
To manually specify I/O attachment in
|
||||
.Pa /boot/device.hints :
|
||||
.Cd hint.ipmi.0.at="isa"
|
||||
.Cd hint.ipmi.0.port="0xCA2"
|
||||
.Cd hint.ipmi.0.spacing="8"
|
||||
.Cd hint.ipmi.0.mode="KCS"
|
||||
.Pp
|
||||
To manually specify memory attachment in
|
||||
.Pa /boot/device.hints :
|
||||
.Cd hint.ipmi.0.at="isa"
|
||||
.Cd hint.ipmi.0.maddr="0xf0000000"
|
||||
.Cd hint.ipmi.0.spacing="8"
|
||||
.Cd hint.ipmi.0.mode="SMIC"
|
||||
.Pp
|
||||
Meaning of
|
||||
.Ar spacing :
|
||||
.Bl -tag -offset indent -compact -width 0x0
|
||||
.It 8
|
||||
8 bit alignment
|
||||
.It 16
|
||||
16 bit alignment
|
||||
.It 32
|
||||
32 bit alignment
|
||||
.El
|
||||
.Pp
|
||||
If the
|
||||
.Ar port
|
||||
and
|
||||
.Ar spacing
|
||||
are not specified the interface type default will be used. Only specify
|
||||
either the
|
||||
.Ar port
|
||||
for I/O access or
|
||||
.Ar maddr
|
||||
for memory access.
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Tn IPMI
|
||||
|
@ -86,6 +86,79 @@ ipmi_isa_probe(device_t dev)
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_hint_identify(device_t dev, struct ipmi_get_info *info)
|
||||
{
|
||||
const char *mode, *name;
|
||||
int i, unit, val;
|
||||
|
||||
/* We require at least a "mode" hint. */
|
||||
name = device_get_name(dev);
|
||||
unit = device_get_unit(dev);
|
||||
if (resource_string_value(name, unit, "mode", &mode) != 0)
|
||||
return (0);
|
||||
|
||||
/* Set the mode and default I/O resources for each mode. */
|
||||
bzero(info, sizeof(struct ipmi_get_info));
|
||||
if (strcasecmp(mode, "KCS") == 0) {
|
||||
info->iface_type = KCS_MODE;
|
||||
info->address = 0xca2;
|
||||
info->io_mode = 1;
|
||||
info->offset = 1;
|
||||
} else if (strcasecmp(mode, "SMIC") == 0) {
|
||||
info->iface_type = SMIC_MODE;
|
||||
info->address = 0xca9;
|
||||
info->io_mode = 1;
|
||||
info->offset = 1;
|
||||
} else if (strcasecmp(mode, "BT") == 0) {
|
||||
info->iface_type = BT_MODE;
|
||||
info->address = 0xe4;
|
||||
info->io_mode = 1;
|
||||
info->offset = 1;
|
||||
} else {
|
||||
device_printf(dev, "Invalid mode %s\n", mode);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kill any resources that isahint.c might have setup for us
|
||||
* since it will conflict with how we do resources.
|
||||
*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
bus_delete_resource(dev, SYS_RES_MEMORY, i);
|
||||
bus_delete_resource(dev, SYS_RES_IOPORT, i);
|
||||
}
|
||||
|
||||
/* Allow the I/O address to be overriden via hints. */
|
||||
if (resource_int_value(name, unit, "port", &val) == 0 && val != 0) {
|
||||
info->address = val;
|
||||
info->io_mode = 1;
|
||||
} else if (resource_int_value(name, unit, "maddr", &val) == 0 &&
|
||||
val != 0) {
|
||||
info->address = val;
|
||||
info->io_mode = 0;
|
||||
}
|
||||
|
||||
/* Allow the spacing to be overriden. */
|
||||
if (resource_int_value(name, unit, "spacing", &val) == 0) {
|
||||
switch (val) {
|
||||
case 8:
|
||||
info->offset = 1;
|
||||
break;
|
||||
case 16:
|
||||
info->offset = 2;
|
||||
break;
|
||||
case 32:
|
||||
info->offset = 4;
|
||||
break;
|
||||
default:
|
||||
device_printf(dev, "Invalid register spacing\n");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_isa_attach(device_t dev)
|
||||
{
|
||||
@ -94,8 +167,12 @@ ipmi_isa_attach(device_t dev)
|
||||
const char *mode;
|
||||
int count, error, i, type;
|
||||
|
||||
/* This should never fail. */
|
||||
if (!ipmi_smbios_identify(&info))
|
||||
/*
|
||||
* Pull info out of the SMBIOS table. If that doesn't work, use
|
||||
* hints to enumerate a device.
|
||||
*/
|
||||
if (!ipmi_smbios_identify(&info) &&
|
||||
!ipmi_hint_identify(dev, &info))
|
||||
return (ENXIO);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user