diff options
Diffstat (limited to 'drivers/pci')
-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; |