static int assigned_device_pci_cap_init(PCIDevice *pci_dev)

{

    AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);

    PCIRegion *pci_region = dev->real_device.regions;

    int ret, pos;



    /* Clear initial capabilities pointer and status copied from hw */

    pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0);

    pci_set_word(pci_dev->config + PCI_STATUS,

                 pci_get_word(pci_dev->config + PCI_STATUS) &

                 ~PCI_STATUS_CAP_LIST);



    /* Expose MSI capability

     * MSI capability is the 1st capability in capability config */

    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0);

    if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {

        if (!check_irqchip_in_kernel()) {

            return -ENOTSUP;

        }

        dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;

        /* Only 32-bit/no-mask currently supported */

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10);

        if (ret < 0) {

            return ret;

        }

        pci_dev->msi_cap = pos;



        pci_set_word(pci_dev->config + pos + PCI_MSI_FLAGS,

                     pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS) &

                     PCI_MSI_FLAGS_QMASK);

        pci_set_long(pci_dev->config + pos + PCI_MSI_ADDRESS_LO, 0);

        pci_set_word(pci_dev->config + pos + PCI_MSI_DATA_32, 0);



        /* Set writable fields */

        pci_set_word(pci_dev->wmask + pos + PCI_MSI_FLAGS,

                     PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);

        pci_set_long(pci_dev->wmask + pos + PCI_MSI_ADDRESS_LO, 0xfffffffc);

        pci_set_word(pci_dev->wmask + pos + PCI_MSI_DATA_32, 0xffff);

    }

    /* Expose MSI-X capability */

    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX, 0);

    if (pos != 0 && kvm_device_msix_supported(kvm_state)) {

        int bar_nr;

        uint32_t msix_table_entry;



        if (!check_irqchip_in_kernel()) {

            return -ENOTSUP;

        }

        dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, 12);

        if (ret < 0) {

            return ret;

        }

        pci_dev->msix_cap = pos;



        pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS,

                     pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) &

                     PCI_MSIX_FLAGS_QSIZE);



        /* Only enable and function mask bits are writable */

        pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS,

                     PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);



        msix_table_entry = pci_get_long(pci_dev->config + pos + PCI_MSIX_TABLE);

        bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK;

        msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK;

        dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry;

        dev->msix_max = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS);

        dev->msix_max &= PCI_MSIX_FLAGS_QSIZE;

        dev->msix_max += 1;

    }



    /* Minimal PM support, nothing writable, device appears to NAK changes */

    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PM, 0);

    if (pos) {

        uint16_t pmc;



        ret = pci_add_capability(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, PCI_PM_SIZEOF);



        pmc = pci_get_word(pci_dev->config + pos + PCI_CAP_FLAGS);

        pmc &= (PCI_PM_CAP_VER_MASK | PCI_PM_CAP_DSI);

        pci_set_word(pci_dev->config + pos + PCI_CAP_FLAGS, pmc);



        /* assign_device will bring the device up to D0, so we don't need

         * to worry about doing that ourselves here. */

        pci_set_word(pci_dev->config + pos + PCI_PM_CTRL,

                     PCI_PM_CTRL_NO_SOFT_RESET);



        pci_set_byte(pci_dev->config + pos + PCI_PM_PPB_EXTENSIONS, 0);

        pci_set_byte(pci_dev->config + pos + PCI_PM_DATA_REGISTER, 0);

    }



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_EXP, 0);

    if (pos) {

        uint8_t version, size = 0;

        uint16_t type, devctl, lnksta;

        uint32_t devcap, lnkcap;



        version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS);

        version &= PCI_EXP_FLAGS_VERS;

        if (version == 1) {

            size = 0x14;

        } else if (version == 2) {

            /*

             * Check for non-std size, accept reduced size to 0x34,

             * which is what bcm5761 implemented, violating the

             * PCIe v3.0 spec that regs should exist and be read as 0,

             * not optionally provided and shorten the struct size.

             */

            size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - pos);

            if (size < 0x34) {

                error_report("%s: Invalid size PCIe cap-id 0x%x",

                             __func__, PCI_CAP_ID_EXP);

                return -EINVAL;

            } else if (size != 0x3c) {

                error_report("WARNING, %s: PCIe cap-id 0x%x has "

                             "non-standard size 0x%x; std size should be 0x3c",

                             __func__, PCI_CAP_ID_EXP, size);

            }

        } else if (version == 0) {

            uint16_t vid, did;

            vid = pci_get_word(pci_dev->config + PCI_VENDOR_ID);

            did = pci_get_word(pci_dev->config + PCI_DEVICE_ID);

            if (vid == PCI_VENDOR_ID_INTEL && did == 0x10ed) {

                /*

                 * quirk for Intel 82599 VF with invalid PCIe capability

                 * version, should really be version 2 (same as PF)

                 */

                size = 0x3c;

            }

        }



        if (size == 0) {

            error_report("%s: Unsupported PCI express capability version %d",

                         __func__, version);

            return -EINVAL;

        }



        ret = pci_add_capability(pci_dev, PCI_CAP_ID_EXP, pos, size);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, size);



        type = pci_get_word(pci_dev->config + pos + PCI_EXP_FLAGS);

        type = (type & PCI_EXP_FLAGS_TYPE) >> 4;

        if (type != PCI_EXP_TYPE_ENDPOINT &&

            type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) {

            error_report("Device assignment only supports endpoint assignment,"

                         " device type %d", type);

            return -EINVAL;

        }



        /* capabilities, pass existing read-only copy

         * PCI_EXP_FLAGS_IRQ: updated by hardware, should be direct read */



        /* device capabilities: hide FLR */

        devcap = pci_get_long(pci_dev->config + pos + PCI_EXP_DEVCAP);

        devcap &= ~PCI_EXP_DEVCAP_FLR;

        pci_set_long(pci_dev->config + pos + PCI_EXP_DEVCAP, devcap);



        /* device control: clear all error reporting enable bits, leaving

         *                 only a few host values.  Note, these are

         *                 all writable, but not passed to hw.

         */

        devctl = pci_get_word(pci_dev->config + pos + PCI_EXP_DEVCTL);

        devctl = (devctl & (PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_PAYLOAD)) |

                  PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN;

        pci_set_word(pci_dev->config + pos + PCI_EXP_DEVCTL, devctl);

        devctl = PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_AUX_PME;

        pci_set_word(pci_dev->wmask + pos + PCI_EXP_DEVCTL, ~devctl);



        /* Clear device status */

        pci_set_word(pci_dev->config + pos + PCI_EXP_DEVSTA, 0);



        /* Link capabilities, expose links and latencues, clear reporting */

        lnkcap = pci_get_long(pci_dev->config + pos + PCI_EXP_LNKCAP);

        lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW |

                   PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL |

                   PCI_EXP_LNKCAP_L1EL);

        pci_set_long(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap);



        /* Link control, pass existing read-only copy.  Should be writable? */



        /* Link status, only expose current speed and width */

        lnksta = pci_get_word(pci_dev->config + pos + PCI_EXP_LNKSTA);

        lnksta &= (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW);

        pci_set_word(pci_dev->config + pos + PCI_EXP_LNKSTA, lnksta);



        if (version >= 2) {

            /* Slot capabilities, control, status - not needed for endpoints */

            pci_set_long(pci_dev->config + pos + PCI_EXP_SLTCAP, 0);

            pci_set_word(pci_dev->config + pos + PCI_EXP_SLTCTL, 0);

            pci_set_word(pci_dev->config + pos + PCI_EXP_SLTSTA, 0);



            /* Root control, capabilities, status - not needed for endpoints */

            pci_set_word(pci_dev->config + pos + PCI_EXP_RTCTL, 0);

            pci_set_word(pci_dev->config + pos + PCI_EXP_RTCAP, 0);

            pci_set_long(pci_dev->config + pos + PCI_EXP_RTSTA, 0);



            /* Device capabilities/control 2, pass existing read-only copy */

            /* Link control 2, pass existing read-only copy */

        }

    }



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PCIX, 0);

    if (pos) {

        uint16_t cmd;

        uint32_t status;



        /* Only expose the minimum, 8 byte capability */

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_PCIX, pos, 8);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, 8);



        /* Command register, clear upper bits, including extended modes */

        cmd = pci_get_word(pci_dev->config + pos + PCI_X_CMD);

        cmd &= (PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO | PCI_X_CMD_MAX_READ |

                PCI_X_CMD_MAX_SPLIT);

        pci_set_word(pci_dev->config + pos + PCI_X_CMD, cmd);



        /* Status register, update with emulated PCI bus location, clear

         * error bits, leave the rest. */

        status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS);

        status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN);

        status |= (pci_bus_num(pci_dev->bus) << 8) | pci_dev->devfn;

        status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL |

                    PCI_X_STATUS_SPL_ERR);

        pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status);

    }



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0);

    if (pos) {

        /* Direct R/W passthrough */

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_VPD, pos, 8);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, 8);



        /* direct write for cap content */

        assigned_dev_direct_config_write(dev, pos + 2, 6);

    }



    /* Devices can have multiple vendor capabilities, get them all */

    for (pos = 0; (pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VNDR, pos));

        pos += PCI_CAP_LIST_NEXT) {

        uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS);

        /* Direct R/W passthrough */

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_VNDR, pos, len);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, len);



        /* direct write for cap content */

        assigned_dev_direct_config_write(dev, pos + 2, len - 2);

    }



    /* If real and virtual capability list status bits differ, virtualize the

     * access. */

    if ((pci_get_word(pci_dev->config + PCI_STATUS) & PCI_STATUS_CAP_LIST) !=

        (assigned_dev_pci_read_byte(pci_dev, PCI_STATUS) &

         PCI_STATUS_CAP_LIST)) {

        dev->emulate_config_read[PCI_STATUS] |= PCI_STATUS_CAP_LIST;

    }



    return 0;

}

