@@ -2095,9 +2095,18 @@ static int try_smi_init(struct smi_info *new_smi)
2095
2095
return rv ;
2096
2096
}
2097
2097
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
+
2098
2107
static int __init init_ipmi_si (void )
2099
2108
{
2100
- struct smi_info * e ;
2109
+ struct smi_info * e , * e2 ;
2101
2110
enum ipmi_addr_src type = SI_INVALID ;
2102
2111
2103
2112
if (initialized )
@@ -2113,37 +2122,70 @@ static int __init init_ipmi_si(void)
2113
2122
2114
2123
ipmi_si_parisc_init ();
2115
2124
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 */
2120
2125
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
+ */
2121
2132
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 ;
2128
2149
}
2129
2150
}
2151
+ if (!dup )
2152
+ try_smi_init (e );
2130
2153
}
2131
2154
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;
2135
2160
2136
- /* Fall back to the preferred device */
2161
+ if (e -> io .irq )
2162
+ continue ;
2137
2163
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 ;
2142
2183
}
2143
2184
}
2185
+ if (!dup )
2186
+ try_smi_init (e );
2144
2187
}
2145
2188
2146
- skip_fallback_noirq :
2147
2189
initialized = true;
2148
2190
mutex_unlock (& smi_infos_lock );
2149
2191
0 commit comments