pcie_aer: get rid of recursion

Added some TODOs: they are trivial but omitted here
to make the patch logic as transparent as possible.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Michael S. Tsirkin 2010-11-17 15:02:26 +02:00
parent 34e65944c0
commit 247c97f3f5
1 changed files with 31 additions and 17 deletions

View File

@ -175,15 +175,9 @@ static void pcie_aer_update_uncor_status(PCIDevice *dev)
} }
} }
/*
* pcie_aer_msg() is called recursively by
* pcie_aer_msg_alldev(), pci_aer_msg_vbridge() and pcie_aer_msg_root_port()
*/
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg);
/* /*
* return value: * return value:
* true: error message is sent up * true: error message needs to be sent up
* false: error message is masked * false: error message is masked
* *
* 6.2.6 Error Message Control * 6.2.6 Error Message Control
@ -193,8 +187,6 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg);
static bool static bool
pcie_aer_msg_alldev(PCIDevice *dev, const PCIEAERMsg *msg) pcie_aer_msg_alldev(PCIDevice *dev, const PCIEAERMsg *msg)
{ {
PCIDevice *parent_port;
if (!(pcie_aer_msg_is_uncor(msg) && if (!(pcie_aer_msg_is_uncor(msg) &&
(pci_get_word(dev->config + PCI_COMMAND) & PCI_COMMAND_SERR))) { (pci_get_word(dev->config + PCI_COMMAND) & PCI_COMMAND_SERR))) {
return false; return false;
@ -220,13 +212,21 @@ pcie_aer_msg_alldev(PCIDevice *dev, const PCIEAERMsg *msg)
} }
/* send up error message */ /* send up error message */
return true;
}
/* Get parent port to send up error message on.
* TODO: clean up and open-code this logic */
static PCIDevice *pcie_aer_parent_port(PCIDevice *dev)
{
PCIDevice *parent_port;
if (pci_is_express(dev) && if (pci_is_express(dev) &&
pcie_cap_get_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { pcie_cap_get_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
/* Root port notify system itself, /* Root port can notify system itself,
or send the error message to root complex event collector. */ or send the error message to root complex event collector. */
/* /*
* if root port is associated to event collector, set * if root port is associated with an event collector,
* parent_port = root complex event collector * return the root complex event collector here.
* For now root complex event collector isn't supported. * For now root complex event collector isn't supported.
*/ */
parent_port = NULL; parent_port = NULL;
@ -236,11 +236,10 @@ pcie_aer_msg_alldev(PCIDevice *dev, const PCIEAERMsg *msg)
if (parent_port) { if (parent_port) {
if (!pci_is_express(parent_port)) { if (!pci_is_express(parent_port)) {
/* just ignore it */ /* just ignore it */
return false; return NULL;
} }
pcie_aer_msg(parent_port, msg);
} }
return true; return parent_port;
} }
/* /*
@ -381,8 +380,12 @@ static bool pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg)
/* /*
* 6.2.6 Error Message Control Figure 6-3 * 6.2.6 Error Message Control Figure 6-3
*
* Returns true in case the error needs to
* be propagated up.
* TODO: open-code.
*/ */
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg) static bool pcie_send_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
{ {
uint8_t type; uint8_t type;
bool msg_sent; bool msg_sent;
@ -402,6 +405,18 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
if (type == PCI_EXP_TYPE_ROOT_PORT && msg_sent) { if (type == PCI_EXP_TYPE_ROOT_PORT && msg_sent) {
pcie_aer_msg_root_port(dev, msg); pcie_aer_msg_root_port(dev, msg);
} }
return msg_sent;
}
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
{
bool send_to_parent;
while (dev) {
if (!pcie_send_aer_msg(dev, msg)) {
return;
}
dev = pcie_aer_parent_port(dev);
}
} }
static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err) static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
@ -824,4 +839,3 @@ const VMStateDescription vmstate_pcie_aer_log = {
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
} }
}; };