static int assigned_device_pci_cap_init(PCIDevice *pci_dev)

{

    AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);

    PCIRegion *pci_region = dev->real_device.regions;

    int ret, pos;



    

    pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0);

    pci_set_word(pci_dev->config + PCI_STATUS,

                 pci_get_word(pci_dev->config + PCI_STATUS) &

                 ~PCI_STATUS_CAP_LIST);



    



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0);

    if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {

        if (!check_irqchip_in_kernel()) {

            return -ENOTSUP;

        }

        dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;

        

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10);

        if (ret < 0) {

            return ret;

        }

        pci_dev->msi_cap = pos;



        pci_set_word(pci_dev->config + pos + PCI_MSI_FLAGS,

                     pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS) &

                     PCI_MSI_FLAGS_QMASK);

        pci_set_long(pci_dev->config + pos + PCI_MSI_ADDRESS_LO, 0);

        pci_set_word(pci_dev->config + pos + PCI_MSI_DATA_32, 0);



        

        pci_set_word(pci_dev->wmask + pos + PCI_MSI_FLAGS,

                     PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);

        pci_set_long(pci_dev->wmask + pos + PCI_MSI_ADDRESS_LO, 0xfffffffc);

        pci_set_word(pci_dev->wmask + pos + PCI_MSI_DATA_32, 0xffff);

    }

    

    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX, 0);

    if (pos != 0 && kvm_device_msix_supported(kvm_state)) {

        int bar_nr;

        uint32_t msix_table_entry;



        if (!check_irqchip_in_kernel()) {

            return -ENOTSUP;

        }

        dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, 12);

        if (ret < 0) {

            return ret;

        }

        pci_dev->msix_cap = pos;



        pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS,

                     pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) &

                     PCI_MSIX_FLAGS_QSIZE);



        

        pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS,

                     PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);



        msix_table_entry = pci_get_long(pci_dev->config + pos + PCI_MSIX_TABLE);

        bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK;

        msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK;

        dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry;

        dev->msix_max = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS);

        dev->msix_max &= PCI_MSIX_FLAGS_QSIZE;

        dev->msix_max += 1;

    }



    

    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PM, 0);

    if (pos) {

        uint16_t pmc;



        ret = pci_add_capability(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, PCI_PM_SIZEOF);



        pmc = pci_get_word(pci_dev->config + pos + PCI_CAP_FLAGS);

        pmc &= (PCI_PM_CAP_VER_MASK | PCI_PM_CAP_DSI);

        pci_set_word(pci_dev->config + pos + PCI_CAP_FLAGS, pmc);



        



        pci_set_word(pci_dev->config + pos + PCI_PM_CTRL,

                     PCI_PM_CTRL_NO_SOFT_RESET);



        pci_set_byte(pci_dev->config + pos + PCI_PM_PPB_EXTENSIONS, 0);

        pci_set_byte(pci_dev->config + pos + PCI_PM_DATA_REGISTER, 0);

    }



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_EXP, 0);

    if (pos) {

        uint8_t version, size = 0;

        uint16_t type, devctl, lnksta;

        uint32_t devcap, lnkcap;



        version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS);

        version &= PCI_EXP_FLAGS_VERS;

        if (version == 1) {

            size = 0x14;

        } else if (version == 2) {

            











            size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - pos);

            if (size < 0x34) {

                error_report("%s: Invalid size PCIe cap-id 0x%x",

                             __func__, PCI_CAP_ID_EXP);

                return -EINVAL;

            } else if (size != 0x3c) {

                error_report("WARNING, %s: PCIe cap-id 0x%x has "

                             "non-standard size 0x%x; std size should be 0x3c",

                             __func__, PCI_CAP_ID_EXP, size);

            }

        } else if (version == 0) {

            uint16_t vid, did;

            vid = pci_get_word(pci_dev->config + PCI_VENDOR_ID);

            did = pci_get_word(pci_dev->config + PCI_DEVICE_ID);

            if (vid == PCI_VENDOR_ID_INTEL && did == 0x10ed) {

                







                size = 0x3c;

            }

        }



        if (size == 0) {

            error_report("%s: Unsupported PCI express capability version %d",

                         __func__, version);

            return -EINVAL;

        }



        ret = pci_add_capability(pci_dev, PCI_CAP_ID_EXP, pos, size);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, size);



        type = pci_get_word(pci_dev->config + pos + PCI_EXP_FLAGS);

        type = (type & PCI_EXP_FLAGS_TYPE) >> 4;

        if (type != PCI_EXP_TYPE_ENDPOINT &&

            type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) {

            error_report("Device assignment only supports endpoint assignment,"

                         " device type %d", type);

            return -EINVAL;

        }



        





        

        devcap = pci_get_long(pci_dev->config + pos + PCI_EXP_DEVCAP);

        devcap &= ~PCI_EXP_DEVCAP_FLR;

        pci_set_long(pci_dev->config + pos + PCI_EXP_DEVCAP, devcap);



        







        devctl = pci_get_word(pci_dev->config + pos + PCI_EXP_DEVCTL);

        devctl = (devctl & (PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_PAYLOAD)) |

                  PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN;

        pci_set_word(pci_dev->config + pos + PCI_EXP_DEVCTL, devctl);

        devctl = PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_AUX_PME;

        pci_set_word(pci_dev->wmask + pos + PCI_EXP_DEVCTL, ~devctl);



        

        pci_set_word(pci_dev->config + pos + PCI_EXP_DEVSTA, 0);



        

        lnkcap = pci_get_long(pci_dev->config + pos + PCI_EXP_LNKCAP);

        lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW |

                   PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL |

                   PCI_EXP_LNKCAP_L1EL);

        pci_set_long(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap);



        



        

        lnksta = pci_get_word(pci_dev->config + pos + PCI_EXP_LNKSTA);

        lnksta &= (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW);

        pci_set_word(pci_dev->config + pos + PCI_EXP_LNKSTA, lnksta);



        if (version >= 2) {

            

            pci_set_long(pci_dev->config + pos + PCI_EXP_SLTCAP, 0);

            pci_set_word(pci_dev->config + pos + PCI_EXP_SLTCTL, 0);

            pci_set_word(pci_dev->config + pos + PCI_EXP_SLTSTA, 0);



            

            pci_set_word(pci_dev->config + pos + PCI_EXP_RTCTL, 0);

            pci_set_word(pci_dev->config + pos + PCI_EXP_RTCAP, 0);

            pci_set_long(pci_dev->config + pos + PCI_EXP_RTSTA, 0);



            

            

        }

    }



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_PCIX, 0);

    if (pos) {

        uint16_t cmd;

        uint32_t status;



        

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_PCIX, pos, 8);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, 8);



        

        cmd = pci_get_word(pci_dev->config + pos + PCI_X_CMD);

        cmd &= (PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO | PCI_X_CMD_MAX_READ |

                PCI_X_CMD_MAX_SPLIT);

        pci_set_word(pci_dev->config + pos + PCI_X_CMD, cmd);



        



        status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS);

        status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN);

        status |= (pci_bus_num(pci_dev->bus) << 8) | pci_dev->devfn;

        status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL |

                    PCI_X_STATUS_SPL_ERR);

        pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status);

    }



    pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0);

    if (pos) {

        

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_VPD, pos, 8);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, 8);



        

        assigned_dev_direct_config_write(dev, pos + 2, 6);

    }



    

    for (pos = 0; (pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VNDR, pos));

        pos += PCI_CAP_LIST_NEXT) {

        uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS);

        

        ret = pci_add_capability(pci_dev, PCI_CAP_ID_VNDR, pos, len);

        if (ret < 0) {

            return ret;

        }



        assigned_dev_setup_cap_read(dev, pos, len);



        

        assigned_dev_direct_config_write(dev, pos + 2, len - 2);

    }



    



    if ((pci_get_word(pci_dev->config + PCI_STATUS) & PCI_STATUS_CAP_LIST) !=

        (assigned_dev_pci_read_byte(pci_dev, PCI_STATUS) &

         PCI_STATUS_CAP_LIST)) {

        dev->emulate_config_read[PCI_STATUS] |= PCI_STATUS_CAP_LIST;

    }



    return 0;

}

        if (!check_irqchip_in_kernel()) {         if (!check_irqchip_in_kernel()) {
static int FUNC_0(PCIDevice *VAR_0)

{

    AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, VAR_0);

    PCIRegion *pci_region = dev->real_device.regions;

    int VAR_1, VAR_2;



    

    pci_set_byte(VAR_0->config + PCI_CAPABILITY_LIST, 0);

    pci_set_word(VAR_0->config + PCI_STATUS,

                 pci_get_word(VAR_0->config + PCI_STATUS) &

                 ~PCI_STATUS_CAP_LIST);



    



    VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_MSI, 0);

    if (VAR_2 != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {

        if (!check_irqchip_in_kernel()) {

            return -ENOTSUP;

        }

        dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;

        

        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_MSI, VAR_2, 10);

        if (VAR_1 < 0) {

            return VAR_1;

        }

        VAR_0->msi_cap = VAR_2;



        pci_set_word(VAR_0->config + VAR_2 + PCI_MSI_FLAGS,

                     pci_get_word(VAR_0->config + VAR_2 + PCI_MSI_FLAGS) &

                     PCI_MSI_FLAGS_QMASK);

        pci_set_long(VAR_0->config + VAR_2 + PCI_MSI_ADDRESS_LO, 0);

        pci_set_word(VAR_0->config + VAR_2 + PCI_MSI_DATA_32, 0);



        

        pci_set_word(VAR_0->wmask + VAR_2 + PCI_MSI_FLAGS,

                     PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);

        pci_set_long(VAR_0->wmask + VAR_2 + PCI_MSI_ADDRESS_LO, 0xfffffffc);

        pci_set_word(VAR_0->wmask + VAR_2 + PCI_MSI_DATA_32, 0xffff);

    }

    

    VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_MSIX, 0);

    if (VAR_2 != 0 && kvm_device_msix_supported(kvm_state)) {

        int VAR_3;

        uint32_t msix_table_entry;



        if (!check_irqchip_in_kernel()) {

            return -ENOTSUP;

        }

        dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;

        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_MSIX, VAR_2, 12);

        if (VAR_1 < 0) {

            return VAR_1;

        }

        VAR_0->msix_cap = VAR_2;



        pci_set_word(VAR_0->config + VAR_2 + PCI_MSIX_FLAGS,

                     pci_get_word(VAR_0->config + VAR_2 + PCI_MSIX_FLAGS) &

                     PCI_MSIX_FLAGS_QSIZE);



        

        pci_set_word(VAR_0->wmask + VAR_2 + PCI_MSIX_FLAGS,

                     PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);



        msix_table_entry = pci_get_long(VAR_0->config + VAR_2 + PCI_MSIX_TABLE);

        VAR_3 = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK;

        msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK;

        dev->msix_table_addr = pci_region[VAR_3].base_addr + msix_table_entry;

        dev->msix_max = pci_get_word(VAR_0->config + VAR_2 + PCI_MSIX_FLAGS);

        dev->msix_max &= PCI_MSIX_FLAGS_QSIZE;

        dev->msix_max += 1;

    }



    

    VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_PM, 0);

    if (VAR_2) {

        uint16_t pmc;



        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_PM, VAR_2, PCI_PM_SIZEOF);

        if (VAR_1 < 0) {

            return VAR_1;

        }



        assigned_dev_setup_cap_read(dev, VAR_2, PCI_PM_SIZEOF);



        pmc = pci_get_word(VAR_0->config + VAR_2 + PCI_CAP_FLAGS);

        pmc &= (PCI_PM_CAP_VER_MASK | PCI_PM_CAP_DSI);

        pci_set_word(VAR_0->config + VAR_2 + PCI_CAP_FLAGS, pmc);



        



        pci_set_word(VAR_0->config + VAR_2 + PCI_PM_CTRL,

                     PCI_PM_CTRL_NO_SOFT_RESET);



        pci_set_byte(VAR_0->config + VAR_2 + PCI_PM_PPB_EXTENSIONS, 0);

        pci_set_byte(VAR_0->config + VAR_2 + PCI_PM_DATA_REGISTER, 0);

    }



    VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_EXP, 0);

    if (VAR_2) {

        uint8_t version, size = 0;

        uint16_t type, devctl, lnksta;

        uint32_t devcap, lnkcap;



        version = pci_get_byte(VAR_0->config + VAR_2 + PCI_EXP_FLAGS);

        version &= PCI_EXP_FLAGS_VERS;

        if (version == 1) {

            size = 0x14;

        } else if (version == 2) {

            











            size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - VAR_2);

            if (size < 0x34) {

                error_report("%s: Invalid size PCIe cap-id 0x%x",

                             __func__, PCI_CAP_ID_EXP);

                return -EINVAL;

            } else if (size != 0x3c) {

                error_report("WARNING, %s: PCIe cap-id 0x%x has "

                             "non-standard size 0x%x; std size should be 0x3c",

                             __func__, PCI_CAP_ID_EXP, size);

            }

        } else if (version == 0) {

            uint16_t vid, did;

            vid = pci_get_word(VAR_0->config + PCI_VENDOR_ID);

            did = pci_get_word(VAR_0->config + PCI_DEVICE_ID);

            if (vid == PCI_VENDOR_ID_INTEL && did == 0x10ed) {

                







                size = 0x3c;

            }

        }



        if (size == 0) {

            error_report("%s: Unsupported PCI express capability version %d",

                         __func__, version);

            return -EINVAL;

        }



        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_EXP, VAR_2, size);

        if (VAR_1 < 0) {

            return VAR_1;

        }



        assigned_dev_setup_cap_read(dev, VAR_2, size);



        type = pci_get_word(VAR_0->config + VAR_2 + PCI_EXP_FLAGS);

        type = (type & PCI_EXP_FLAGS_TYPE) >> 4;

        if (type != PCI_EXP_TYPE_ENDPOINT &&

            type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) {

            error_report("Device assignment only supports endpoint assignment,"

                         " device type %d", type);

            return -EINVAL;

        }



        





        

        devcap = pci_get_long(VAR_0->config + VAR_2 + PCI_EXP_DEVCAP);

        devcap &= ~PCI_EXP_DEVCAP_FLR;

        pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_DEVCAP, devcap);



        







        devctl = pci_get_word(VAR_0->config + VAR_2 + PCI_EXP_DEVCTL);

        devctl = (devctl & (PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_PAYLOAD)) |

                  PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN;

        pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_DEVCTL, devctl);

        devctl = PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_AUX_PME;

        pci_set_word(VAR_0->wmask + VAR_2 + PCI_EXP_DEVCTL, ~devctl);



        

        pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_DEVSTA, 0);



        

        lnkcap = pci_get_long(VAR_0->config + VAR_2 + PCI_EXP_LNKCAP);

        lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW |

                   PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL |

                   PCI_EXP_LNKCAP_L1EL);

        pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_LNKCAP, lnkcap);



        



        

        lnksta = pci_get_word(VAR_0->config + VAR_2 + PCI_EXP_LNKSTA);

        lnksta &= (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW);

        pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_LNKSTA, lnksta);



        if (version >= 2) {

            

            pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_SLTCAP, 0);

            pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_SLTCTL, 0);

            pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_SLTSTA, 0);



            

            pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_RTCTL, 0);

            pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_RTCAP, 0);

            pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_RTSTA, 0);



            

            

        }

    }



    VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_PCIX, 0);

    if (VAR_2) {

        uint16_t cmd;

        uint32_t status;



        

        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_PCIX, VAR_2, 8);

        if (VAR_1 < 0) {

            return VAR_1;

        }



        assigned_dev_setup_cap_read(dev, VAR_2, 8);



        

        cmd = pci_get_word(VAR_0->config + VAR_2 + PCI_X_CMD);

        cmd &= (PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO | PCI_X_CMD_MAX_READ |

                PCI_X_CMD_MAX_SPLIT);

        pci_set_word(VAR_0->config + VAR_2 + PCI_X_CMD, cmd);



        



        status = pci_get_long(VAR_0->config + VAR_2 + PCI_X_STATUS);

        status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN);

        status |= (pci_bus_num(VAR_0->bus) << 8) | VAR_0->devfn;

        status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL |

                    PCI_X_STATUS_SPL_ERR);

        pci_set_long(VAR_0->config + VAR_2 + PCI_X_STATUS, status);

    }



    VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_VPD, 0);

    if (VAR_2) {

        

        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_VPD, VAR_2, 8);

        if (VAR_1 < 0) {

            return VAR_1;

        }



        assigned_dev_setup_cap_read(dev, VAR_2, 8);



        

        assigned_dev_direct_config_write(dev, VAR_2 + 2, 6);

    }



    

    for (VAR_2 = 0; (VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_VNDR, VAR_2));

        VAR_2 += PCI_CAP_LIST_NEXT) {

        uint8_t len = pci_get_byte(VAR_0->config + VAR_2 + PCI_CAP_FLAGS);

        

        VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_VNDR, VAR_2, len);

        if (VAR_1 < 0) {

            return VAR_1;

        }



        assigned_dev_setup_cap_read(dev, VAR_2, len);



        

        assigned_dev_direct_config_write(dev, VAR_2 + 2, len - 2);

    }



    



    if ((pci_get_word(VAR_0->config + PCI_STATUS) & PCI_STATUS_CAP_LIST) !=

        (assigned_dev_pci_read_byte(VAR_0, PCI_STATUS) &

         PCI_STATUS_CAP_LIST)) {

        dev->emulate_config_read[PCI_STATUS] |= PCI_STATUS_CAP_LIST;

    }



    return 0;

}

