Revision 247c97f3 hw/pcie_aer.c

b/hw/pcie_aer.c
176 176
}
177 177

  
178 178
/*
179
 * pcie_aer_msg() is called recursively by
180
 * pcie_aer_msg_alldev(), pci_aer_msg_vbridge() and pcie_aer_msg_root_port()
181
 */
182
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg);
183

  
184
/*
185 179
 * return value:
186
 * true: error message is sent up
180
 * true: error message needs to be sent up
187 181
 * false: error message is masked
188 182
 *
189 183
 * 6.2.6 Error Message Control
......
193 187
static bool
194 188
pcie_aer_msg_alldev(PCIDevice *dev, const PCIEAERMsg *msg)
195 189
{
196
    PCIDevice *parent_port;
197

  
198 190
    if (!(pcie_aer_msg_is_uncor(msg) &&
199 191
          (pci_get_word(dev->config + PCI_COMMAND) & PCI_COMMAND_SERR))) {
200 192
        return false;
......
220 212
    }
221 213

  
222 214
    /* send up error message */
215
    return true;
216
}
217

  
218
/* Get parent port to send up error message on.
219
 * TODO: clean up and open-code this logic */
220
static PCIDevice *pcie_aer_parent_port(PCIDevice *dev)
221
{
222
    PCIDevice *parent_port;
223 223
    if (pci_is_express(dev) &&
224 224
        pcie_cap_get_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
225
        /* Root port notify system itself,
225
        /* Root port can notify system itself,
226 226
           or send the error message to root complex event collector. */
227 227
        /*
228
         * if root port is associated to event collector, set
229
         * parent_port = root complex event collector
228
         * if root port is associated with an event collector,
229
         * return the root complex event collector here.
230 230
         * For now root complex event collector isn't supported.
231 231
         */
232 232
        parent_port = NULL;
......
236 236
    if (parent_port) {
237 237
        if (!pci_is_express(parent_port)) {
238 238
            /* just ignore it */
239
            return false;
239
            return NULL;
240 240
        }
241
        pcie_aer_msg(parent_port, msg);
242 241
    }
243
    return true;
242
    return parent_port;
244 243
}
245 244

  
246 245
/*
......
381 380

  
382 381
/*
383 382
 * 6.2.6 Error Message Control Figure 6-3
383
 *
384
 * Returns true in case the error needs to
385
 * be propagated up.
386
 * TODO: open-code.
384 387
 */
385
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
388
static bool pcie_send_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
386 389
{
387 390
    uint8_t type;
388 391
    bool msg_sent;
......
402 405
    if (type == PCI_EXP_TYPE_ROOT_PORT && msg_sent) {
403 406
        pcie_aer_msg_root_port(dev, msg);
404 407
    }
408
    return msg_sent;
409
}
410

  
411
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
412
{
413
    bool send_to_parent;
414
    while (dev) {
415
        if (!pcie_send_aer_msg(dev, msg)) {
416
            return;
417
        }
418
        dev =  pcie_aer_parent_port(dev);
419
    }
405 420
}
406 421

  
407 422
static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
......
824 839
        VMSTATE_END_OF_LIST()
825 840
    }
826 841
};
827

  

Also available in: Unified diff