Revision d587e078 hw/pci.c
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 | |
|
522 |
PCI_COMMAND_INTX_DISABLE); |
|
521 |
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); |
|
523 | 522 |
|
524 | 523 |
memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff, |
525 | 524 |
config_size - PCI_CONFIG_HEADER_SIZE); |
... | ... | |
944 | 943 |
} |
945 | 944 |
} |
946 | 945 |
|
947 |
static inline int pci_irq_disabled(PCIDevice *d) |
|
948 |
{ |
|
949 |
return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE; |
|
950 |
} |
|
951 |
|
|
952 |
/* Called after interrupt disabled field update in config space, |
|
953 |
* assert/deassert interrupts if necessary. |
|
954 |
* Gets original interrupt disable bit value (before update). */ |
|
955 |
static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled) |
|
956 |
{ |
|
957 |
int i, disabled = pci_irq_disabled(d); |
|
958 |
if (disabled == was_irq_disabled) |
|
959 |
return; |
|
960 |
for (i = 0; i < PCI_NUM_PINS; ++i) { |
|
961 |
int state = pci_irq_state(d, i); |
|
962 |
pci_change_irq_level(d, i, disabled ? -state : state); |
|
963 |
} |
|
964 |
} |
|
965 |
|
|
966 | 946 |
uint32_t pci_default_read_config(PCIDevice *d, |
967 | 947 |
uint32_t address, int len) |
968 | 948 |
{ |
... | ... | |
975 | 955 |
|
976 | 956 |
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) |
977 | 957 |
{ |
978 |
int i, was_irq_disabled = pci_irq_disabled(d);
|
|
958 |
int i; |
|
979 | 959 |
uint32_t config_size = pci_config_size(d); |
980 | 960 |
|
981 | 961 |
for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) { |
... | ... | |
987 | 967 |
ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) || |
988 | 968 |
range_covers_byte(addr, l, PCI_COMMAND)) |
989 | 969 |
pci_update_mappings(d); |
990 |
|
|
991 |
if (range_covers_byte(addr, l, PCI_COMMAND)) |
|
992 |
pci_update_irq_disabled(d, was_irq_disabled); |
|
993 | 970 |
} |
994 | 971 |
|
995 | 972 |
/***********************************************************/ |
... | ... | |
1007 | 984 |
|
1008 | 985 |
pci_set_irq_state(pci_dev, irq_num, level); |
1009 | 986 |
pci_update_irq_status(pci_dev); |
1010 |
if (pci_irq_disabled(pci_dev)) |
|
1011 |
return; |
|
1012 | 987 |
pci_change_irq_level(pci_dev, irq_num, change); |
1013 | 988 |
} |
1014 | 989 |
|
Also available in: Unified diff