@@ -170,6 +170,7 @@ static inline void pci_msix_clear_and_set_ctrl(struct pci_dev *dev, u16 clear, u
}
void pci_realloc_get_opt(char *);
+bool pci_realloc_user_enabled(void);
static inline int pci_no_d1d2(struct pci_dev *dev)
{
@@ -335,6 +335,26 @@ static void quirk_s3_64M(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M);
+/*
+ * LSI devices firmware does not like BAR get changed
+ */
+static void quirk_bar_fixed(struct pci_dev *dev)
+{
+ int i;
+
+ if (pci_realloc_user_enabled())
+ return;
+
+ for (i = 0; i < PCI_STD_RESOURCE_END; i++) {
+ struct resource *r = &dev->resource[i];
+
+ if (!r->start || !r->flags)
+ continue;
+ r->flags |= IORESOURCE_PCI_FIXED;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LSI_LOGIC, PCI_ANY_ID, quirk_bar_fixed);
+
/* for pci remove and rescan */
static void quirk_allocate_fixed(struct pci_dev *dev)
{
@@ -1677,6 +1677,10 @@ void __init pci_realloc_get_opt(char *str)
else if (!strncmp(str, "on", 2))
pci_realloc_enable = user_enabled;
}
+bool pci_realloc_user_enabled(void)
+{
+ return pci_realloc_enable == user_enabled;
+}
static bool pci_realloc_enabled(enum enable_type enable)
{
return enable >= user_enabled;
LSI HBA firmware stop responding pci read from host if pci core ever change pci device BAR values. Set their resources to FIXED, so let realloc to skip them. v2: check if start is 0. Reported-by: Paul Johnson <pjay@nwtrail.com> Suggested-by: Bjorn Helgaas <bhelgaas@google.com> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=92351 Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: stable@vger.kernel.org --- drivers/pci/pci.h | 1 + drivers/pci/quirks.c | 20 ++++++++++++++++++++ drivers/pci/setup-bus.c | 4 ++++ 3 files changed, 25 insertions(+)