From: Shaohua Li <shaohua.li@intel.com>
To: lkml <linux-kernel@vger.kernel.org>
Cc: tom.l.nguyen@intel.com, Greg KH <greg@kroah.com>, akpm <akpm@osdl.org>
Subject: [RFC/PATCH]reconfigure MSI registers after resume
Date: Thu, 18 Aug 2005 13:35:46 +0800 [thread overview]
Message-ID: <1124343346.6272.8.camel@linux-hp.sh.intel.com> (raw)
Hi,
It appears pci_enable_msi doesn't reconfigure msi registers if it
successfully look up a msi for a device. It assumes the data and address
registers unchanged after calling pci_disable_msi. But this isn't always
true, such as in a suspend/resume circle. In my test system, the
registers unsurprised become zero after a S3 resume. This patch fixes my
problem, please look at it. MSIX might have the same issue, but I
haven't taken a close look.
Thanks,
Shaohua
---
linux-2.6.13-rc6-root/drivers/pci/msi.c | 72 +++++++++++++++++++-------------
1 files changed, 43 insertions(+), 29 deletions(-)
diff -puN drivers/pci/msi.c~pci-msi drivers/pci/msi.c
--- linux-2.6.13-rc6/drivers/pci/msi.c~pci-msi 2005-08-18 12:58:45.032124008 +0800
+++ linux-2.6.13-rc6-root/drivers/pci/msi.c 2005-08-18 13:06:02.080682528 +0800
@@ -508,6 +508,45 @@ void pci_scan_msi_device(struct pci_dev
nr_reserved_vectors++;
}
+static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
+{
+ struct msg_address address;
+ struct msg_data data;
+ int pos, vector = dev->irq;
+ u16 control;
+
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+ pci_read_config_word(dev, msi_control_reg(pos), &control);
+ /* Configure MSI capability structure */
+ msi_address_init(&address);
+ msi_data_init(&data, vector);
+ entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
+ MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
+ pci_write_config_dword(dev, msi_lower_address_reg(pos),
+ address.lo_address.value);
+ if (is_64bit_address(control)) {
+ pci_write_config_dword(dev,
+ msi_upper_address_reg(pos), address.hi_address);
+ pci_write_config_word(dev,
+ msi_data_reg(pos, 1), *((u32*)&data));
+ } else
+ pci_write_config_word(dev,
+ msi_data_reg(pos, 0), *((u32*)&data));
+ if (entry->msi_attrib.maskbit) {
+ unsigned int maskbits, temp;
+ /* All MSIs are unmasked by default, Mask them all */
+ pci_read_config_dword(dev,
+ msi_mask_bits_reg(pos, is_64bit_address(control)),
+ &maskbits);
+ temp = (1 << multi_msi_capable(control));
+ temp = ((temp - 1) & ~temp);
+ maskbits |= temp;
+ pci_write_config_dword(dev,
+ msi_mask_bits_reg(pos, is_64bit_address(control)),
+ maskbits);
+ }
+}
+
/**
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
@@ -520,8 +559,6 @@ void pci_scan_msi_device(struct pci_dev
static int msi_capability_init(struct pci_dev *dev)
{
struct msi_desc *entry;
- struct msg_address address;
- struct msg_data data;
int pos, vector;
u16 control;
@@ -551,33 +588,8 @@ static int msi_capability_init(struct pc
/* Replace with MSI handler */
irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
/* Configure MSI capability structure */
- msi_address_init(&address);
- msi_data_init(&data, vector);
- entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
- MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
- pci_write_config_dword(dev, msi_lower_address_reg(pos),
- address.lo_address.value);
- if (is_64bit_address(control)) {
- pci_write_config_dword(dev,
- msi_upper_address_reg(pos), address.hi_address);
- pci_write_config_word(dev,
- msi_data_reg(pos, 1), *((u32*)&data));
- } else
- pci_write_config_word(dev,
- msi_data_reg(pos, 0), *((u32*)&data));
- if (entry->msi_attrib.maskbit) {
- unsigned int maskbits, temp;
- /* All MSIs are unmasked by default, Mask them all */
- pci_read_config_dword(dev,
- msi_mask_bits_reg(pos, is_64bit_address(control)),
- &maskbits);
- temp = (1 << multi_msi_capable(control));
- temp = ((temp - 1) & ~temp);
- maskbits |= temp;
- pci_write_config_dword(dev,
- msi_mask_bits_reg(pos, is_64bit_address(control)),
- maskbits);
- }
+ msi_register_init(dev, entry);
+
attach_msi_entry(entry, vector);
/* Set MSI enabled bits */
enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
@@ -721,6 +733,8 @@ int pci_enable_msi(struct pci_dev* dev)
vector_irq[dev->irq] = -1;
nr_released_vectors--;
spin_unlock_irqrestore(&msi_lock, flags);
+
+ msi_register_init(dev, msi_desc[dev->irq]);
enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
return 0;
}
_
next reply other threads:[~2005-08-18 5:33 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-18 5:35 Shaohua Li [this message]
2005-08-31 21:43 ` [RFC/PATCH]reconfigure MSI registers after resume Greg KH
-- strict thread matches above, loose matches on Subject: below --
2005-09-01 15:20 Nguyen, Tom L
2005-09-01 19:31 ` Andrew Morton
2005-09-02 1:03 ` Shaohua Li
2005-09-01 20:01 Nguyen, Tom L
2005-09-01 20:10 ` Andrew Morton
2005-09-01 20:59 Nguyen, Tom L
2005-09-02 5:38 ` Greg KH
2005-09-02 19:58 ` Rajesh Shah
2005-09-02 22:00 ` Andrew Morton
2005-09-02 18:51 Nguyen, Tom L
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1124343346.6272.8.camel@linux-hp.sh.intel.com \
--to=shaohua.li@intel.com \
--cc=akpm@osdl.org \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tom.l.nguyen@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.