diff options
| author | Stephen Kitt <steve@sk2.org> | 2011-01-31 17:25:43 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2011-02-03 18:43:57 -0500 |
| commit | a70b95c017e8b518e1e069853355e4e497453dbb (patch) | |
| tree | c4264dc861b449f83fc40d9fb942083c5d985870 | |
| parent | cecd1455bc9cbd9568036f502ee8ded0a64354a7 (diff) | |
agp: ensure GART has an address before enabling it
Some BIOSs (eg. the AMI BIOS on the Asus P4P800 motherboard) don't
initialise the GART address, and pcibios_assign_resources() can ignore it
because it can be marked as a host bridge (see
https://bugzilla.kernel.org/show_bug.cgi?id=24392#c5 for details). This
was handled correctly up to 2.6.35, but the pci_enable_device() cleanup in
2.6.36 96576a9e1a0cdb8 ("agp: intel-agp: do not use PCI resources before
pci_enable_device()") means that the kernel tries to enable the GART
before assigning it an address; in such cases the GART overlaps with other
device assignments and ends up being disabled.
This patch fixes https://bugzilla.kernel.org/show_bug.cgi?id=24392
Note that I imagine efficeon-agp.c probably has the same problem, but
I can't test that and I'd like to make sure this patch is suitable for
-stable (since 2.6.36 and 2.6.37 are affected).
Signed-off-by: Stephen Kitt <steve@sk2.org>
Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Maciej Rutecki <maciej.rutecki@gmail.com>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Kulikov Vasiliy <segooon@gmail.com>
Cc: Florian Mickler <florian@mickler.org>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/char/agp/intel-agp.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 857df10c042..b0a0dccc98c 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
| @@ -774,20 +774,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
| 774 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | 774 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); |
| 775 | 775 | ||
| 776 | /* | 776 | /* |
| 777 | * If the device has not been properly setup, the following will catch | ||
| 778 | * the problem and should stop the system from crashing. | ||
| 779 | * 20030610 - hamish@zot.org | ||
| 780 | */ | ||
| 781 | if (pci_enable_device(pdev)) { | ||
| 782 | dev_err(&pdev->dev, "can't enable PCI device\n"); | ||
| 783 | agp_put_bridge(bridge); | ||
| 784 | return -ENODEV; | ||
| 785 | } | ||
| 786 | |||
| 787 | /* | ||
| 788 | * The following fixes the case where the BIOS has "forgotten" to | 777 | * The following fixes the case where the BIOS has "forgotten" to |
| 789 | * provide an address range for the GART. | 778 | * provide an address range for the GART. |
| 790 | * 20030610 - hamish@zot.org | 779 | * 20030610 - hamish@zot.org |
| 780 | * This happens before pci_enable_device() intentionally; | ||
| 781 | * calling pci_enable_device() before assigning the resource | ||
| 782 | * will result in the GART being disabled on machines with such | ||
| 783 | * BIOSs (the GART ends up with a BAR starting at 0, which | ||
| 784 | * conflicts a lot of other devices). | ||
| 791 | */ | 785 | */ |
| 792 | r = &pdev->resource[0]; | 786 | r = &pdev->resource[0]; |
| 793 | if (!r->start && r->end) { | 787 | if (!r->start && r->end) { |
| @@ -798,6 +792,17 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
| 798 | } | 792 | } |
| 799 | } | 793 | } |
| 800 | 794 | ||
| 795 | /* | ||
| 796 | * If the device has not been properly setup, the following will catch | ||
| 797 | * the problem and should stop the system from crashing. | ||
| 798 | * 20030610 - hamish@zot.org | ||
| 799 | */ | ||
| 800 | if (pci_enable_device(pdev)) { | ||
| 801 | dev_err(&pdev->dev, "can't enable PCI device\n"); | ||
| 802 | agp_put_bridge(bridge); | ||
| 803 | return -ENODEV; | ||
| 804 | } | ||
| 805 | |||
| 801 | /* Fill in the mode register */ | 806 | /* Fill in the mode register */ |
| 802 | if (cap_ptr) { | 807 | if (cap_ptr) { |
| 803 | pci_read_config_dword(pdev, | 808 | pci_read_config_dword(pdev, |
