Bug 3248 - MGA driver fails in unfriendly way on PCI cards
Summary: MGA driver fails in unfriendly way on PCI cards
Status: RESOLVED FIXED
Alias: None
Product: DRI
Classification: Unclassified
Component: DRM/other (show other bugs)
Version: DRI git
Hardware: x86 (IA32) Linux (All)
: high normal
Assignee: Default DRI bug account
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 3259
  Show dependency treegraph
 
Reported: 2005-05-09 09:39 UTC by Ian Romanick
Modified: 2005-06-27 22:44 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
First attempt at detecting PCI G450 cards (1.77 KB, patch)
2005-05-09 14:58 UTC, Ian Romanick
no flags Details | Splinter Review
Reject PCI G450 cards in drm_agp_init path (3.23 KB, patch)
2005-05-10 07:54 UTC, Ian Romanick
no flags Details | Splinter Review
Reject PCI G450 cards via drm_device_is_agp callback (7.47 KB, patch)
2005-05-13 14:21 UTC, Ian Romanick
no flags Details | Splinter Review

Description Ian Romanick 2005-05-09 09:39:28 UTC
When DRI is enabled on a PCI G450 card, everything /appears/ to initialize
correctly, but all is not right.  As near as I can tell, the driver detects that
AGP is available in the system and assumes that the card is connected to the AGP
slot.  As soon as a direct-rendering application (e.g., glxgears) runs, the
X-server locks hard.

It seems as though the driver should test whether or not the card is connected
to AGP in addtion to testing whether or not AGP is available in the system.  Is
there a core-DRM utility function to do this (e.g., drm_card_is_agp_attached)?
Comment 1 Ian Romanick 2005-05-09 14:58:05 UTC
Created attachment 2649 [details] [review]
First attempt at detecting PCI G450 cards

This patch detects PCI G450 cards by looking at the PCI vendor / device of the
bus the card is on.  If the vendor / device matches that of the PCI-to-PCI
bridge that is known to be used on the PCI G450 cards, the card is rejected. 
Currently, this rejection happens when the card's device is opened.  Since the
open fails, the X DDX will not try to initialize DRI for the card.

Currently, this fix is only in linux-core/mga_drv.c.  I'm not sure how to do
this for BSD.

Since I haven't done anything in the kernel since the 2.2 / 2.3 time frame, I'm
going to let this be reviewed before I commit it.
Comment 2 Ian Romanick 2005-05-09 23:48:46 UTC
I've been thinking about this some more.  I've decided that I don't like the
idea of failing at device open.  The problem is that if the MGA DRM is updated
to support PCI cards, the device open can't fail.  In that case, old versions of
the DDX will go back to being broken (i.e., exactly as they are today).

After digging a bit deeper, I think a better sollution is to add a
device-specific hook in drm_agp_init.  At the start of drm_agp_init,
dev->driver->agp_preinit().  agp_preinit could then determine if the card was
really an AGP card or not.  If it's not, it would return false and drm_agp_init
would fail.  In the case of drivers that require AGP (i.e., the current MGA
DRM), this would result in driver failing to initialize.

If nothing else, it looks like it should make the drmAgpAcquire call in the DDX
fail.  That /should/ be good enough for now.  In the future, when the DRM and
DDX support DRI on PCI cards, the DDX could take a different, non-failure path
when drmAgpAcquire fails.

I'll code up something in the morning and post a patch.  Does this seem like the
right approach?
Comment 3 Ian Romanick 2005-05-10 07:54:20 UTC
Created attachment 2654 [details] [review]
Reject PCI G450 cards in drm_agp_init path

This patch implements the mechanism that I proposed in my previous post.  This
patch prevents DRI from begin initialized on PCI G450 with the current DDX even
if DRIVER_REQUIRE_AGP is removed from driver_features.	This means that old DDX
versions will still be "fixed" even when the DRM is updated to support PCI
cards.

Unless there are objections, I will commit this on 2005-May-11.
Comment 4 Ian Romanick 2005-05-13 14:21:29 UTC
Created attachment 2676 [details] [review]
Reject PCI G450 cards via drm_device_is_agp callback

This is the thrird (and hopefully final!) iteration of this patch. 
drm_device_is_agp was modified to use a device-specific callback on both Linux
and BSD.  The Linux code was then modified to use drm_device_is_agp before
calling drm_agp_init (this is the way BSD already works).

This achieves essentially the same effect as the previous patch, but, since it
makes the Linux code more like the BSD code and will require less changes to
BSD to implement, I think I like this version better.
Comment 5 Mike A. Harris 2005-06-14 14:47:07 UTC
I'm not convinced the patches attached above are the correct approach for
this.  The only safe way to determine wether a card is actually AGP or not,
is to walk the PCI extended capabilities list.  I wrote a patch for the
Radeon driver a couple of years ago which does just that, which is present
in Xorg 6.7.0 and later releases.  My code was initially just a Radeon driver
specific temporary implementation, but the code has been copied aparently
into the SiS or some other driver (I don't recall which).

Ideally, the code should be factored into os-support somewhere, and all
drivers modified to use the genericized code instead of cut and pasting
it everywhere.

Initially I would have placed the code X server side, but perhaps it fits
better in kernel land?

Any thoughts?
Comment 6 Adam Jackson 2005-06-14 15:26:26 UTC
mike, that's what drm_device_is_agp does:

static __inline__ int drm_device_is_agp(drm_device_t *dev)
{
        return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
}

the problem is that the PCI G450 will appear to be an AGP device all the time. 
so merely walking the cap list will actually be wrong for this device, yay
matrox.  you have to both walk the cap list _and_ allow for a device-specific check.
Comment 7 Ian Romanick 2005-06-28 15:44:24 UTC
My patches have been commited to Mesa and DRM CVS.  Eric Anholt committed
similar patches for *BSD in DRM CVS.  Closing.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.