Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0+
  2
  3#include <linux/moduleparam.h>
  4#include "ipmi_si.h"
  5
  6#define PFX "ipmi_hardcode: "
  7/*
  8 * There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
  9 * a default IO port, and 1 ACPI/SPMI address.  That sets SI_MAX_DRIVERS.
 10 */
 11
 12#define SI_MAX_PARMS 4
 13
 14static char          *si_type[SI_MAX_PARMS];
 15#define MAX_SI_TYPE_STR 30
 16static char          si_type_str[MAX_SI_TYPE_STR];
 17static unsigned long addrs[SI_MAX_PARMS];
 18static unsigned int num_addrs;
 19static unsigned int  ports[SI_MAX_PARMS];
 20static unsigned int num_ports;
 21static int           irqs[SI_MAX_PARMS];
 22static unsigned int num_irqs;
 23static int           regspacings[SI_MAX_PARMS];
 24static unsigned int num_regspacings;
 25static int           regsizes[SI_MAX_PARMS];
 26static unsigned int num_regsizes;
 27static int           regshifts[SI_MAX_PARMS];
 28static unsigned int num_regshifts;
 29static int slave_addrs[SI_MAX_PARMS]; /* Leaving 0 chooses the default value */
 30static unsigned int num_slave_addrs;
 31
 32module_param_string(type, si_type_str, MAX_SI_TYPE_STR, 0);
 33MODULE_PARM_DESC(type, "Defines the type of each interface, each"
 34		 " interface separated by commas.  The types are 'kcs',"
 35		 " 'smic', and 'bt'.  For example si_type=kcs,bt will set"
 36		 " the first interface to kcs and the second to bt");
 37module_param_hw_array(addrs, ulong, iomem, &num_addrs, 0);
 38MODULE_PARM_DESC(addrs, "Sets the memory address of each interface, the"
 39		 " addresses separated by commas.  Only use if an interface"
 40		 " is in memory.  Otherwise, set it to zero or leave"
 41		 " it blank.");
 42module_param_hw_array(ports, uint, ioport, &num_ports, 0);
 43MODULE_PARM_DESC(ports, "Sets the port address of each interface, the"
 44		 " addresses separated by commas.  Only use if an interface"
 45		 " is a port.  Otherwise, set it to zero or leave"
 46		 " it blank.");
 47module_param_hw_array(irqs, int, irq, &num_irqs, 0);
 48MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
 49		 " addresses separated by commas.  Only use if an interface"
 50		 " has an interrupt.  Otherwise, set it to zero or leave"
 51		 " it blank.");
 52module_param_hw_array(regspacings, int, other, &num_regspacings, 0);
 53MODULE_PARM_DESC(regspacings, "The number of bytes between the start address"
 54		 " and each successive register used by the interface.  For"
 55		 " instance, if the start address is 0xca2 and the spacing"
 56		 " is 2, then the second address is at 0xca4.  Defaults"
 57		 " to 1.");
 58module_param_hw_array(regsizes, int, other, &num_regsizes, 0);
 59MODULE_PARM_DESC(regsizes, "The size of the specific IPMI register in bytes."
 60		 " This should generally be 1, 2, 4, or 8 for an 8-bit,"
 61		 " 16-bit, 32-bit, or 64-bit register.  Use this if you"
 62		 " the 8-bit IPMI register has to be read from a larger"
 63		 " register.");
 64module_param_hw_array(regshifts, int, other, &num_regshifts, 0);
 65MODULE_PARM_DESC(regshifts, "The amount to shift the data read from the."
 66		 " IPMI register, in bits.  For instance, if the data"
 67		 " is read from a 32-bit word and the IPMI data is in"
 68		 " bit 8-15, then the shift would be 8");
 69module_param_hw_array(slave_addrs, int, other, &num_slave_addrs, 0);
 70MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
 71		 " the controller.  Normally this is 0x20, but can be"
 72		 " overridden by this parm.  This is an array indexed"
 73		 " by interface number.");
 74
 75int ipmi_si_hardcode_find_bmc(void)
 76{
 77	int ret = -ENODEV;
 78	int             i;
 79	struct si_sm_io io;
 80	char *str;
 81
 82	/* Parse out the si_type string into its components. */
 83	str = si_type_str;
 84	if (*str != '\0') {
 85		for (i = 0; (i < SI_MAX_PARMS) && (*str != '\0'); i++) {
 86			si_type[i] = str;
 87			str = strchr(str, ',');
 88			if (str) {
 89				*str = '\0';
 90				str++;
 91			} else {
 92				break;
 93			}
 94		}
 95	}
 96
 97	memset(&io, 0, sizeof(io));
 98	for (i = 0; i < SI_MAX_PARMS; i++) {
 99		if (!ports[i] && !addrs[i])
100			continue;
101
102		io.addr_source = SI_HARDCODED;
103		pr_info(PFX "probing via hardcoded address\n");
104
105		if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
106			io.si_type = SI_KCS;
107		} else if (strcmp(si_type[i], "smic") == 0) {
108			io.si_type = SI_SMIC;
109		} else if (strcmp(si_type[i], "bt") == 0) {
110			io.si_type = SI_BT;
111		} else {
112			pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n",
113				i, si_type[i]);
114			continue;
115		}
116
117		if (ports[i]) {
118			/* An I/O port */
119			io.addr_data = ports[i];
120			io.addr_type = IPMI_IO_ADDR_SPACE;
121		} else if (addrs[i]) {
122			/* A memory port */
123			io.addr_data = addrs[i];
124			io.addr_type = IPMI_MEM_ADDR_SPACE;
125		} else {
126			pr_warn(PFX "Interface type specified for interface %d, but port and address were not set or set to zero.\n",
127				i);
128			continue;
129		}
130
131		io.addr = NULL;
132		io.regspacing = regspacings[i];
133		if (!io.regspacing)
134			io.regspacing = DEFAULT_REGSPACING;
135		io.regsize = regsizes[i];
136		if (!io.regsize)
137			io.regsize = DEFAULT_REGSIZE;
138		io.regshift = regshifts[i];
139		io.irq = irqs[i];
140		if (io.irq)
141			io.irq_setup = ipmi_std_irq_setup;
142		io.slave_addr = slave_addrs[i];
143
144		ret = ipmi_si_add_smi(&io);
145	}
146	return ret;
147}