aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2007-03-03 11:48:54 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-03-03 11:48:54 -0500
commited8ccee0918ad063a4741c0656fda783e02df627 (patch)
treec624b62b93f594511e8802232c0c00a2cdfcd99f
parent9e5755bce00bb563739aeb0f09932a1907521167 (diff)
adjust legacy IDE resource setting (v2)
The change to force legacy mode IDE channels' resources to fixed non-zero values confuses (at least some versions of) X, because the values reported by the kernel and those readable from PCI config space aren't consistent anymore. Therefore, this patch arranges for the respective BARs to also get updated if possible. Signed-off-by: Jan Beulich <jbeulich@novell.com> Acked-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/pci/probe.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2fe1d690eb13..a4a96826d9e0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -682,7 +682,34 @@ static void pci_read_irq(struct pci_dev *dev)
682 dev->irq = irq; 682 dev->irq = irq;
683} 683}
684 684
685#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) 685static void change_legacy_io_resource(struct pci_dev * dev, unsigned index,
686 unsigned start, unsigned end)
687{
688 unsigned base = start & PCI_BASE_ADDRESS_IO_MASK;
689 unsigned len = (end | ~PCI_BASE_ADDRESS_IO_MASK) - base + 1;
690
691 /*
692 * Some X versions get confused when the BARs reported through
693 * /sys or /proc differ from those seen in config space, thus
694 * try to update the config space values, too.
695 */
696 if (!(pci_resource_flags(dev, index) & IORESOURCE_IO))
697 printk(KERN_WARNING "%s: cannot adjust BAR%u (not I/O)\n",
698 pci_name(dev), index);
699 else if (pci_resource_len(dev, index) != len)
700 printk(KERN_WARNING "%s: cannot adjust BAR%u (size %04X)\n",
701 pci_name(dev), index, (unsigned)pci_resource_len(dev, index));
702 else {
703 printk(KERN_INFO "%s: trying to change BAR%u from %04X to %04X\n",
704 pci_name(dev), index,
705 (unsigned)pci_resource_start(dev, index), base);
706 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + index * 4, base);
707 }
708 pci_resource_start(dev, index) = start;
709 pci_resource_end(dev, index) = end;
710 pci_resource_flags(dev, index) =
711 IORESOURCE_IO | IORESOURCE_PCI_FIXED | PCI_BASE_ADDRESS_SPACE_IO;
712}
686 713
687/** 714/**
688 * pci_setup_device - fill in class and map information of a device 715 * pci_setup_device - fill in class and map information of a device
@@ -735,20 +762,12 @@ static int pci_setup_device(struct pci_dev * dev)
735 u8 progif; 762 u8 progif;
736 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); 763 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
737 if ((progif & 1) == 0) { 764 if ((progif & 1) == 0) {
738 dev->resource[0].start = 0x1F0; 765 change_legacy_io_resource(dev, 0, 0x1F0, 0x1F7);
739 dev->resource[0].end = 0x1F7; 766 change_legacy_io_resource(dev, 1, 0x3F6, 0x3F6);
740 dev->resource[0].flags = LEGACY_IO_RESOURCE;
741 dev->resource[1].start = 0x3F6;
742 dev->resource[1].end = 0x3F6;
743 dev->resource[1].flags = LEGACY_IO_RESOURCE;
744 } 767 }
745 if ((progif & 4) == 0) { 768 if ((progif & 4) == 0) {
746 dev->resource[2].start = 0x170; 769 change_legacy_io_resource(dev, 2, 0x170, 0x177);
747 dev->resource[2].end = 0x177; 770 change_legacy_io_resource(dev, 3, 0x376, 0x376);
748 dev->resource[2].flags = LEGACY_IO_RESOURCE;
749 dev->resource[3].start = 0x376;
750 dev->resource[3].end = 0x376;
751 dev->resource[3].flags = LEGACY_IO_RESOURCE;
752 } 771 }
753 } 772 }
754 break; 773 break;