static int FUNC_0(PCIDevice *VAR_0)
{ AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, VAR_0); PCIRegion *pci_region = dev->real_device.regions; int VAR_1, VAR_2; pci_set_byte(VAR_0->config + PCI_CAPABILITY_LIST, 0); pci_set_word(VAR_0->config + PCI_STATUS,
pci_get_word(VAR_0->config + PCI_STATUS) &
~PCI_STATUS_CAP_LIST); VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_MSI, 0); if (VAR_2 != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) { if (!check_irqchip_in_kernel()) { return -ENOTSUP; } dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI; VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_MSI, VAR_2, 10); if (VAR_1 < 0) { return VAR_1; } VAR_0->msi_cap = VAR_2; pci_set_word(VAR_0->config + VAR_2 + PCI_MSI_FLAGS,
pci_get_word(VAR_0->config + VAR_2 + PCI_MSI_FLAGS) &
PCI_MSI_FLAGS_QMASK); pci_set_long(VAR_0->config + VAR_2 + PCI_MSI_ADDRESS_LO, 0); pci_set_word(VAR_0->config + VAR_2 + PCI_MSI_DATA_32, 0); pci_set_word(VAR_0->wmask + VAR_2 + PCI_MSI_FLAGS,
PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); pci_set_long(VAR_0->wmask + VAR_2 + PCI_MSI_ADDRESS_LO, 0xfffffffc); pci_set_word(VAR_0->wmask + VAR_2 + PCI_MSI_DATA_32, 0xffff); } VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_MSIX, 0); if (VAR_2 != 0 && kvm_device_msix_supported(kvm_state)) { int VAR_3; uint32_t msix_table_entry; if (!check_irqchip_in_kernel()) { return -ENOTSUP; } dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX; VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_MSIX, VAR_2, 12); if (VAR_1 < 0) { return VAR_1; } VAR_0->msix_cap = VAR_2; pci_set_word(VAR_0->config + VAR_2 + PCI_MSIX_FLAGS,
pci_get_word(VAR_0->config + VAR_2 + PCI_MSIX_FLAGS) &
PCI_MSIX_FLAGS_QSIZE); pci_set_word(VAR_0->wmask + VAR_2 + PCI_MSIX_FLAGS,
PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); msix_table_entry = pci_get_long(VAR_0->config + VAR_2 + PCI_MSIX_TABLE); VAR_3 = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK; msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK; dev->msix_table_addr = pci_region[VAR_3].base_addr + msix_table_entry; dev->msix_max = pci_get_word(VAR_0->config + VAR_2 + PCI_MSIX_FLAGS); dev->msix_max &= PCI_MSIX_FLAGS_QSIZE; dev->msix_max += 1; } VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_PM, 0); if (VAR_2) { uint16_t pmc; VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_PM, VAR_2, PCI_PM_SIZEOF); if (VAR_1 < 0) { return VAR_1; } assigned_dev_setup_cap_read(dev, VAR_2, PCI_PM_SIZEOF); pmc = pci_get_word(VAR_0->config + VAR_2 + PCI_CAP_FLAGS); pmc &= (PCI_PM_CAP_VER_MASK | PCI_PM_CAP_DSI); pci_set_word(VAR_0->config + VAR_2 + PCI_CAP_FLAGS, pmc); pci_set_word(VAR_0->config + VAR_2 + PCI_PM_CTRL,
PCI_PM_CTRL_NO_SOFT_RESET); pci_set_byte(VAR_0->config + VAR_2 + PCI_PM_PPB_EXTENSIONS, 0); pci_set_byte(VAR_0->config + VAR_2 + PCI_PM_DATA_REGISTER, 0); } VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_EXP, 0); if (VAR_2) { uint8_t version, size = 0; uint16_t type, devctl, lnksta; uint32_t devcap, lnkcap; version = pci_get_byte(VAR_0->config + VAR_2 + PCI_EXP_FLAGS); version &= PCI_EXP_FLAGS_VERS; if (version == 1) { size = 0x14; } else if (version == 2) { size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - VAR_2); if (size < 0x34) { error_report("%s: Invalid size PCIe cap-id 0x%x",
__func__, PCI_CAP_ID_EXP); return -EINVAL; } else if (size != 0x3c) { error_report("WARNING, %s: PCIe cap-id 0x%x has "
"non-standard size 0x%x; std size should be 0x3c", __func__, PCI_CAP_ID_EXP, size); } } else if (version == 0) { uint16_t vid, did; vid = pci_get_word(VAR_0->config + PCI_VENDOR_ID); did = pci_get_word(VAR_0->config + PCI_DEVICE_ID); if (vid == PCI_VENDOR_ID_INTEL && did == 0x10ed) { size = 0x3c; } } if (size == 0) { error_report("%s: Unsupported PCI express capability version %d",
__func__, version); return -EINVAL; } VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_EXP, VAR_2, size); if (VAR_1 < 0) { return VAR_1; } assigned_dev_setup_cap_read(dev, VAR_2, size); type = pci_get_word(VAR_0->config + VAR_2 + PCI_EXP_FLAGS); type = (type & PCI_EXP_FLAGS_TYPE) >> 4; if (type != PCI_EXP_TYPE_ENDPOINT &&
type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) { error_report("Device assignment only supports endpoint assignment,"
" device type %d", type); return -EINVAL; } devcap = pci_get_long(VAR_0->config + VAR_2 + PCI_EXP_DEVCAP); devcap &= ~PCI_EXP_DEVCAP_FLR; pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_DEVCAP, devcap); devctl = pci_get_word(VAR_0->config + VAR_2 + PCI_EXP_DEVCTL); devctl = (devctl & (PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_PAYLOAD)) |
PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN; pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_DEVCTL, devctl); devctl = PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_AUX_PME; pci_set_word(VAR_0->wmask + VAR_2 + PCI_EXP_DEVCTL, ~devctl); pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_DEVSTA, 0); lnkcap = pci_get_long(VAR_0->config + VAR_2 + PCI_EXP_LNKCAP); lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW |
PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL |
PCI_EXP_LNKCAP_L1EL); pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_LNKCAP, lnkcap); lnksta = pci_get_word(VAR_0->config + VAR_2 + PCI_EXP_LNKSTA); lnksta &= (PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW); pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_LNKSTA, lnksta); if (version >= 2) { pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_SLTCAP, 0); pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_SLTCTL, 0); pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_SLTSTA, 0); pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_RTCTL, 0); pci_set_word(VAR_0->config + VAR_2 + PCI_EXP_RTCAP, 0); pci_set_long(VAR_0->config + VAR_2 + PCI_EXP_RTSTA, 0); } } VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_PCIX, 0); if (VAR_2) { uint16_t cmd; uint32_t status; VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_PCIX, VAR_2, 8); if (VAR_1 < 0) { return VAR_1; } assigned_dev_setup_cap_read(dev, VAR_2, 8); cmd = pci_get_word(VAR_0->config + VAR_2 + PCI_X_CMD); cmd &= (PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO | PCI_X_CMD_MAX_READ |
PCI_X_CMD_MAX_SPLIT); pci_set_word(VAR_0->config + VAR_2 + PCI_X_CMD, cmd); status = pci_get_long(VAR_0->config + VAR_2 + PCI_X_STATUS); status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN); status |= (pci_bus_num(VAR_0->bus) << 8) | VAR_0->devfn; status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL |
PCI_X_STATUS_SPL_ERR); pci_set_long(VAR_0->config + VAR_2 + PCI_X_STATUS, status); } VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_VPD, 0); if (VAR_2) { VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_VPD, VAR_2, 8); if (VAR_1 < 0) { return VAR_1; } assigned_dev_setup_cap_read(dev, VAR_2, 8); assigned_dev_direct_config_write(dev, VAR_2 + 2, 6); } for (VAR_2 = 0; (VAR_2 = pci_find_cap_offset(VAR_0, PCI_CAP_ID_VNDR, VAR_2)); VAR_2 += PCI_CAP_LIST_NEXT) { uint8_t len = pci_get_byte(VAR_0->config + VAR_2 + PCI_CAP_FLAGS); VAR_1 = pci_add_capability(VAR_0, PCI_CAP_ID_VNDR, VAR_2, len); if (VAR_1 < 0) { return VAR_1; } assigned_dev_setup_cap_read(dev, VAR_2, len); assigned_dev_direct_config_write(dev, VAR_2 + 2, len - 2); } if ((pci_get_word(VAR_0->config + PCI_STATUS) & PCI_STATUS_CAP_LIST) !=
(assigned_dev_pci_read_byte(VAR_0, PCI_STATUS) &
PCI_STATUS_CAP_LIST)) { dev->emulate_config_read[PCI_STATUS] |= PCI_STATUS_CAP_LIST; } return 0; }