ipmbbridged: Fix the issue with busy caused by incorrect requests

D-bus method:
  sendRequest yyyyay <channel> <netf> <lun> <cmd> <dataLen> <data>

If dataLen is greater than ipmbMaxFrameLength (264), the request will
not be set to invalid and will continue to occupy outstandingRequests
until it is full, which will result in all subsequent requests being
busy.

busctl call xyz.openbmc_project.Ipmi.Channel.Ipmb \
           /xyz/openbmc_project/Ipmi/Channel/Ipmb org.openbmc.Ipmb \
           sendRequest yyyyay 0x00 0x30 0x00 0x06 0x00
(iyyyyay) 3 0 0 0 0 0

Error:
sendRequest (dataLen > 264)              ipmbHandleRequest
                                                 |
                                            requestAdd
                                                 |
(outstandingRequests save request) <-- makeRequestValid(request)
                                                 |
       (dataLen > 264, return -1)  <-- ipmbToi2cConstruct(buffer)
                                                 |
                           returnStatus(ipmbResponseStatus::error)

(Repeat sending until outstandingRequests is full)
------------------------------------------------------------------
sendRequest                              ipmbHandleRequest
                                                 |
                                            requestAdd
                                                 |
                                             seqNumGet \
(outstandingRequests is full, return false) <----
                                                 |
                            returnStatus(ipmbResponseStatus::busy)

All subsequent requests will be returned to busy and can only be
restored by restarting the service.

Change-Id: Idfda2af1a136dfcdc478e21d172de673f1efef03
Signed-off-by: Tian Jingzai <tianjingzai@phytium.com.cn>
1 file changed
tree: 6da8c6bc950c7bc669ff940197a09ee510c85bca
  1. subprojects/
  2. .clang-format
  3. ipmb-channels.json
  4. ipmb.service
  5. ipmbbridged.cpp
  6. ipmbbridged.hpp
  7. ipmbdefines.hpp
  8. ipmbutils.cpp
  9. ipmbutils.hpp
  10. LICENSE
  11. meson.build
  12. OWNERS
  13. README.md
README.md

Sample config options available to configure :

  1. Single channel with one me and ipmb :
{
  "channels": [
    {
      "type": "me",
      "slave-path": "/dev/ipmb-4",
      "bmc-addr": 32,
      "remote-addr": 44
    },
    {
      "type": "ipmb",
      "slave-path": "/dev/ipmb-9",
      "bmc-addr": 32,
      "remote-addr": 96
    }
  ]
}
  1. Multiple sub channels with me and ipmb :
{
  "channels": [
    {
      "type": "me",
      "slave-path": "/dev/ipmb-1",
      "bmc-addr": 32,
      "remote-addr": 64,
      "devIndex": 0
    },
    {
      "type": "ipmb",
      "slave-path": "/dev/ipmb-3",
      "bmc-addr": 32,
      "remote-addr": 64,
      "devIndex": 0
    },
    {
      "type": "me",
      "slave-path": "/dev/ipmb-5",
      "bmc-addr": 32,
      "remote-addr": 64,
      "devIndex": 1
    },
    {
      "type": "ipmb",
      "slave-path": "/dev/ipmb-7",
      "bmc-addr": 32,
      "remote-addr": 64,
      "devIndex": 1
    }
  ]
}
Config fields :

type          : This points to the ChannelType. It can be ME or ipmb channel.
slave-path    : The ipmb device path.
bmc-addr      : This is BMC target address to communicate between BMC and device.
remote-addr   : This is Remote/requester target address to communicate between BMC and device.
devIndex      : This devIndex used to identify the particular device/host.