diff options
| -rw-r--r-- | drivers/pci/msi.c | 34 |
1 files changed, 11 insertions, 23 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 6a0f2f07f955..4c14f31f2b4d 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -196,30 +196,15 @@ void unmask_msi_irq(unsigned int irq) | |||
| 196 | void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) | 196 | void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) |
| 197 | { | 197 | { |
| 198 | struct msi_desc *entry = get_irq_desc_msi(desc); | 198 | struct msi_desc *entry = get_irq_desc_msi(desc); |
| 199 | if (entry->msi_attrib.is_msix) { | ||
| 200 | void __iomem *base = entry->mask_base + | ||
| 201 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | ||
| 202 | 199 | ||
| 203 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); | 200 | /* We do not touch the hardware (which may not even be |
| 204 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); | 201 | * accessible at the moment) but return the last message |
| 205 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); | 202 | * written. Assert that this is valid, assuming that |
| 206 | } else { | 203 | * valid messages are not all-zeroes. */ |
| 207 | struct pci_dev *dev = entry->dev; | 204 | BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | |
| 208 | int pos = entry->msi_attrib.pos; | 205 | entry->msg.data)); |
| 209 | u16 data; | ||
| 210 | 206 | ||
| 211 | pci_read_config_dword(dev, msi_lower_address_reg(pos), | 207 | *msg = entry->msg; |
| 212 | &msg->address_lo); | ||
| 213 | if (entry->msi_attrib.is_64) { | ||
| 214 | pci_read_config_dword(dev, msi_upper_address_reg(pos), | ||
| 215 | &msg->address_hi); | ||
| 216 | pci_read_config_word(dev, msi_data_reg(pos, 1), &data); | ||
| 217 | } else { | ||
| 218 | msg->address_hi = 0; | ||
| 219 | pci_read_config_word(dev, msi_data_reg(pos, 0), &data); | ||
| 220 | } | ||
| 221 | msg->data = data; | ||
| 222 | } | ||
| 223 | } | 208 | } |
| 224 | 209 | ||
| 225 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) | 210 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) |
| @@ -232,7 +217,10 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) | |||
| 232 | void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) | 217 | void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) |
| 233 | { | 218 | { |
| 234 | struct msi_desc *entry = get_irq_desc_msi(desc); | 219 | struct msi_desc *entry = get_irq_desc_msi(desc); |
| 235 | if (entry->msi_attrib.is_msix) { | 220 | |
| 221 | if (entry->dev->current_state != PCI_D0) { | ||
| 222 | /* Don't touch the hardware now */ | ||
| 223 | } else if (entry->msi_attrib.is_msix) { | ||
| 236 | void __iomem *base; | 224 | void __iomem *base; |
| 237 | base = entry->mask_base + | 225 | base = entry->mask_base + |
| 238 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | 226 | entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; |
