Revision d33d9156

b/hw/pcie_aer.c
215 215
    return true;
216 216
}
217 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
    if (pci_is_express(dev) &&
224
        pcie_cap_get_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
225
        /* Root port can notify system itself,
226
           or send the error message to root complex event collector. */
227
        /*
228
         * if root port is associated with an event collector,
229
         * return the root complex event collector here.
230
         * For now root complex event collector isn't supported.
231
         */
232
        parent_port = NULL;
233
    } else {
234
        parent_port = pci_bridge_get_device(dev->bus);
235
    }
236
    if (parent_port) {
237
        if (!pci_is_express(parent_port)) {
238
            /* just ignore it */
239
            return NULL;
240
        }
241
    }
242
    return parent_port;
243
}
244

  
245 218
/*
246 219
 * return value:
247 220
 * true: error message is sent up
......
381 354
/*
382 355
 * 6.2.6 Error Message Control Figure 6-3
383 356
 *
384
 * Returns true in case the error needs to
385
 * be propagated up.
386
 * TODO: open-code.
357
 * Walk up the bus tree from the device, propagate the error message.
387 358
 */
388
static bool pcie_send_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
359
static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
389 360
{
390 361
    uint8_t type;
391
    bool msg_sent;
392

  
393
    assert(pci_is_express(dev));
394 362

  
395
    type = pcie_cap_get_type(dev);
396
    if (type == PCI_EXP_TYPE_ROOT_PORT ||
397
        type == PCI_EXP_TYPE_UPSTREAM ||
398
        type == PCI_EXP_TYPE_DOWNSTREAM) {
399
        msg_sent = pcie_aer_msg_vbridge(dev, msg);
400
        if (!msg_sent) {
363
    while (dev) {
364
        if (!pci_is_express(dev)) {
365
            /* just ignore it */
366
            /* TODO: Shouldn't we set PCI_STATUS_SIG_SYSTEM_ERROR?
367
             * Consider e.g. a PCI bridge above a PCI Express device. */
401 368
            return;
402 369
        }
403
    }
404
    msg_sent = pcie_aer_msg_alldev(dev, msg);
405
    if (type == PCI_EXP_TYPE_ROOT_PORT && msg_sent) {
406
        pcie_aer_msg_root_port(dev, msg);
407
    }
408
    return msg_sent;
409
}
410 370

  
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)) {
371
        type = pcie_cap_get_type(dev);
372
        if ((type == PCI_EXP_TYPE_ROOT_PORT ||
373
            type == PCI_EXP_TYPE_UPSTREAM ||
374
            type == PCI_EXP_TYPE_DOWNSTREAM) &&
375
            !pcie_aer_msg_vbridge(dev, msg)) {
376
                return;
377
        }
378
        if (!pcie_aer_msg_alldev(dev, msg)) {
379
            return;
380
        }
381
        if (type == PCI_EXP_TYPE_ROOT_PORT) {
382
            pcie_aer_msg_root_port(dev, msg);
383
            /* Root port can notify system itself,
384
               or send the error message to root complex event collector. */
385
            /*
386
             * if root port is associated with an event collector,
387
             * return the root complex event collector here.
388
             * For now root complex event collector isn't supported.
389
             */
416 390
            return;
417 391
        }
418
        dev =  pcie_aer_parent_port(dev);
392
        dev = pci_bridge_get_device(dev->bus);
419 393
    }
420 394
}
421 395

  

Also available in: Unified diff