summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/ipmi.438
-rw-r--r--sys/dev/ipmi/ipmi_isa.c81
2 files changed, 116 insertions, 3 deletions
diff --git a/share/man/man4/ipmi.4 b/share/man/man4/ipmi.4
index a061df2..9ae078d 100644
--- a/share/man/man4/ipmi.4
+++ b/share/man/man4/ipmi.4
@@ -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
diff --git a/sys/dev/ipmi/ipmi_isa.c b/sys/dev/ipmi/ipmi_isa.c
index a77081a..9d3f9f3 100644
--- a/sys/dev/ipmi/ipmi_isa.c
+++ b/sys/dev/ipmi/ipmi_isa.c
@@ -87,6 +87,79 @@ ipmi_isa_probe(device_t dev)
}
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)
{
struct ipmi_softc *sc = device_get_softc(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);
/*
OpenPOWER on IntegriCloud