• L
    ACPI / IPMI: Use global IPMI operation region handler · e96a94ed
    Lv Zheng 提交于
    It is found on a real machine, in its ACPI namespace, the IPMI
    OperationRegions (in the ACPI000D - ACPI power meter) are not defined under
    the IPMI system interface device (the IPI0001 with KCS type returned from
    _IFT control method):
      Device (PMI0)
      {
          Name (_HID, "ACPI000D")  // _HID: Hardware ID
          OperationRegion (SYSI, IPMI, 0x0600, 0x0100)
          Field (SYSI, BufferAcc, Lock, Preserve)
          {
              AccessAs (BufferAcc, 0x01),
              Offset (0x58),
              SCMD,   8,
              GCMD,   8
          }
    
          OperationRegion (POWR, IPMI, 0x3000, 0x0100)
          Field (POWR, BufferAcc, Lock, Preserve)
          {
              AccessAs (BufferAcc, 0x01),
              Offset (0xB3),
              GPMM,   8
          }
      }
    
      Device (PCI0)
      {
          Device (ISA)
          {
              Device (NIPM)
              {
                  Name (_HID, EisaId ("IPI0001"))  // _HID: Hardware ID
                  Method (_IFT, 0, NotSerialized)  // _IFT: IPMI Interface Type
                  {
                      Return (0x01)
                  }
              }
          }
      }
    
    Current ACPI_IPMI code registers IPMI operation region handler on a
    per-device basis, so for the above namespace the IPMI operation region
    handler is registered only under the scope of \_SB.PCI0.ISA.NIPM.  Thus
    when an IPMI operation region field of \PMI0 is accessed, there are errors
    reported on such platform:
      ACPI Error: No handlers for Region [IPMI]
      ACPI Error: Region IPMI(7) has no handler
    The solution is to install an IPMI operation region handler from root node
    so that every object that defines IPMI OperationRegion can get an address
    space handler registered.
    
    When an IPMI operation region field is accessed, the Network Function
    (0x06 for SYSI and 0x30 for POWR) and the Command (SCMD, GCMD, GPMM) are
    passed to the operation region handler, there is no system interface
    specified by the BIOS.  The patch tries to select one system interface by
    monitoring the system interface notification.  IPMI messages passed from
    the ACPI codes are sent to this selected global IPMI system interface.
    
    The ACPI_IPMI will always select the first registered IPMI interface
    with an ACPI handle (i.e., defined in the ACPI namespace).  It's hard to
    determine the selection when there are multiple IPMI system interfaces
    defined in the ACPI namespace. According to the IPMI specification:
    
      A BMC device may make available multiple system interfaces, but only one
      management controller is allowed to be 'active' BMC that provides BMC
      functionality for the system (in case of a 'partitioned' system, there
      can be only one active BMC per partition).  Only the system interface(s)
      for the active BMC allowed to respond to the 'Get Device Id' command.
    
    According to the ipmi_si desigin:
    
      The ipmi_si registeration notifications can only happen after a
      successful "Get Device ID" command.
    
    Thus it should be OK for non-partitioned systems to do such selection.
    However, we do not have much knowledge on 'partitioned' systems.
    
    References: https://bugzilla.kernel.org/show_bug.cgi?id=46741Signed-off-by: NLv Zheng <lv.zheng@intel.com>
    Reviewed-by: NHuang Ying <ying.huang@intel.com>
    Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
    e96a94ed
acpi_ipmi.c 16.8 KB