diff options
-rw-r--r-- | share/man/man4/ipmi.4 | 38 | ||||
-rw-r--r-- | sys/dev/ipmi/ipmi_isa.c | 81 |
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); /* |