• K
    PCI: pciehp: Fix hot-add vs powerfault detection order · 34fb6bf9
    Keith Busch 提交于
    If both hot-add and power fault were observed in a single interrupt, we
    handled the hot-add first, then the power fault, in this path:
    
      pciehp_ist
        if (events & (PDC | DLLSC))
          pciehp_handle_presence_or_link_change
            case OFF_STATE:
              pciehp_enable_slot
                __pciehp_enable_slot
                  board_added
                    pciehp_power_on_slot
                      ctrl->power_fault_detected = 0
                      pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_ON, PCI_EXP_SLTCTL_PCC)
                    pciehp_green_led_on(p_slot)             # power LED on
    		pciehp_set_attention_status(p_slot, 0)  # attention LED off
        if ((events & PFD) && !ctrl->power_fault_detected)
          ctrl->power_fault_detected = 1
          pciehp_set_attention_status(1)                    # attention LED on
          pciehp_green_led_off(slot)                        # power LED off
    
    This left the attention indicator on (even though the hot-add succeeded)
    and the power indicator off (even though the slot power was on).
    
    Fix this by checking for power faults before checking for new devices.
    
    Prior to 0e94916e, this was successful because everything was chained
    through work queues and the order was:
    
      INT_PRESENCE_ON -> INT_POWER_FAULT -> ENABLE_REQ
    
    The ENABLE_REQ cleared the power fault at the end, but now everything is
    handled inline with the interrupt thread, such that the work ENABLE_REQ was
    doing happens before power fault handling now.
    
    Fixes: 0e94916e ("PCI: pciehp: Handle events synchronously")
    Signed-off-by: NKeith Busch <keith.busch@intel.com>
    [bhelgaas: changelog]
    Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
    Reviewed-by: NLukas Wunner <lukas@wunner.de>
    34fb6bf9
pciehp_hpc.c 25.0 KB