Message ID | 1510256927-8033-1-git-send-email-minyard@acm.org |
---|---|
State | New |
Headers | show |
Series | ipmi: Prefer ACPI system interfaces over SMBIOS ones | expand |
Corey, This patch worked on my system. Thank you! Tested-by: Andrew Banman <abanman@hpe.com> # insmod ipmi_si.ko; dmesg -c [ 225.793934] ipmi_si IPI0001:00: ipmi_si: probing via ACPI [ 225.799982] ipmi_si IPI0001:00: [io 0x0ce4-0x0ce6] regsize 1 spacing 1 irq 6 [ 225.807953] ipmi_si: Adding ACPI-specified bt state machine [ 225.814202] IPMI System Interface driver. [ 225.818895] ipmi_si: probing via SMBIOS [ 225.823183] ipmi_si: SMBIOS: mem 0xce4 regsize 1 spacing 1 irq 6 [ 225.829894] ipmi_si: Adding SMBIOS-specified bt state machine [ 225.836318] ipmi_si: probing via SPMI [ 225.840411] ipmi_si: SPMI: io 0xce4 regsize 1 spacing 1 irq 6 [ 225.846832] (NULL device *): SPMI-specified bt state machine: duplicate [ 225.854220] ipmi_si: Trying ACPI-specified bt state machine at i/o address 0xce4, slave address 0x0, irq 6 [ 225.870711] ipmi_si IPI0001:00: Using irq 6 [ 225.875530] ipmi_si IPI0001:00: Found new BMC (man_id: 0x000000, prod_id: 0x0101, dev_id: 0x20) [ 225.876266] IPMI BT: req2rsp=2 secs retries=1 [ 225.890166] ipmi_si IPI0001:00: IPMI bt interface initialized # rmmod ipmi_si.ko; dmesg -c # Andrew On 11/9/17 1:48 PM, minyard@acm.org wrote: > From: Corey Minyard <cminyard@mvista.com> > > The recent changes to add SMBIOS (DMI) IPMI interfaces as platform > devices caused DMI to be selected before ACPI, causing ACPI type > of operations to not work. > > Signed-off-by: Corey Minyard <cminyard@mvista.com> > --- > > Andrew, > > I looked a bit more and found that I already had this queued for the > next kernel release, it fixes your issue and another issue, too. > If this works for you, I'll request this for stable. > > -corey > > drivers/char/ipmi/ipmi_si_intf.c | 33 +++++++++++++++++++++++---------- > 1 file changed, 23 insertions(+), 10 deletions(-) > > diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c > index 39c55f4..f8e28ba 100644 > --- a/drivers/char/ipmi/ipmi_si_intf.c > +++ b/drivers/char/ipmi/ipmi_si_intf.c > @@ -3425,7 +3425,7 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) > del_timer_sync(&smi_info->si_timer); > } > > -static int is_new_interface(struct smi_info *info) > +static struct smi_info *find_dup_si(struct smi_info *info) > { > struct smi_info *e; > > @@ -3440,24 +3440,36 @@ static int is_new_interface(struct smi_info *info) > */ > if (info->slave_addr && !e->slave_addr) > e->slave_addr = info->slave_addr; > - return 0; > + return e; > } > } > > - return 1; > + return NULL; > } > > static int add_smi(struct smi_info *new_smi) > { > int rv = 0; > + struct smi_info *dup; > > mutex_lock(&smi_infos_lock); > - if (!is_new_interface(new_smi)) { > - 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; > - goto out_err; > + dup = find_dup_si(new_smi); > + if (dup) { > + if (new_smi->addr_source == SI_ACPI && > + dup->addr_source == SI_SMBIOS) { > + /* We prefer ACPI over SMBIOS. */ > + dev_info(dup->dev, > + "Removing SMBIOS-specified %s state machine in favor of ACPI\n", > + si_to_str[new_smi->si_type]); > + cleanup_one_si(dup); > + } else { > + dev_info(new_smi->dev, > + "%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; > + goto out_err; > + } > } > > pr_info(PFX "Adding %s-specified %s state machine\n", > @@ -3866,7 +3878,8 @@ static void cleanup_one_si(struct smi_info *to_clean) > poll(to_clean); > schedule_timeout_uninterruptible(1); > } > - disable_si_irq(to_clean, false); > + if (to_clean->handlers) > + disable_si_irq(to_clean, false); > while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { > poll(to_clean); > schedule_timeout_uninterruptible(1); >
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 39c55f4..f8e28ba 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -3425,7 +3425,7 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) del_timer_sync(&smi_info->si_timer); } -static int is_new_interface(struct smi_info *info) +static struct smi_info *find_dup_si(struct smi_info *info) { struct smi_info *e; @@ -3440,24 +3440,36 @@ static int is_new_interface(struct smi_info *info) */ if (info->slave_addr && !e->slave_addr) e->slave_addr = info->slave_addr; - return 0; + return e; } } - return 1; + return NULL; } static int add_smi(struct smi_info *new_smi) { int rv = 0; + struct smi_info *dup; mutex_lock(&smi_infos_lock); - if (!is_new_interface(new_smi)) { - 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; - goto out_err; + dup = find_dup_si(new_smi); + if (dup) { + if (new_smi->addr_source == SI_ACPI && + dup->addr_source == SI_SMBIOS) { + /* We prefer ACPI over SMBIOS. */ + dev_info(dup->dev, + "Removing SMBIOS-specified %s state machine in favor of ACPI\n", + si_to_str[new_smi->si_type]); + cleanup_one_si(dup); + } else { + dev_info(new_smi->dev, + "%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; + goto out_err; + } } pr_info(PFX "Adding %s-specified %s state machine\n", @@ -3866,7 +3878,8 @@ static void cleanup_one_si(struct smi_info *to_clean) poll(to_clean); schedule_timeout_uninterruptible(1); } - disable_si_irq(to_clean, false); + if (to_clean->handlers) + disable_si_irq(to_clean, false); while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { poll(to_clean); schedule_timeout_uninterruptible(1);