Revision b6981cb5

b/hw/pci.c
518 518
    dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
519 519
    dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
520 520
    pci_set_word(dev->wmask + PCI_COMMAND,
521
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
521
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
522
                 PCI_COMMAND_INTX_DISABLE);
522 523

  
523 524
    memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
524 525
           config_size - PCI_CONFIG_HEADER_SIZE);
......
938 939
    }
939 940
}
940 941

  
942
static inline int pci_irq_disabled(PCIDevice *d)
943
{
944
    return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
945
}
946

  
947
/* Called after interrupt disabled field update in config space,
948
 * assert/deassert interrupts if necessary.
949
 * Gets original interrupt disable bit value (before update). */
950
static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
951
{
952
    int i, disabled = pci_irq_disabled(d);
953
    if (disabled == was_irq_disabled)
954
        return;
955
    for (i = 0; i < PCI_NUM_PINS; ++i) {
956
        int state = pci_irq_state(d, i);
957
        pci_change_irq_level(d, i, disabled ? -state : state);
958
    }
959
}
960

  
941 961
uint32_t pci_default_read_config(PCIDevice *d,
942 962
                                 uint32_t address, int len)
943 963
{
......
950 970

  
951 971
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
952 972
{
953
    int i;
973
    int i, was_irq_disabled = pci_irq_disabled(d);
954 974
    uint32_t config_size = pci_config_size(d);
955 975

  
956 976
    for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) {
......
962 982
        ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
963 983
        range_covers_byte(addr, l, PCI_COMMAND))
964 984
        pci_update_mappings(d);
985

  
986
    if (range_covers_byte(addr, l, PCI_COMMAND))
987
        pci_update_irq_disabled(d, was_irq_disabled);
965 988
}
966 989

  
967 990
/***********************************************************/
......
979 1002

  
980 1003
    pci_set_irq_state(pci_dev, irq_num, level);
981 1004
    pci_update_irq_status(pci_dev);
1005
    if (pci_irq_disabled(pci_dev))
1006
        return;
982 1007
    pci_change_irq_level(pci_dev, irq_num, change);
983 1008
}
984 1009

  
b/hw/pci.h
101 101
#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
102 102
#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
103 103
#define  PCI_COMMAND_MASTER	0x4	/* Enable bus master */
104
#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
104 105
#define PCI_STATUS              0x06    /* 16 bits */
105 106
#define  PCI_STATUS_INTERRUPT   0x08
106 107
#define PCI_REVISION_ID         0x08    /* 8 bits  */

Also available in: Unified diff