Revision 247c97f3
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