Various small fixes for IPMI. Cleanups in the documentation and
convertion printk() to pr_xxx() and removal of an unused module parameter. Some small bug fixes and enhancements. This also adds a post softdep from the IPMI core module to the IPMI device interface. Many people have complained that the device interface isn't automatically avaiable when IPMI is loaded. I don't want to make the device interface mandatory, though, plenty of people use IPMI internally (like with ACPI) and don't need a device interface or the added possible security entry. A softdep should make it work "out of the box" but allow people to not have it if they don't want it. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlhSE9cACgkQIXnXXONXERe6iACgsiU5/LG4tbKu9EyZXp5isRw6 AdsAn1dT08aobOzJhFI3dVx6oTnJQDDC =ifi5 -----END PGP SIGNATURE----- Merge tag 'for-linus-4.10' of git://git.code.sf.net/p/openipmi/linux-ipmi Pull IPMI updates from Corey Minyard: "Various small fixes for IPMI. Cleanups in the documentation and convertion printk() to pr_xxx() and removal of an unused module parameter. Some small bug fixes and enhancements. This also adds a post softdep from the IPMI core module to the IPMI device interface. Many people have complained that the device interface isn't automatically avaiable when IPMI is loaded. I don't want to make the device interface mandatory, though, plenty of people use IPMI internally (like with ACPI) and don't need a device interface or the added possible security entry. A softdep should make it work 'out of the box' but allow people to not have it if they don't want it" * tag 'for-linus-4.10' of git://git.code.sf.net/p/openipmi/linux-ipmi: ipmi: create hardware-independent softdep for ipmi_devintf ipmi: Fix sequence number handling ipmi: Pick up slave address from SMBIOS on an ACPI device ipmi_si: Clean up printks Move platform device creation earlier in the initialization ipmi: Update documentation ipmi_ssif: Remove an unused module parameter ipmi: Periodically check for events, not messages
This commit is contained in:
commit
196202be3c
@ -111,6 +111,8 @@ ipmi_ssif - A driver for accessing BMCs on the SMBus. It uses the
|
|||||||
I2C kernel driver's SMBus interfaces to send and receive IPMI messages
|
I2C kernel driver's SMBus interfaces to send and receive IPMI messages
|
||||||
over the SMBus.
|
over the SMBus.
|
||||||
|
|
||||||
|
ipmi_powernv - A driver for access BMCs on POWERNV systems.
|
||||||
|
|
||||||
ipmi_watchdog - IPMI requires systems to have a very capable watchdog
|
ipmi_watchdog - IPMI requires systems to have a very capable watchdog
|
||||||
timer. This driver implements the standard Linux watchdog timer
|
timer. This driver implements the standard Linux watchdog timer
|
||||||
interface on top of the IPMI message handler.
|
interface on top of the IPMI message handler.
|
||||||
@ -118,17 +120,15 @@ interface on top of the IPMI message handler.
|
|||||||
ipmi_poweroff - Some systems support the ability to be turned off via
|
ipmi_poweroff - Some systems support the ability to be turned off via
|
||||||
IPMI commands.
|
IPMI commands.
|
||||||
|
|
||||||
These are all individually selectable via configuration options.
|
bt-bmc - This is not part of the main driver, but instead a driver for
|
||||||
|
accessing a BMC-side interface of a BT interface. It is used on BMCs
|
||||||
|
running Linux to provide an interface to the host.
|
||||||
|
|
||||||
Note that the KCS-only interface has been removed. The af_ipmi driver
|
These are all individually selectable via configuration options.
|
||||||
is no longer supported and has been removed because it was impossible
|
|
||||||
to do 32 bit emulation on 64-bit kernels with it.
|
|
||||||
|
|
||||||
Much documentation for the interface is in the include files. The
|
Much documentation for the interface is in the include files. The
|
||||||
IPMI include files are:
|
IPMI include files are:
|
||||||
|
|
||||||
net/af_ipmi.h - Contains the socket interface.
|
|
||||||
|
|
||||||
linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
|
linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
|
||||||
|
|
||||||
linux/ipmi_smi.h - Contains the interface for system management interfaces
|
linux/ipmi_smi.h - Contains the interface for system management interfaces
|
||||||
@ -245,6 +245,16 @@ addressed (because some boards actually have multiple BMCs on them)
|
|||||||
and the user should not have to care what type of SMI is below them.
|
and the user should not have to care what type of SMI is below them.
|
||||||
|
|
||||||
|
|
||||||
|
Watching For Interfaces
|
||||||
|
|
||||||
|
When your code comes up, the IPMI driver may or may not have detected
|
||||||
|
if IPMI devices exist. So you might have to defer your setup until
|
||||||
|
the device is detected, or you might be able to do it immediately.
|
||||||
|
To handle this, and to allow for discovery, you register an SMI
|
||||||
|
watcher with ipmi_smi_watcher_register() to iterate over interfaces
|
||||||
|
and tell you when they come and go.
|
||||||
|
|
||||||
|
|
||||||
Creating the User
|
Creating the User
|
||||||
|
|
||||||
To user the message handler, you must first create a user using
|
To user the message handler, you must first create a user using
|
||||||
@ -263,7 +273,7 @@ closing the device automatically destroys the user.
|
|||||||
|
|
||||||
Messaging
|
Messaging
|
||||||
|
|
||||||
To send a message from kernel-land, the ipmi_request() call does
|
To send a message from kernel-land, the ipmi_request_settime() call does
|
||||||
pretty much all message handling. Most of the parameter are
|
pretty much all message handling. Most of the parameter are
|
||||||
self-explanatory. However, it takes a "msgid" parameter. This is NOT
|
self-explanatory. However, it takes a "msgid" parameter. This is NOT
|
||||||
the sequence number of messages. It is simply a long value that is
|
the sequence number of messages. It is simply a long value that is
|
||||||
@ -352,11 +362,12 @@ that for more details.
|
|||||||
The SI Driver
|
The SI Driver
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The SI driver allows up to 4 KCS or SMIC interfaces to be configured
|
The SI driver allows KCS, BT, and SMIC interfaces to be configured
|
||||||
in the system. By default, scan the ACPI tables for interfaces, and
|
in the system. It discovers interfaces through a host of different
|
||||||
if it doesn't find any the driver will attempt to register one KCS
|
methods, depending on the system.
|
||||||
interface at the spec-specified I/O port 0xca2 without interrupts.
|
|
||||||
You can change this at module load time (for a module) with:
|
You can specify up to four interfaces on the module load line and
|
||||||
|
control some module parameters:
|
||||||
|
|
||||||
modprobe ipmi_si.o type=<type1>,<type2>....
|
modprobe ipmi_si.o type=<type1>,<type2>....
|
||||||
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
|
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
|
||||||
@ -367,7 +378,7 @@ You can change this at module load time (for a module) with:
|
|||||||
force_kipmid=<enable1>,<enable2>,...
|
force_kipmid=<enable1>,<enable2>,...
|
||||||
kipmid_max_busy_us=<ustime1>,<ustime2>,...
|
kipmid_max_busy_us=<ustime1>,<ustime2>,...
|
||||||
unload_when_empty=[0|1]
|
unload_when_empty=[0|1]
|
||||||
trydefaults=[0|1] trydmi=[0|1] tryacpi=[0|1]
|
trydmi=[0|1] tryacpi=[0|1]
|
||||||
tryplatform=[0|1] trypci=[0|1]
|
tryplatform=[0|1] trypci=[0|1]
|
||||||
|
|
||||||
Each of these except try... items is a list, the first item for the
|
Each of these except try... items is a list, the first item for the
|
||||||
@ -386,10 +397,6 @@ use the I/O port given as the device address.
|
|||||||
If you specify irqs as non-zero for an interface, the driver will
|
If you specify irqs as non-zero for an interface, the driver will
|
||||||
attempt to use the given interrupt for the device.
|
attempt to use the given interrupt for the device.
|
||||||
|
|
||||||
trydefaults sets whether the standard IPMI interface at 0xca2 and
|
|
||||||
any interfaces specified by ACPE are tried. By default, the driver
|
|
||||||
tries it, set this value to zero to turn this off.
|
|
||||||
|
|
||||||
The other try... items disable discovery by their corresponding
|
The other try... items disable discovery by their corresponding
|
||||||
names. These are all enabled by default, set them to zero to disable
|
names. These are all enabled by default, set them to zero to disable
|
||||||
them. The tryplatform disables openfirmware.
|
them. The tryplatform disables openfirmware.
|
||||||
@ -434,7 +441,7 @@ kernel command line as:
|
|||||||
|
|
||||||
ipmi_si.type=<type1>,<type2>...
|
ipmi_si.type=<type1>,<type2>...
|
||||||
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
|
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
|
||||||
ipmi_si.irqs=<irq1>,<irq2>... ipmi_si.trydefaults=[0|1]
|
ipmi_si.irqs=<irq1>,<irq2>...
|
||||||
ipmi_si.regspacings=<sp1>,<sp2>,...
|
ipmi_si.regspacings=<sp1>,<sp2>,...
|
||||||
ipmi_si.regsizes=<size1>,<size2>,...
|
ipmi_si.regsizes=<size1>,<size2>,...
|
||||||
ipmi_si.regshifts=<shift1>,<shift2>,...
|
ipmi_si.regshifts=<shift1>,<shift2>,...
|
||||||
@ -444,11 +451,6 @@ kernel command line as:
|
|||||||
|
|
||||||
It works the same as the module parameters of the same names.
|
It works the same as the module parameters of the same names.
|
||||||
|
|
||||||
By default, the driver will attempt to detect any device specified by
|
|
||||||
ACPI, and if none of those then a KCS device at the spec-specified
|
|
||||||
0xca2. If you want to turn this off, set the "trydefaults" option to
|
|
||||||
false.
|
|
||||||
|
|
||||||
If your IPMI interface does not support interrupts and is a KCS or
|
If your IPMI interface does not support interrupts and is a KCS or
|
||||||
SMIC interface, the IPMI driver will start a kernel thread for the
|
SMIC interface, the IPMI driver will start a kernel thread for the
|
||||||
interface to help speed things up. This is a low-priority kernel
|
interface to help speed things up. This is a low-priority kernel
|
||||||
@ -500,7 +502,8 @@ at module load time (for a module) with:
|
|||||||
addr=<i2caddr1>[,<i2caddr2>[,...]]
|
addr=<i2caddr1>[,<i2caddr2>[,...]]
|
||||||
adapter=<adapter1>[,<adapter2>[...]]
|
adapter=<adapter1>[,<adapter2>[...]]
|
||||||
dbg=<flags1>,<flags2>...
|
dbg=<flags1>,<flags2>...
|
||||||
slave_addrs=<addr1>,<addr2>,...
|
slave_addrs=<addr1>,<addr2>,...
|
||||||
|
tryacpi=[0|1] trydmi=[0|1]
|
||||||
[dbg_probe=1]
|
[dbg_probe=1]
|
||||||
|
|
||||||
The addresses are normal I2C addresses. The adapter is the string
|
The addresses are normal I2C addresses. The adapter is the string
|
||||||
@ -513,6 +516,9 @@ spaces in kernel parameters.
|
|||||||
The debug flags are bit flags for each BMC found, they are:
|
The debug flags are bit flags for each BMC found, they are:
|
||||||
IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
|
IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
|
||||||
|
|
||||||
|
The tryxxx parameters can be used to disable detecting interfaces
|
||||||
|
from various sources.
|
||||||
|
|
||||||
Setting dbg_probe to 1 will enable debugging of the probing and
|
Setting dbg_probe to 1 will enable debugging of the probing and
|
||||||
detection process for BMCs on the SMBusses.
|
detection process for BMCs on the SMBusses.
|
||||||
|
|
||||||
@ -535,7 +541,8 @@ kernel command line as:
|
|||||||
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
|
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
|
||||||
ipmi_ssif.dbg=<flags1>[,<flags2>[...]]
|
ipmi_ssif.dbg=<flags1>[,<flags2>[...]]
|
||||||
ipmi_ssif.dbg_probe=1
|
ipmi_ssif.dbg_probe=1
|
||||||
ipmi_ssif.slave_addrs=<addr1>[,<addr2>[...]]
|
ipmi_ssif.slave_addrs=<addr1>[,<addr2>[...]]
|
||||||
|
ipmi_ssif.tryacpi=[0|1] ipmi_ssif.trydmi=[0|1]
|
||||||
|
|
||||||
These are the same options as on the module command line.
|
These are the same options as on the module command line.
|
||||||
|
|
||||||
|
@ -989,4 +989,3 @@ module_exit(cleanup_ipmi);
|
|||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
|
MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
|
||||||
MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
|
MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
|
||||||
MODULE_ALIAS("platform:ipmi_si");
|
|
||||||
|
@ -158,15 +158,16 @@ struct seq_table {
|
|||||||
* Store the information in a msgid (long) to allow us to find a
|
* Store the information in a msgid (long) to allow us to find a
|
||||||
* sequence table entry from the msgid.
|
* sequence table entry from the msgid.
|
||||||
*/
|
*/
|
||||||
#define STORE_SEQ_IN_MSGID(seq, seqid) (((seq&0xff)<<26) | (seqid&0x3ffffff))
|
#define STORE_SEQ_IN_MSGID(seq, seqid) \
|
||||||
|
((((seq) & 0x3f) << 26) | ((seqid) & 0x3ffffff))
|
||||||
|
|
||||||
#define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \
|
#define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \
|
||||||
do { \
|
do { \
|
||||||
seq = ((msgid >> 26) & 0x3f); \
|
seq = (((msgid) >> 26) & 0x3f); \
|
||||||
seqid = (msgid & 0x3fffff); \
|
seqid = ((msgid) & 0x3ffffff); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3fffff)
|
#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3ffffff)
|
||||||
|
|
||||||
struct ipmi_channel {
|
struct ipmi_channel {
|
||||||
unsigned char medium;
|
unsigned char medium;
|
||||||
@ -4645,3 +4646,4 @@ MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
|
|||||||
MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI"
|
MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI"
|
||||||
" interface.");
|
" interface.");
|
||||||
MODULE_VERSION(IPMI_DRIVER_VERSION);
|
MODULE_VERSION(IPMI_DRIVER_VERSION);
|
||||||
|
MODULE_SOFTDEP("post: ipmi_devintf");
|
||||||
|
@ -789,7 +789,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
|
|||||||
smi_info->si_state = SI_NORMAL;
|
smi_info->si_state = SI_NORMAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
start_getting_msg_queue(smi_info);
|
start_getting_events(smi_info);
|
||||||
} else {
|
} else {
|
||||||
smi_info->si_state = SI_NORMAL;
|
smi_info->si_state = SI_NORMAL;
|
||||||
}
|
}
|
||||||
@ -812,7 +812,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
|
|||||||
smi_info->si_state = SI_NORMAL;
|
smi_info->si_state = SI_NORMAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
start_getting_msg_queue(smi_info);
|
start_getting_events(smi_info);
|
||||||
} else {
|
} else {
|
||||||
smi_info->si_state = SI_NORMAL;
|
smi_info->si_state = SI_NORMAL;
|
||||||
}
|
}
|
||||||
@ -1764,7 +1764,7 @@ static int parse_str(const struct hotmod_vals *v, int *val, char *name,
|
|||||||
|
|
||||||
s = strchr(*curr, ',');
|
s = strchr(*curr, ',');
|
||||||
if (!s) {
|
if (!s) {
|
||||||
printk(KERN_WARNING PFX "No hotmod %s given.\n", name);
|
pr_warn(PFX "No hotmod %s given.\n", name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
@ -1777,7 +1777,7 @@ static int parse_str(const struct hotmod_vals *v, int *val, char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_WARNING PFX "Invalid hotmod %s '%s'\n", name, *curr);
|
pr_warn(PFX "Invalid hotmod %s '%s'\n", name, *curr);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1788,16 +1788,12 @@ static int check_hotmod_int_op(const char *curr, const char *option,
|
|||||||
|
|
||||||
if (strcmp(curr, name) == 0) {
|
if (strcmp(curr, name) == 0) {
|
||||||
if (!option) {
|
if (!option) {
|
||||||
printk(KERN_WARNING PFX
|
pr_warn(PFX "No option given for '%s'\n", curr);
|
||||||
"No option given for '%s'\n",
|
|
||||||
curr);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
*val = simple_strtoul(option, &n, 0);
|
*val = simple_strtoul(option, &n, 0);
|
||||||
if ((*n != '\0') || (*option == '\0')) {
|
if ((*n != '\0') || (*option == '\0')) {
|
||||||
printk(KERN_WARNING PFX
|
pr_warn(PFX "Bad option given for '%s'\n", curr);
|
||||||
"Bad option given for '%s'\n",
|
|
||||||
curr);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1877,8 +1873,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
|
|||||||
}
|
}
|
||||||
addr = simple_strtoul(curr, &n, 0);
|
addr = simple_strtoul(curr, &n, 0);
|
||||||
if ((*n != '\0') || (*curr == '\0')) {
|
if ((*n != '\0') || (*curr == '\0')) {
|
||||||
printk(KERN_WARNING PFX "Invalid hotmod address"
|
pr_warn(PFX "Invalid hotmod address '%s'\n", curr);
|
||||||
" '%s'\n", curr);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1921,9 +1916,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
printk(KERN_WARNING PFX
|
pr_warn(PFX "Invalid hotmod option '%s'\n", curr);
|
||||||
"Invalid hotmod option '%s'\n",
|
|
||||||
curr);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2003,7 +1996,7 @@ static int hardcode_find_bmc(void)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
info->addr_source = SI_HARDCODED;
|
info->addr_source = SI_HARDCODED;
|
||||||
printk(KERN_INFO PFX "probing via hardcoded address\n");
|
pr_info(PFX "probing via hardcoded address\n");
|
||||||
|
|
||||||
if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
|
if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
|
||||||
info->si_type = SI_KCS;
|
info->si_type = SI_KCS;
|
||||||
@ -2012,9 +2005,8 @@ static int hardcode_find_bmc(void)
|
|||||||
} else if (strcmp(si_type[i], "bt") == 0) {
|
} else if (strcmp(si_type[i], "bt") == 0) {
|
||||||
info->si_type = SI_BT;
|
info->si_type = SI_BT;
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING PFX "Interface type specified "
|
pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n",
|
||||||
"for interface %d, was invalid: %s\n",
|
i, si_type[i]);
|
||||||
i, si_type[i]);
|
|
||||||
kfree(info);
|
kfree(info);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2030,9 +2022,8 @@ static int hardcode_find_bmc(void)
|
|||||||
info->io.addr_data = addrs[i];
|
info->io.addr_data = addrs[i];
|
||||||
info->io.addr_type = IPMI_MEM_ADDR_SPACE;
|
info->io.addr_type = IPMI_MEM_ADDR_SPACE;
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING PFX "Interface type specified "
|
pr_warn(PFX "Interface type specified for interface %d, but port and address were not set or set to zero.\n",
|
||||||
"for interface %d, but port and address were "
|
i);
|
||||||
"not set or set to zero.\n", i);
|
|
||||||
kfree(info);
|
kfree(info);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2173,18 +2164,18 @@ static int try_init_spmi(struct SPMITable *spmi)
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (spmi->IPMIlegacy != 1) {
|
if (spmi->IPMIlegacy != 1) {
|
||||||
printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
|
pr_info(PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = smi_info_alloc();
|
info = smi_info_alloc();
|
||||||
if (!info) {
|
if (!info) {
|
||||||
printk(KERN_ERR PFX "Could not allocate SI data (3)\n");
|
pr_err(PFX "Could not allocate SI data (3)\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->addr_source = SI_SPMI;
|
info->addr_source = SI_SPMI;
|
||||||
printk(KERN_INFO PFX "probing via SPMI\n");
|
pr_info(PFX "probing via SPMI\n");
|
||||||
|
|
||||||
/* Figure out the interface type. */
|
/* Figure out the interface type. */
|
||||||
switch (spmi->InterfaceType) {
|
switch (spmi->InterfaceType) {
|
||||||
@ -2201,8 +2192,8 @@ static int try_init_spmi(struct SPMITable *spmi)
|
|||||||
kfree(info);
|
kfree(info);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
default:
|
default:
|
||||||
printk(KERN_INFO PFX "Unknown ACPI/SPMI SI type %d\n",
|
pr_info(PFX "Unknown ACPI/SPMI SI type %d\n",
|
||||||
spmi->InterfaceType);
|
spmi->InterfaceType);
|
||||||
kfree(info);
|
kfree(info);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2238,15 +2229,15 @@ static int try_init_spmi(struct SPMITable *spmi)
|
|||||||
info->io.addr_type = IPMI_IO_ADDR_SPACE;
|
info->io.addr_type = IPMI_IO_ADDR_SPACE;
|
||||||
} else {
|
} else {
|
||||||
kfree(info);
|
kfree(info);
|
||||||
printk(KERN_WARNING PFX "Unknown ACPI I/O Address type\n");
|
pr_warn(PFX "Unknown ACPI I/O Address type\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
info->io.addr_data = spmi->addr.address;
|
info->io.addr_data = spmi->addr.address;
|
||||||
|
|
||||||
pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n",
|
pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n",
|
||||||
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
|
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
|
||||||
info->io.addr_data, info->io.regsize, info->io.regspacing,
|
info->io.addr_data, info->io.regsize, info->io.regspacing,
|
||||||
info->irq);
|
info->irq);
|
||||||
|
|
||||||
rv = add_smi(info);
|
rv = add_smi(info);
|
||||||
if (rv)
|
if (rv)
|
||||||
@ -2356,12 +2347,12 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
|
|||||||
|
|
||||||
info = smi_info_alloc();
|
info = smi_info_alloc();
|
||||||
if (!info) {
|
if (!info) {
|
||||||
printk(KERN_ERR PFX "Could not allocate SI data\n");
|
pr_err(PFX "Could not allocate SI data\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->addr_source = SI_SMBIOS;
|
info->addr_source = SI_SMBIOS;
|
||||||
printk(KERN_INFO PFX "probing via SMBIOS\n");
|
pr_info(PFX "probing via SMBIOS\n");
|
||||||
|
|
||||||
switch (ipmi_data->type) {
|
switch (ipmi_data->type) {
|
||||||
case 0x01: /* KCS */
|
case 0x01: /* KCS */
|
||||||
@ -2391,8 +2382,8 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
kfree(info);
|
kfree(info);
|
||||||
printk(KERN_WARNING PFX "Unknown SMBIOS I/O Address type: %d\n",
|
pr_warn(PFX "Unknown SMBIOS I/O Address type: %d\n",
|
||||||
ipmi_data->addr_space);
|
ipmi_data->addr_space);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
info->io.addr_data = ipmi_data->base_addr;
|
info->io.addr_data = ipmi_data->base_addr;
|
||||||
@ -2410,9 +2401,9 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
|
|||||||
info->irq_setup = std_irq_setup;
|
info->irq_setup = std_irq_setup;
|
||||||
|
|
||||||
pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
|
pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
|
||||||
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
|
(info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
|
||||||
info->io.addr_data, info->io.regsize, info->io.regspacing,
|
info->io.addr_data, info->io.regsize, info->io.regspacing,
|
||||||
info->irq);
|
info->irq);
|
||||||
|
|
||||||
if (add_smi(info))
|
if (add_smi(info))
|
||||||
kfree(info);
|
kfree(info);
|
||||||
@ -3141,9 +3132,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
|
|||||||
|
|
||||||
rv = wait_for_msg_done(smi_info);
|
rv = wait_for_msg_done(smi_info);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
printk(KERN_WARNING PFX "Error getting response from get"
|
pr_warn(PFX "Error getting response from get global enables command, the event buffer is not enabled.\n");
|
||||||
" global enables command, the event buffer is not"
|
|
||||||
" enabled.\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3154,8 +3143,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
|
|||||||
resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
|
resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
|
||||||
resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD ||
|
resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD ||
|
||||||
resp[2] != 0) {
|
resp[2] != 0) {
|
||||||
printk(KERN_WARNING PFX "Invalid return from get global"
|
pr_warn(PFX "Invalid return from get global enables command, cannot enable the event buffer.\n");
|
||||||
" enables command, cannot enable the event buffer.\n");
|
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -3173,9 +3161,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
|
|||||||
|
|
||||||
rv = wait_for_msg_done(smi_info);
|
rv = wait_for_msg_done(smi_info);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
printk(KERN_WARNING PFX "Error getting response from set"
|
pr_warn(PFX "Error getting response from set global, enables command, the event buffer is not enabled.\n");
|
||||||
" global, enables command, the event buffer is not"
|
|
||||||
" enabled.\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3185,8 +3171,7 @@ static int try_enable_event_buffer(struct smi_info *smi_info)
|
|||||||
if (resp_len < 3 ||
|
if (resp_len < 3 ||
|
||||||
resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
|
resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
|
||||||
resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
|
resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
|
||||||
printk(KERN_WARNING PFX "Invalid return from get global,"
|
pr_warn(PFX "Invalid return from get global, enables command, not enable the event buffer.\n");
|
||||||
"enables command, not enable the event buffer.\n");
|
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -3463,8 +3448,16 @@ static int is_new_interface(struct smi_info *info)
|
|||||||
list_for_each_entry(e, &smi_infos, link) {
|
list_for_each_entry(e, &smi_infos, link) {
|
||||||
if (e->io.addr_type != info->io.addr_type)
|
if (e->io.addr_type != info->io.addr_type)
|
||||||
continue;
|
continue;
|
||||||
if (e->io.addr_data == info->io.addr_data)
|
if (e->io.addr_data == info->io.addr_data) {
|
||||||
|
/*
|
||||||
|
* This is a cheap hack, ACPI doesn't have a defined
|
||||||
|
* slave address but SMBIOS does. Pick it up from
|
||||||
|
* any source that has it available.
|
||||||
|
*/
|
||||||
|
if (info->slave_addr && !e->slave_addr)
|
||||||
|
e->slave_addr = info->slave_addr;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -3474,17 +3467,18 @@ static int add_smi(struct smi_info *new_smi)
|
|||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
printk(KERN_INFO PFX "Adding %s-specified %s state machine",
|
|
||||||
ipmi_addr_src_to_str(new_smi->addr_source),
|
|
||||||
si_to_str[new_smi->si_type]);
|
|
||||||
mutex_lock(&smi_infos_lock);
|
mutex_lock(&smi_infos_lock);
|
||||||
if (!is_new_interface(new_smi)) {
|
if (!is_new_interface(new_smi)) {
|
||||||
printk(KERN_CONT " duplicate interface\n");
|
pr_info(PFX "%s-specified %s state machine: duplicate\n",
|
||||||
|
ipmi_addr_src_to_str(new_smi->addr_source),
|
||||||
|
si_to_str[new_smi->si_type]);
|
||||||
rv = -EBUSY;
|
rv = -EBUSY;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_CONT "\n");
|
pr_info(PFX "Adding %s-specified %s state machine\n",
|
||||||
|
ipmi_addr_src_to_str(new_smi->addr_source),
|
||||||
|
si_to_str[new_smi->si_type]);
|
||||||
|
|
||||||
/* So we know not to free it unless we have allocated one. */
|
/* So we know not to free it unless we have allocated one. */
|
||||||
new_smi->intf = NULL;
|
new_smi->intf = NULL;
|
||||||
@ -3502,15 +3496,14 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
int i;
|
int i;
|
||||||
|
char *init_name = NULL;
|
||||||
|
|
||||||
printk(KERN_INFO PFX "Trying %s-specified %s state"
|
pr_info(PFX "Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n",
|
||||||
" machine at %s address 0x%lx, slave address 0x%x,"
|
ipmi_addr_src_to_str(new_smi->addr_source),
|
||||||
" irq %d\n",
|
si_to_str[new_smi->si_type],
|
||||||
ipmi_addr_src_to_str(new_smi->addr_source),
|
addr_space_to_str[new_smi->io.addr_type],
|
||||||
si_to_str[new_smi->si_type],
|
new_smi->io.addr_data,
|
||||||
addr_space_to_str[new_smi->io.addr_type],
|
new_smi->slave_addr, new_smi->irq);
|
||||||
new_smi->io.addr_data,
|
|
||||||
new_smi->slave_addr, new_smi->irq);
|
|
||||||
|
|
||||||
switch (new_smi->si_type) {
|
switch (new_smi->si_type) {
|
||||||
case SI_KCS:
|
case SI_KCS:
|
||||||
@ -3531,11 +3524,30 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do this early so it's available for logs. */
|
||||||
|
if (!new_smi->dev) {
|
||||||
|
init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we don't already have a device from something
|
||||||
|
* else (like PCI), then register a new one.
|
||||||
|
*/
|
||||||
|
new_smi->pdev = platform_device_alloc("ipmi_si",
|
||||||
|
new_smi->intf_num);
|
||||||
|
if (!new_smi->pdev) {
|
||||||
|
pr_err(PFX "Unable to allocate platform device\n");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
new_smi->dev = &new_smi->pdev->dev;
|
||||||
|
new_smi->dev->driver = &ipmi_driver.driver;
|
||||||
|
/* Nulled by device_add() */
|
||||||
|
new_smi->dev->init_name = init_name;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate the state machine's data and initialize it. */
|
/* Allocate the state machine's data and initialize it. */
|
||||||
new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL);
|
new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL);
|
||||||
if (!new_smi->si_sm) {
|
if (!new_smi->si_sm) {
|
||||||
printk(KERN_ERR PFX
|
pr_err(PFX "Could not allocate state machine memory\n");
|
||||||
"Could not allocate state machine memory\n");
|
|
||||||
rv = -ENOMEM;
|
rv = -ENOMEM;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
@ -3545,14 +3557,14 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||||||
/* Now that we know the I/O size, we can set up the I/O. */
|
/* Now that we know the I/O size, we can set up the I/O. */
|
||||||
rv = new_smi->io_setup(new_smi);
|
rv = new_smi->io_setup(new_smi);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
printk(KERN_ERR PFX "Could not set up I/O space\n");
|
dev_err(new_smi->dev, "Could not set up I/O space\n");
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do low-level detection first. */
|
/* Do low-level detection first. */
|
||||||
if (new_smi->handlers->detect(new_smi->si_sm)) {
|
if (new_smi->handlers->detect(new_smi->si_sm)) {
|
||||||
if (new_smi->addr_source)
|
if (new_smi->addr_source)
|
||||||
printk(KERN_INFO PFX "Interface detection failed\n");
|
dev_err(new_smi->dev, "Interface detection failed\n");
|
||||||
rv = -ENODEV;
|
rv = -ENODEV;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
@ -3564,8 +3576,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||||||
rv = try_get_dev_id(new_smi);
|
rv = try_get_dev_id(new_smi);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
if (new_smi->addr_source)
|
if (new_smi->addr_source)
|
||||||
printk(KERN_INFO PFX "There appears to be no BMC"
|
dev_err(new_smi->dev, "There appears to be no BMC at this location\n");
|
||||||
" at this location\n");
|
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3604,27 +3615,12 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||||||
atomic_set(&new_smi->req_events, 1);
|
atomic_set(&new_smi->req_events, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_smi->dev) {
|
if (new_smi->pdev) {
|
||||||
/*
|
|
||||||
* If we don't already have a device from something
|
|
||||||
* else (like PCI), then register a new one.
|
|
||||||
*/
|
|
||||||
new_smi->pdev = platform_device_alloc("ipmi_si",
|
|
||||||
new_smi->intf_num);
|
|
||||||
if (!new_smi->pdev) {
|
|
||||||
printk(KERN_ERR PFX
|
|
||||||
"Unable to allocate platform device\n");
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
new_smi->dev = &new_smi->pdev->dev;
|
|
||||||
new_smi->dev->driver = &ipmi_driver.driver;
|
|
||||||
|
|
||||||
rv = platform_device_add(new_smi->pdev);
|
rv = platform_device_add(new_smi->pdev);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
printk(KERN_ERR PFX
|
dev_err(new_smi->dev,
|
||||||
"Unable to register system interface device:"
|
"Unable to register system interface device: %d\n",
|
||||||
" %d\n",
|
rv);
|
||||||
rv);
|
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
new_smi->dev_registered = true;
|
new_smi->dev_registered = true;
|
||||||
@ -3668,6 +3664,9 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||||||
dev_info(new_smi->dev, "IPMI %s interface initialized\n",
|
dev_info(new_smi->dev, "IPMI %s interface initialized\n",
|
||||||
si_to_str[new_smi->si_type]);
|
si_to_str[new_smi->si_type]);
|
||||||
|
|
||||||
|
WARN_ON(new_smi->dev->init_name != NULL);
|
||||||
|
kfree(init_name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_err_stop_timer:
|
out_err_stop_timer:
|
||||||
@ -3712,8 +3711,14 @@ out_err:
|
|||||||
if (new_smi->dev_registered) {
|
if (new_smi->dev_registered) {
|
||||||
platform_device_unregister(new_smi->pdev);
|
platform_device_unregister(new_smi->pdev);
|
||||||
new_smi->dev_registered = false;
|
new_smi->dev_registered = false;
|
||||||
|
new_smi->pdev = NULL;
|
||||||
|
} else if (new_smi->pdev) {
|
||||||
|
platform_device_put(new_smi->pdev);
|
||||||
|
new_smi->pdev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kfree(init_name);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3732,8 +3737,7 @@ static int init_ipmi_si(void)
|
|||||||
if (si_tryplatform) {
|
if (si_tryplatform) {
|
||||||
rv = platform_driver_register(&ipmi_driver);
|
rv = platform_driver_register(&ipmi_driver);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
printk(KERN_ERR PFX "Unable to register "
|
pr_err(PFX "Unable to register driver: %d\n", rv);
|
||||||
"driver: %d\n", rv);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3753,7 +3757,7 @@ static int init_ipmi_si(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "IPMI System Interface driver.\n");
|
pr_info("IPMI System Interface driver.\n");
|
||||||
|
|
||||||
/* If the user gave us a device, they presumably want us to use it */
|
/* If the user gave us a device, they presumably want us to use it */
|
||||||
if (!hardcode_find_bmc())
|
if (!hardcode_find_bmc())
|
||||||
@ -3763,8 +3767,7 @@ static int init_ipmi_si(void)
|
|||||||
if (si_trypci) {
|
if (si_trypci) {
|
||||||
rv = pci_register_driver(&ipmi_pci_driver);
|
rv = pci_register_driver(&ipmi_pci_driver);
|
||||||
if (rv)
|
if (rv)
|
||||||
printk(KERN_ERR PFX "Unable to register "
|
pr_err(PFX "Unable to register PCI driver: %d\n", rv);
|
||||||
"PCI driver: %d\n", rv);
|
|
||||||
else
|
else
|
||||||
pci_registered = true;
|
pci_registered = true;
|
||||||
}
|
}
|
||||||
@ -3826,8 +3829,7 @@ static int init_ipmi_si(void)
|
|||||||
if (unload_when_empty && list_empty(&smi_infos)) {
|
if (unload_when_empty && list_empty(&smi_infos)) {
|
||||||
mutex_unlock(&smi_infos_lock);
|
mutex_unlock(&smi_infos_lock);
|
||||||
cleanup_ipmi_si();
|
cleanup_ipmi_si();
|
||||||
printk(KERN_WARNING PFX
|
pr_warn(PFX "Unable to find any System Interface(s)\n");
|
||||||
"Unable to find any System Interface(s)\n");
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
mutex_unlock(&smi_infos_lock);
|
mutex_unlock(&smi_infos_lock);
|
||||||
|
@ -174,7 +174,6 @@ enum ssif_stat_indexes {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ssif_addr_info {
|
struct ssif_addr_info {
|
||||||
unsigned short addr;
|
|
||||||
struct i2c_board_info binfo;
|
struct i2c_board_info binfo;
|
||||||
char *adapter_name;
|
char *adapter_name;
|
||||||
int debug;
|
int debug;
|
||||||
@ -1154,10 +1153,6 @@ static bool ssif_dbg_probe;
|
|||||||
module_param_named(dbg_probe, ssif_dbg_probe, bool, 0);
|
module_param_named(dbg_probe, ssif_dbg_probe, bool, 0);
|
||||||
MODULE_PARM_DESC(dbg_probe, "Enable debugging of probing of adapters.");
|
MODULE_PARM_DESC(dbg_probe, "Enable debugging of probing of adapters.");
|
||||||
|
|
||||||
static int use_thread;
|
|
||||||
module_param(use_thread, int, 0);
|
|
||||||
MODULE_PARM_DESC(use_thread, "Use the thread interface.");
|
|
||||||
|
|
||||||
static bool ssif_tryacpi = true;
|
static bool ssif_tryacpi = true;
|
||||||
module_param_named(tryacpi, ssif_tryacpi, bool, 0);
|
module_param_named(tryacpi, ssif_tryacpi, bool, 0);
|
||||||
MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI");
|
MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI");
|
||||||
@ -1405,6 +1400,34 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int find_slave_address(struct i2c_client *client, int slave_addr)
|
||||||
|
{
|
||||||
|
struct ssif_addr_info *info;
|
||||||
|
|
||||||
|
if (slave_addr)
|
||||||
|
return slave_addr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Came in without a slave address, search around to see if
|
||||||
|
* the other sources have a slave address. This lets us pick
|
||||||
|
* up an SMBIOS slave address when using ACPI.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(info, &ssif_infos, link) {
|
||||||
|
if (info->binfo.addr != client->addr)
|
||||||
|
continue;
|
||||||
|
if (info->adapter_name && client->adapter->name &&
|
||||||
|
strcmp_nospace(info->adapter_name,
|
||||||
|
client->adapter->name))
|
||||||
|
continue;
|
||||||
|
if (info->slave_addr) {
|
||||||
|
slave_addr = info->slave_addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return slave_addr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global enables we care about.
|
* Global enables we care about.
|
||||||
*/
|
*/
|
||||||
@ -1447,6 +1470,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slave_addr = find_slave_address(client, slave_addr);
|
||||||
|
|
||||||
pr_info(PFX "Trying %s-specified SSIF interface at i2c address 0x%x, adapter %s, slave address 0x%x\n",
|
pr_info(PFX "Trying %s-specified SSIF interface at i2c address 0x%x, adapter %s, slave address 0x%x\n",
|
||||||
ipmi_addr_src_to_str(ssif_info->addr_source),
|
ipmi_addr_src_to_str(ssif_info->addr_source),
|
||||||
client->addr, client->adapter->name, slave_addr);
|
client->addr, client->adapter->name, slave_addr);
|
||||||
@ -1935,7 +1960,7 @@ static int decode_dmi(const struct dmi_device *dmi_dev)
|
|||||||
slave_addr = data[6];
|
slave_addr = data[6];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_ssif_client(myaddr, NULL, 0, 0, SI_SMBIOS);
|
return new_ssif_client(myaddr, NULL, 0, slave_addr, SI_SMBIOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dmi_iterator(void)
|
static void dmi_iterator(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user