static void
ipmi_smbus_identify(driver_t *driver, device_t parent)
{
	struct ipmi_get_info info;

	if (ipmi_smbios_identify(&info) && info.iface_type == SSIF_MODE &&
	    device_find_child(parent, "ipmi", -1) == NULL)
		BUS_ADD_CHILD(parent, 0, "ipmi", -1);
}
static int
ipmi_smbus_attach(device_t dev)
{
	struct ipmi_softc *sc = device_get_softc(dev);
	struct ipmi_get_info info;
	int error;

	/* This should never fail. */
	if (!ipmi_smbios_identify(&info))
		return (ENXIO);

	if (info.iface_type != SSIF_MODE) {
		device_printf(dev, "No SSIF IPMI interface found\n");
		return (ENXIO);
	}

	sc->ipmi_dev = dev;

	if (info.irq != 0) {
		sc->ipmi_irq_rid = 0;
		sc->ipmi_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
		    &sc->ipmi_irq_rid, info.irq, info.irq, 1,
		    RF_SHAREABLE | RF_ACTIVE);
	}

	device_printf(dev, "SSIF mode found at address 0x%llx on %s\n",
	    (long long)info.address, device_get_name(device_get_parent(dev)));
	error = ipmi_ssif_attach(sc, device_get_parent(dev), info.address);
	if (error)
		goto bad;

	error = ipmi_attach(dev);
	if (error)
		goto bad;

	return (0);
bad:
	ipmi_release_resources(dev);
	return (error);
}
Exemple #3
0
static int
ipmi_pci_attach(device_t dev)
{
	struct ipmi_softc *sc = device_get_softc(dev);
	struct ipmi_get_info info;
	const char *mode;
	int error, type;

	/* Look for an IPMI entry in the SMBIOS table. */
	if (!ipmi_smbios_identify(&info))
		return (ENXIO);

	sc->ipmi_dev = dev;

	switch (info.iface_type) {
	case KCS_MODE:
		mode = "KCS";
		break;
	case SMIC_MODE:
		mode = "SMIC";
		break;
	case BT_MODE:
		device_printf(dev, "BT mode is unsupported\n");
		return (ENXIO);
	default:
		device_printf(dev, "No IPMI interface found\n");
		return (ENXIO);
	}

	device_printf(dev, "%s mode found at %s 0x%jx alignment 0x%x on %s\n",
	    mode, info.io_mode ? "io" : "mem",
	    (uintmax_t)info.address, info.offset,
	    device_get_name(device_get_parent(dev)));
	if (info.io_mode)
		type = SYS_RES_IOPORT;
	else
		type = SYS_RES_MEMORY;

	sc->ipmi_io_rid = PCIR_BAR(0);
	sc->ipmi_io_res[0] = bus_alloc_resource_any(dev, type,
	    &sc->ipmi_io_rid, RF_ACTIVE);
	sc->ipmi_io_type = type;
	sc->ipmi_io_spacing = info.offset;

	if (sc->ipmi_io_res[0] == NULL) {
		device_printf(dev, "couldn't configure pci io res\n");
		return (ENXIO);
	}

	sc->ipmi_irq_rid = 0;
	sc->ipmi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &sc->ipmi_irq_rid, RF_SHAREABLE | RF_ACTIVE);

	switch (info.iface_type) {
	case KCS_MODE:
		error = ipmi_kcs_attach(sc);
		if (error)
			goto bad;
		break;
	case SMIC_MODE:
		error = ipmi_smic_attach(sc);
		if (error)
			goto bad;
		break;
	}
	error = ipmi_attach(dev);
	if (error)
		goto bad;

	return (0);
bad:
	ipmi_release_resources(dev);
	return (error);
}