Skip to content

Commit ada2aba

Browse files
committed
ipmi:si: Rework startup of IPMI devices
It is possible in some situations that IPMI devices won't get started up properly. This change makes it so all non-duplicate devices will get started up. Signed-off-by: Corey Minyard <cminyard@mvista.com>
1 parent ed59cd2 commit ada2aba

File tree

1 file changed

+62
-20
lines changed

1 file changed

+62
-20
lines changed

drivers/char/ipmi/ipmi_si_intf.c

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,9 +2095,18 @@ static int try_smi_init(struct smi_info *new_smi)
20952095
return rv;
20962096
}
20972097

2098+
/*
2099+
* Devices in the same address space at the same address are the same.
2100+
*/
2101+
static bool __init ipmi_smi_info_same(struct smi_info *e1, struct smi_info *e2)
2102+
{
2103+
return (e1->io.addr_space == e2->io.addr_space &&
2104+
e1->io.addr_data == e2->io.addr_data);
2105+
}
2106+
20982107
static int __init init_ipmi_si(void)
20992108
{
2100-
struct smi_info *e;
2109+
struct smi_info *e, *e2;
21012110
enum ipmi_addr_src type = SI_INVALID;
21022111

21032112
if (initialized)
@@ -2113,37 +2122,70 @@ static int __init init_ipmi_si(void)
21132122

21142123
ipmi_si_parisc_init();
21152124

2116-
/* We prefer devices with interrupts, but in the case of a machine
2117-
with multiple BMCs we assume that there will be several instances
2118-
of a given type so if we succeed in registering a type then also
2119-
try to register everything else of the same type */
21202125
mutex_lock(&smi_infos_lock);
2126+
2127+
/*
2128+
* Scan through all the devices. We prefer devices with
2129+
* interrupts, so go through those first in case there are any
2130+
* duplicates that don't have the interrupt set.
2131+
*/
21212132
list_for_each_entry(e, &smi_infos, link) {
2122-
/* Try to register a device if it has an IRQ and we either
2123-
haven't successfully registered a device yet or this
2124-
device has the same type as one we successfully registered */
2125-
if (e->io.irq && (!type || e->io.addr_source == type)) {
2126-
if (!try_smi_init(e)) {
2127-
type = e->io.addr_source;
2133+
bool dup = false;
2134+
2135+
/* Register ones with interrupts first. */
2136+
if (!e->io.irq)
2137+
continue;
2138+
2139+
/*
2140+
* Go through the ones we have already seen to see if this
2141+
* is a dup.
2142+
*/
2143+
list_for_each_entry(e2, &smi_infos, link) {
2144+
if (e2 == e)
2145+
break;
2146+
if (e2->io.irq && ipmi_smi_info_same(e, e2)) {
2147+
dup = true;
2148+
break;
21282149
}
21292150
}
2151+
if (!dup)
2152+
try_smi_init(e);
21302153
}
21312154

2132-
/* type will only have been set if we successfully registered an si */
2133-
if (type)
2134-
goto skip_fallback_noirq;
2155+
/*
2156+
* Now try devices without interrupts.
2157+
*/
2158+
list_for_each_entry(e, &smi_infos, link) {
2159+
bool dup = false;
21352160

2136-
/* Fall back to the preferred device */
2161+
if (e->io.irq)
2162+
continue;
21372163

2138-
list_for_each_entry(e, &smi_infos, link) {
2139-
if (!e->io.irq && (!type || e->io.addr_source == type)) {
2140-
if (!try_smi_init(e)) {
2141-
type = e->io.addr_source;
2164+
/*
2165+
* Go through the ones we have already seen to see if
2166+
* this is a dup. We have already looked at the ones
2167+
* with interrupts.
2168+
*/
2169+
list_for_each_entry(e2, &smi_infos, link) {
2170+
if (!e2->io.irq)
2171+
continue;
2172+
if (ipmi_smi_info_same(e, e2)) {
2173+
dup = true;
2174+
break;
2175+
}
2176+
}
2177+
list_for_each_entry(e2, &smi_infos, link) {
2178+
if (e2 == e)
2179+
break;
2180+
if (ipmi_smi_info_same(e, e2)) {
2181+
dup = true;
2182+
break;
21422183
}
21432184
}
2185+
if (!dup)
2186+
try_smi_init(e);
21442187
}
21452188

2146-
skip_fallback_noirq:
21472189
initialized = true;
21482190
mutex_unlock(&smi_infos_lock);
21492191

0 commit comments

Comments
 (0)