mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
vpci/header: Emulate extended capability list for dom0
Add a new function to emulate extended capability list for dom0, and call it in init_header(). So that it will be easy to hide an extended capability whose initialization fails. As for the extended capability list of domU, just move the logic into above function and keep hiding it for domU. Signed-off-by: Jiqian Chen <Jiqian.Chen@amd.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Roger Pau Monné <roger.pau@citirx.com>
This commit is contained in:
1 parent
ce1b66e72c
commit
a845b50c12
1 file changed
+36
-8
@@ -825,6 +825,39 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
|
||||
PCI_STATUS_RSVDZ_MASK);
|
||||
}
|
||||
|
||||
static int vpci_init_ext_capability_list(const struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int pos = PCI_CFG_SPACE_SIZE;
|
||||
|
||||
if ( !is_hardware_domain(pdev->domain) )
|
||||
/* Extended capabilities read as zero, write ignore for DomU */
|
||||
return vpci_add_register(pdev->vpci, vpci_read_val, NULL,
|
||||
pos, 4, (void *)0);
|
||||
|
||||
do
|
||||
{
|
||||
uint32_t header = pci_conf_read32(pdev->sbdf, pos);
|
||||
int rc;
|
||||
|
||||
rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
|
||||
pos, 4, (void *)(uintptr_t)header);
|
||||
if ( rc == -EEXIST )
|
||||
{
|
||||
printk(XENLOG_WARNING
|
||||
"%pd %pp: overlap in extended cap list, offset %#x\n",
|
||||
pdev->domain, &pdev->sbdf, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
pos = PCI_EXT_CAP_NEXT(header);
|
||||
} while ( pos >= PCI_CFG_SPACE_SIZE );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cf_check init_header(struct pci_dev *pdev)
|
||||
{
|
||||
uint16_t cmd;
|
||||
@@ -877,14 +910,9 @@ static int cf_check init_header(struct pci_dev *pdev)
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
if ( !is_hwdom )
|
||||
{
|
||||
/* Extended capabilities read as zero, write ignore */
|
||||
rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, 0x100, 4,
|
||||
(void *)0);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
rc = vpci_init_ext_capability_list(pdev);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
if ( pdev->ignore_bars )
|
||||
return 0;
|
||||
|
||||