Can you try the attached patch? It should auto-detect and compensate. -corey
On 08/18/2015 06:38 AM, Henrik Korkuc wrote: > Initialization: > [ 8.981172] ipmi message handler version 39.2 > [ 8.997813] ipmi device interface > [ 9.002179] Copyright (C) 2004 MontaVista Software - IPMI Powerdown > via sys_reboot. > [ 9.047200] IPMI System Interface driver. > [ 9.051849] ipmi_si: probing via SMBIOS > [ 9.056237] ipmi_si: SMBIOS: io 0xca8 regsize 1 spacing 4 irq 10 > [ 9.063049] ipmi_si: Adding SMBIOS-specified kcs state machine > [ 9.076464] ipmi_si: Trying SMBIOS-specified kcs state machine at > i/o address 0xca8, slave address 0x20, irq 10 > [ 9.226065] ipmi_si ipmi_si.0: Using irq 10 > [ 9.229405] ipmi_si ipmi_si.0: Could not set the global enables: 0xcc. > [ 9.267096] ipmi_si ipmi_si.0: Found new BMC (man_id: 0x0002a2, > prod_id: 0x0100, dev_id: 0x20) > [ 9.279494] IPMI poweroff: ATCA Detect mfg 0x2A2 prod 0x100 > [ 9.285828] IPMI poweroff: Found a chassis style poweroff function > [ 9.292976] ipmi_si ipmi_si.0: IPMI kcs interface initialized > > > Rerun of 0x02 (message gets repeated): > # dmesg |tail -n1; echo "----------" > [145215.602590] start_kcs_transaction - 18 2e 02 > ---------- > root@cephold01-sjc1:/home/henrik# ipmitool raw 6 0x2e 0x02; sleep 1; > dmesg |tail -n1; echo "----------" > Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0 cmd=0x2e > rsp=0xcc): Invalid data field in request > [145233.596151] ipmi_si ipmi_si.0: Could not set the global enables: > 0xcc. > > si_stats: > interrupts_enabled: 1 > short_timeouts: 0 > long_timeouts: 3619 > idles: 32164 > interrupts: 373721 > attentions: 0 > flag_fetches: 0 > hosed_count: 0 > complete_transactions: 33586 > events: 0 > watchdog_pretimeouts: 0 > incoming_messages: 0 > > > MC Info: > # ipmitool mc info > Device ID : 32 > Device Revision : 1 > Firmware Revision : 2.0a > IPMI Version : 2.0 > Manufacturer ID : 674 > Manufacturer Name : DELL Inc > Product ID : 256 (0x0100) > Product Name : Unknown (0x100) > Device Available : yes > Provides Device SDRs : yes > Additional Device Support : > Sensor Device > SDR Repository Device > SEL Device > FRU Inventory Device > IPMB Event Receiver > Bridge > Chassis Device > Aux Firmware Rev Info : > 0x00 > 0x31 > 0x0a > 0x0a > > On 15-08-18 13:53, Corey Minyard wrote: >> Well, the BMC appears to have interrupts enabled and does not support >> setting >> the interrupt enable bit in the global enables. >> >> I guess we should see if the interrupts are actually working. Can you >> send me >> the kernel output from the ipmi_si driver loading? The lines should all >> have ipmi_si >> in them. That will tell me where it got the interrupt information. >> >> Then send me the output of /proc/ipmi/0/si_stats after running a few >> commands. >> That should tell me if interrupts are actually working. >> >> Next, can you rerun "ipmitool raw 6 0x2e 0x02" again? In your listing >> below you >> have the last byte as 0x01 twice and didn't run it with 0x02. >> >> And lastly, can you run "ipmitool mc info" and send me the output? If I >> need to >> do this as a blacklist I'll need that output. I think the situation is >> that ACPI or SMBIOS >> is advertising that it has interrupts even though they are not >> supported. I think I >> can detect this automatically, though. >> >> If interrupts are actually working, I've got a more difficult situation >> to handle. >> >> -corey >> >> On 08/18/2015 05:25 AM, Henrik Korkuc wrote: >>> It looks like all of them is a problem... After every command there >>> would be a message in dmesg. >>> >>> # dmesg |tail -n1; echo "----------" >>> [140891.403745] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> ---------- >>> # ipmitool raw 6 0x2f; sleep 1; dmesg |tail -n1; echo "----------" >>> 08 >>> [140912.869867] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> ---------- >>> # ipmitool raw 6 0x2e 0x01; sleep 1; dmesg |tail -n1; echo "----------" >>> Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0 cmd=0x2e >>> rsp=0xcc): Invalid data field in request >>> [140913.915045] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> ---------- >>> # ipmitool raw 6 0x2e 0x01; sleep 1; dmesg |tail -n1; echo "----------" >>> Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0 cmd=0x2e >>> rsp=0xcc): Invalid data field in request >>> [140914.970121] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> ---------- >>> # ipmitool raw 6 0x2e 0x04; sleep 1; dmesg |tail -n1; echo "----------" >>> >>> [140916.016644] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> ---------- >>> # ipmitool raw 6 0x2e 0x08; sleep 1; dmesg |tail -n1; echo "----------" >>> >>> [140917.060922] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> ---------- >>> >>> and a run with debug flag: >>> [141144.316148] start_kcs_transaction - 18 01 >>> [141144.317982] start_kcs_transaction - 18 2f >>> [141144.318822] start_kcs_transaction - 18 2e 0f >>> [141144.319740] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> [141144.327156] start_kcs_transaction - 18 33 >>> [141144.328069] start_kcs_transaction - b0 00 00 >>> [141144.328922] start_kcs_transaction - 18 2f >>> [141145.341225] start_kcs_transaction - 18 01 >>> [141145.343324] start_kcs_transaction - 18 2f >>> [141145.344166] start_kcs_transaction - 18 2e 0f >>> [141145.345007] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> [141145.352412] start_kcs_transaction - 18 33 >>> [141145.354375] start_kcs_transaction - b0 00 00 >>> [141145.355317] start_kcs_transaction - 18 2e 01 >>> [141146.379823] start_kcs_transaction - 18 01 >>> [141146.383840] start_kcs_transaction - 18 2f >>> [141146.384801] start_kcs_transaction - 18 2e 0f >>> [141146.385647] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> [141146.393061] start_kcs_transaction - 18 33 >>> [141146.393996] start_kcs_transaction - b0 00 00 >>> [141146.394957] start_kcs_transaction - 18 2e 02 >>> [141147.410761] start_kcs_transaction - 18 01 >>> [141147.412512] start_kcs_transaction - 18 2f >>> [141147.413620] start_kcs_transaction - 18 2e 0f >>> [141147.414469] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> [141147.421891] start_kcs_transaction - 18 33 >>> [141147.422810] start_kcs_transaction - b0 00 00 >>> [141147.423777] start_kcs_transaction - 18 2e 04 >>> [141148.437792] start_kcs_transaction - 18 01 >>> [141148.439615] start_kcs_transaction - 18 2f >>> [141148.440510] start_kcs_transaction - 18 2e 07 >>> [141148.441338] ipmi_si ipmi_si.0: Could not set the global enables: >>> 0xcc. >>> [141148.448752] start_kcs_transaction - 18 33 >>> [141148.449744] start_kcs_transaction - b0 00 00 >>> [141148.450574] start_kcs_transaction - 18 2e 08 >>> >>> On 15-08-18 00:31, Corey Minyard wrote: >>>> Joy. Another broken management controller. >>>> >>>> It appears that the BMC doesn't like setting one of the global enables >>>> bits. Yes, this is a different issue. Can you try the following: >>>> >>>> ipmitool raw 6 0x2f >>>> ipmitool raw 6 0x2e 0x01 >>>> ipmitool raw 6 0x2e 0x02 >>>> ipmitool raw 6 0x2e 0x04 >>>> ipmitool raw 6 0x2e 0x08 >>>> >>>> That should tell me which bit is the issue. >>>> >>>> Thanks, >>>> >>>> -corey >>>> >>>> On 08/16/2015 02:22 PM, Henrik Korkuc wrote: >>>>> Hey, >>>>> >>>>> Related to >>>>> http://sourceforge.net/p/openipmi/mailman/message/33593756/ >>>>> >>>>> Using 4.1.5 kernel built from source, debian Jessie. >>>>> Using "ipmitool lan print" I can reproduce multiple dmesg messages >>>>> "ipmi_si ipmi_si.0: Could not set the global enables: 0xcc." >>>>> >>>>> I even tried compiling kernel with Corey's fix as a head, so it does >>>>> not look like regression. >>>>> commit 1e7d6a45f6b10bc48a1453bca3d829e210546571 >>>>> Author: Corey Minyard <[email protected]> >>>>> Date: Fri Apr 3 12:13:48 2015 -0500 >>>>> >>>>> Dmesg output with "echo 2 > /sys/module/ipmi_si/parameters/kcs_debug" >>>>> >>>>> [ 570.903942] start_kcs_transaction - 18 01 >>>>> [ 570.905744] start_kcs_transaction - 18 2f >>>>> [ 570.906579] start_kcs_transaction - 18 2e 0f >>>>> [ 570.907456] ipmi_si ipmi_si.0: Could not set the global >>>>> enables: 0xcc. >>>>> [ 570.914826] start_kcs_transaction - 18 33 >>>>> [ 570.915725] start_kcs_transaction - b0 00 00 >>>>> [ 570.916567] start_kcs_transaction - 18 42 01 >>>>> [ 570.917589] start_kcs_transaction - 18 42 01 >>>>> [ 570.918588] start_kcs_transaction - 18 42 01 >>>>> [ 570.919677] start_kcs_transaction - 30 02 01 00 00 00 >>>>> [ 570.920727] start_kcs_transaction - 30 02 01 01 00 00 >>>>> [ 570.921680] start_kcs_transaction - 30 02 01 02 00 00 >>>>> [ 570.922731] start_kcs_transaction - 30 02 01 04 00 00 >>>>> [ 570.923806] start_kcs_transaction - 30 02 01 03 00 00 >>>>> [ 570.924843] start_kcs_transaction - 30 02 01 06 00 00 >>>>> [ 570.925853] start_kcs_transaction - 30 02 01 05 00 00 >>>>> [ 571.027182] start_kcs_transaction - 30 02 01 10 00 00 >>>>> [ 571.028519] start_kcs_transaction - 30 02 01 07 00 00 >>>>> [ 571.029595] start_kcs_transaction - 30 02 01 0a 00 00 >>>>> [ 571.030553] start_kcs_transaction - 30 02 01 0b 00 00 >>>>> [ 571.031526] start_kcs_transaction - 30 02 01 0c 00 00 >>>>> [ 571.032569] start_kcs_transaction - 30 02 01 0d 00 00 >>>>> [ 571.033726] start_kcs_transaction - 30 02 01 0e 00 00 >>>>> [ 571.034723] start_kcs_transaction - 30 02 01 0f 00 00 >>>>> [ 571.035851] start_kcs_transaction - 30 02 01 14 00 00 >>>>> [ 571.036820] start_kcs_transaction - 30 02 01 15 00 00 >>>>> [ 571.037790] start_kcs_transaction - 30 02 01 16 00 00 >>>>> [ 571.038791] start_kcs_transaction - 30 02 01 17 00 00 >>>>> [ 571.039957] start_kcs_transaction - 30 02 01 18 00 00 >>>>> -- >>>>> Henrik Korkuc >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> Openipmi-developer mailing list >>>>> [email protected] >>>>> https://lists.sourceforge.net/lists/listinfo/openipmi-developer > >
>From c6efeb4acc574a4a1c926f97401be9b81b713fd9 Mon Sep 17 00:00:00 2001 From: Corey Minyard <[email protected]> Date: Tue, 18 Aug 2015 14:29:10 -0500 Subject: [PATCH 1/4] ipmi: Compensate for BMCs that wont set the irq enable bit It appears that some BMCs support interrupts but don't support setting the irq enable bits. The interrupts are just always on. Sigh. Add code to compensate. The new code was very similar to another functions, so this also factors out the common code into other functions. Signed-off-by: Corey Minyard <[email protected]> --- drivers/char/ipmi/ipmi_si_intf.c | 180 +++++++++++++++++++++++++++++---------- 1 file changed, 137 insertions(+), 43 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7e50390..c80034d 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -262,9 +262,21 @@ struct smi_info { bool supports_event_msg_buff; /* - * Can we clear the global enables receive irq bit? + * Can we disable interrupts the global enables receive irq + * bit? There are currently two forms of brokenness, some + * systems cannot disable the bit (which is technically within + * the spec but a bad idea) and some systems have the bit + * forced to zero even though interrupts work (which is + * clearly outside the spec). The next bool tells which form + * of brokenness is present. */ - bool cannot_clear_recv_irq_bit; + bool cannot_disable_irq; + + /* + * Some systems are broken and cannot set the irq enable + * bit, even if they support interrupts. + */ + bool irq_enable_broken; /* * Did we get an attention that we did not handle? @@ -554,13 +566,14 @@ static u8 current_global_enables(struct smi_info *smi_info, u8 base, if (smi_info->supports_event_msg_buff) enables |= IPMI_BMC_EVT_MSG_BUFF; - if ((smi_info->irq && !smi_info->interrupt_disabled) || - smi_info->cannot_clear_recv_irq_bit) + if (((smi_info->irq && !smi_info->interrupt_disabled) || + smi_info->cannot_disable_irq) && + !smi_info->irq_enable_broken) enables |= IPMI_BMC_RCV_MSG_INTR; if (smi_info->supports_event_msg_buff && - smi_info->irq && !smi_info->interrupt_disabled) - + smi_info->irq && !smi_info->interrupt_disabled && + !smi_info->irq_enable_broken) enables |= IPMI_BMC_EVT_MSG_INTR; *irq_on = enables & (IPMI_BMC_EVT_MSG_INTR | IPMI_BMC_RCV_MSG_INTR); @@ -2908,12 +2921,7 @@ static int try_get_dev_id(struct smi_info *smi_info) return rv; } -/* - * Some BMCs do not support clearing the receive irq bit in the global - * enables (even if they don't support interrupts on the BMC). Check - * for this and handle it properly. - */ -static void check_clr_rcv_irq(struct smi_info *smi_info) +static int get_global_enables(struct smi_info *smi_info, u8 *enables) { unsigned char msg[3]; unsigned char *resp; @@ -2921,12 +2929,8 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) int rv; resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); - if (!resp) { - printk(KERN_WARNING PFX "Out of memory allocating response for" - " global enables command, cannot check recv irq bit" - " handling.\n"); - return; - } + if (!resp) + return -ENOMEM; msg[0] = IPMI_NETFN_APP_REQUEST << 2; msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; @@ -2934,9 +2938,9 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) rv = wait_for_msg_done(smi_info); if (rv) { - printk(KERN_WARNING PFX "Error getting response from get" - " global enables command, cannot check recv irq bit" - " handling.\n"); + dev_warn(smi_info->dev, + "Error getting response from get global enables command: %d\n", + rv); goto out; } @@ -2947,27 +2951,44 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || resp[2] != 0) { - printk(KERN_WARNING PFX "Invalid return from get global" - " enables command, cannot check recv irq bit" - " handling.\n"); + dev_warn(smi_info->dev, + "Invalid return from get global enables command: %ld %x %x %x\n", + resp_len, resp[0], resp[1], resp[2]); rv = -EINVAL; goto out; + } else { + *enables = resp[3]; } - if ((resp[3] & IPMI_BMC_RCV_MSG_INTR) == 0) - /* Already clear, should work ok. */ - goto out; +out: + kfree(resp); + return rv; +} + +/* + * Returns 1 if it gets an error from the command. + */ +static int set_global_enables(struct smi_info *smi_info, u8 enables) +{ + unsigned char msg[3]; + unsigned char *resp; + unsigned long resp_len; + int rv; + + resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); + if (!resp) + return -ENOMEM; msg[0] = IPMI_NETFN_APP_REQUEST << 2; msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; - msg[2] = resp[3] & ~IPMI_BMC_RCV_MSG_INTR; + msg[2] = enables; smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3); rv = wait_for_msg_done(smi_info); if (rv) { - printk(KERN_WARNING PFX "Error getting response from set" - " global enables command, cannot check recv irq bit" - " handling.\n"); + dev_warn(smi_info->dev, + "Error getting response from set global enables command: %d\n", + rv); goto out; } @@ -2977,25 +2998,93 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) if (resp_len < 3 || resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { - printk(KERN_WARNING PFX "Invalid return from get global" - " enables command, cannot check recv irq bit" - " handling.\n"); + dev_warn(smi_info->dev, + "Invalid return from set global enables command: %ld %x %x\n", + resp_len, resp[0], resp[1]); rv = -EINVAL; goto out; } - if (resp[2] != 0) { + if (resp[2] != 0) + rv = 1; + +out: + kfree(resp); + return rv; +} + +/* + * Some BMCs do not support clearing the receive irq bit in the global + * enables (even if they don't support interrupts on the BMC). Check + * for this and handle it properly. + */ +static void check_clr_rcv_irq(struct smi_info *smi_info) +{ + u8 enables = 0; + int rv; + + rv = get_global_enables(smi_info, &enables); + if (!rv) { + if ((enables & IPMI_BMC_RCV_MSG_INTR) == 0) + /* Already clear, should work ok. */ + return; + + enables &= ~IPMI_BMC_RCV_MSG_INTR; + rv = set_global_enables(smi_info, enables); + } + + if (rv < 0) { + dev_err(smi_info->dev, + "Cannot check clearing the rcv irq: %d\n", rv); + return; + } + + if (rv) { /* * An error when setting the event buffer bit means * clearing the bit is not supported. */ - printk(KERN_WARNING PFX "The BMC does not support clearing" - " the recv irq bit, compensating, but the BMC needs to" - " be fixed.\n"); - smi_info->cannot_clear_recv_irq_bit = true; + dev_warn(smi_info->dev, + "The BMC does not support clearing the recv irq bit, compensating, but the BMC needs to be fixed.\n"); + smi_info->cannot_disable_irq = true; + } +} + +/* + * Some BMCs do not support setting the interrupt bits in the global + * enables even if they support interrupts. Clearly bad, but we can + * compensate. + */ +static void check_set_rcv_irq(struct smi_info *smi_info) +{ + u8 enables = 0; + int rv; + + if (!smi_info->irq) + return; + + rv = get_global_enables(smi_info, &enables); + if (!rv) { + enables |= IPMI_BMC_RCV_MSG_INTR; + rv = set_global_enables(smi_info, enables); + } + + if (rv < 0) { + dev_err(smi_info->dev, + "Cannot check setting the rcv irq: %d\n", rv); + return; + } + + if (rv) { + /* + * An error when setting the event buffer bit means + * setting the bit is not supported. + */ + dev_warn(smi_info->dev, + "The BMC does not support setting the recv irq bit, compensating, but the BMC needs to be fixed.\n"); + smi_info->cannot_disable_irq = true; + smi_info->irq_enable_broken = true; } - out: - kfree(resp); } static int try_enable_event_buffer(struct smi_info *smi_info) @@ -3316,6 +3405,12 @@ static void setup_xaction_handlers(struct smi_info *smi_info) setup_dell_poweredge_bt_xaction_handler(smi_info); } +static void check_for_broken_irqs(struct smi_info *smi_info) +{ + check_clr_rcv_irq(smi_info); + check_set_rcv_irq(smi_info); +} + static inline void wait_for_timer_and_thread(struct smi_info *smi_info) { if (smi_info->thread != NULL) @@ -3493,10 +3588,9 @@ static int try_smi_init(struct smi_info *new_smi) goto out_err; } - check_clr_rcv_irq(new_smi); - setup_oem_data_handler(new_smi); setup_xaction_handlers(new_smi); + check_for_broken_irqs(new_smi); new_smi->waiting_msg = NULL; new_smi->curr_msg = NULL; -- 1.8.3.1
------------------------------------------------------------------------------
_______________________________________________ Openipmi-developer mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openipmi-developer
