Пример #1
0
static int __init ipmi_parisc_probe(struct parisc_device *dev)
{
	struct si_sm_io io;

	io.si_type	= SI_KCS;
	io.addr_source	= SI_DEVICETREE;
	io.addr_type	= IPMI_MEM_ADDR_SPACE;
	io.addr_data	= dev->hpa.start;
	io.regsize	= 1;
	io.regspacing	= 1;
	io.regshift	= 0;
	io.irq		= 0; /* no interrupt */
	io.irq_setup	= NULL;
	io.dev		= &dev->dev;

	dev_dbg(&dev->dev, "addr 0x%lx\n", io.addr_data);

	return ipmi_si_add_smi(&io);
}
Пример #2
0
int ipmi_si_hardcode_find_bmc(void)
{
	int ret = -ENODEV;
	int             i;
	struct si_sm_io io;
	char *str;

	/* Parse out the si_type string into its components. */
	str = si_type_str;
	if (*str != '\0') {
		for (i = 0; (i < SI_MAX_PARMS) && (*str != '\0'); i++) {
			si_type[i] = str;
			str = strchr(str, ',');
			if (str) {
				*str = '\0';
				str++;
			} else {
				break;
			}
		}
	}

	memset(&io, 0, sizeof(io));
	for (i = 0; i < SI_MAX_PARMS; i++) {
		if (!ports[i] && !addrs[i])
			continue;

		io.addr_source = SI_HARDCODED;
		pr_info(PFX "probing via hardcoded address\n");

		if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
			io.si_type = SI_KCS;
		} else if (strcmp(si_type[i], "smic") == 0) {
			io.si_type = SI_SMIC;
		} else if (strcmp(si_type[i], "bt") == 0) {
			io.si_type = SI_BT;
		} else {
			pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n",
				i, si_type[i]);
			continue;
		}

		if (ports[i]) {
			/* An I/O port */
			io.addr_data = ports[i];
			io.addr_type = IPMI_IO_ADDR_SPACE;
		} else if (addrs[i]) {
			/* A memory port */
			io.addr_data = addrs[i];
			io.addr_type = IPMI_MEM_ADDR_SPACE;
		} else {
			pr_warn(PFX "Interface type specified for interface %d, but port and address were not set or set to zero.\n",
				i);
			continue;
		}

		io.addr = NULL;
		io.regspacing = regspacings[i];
		if (!io.regspacing)
			io.regspacing = DEFAULT_REGSPACING;
		io.regsize = regsizes[i];
		if (!io.regsize)
			io.regsize = DEFAULT_REGSIZE;
		io.regshift = regshifts[i];
		io.irq = irqs[i];
		if (io.irq)
			io.irq_setup = ipmi_std_irq_setup;
		io.slave_addr = slave_addrs[i];

		ret = ipmi_si_add_smi(&io);
	}
	return ret;
}
Пример #3
0
static int hotmod_handler(const char *val, const struct kernel_param *kp)
{
	char *str = kstrdup(val, GFP_KERNEL);
	int  rv;
	char *next, *curr, *s, *n, *o;
	enum hotmod_op op;
	enum si_type si_type;
	int  addr_space;
	unsigned long addr;
	int regspacing;
	int regsize;
	int regshift;
	int irq;
	int ipmb;
	int ival;
	int len;

	if (!str)
		return -ENOMEM;

	/* Kill any trailing spaces, as we can get a "\n" from echo. */
	len = strlen(str);
	ival = len - 1;
	while ((ival >= 0) && isspace(str[ival])) {
		str[ival] = '\0';
		ival--;
	}

	for (curr = str; curr; curr = next) {
		regspacing = 1;
		regsize = 1;
		regshift = 0;
		irq = 0;
		ipmb = 0; /* Choose the default if not specified */

		next = strchr(curr, ':');
		if (next) {
			*next = '\0';
			next++;
		}

		rv = parse_str(hotmod_ops, &ival, "operation", &curr);
		if (rv)
			break;
		op = ival;

		rv = parse_str(hotmod_si, &ival, "interface type", &curr);
		if (rv)
			break;
		si_type = ival;

		rv = parse_str(hotmod_as, &addr_space, "address space", &curr);
		if (rv)
			break;

		s = strchr(curr, ',');
		if (s) {
			*s = '\0';
			s++;
		}
		addr = simple_strtoul(curr, &n, 0);
		if ((*n != '\0') || (*curr == '\0')) {
			pr_warn(PFX "Invalid hotmod address '%s'\n", curr);
			break;
		}

		while (s) {
			curr = s;
			s = strchr(curr, ',');
			if (s) {
				*s = '\0';
				s++;
			}
			o = strchr(curr, '=');
			if (o) {
				*o = '\0';
				o++;
			}
			rv = check_hotmod_int_op(curr, o, "rsp", &regspacing);
			if (rv < 0)
				goto out;
			else if (rv)
				continue;
			rv = check_hotmod_int_op(curr, o, "rsi", &regsize);
			if (rv < 0)
				goto out;
			else if (rv)
				continue;
			rv = check_hotmod_int_op(curr, o, "rsh", &regshift);
			if (rv < 0)
				goto out;
			else if (rv)
				continue;
			rv = check_hotmod_int_op(curr, o, "irq", &irq);
			if (rv < 0)
				goto out;
			else if (rv)
				continue;
			rv = check_hotmod_int_op(curr, o, "ipmb", &ipmb);
			if (rv < 0)
				goto out;
			else if (rv)
				continue;

			rv = -EINVAL;
			pr_warn(PFX "Invalid hotmod option '%s'\n", curr);
			goto out;
		}

		if (op == HM_ADD) {
			struct si_sm_io io;

			memset(&io, 0, sizeof(io));
			io.addr_source = SI_HOTMOD;
			io.si_type = si_type;
			io.addr_data = addr;
			io.addr_type = addr_space;

			io.addr = NULL;
			io.regspacing = regspacing;
			if (!io.regspacing)
				io.regspacing = DEFAULT_REGSPACING;
			io.regsize = regsize;
			if (!io.regsize)
				io.regsize = DEFAULT_REGSIZE;
			io.regshift = regshift;
			io.irq = irq;
			if (io.irq)
				io.irq_setup = ipmi_std_irq_setup;
			io.slave_addr = ipmb;

			rv = ipmi_si_add_smi(&io);
			if (rv)
				goto out;
		} else {
			ipmi_si_remove_by_data(addr_space, si_type, addr);
		}
	}
	rv = len;
out:
	kfree(str);
	return rv;
}
Пример #4
0
static int ipmi_pci_probe(struct pci_dev *pdev,
				    const struct pci_device_id *ent)
{
	int rv;
	struct si_sm_io io;

	if (pci_match_id(ipmi_pci_blacklist, pdev))
		return -ENODEV;

	memset(&io, 0, sizeof(io));
	io.addr_source = SI_PCI;
	dev_info(&pdev->dev, "probing via PCI");

	switch (pdev->class) {
	case PCI_CLASS_SERIAL_IPMI_SMIC:
		io.si_type = SI_SMIC;
		break;

	case PCI_CLASS_SERIAL_IPMI_KCS:
		io.si_type = SI_KCS;
		break;

	case PCI_CLASS_SERIAL_IPMI_BT:
		io.si_type = SI_BT;
		break;

	default:
		dev_info(&pdev->dev, "Unknown IPMI class: %x\n", pdev->class);
		return -ENOMEM;
	}

	rv = pci_enable_device(pdev);
	if (rv) {
		dev_err(&pdev->dev, "couldn't enable PCI device\n");
		return rv;
	}

	io.addr_source_cleanup = ipmi_pci_cleanup;
	io.addr_source_data = pdev;

	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
		io.addr_space = IPMI_IO_ADDR_SPACE;
		io.io_setup = ipmi_si_port_setup;
	} else {
		io.addr_space = IPMI_MEM_ADDR_SPACE;
		io.io_setup = ipmi_si_mem_setup;
	}
	io.addr_data = pci_resource_start(pdev, 0);

	io.dev = &pdev->dev;

	io.regspacing = ipmi_pci_probe_regspacing(&io);
	io.regsize = DEFAULT_REGSIZE;
	io.regshift = 0;

	io.irq = pdev->irq;
	if (io.irq)
		io.irq_setup = ipmi_std_irq_setup;

	dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n",
		 &pdev->resource[0], io.regsize, io.regspacing, io.irq);

	rv = ipmi_si_add_smi(&io);
	if (rv)
		pci_disable_device(pdev);

	return rv;
}