Add error checking to the pci_find_cap(, PCIY_MSIX,) call that is returns
success and a good value. Only then try to use it and set the MSIX_ENABLE bit. With the current em(4) driver we have observed failures in this case in a specific environment when pci_find_cap() would not return the assumed value, which meant we ended up writing to PCI register 2 (PCI_DEVICE_ID) which is read-only. PR: 216456 Submitted by: bz
This commit is contained in:
parent
f09f75fec6
commit
f7ae9a84e3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=312755
@ -3733,6 +3733,10 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
if (sctx->isc_flags & IFLIB_SKIP_MSIX) {
|
||||
msix = scctx->isc_vectors;
|
||||
} else if (scctx->isc_msix_bar != 0)
|
||||
/*
|
||||
* The simple fact that isc_msix_bar is not 0 does not mean we
|
||||
* we have a good value there that is known to work.
|
||||
*/
|
||||
msix = iflib_msix_init(ctx);
|
||||
else {
|
||||
scctx->isc_vectors = 1;
|
||||
@ -4779,15 +4783,20 @@ iflib_msix_init(if_ctx_t ctx)
|
||||
uint16_t pci_cmd_word;
|
||||
int msix_ctrl, rid;
|
||||
|
||||
rid = 0;
|
||||
pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
pci_cmd_word |= PCIM_CMD_BUSMASTEREN;
|
||||
pci_write_config(dev, PCIR_COMMAND, pci_cmd_word, 2);
|
||||
pci_find_cap(dev, PCIY_MSIX, &rid);
|
||||
rid += PCIR_MSIX_CTRL;
|
||||
msix_ctrl = pci_read_config(dev, rid, 2);
|
||||
msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE;
|
||||
pci_write_config(dev, rid, msix_ctrl, 2);
|
||||
rid = 0;
|
||||
if (pci_find_cap(dev, PCIY_MSIX, &rid) == 0 && rid != 0) {
|
||||
rid += PCIR_MSIX_CTRL;
|
||||
msix_ctrl = pci_read_config(dev, rid, 2);
|
||||
msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE;
|
||||
pci_write_config(dev, rid, msix_ctrl, 2);
|
||||
} else {
|
||||
device_printf(dev, "PCIY_MSIX capability not found; "
|
||||
"or rid %d == 0.\n", rid);
|
||||
goto msi;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user