int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
        void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
        int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
+       
+       /**
+        * Called by \c drm_device_is_agp.  Typically used to determine if a
+        * card is really attached to AGP or not.
+        *
+        * \param dev  DRM device handle
+        *
+        * \returns
+        * One of three values is returned depending on whether or not the
+        * card is absolutely \b not AGP (return of 0), absolutely \b is AGP
+        * (return of 1), or may or may not be AGP (return of 2).
+        */
+       int (*device_is_agp) (struct drm_device * dev);
+
        /* these have to be filled in */
+  
        int (*postinit)(struct drm_device *, unsigned long flags);
        irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
        void (*irq_preinstall)(struct drm_device *dev);
        return NULL;
 }
 
+static __inline__ int drm_device_is_agp(drm_device_t *dev)
+{
+       if ( dev->driver->device_is_agp != NULL ) {
+               int err = (*dev->driver->device_is_agp)( dev );
+       
+               if (err != 2) {
+                       return err;
+               }
+       }
+
+       return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
+}
+
 static __inline__ void drm_core_dropmap(struct drm_map *map)
 {
 }
 
                        goto error_out_unreg;
 
        if (drm_core_has_AGP(dev)) {
-               dev->agp = drm_agp_init(dev);
+               if (drm_device_is_agp(dev))
+                       dev->agp = drm_agp_init(dev);
                if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
                        DRM_ERROR( "Cannot initialize the agpgart module.\n" );
                        retcode = -EINVAL;
 
 };
 
 int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
+
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * All Intel graphics chipsets are treated as AGP, even if they are really
+ * PCI-e.
+ *
+ * \param dev   The device to be tested.
+ *
+ * \returns
+ * A value of 1 is always retured to indictate every i810 is AGP.
+ */
+int i810_driver_device_is_agp(drm_device_t * dev)
+{
+       return 1;
+}
 
        .dev_priv_size = sizeof(drm_i810_buf_priv_t),
        .pretakedown = i810_driver_pretakedown,
        .prerelease = i810_driver_prerelease,
+       .device_is_agp = i810_driver_device_is_agp,
        .release = i810_driver_release,
        .dma_quiescent = i810_driver_dma_quiescent,
        .reclaim_buffers = i810_reclaim_buffers,
 
 extern void i810_driver_release(drm_device_t *dev, struct file *filp);
 extern void i810_driver_pretakedown(drm_device_t *dev);
 extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern int i810_driver_device_is_agp(drm_device_t * dev);
 
 #define I810_BASE(reg)         ((unsigned long) \
                                dev_priv->mmio_map->handle)
 
 };
 
 int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
+
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * All Intel graphics chipsets are treated as AGP, even if they are really
+ * PCI-e.
+ *
+ * \param dev   The device to be tested.
+ *
+ * \returns
+ * A value of 1 is always retured to indictate every i8xx is AGP.
+ */
+int i830_driver_device_is_agp(drm_device_t * dev)
+{
+       return 1;
+}
 
        .dev_priv_size = sizeof(drm_i830_buf_priv_t),
        .pretakedown = i830_driver_pretakedown,
        .prerelease = i830_driver_prerelease,
+       .device_is_agp = i830_driver_device_is_agp,
        .release = i830_driver_release,
        .dma_quiescent = i830_driver_dma_quiescent,
        .reclaim_buffers = i830_reclaim_buffers,
 
 extern void i830_driver_release(drm_device_t *dev, struct file *filp);
 extern int i830_driver_dma_quiescent(drm_device_t *dev);
 extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern int i830_driver_device_is_agp(drm_device_t * dev);
 
 #define I830_BASE(reg)         ((unsigned long) \
                                dev_priv->mmio_map->handle)
 
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
+
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * All Intel graphics chipsets are treated as AGP, even if they are really
+ * PCI-e.
+ *
+ * \param dev   The device to be tested.
+ *
+ * \returns
+ * A value of 1 is always retured to indictate every i9x5 is AGP.
+ */
+int i915_driver_device_is_agp(drm_device_t * dev)
+{
+       return 1;
+}
 
                                DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
        .pretakedown = i915_driver_pretakedown,
        .prerelease = i915_driver_prerelease,
+       .device_is_agp = i915_driver_device_is_agp,
        .irq_preinstall = i915_driver_irq_preinstall,
        .irq_postinstall = i915_driver_irq_postinstall,
        .irq_uninstall = i915_driver_irq_uninstall,
 
 extern void i915_kernel_lost_context(drm_device_t * dev);
 extern void i915_driver_pretakedown(drm_device_t *dev);
 extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern int i915_driver_device_is_agp(drm_device_t *dev);
 
 /* i915_irq.c */
 extern int i915_irq_emit(DRM_IOCTL_ARGS);
 
   
 #include "drm_pciids.h"
 
+static int mga_driver_device_is_agp(drm_device_t * dev);
 static int postinit( struct drm_device *dev, unsigned long flags )
 {
        dev->counters += 3;
        .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
        .pretakedown = mga_driver_pretakedown,
        .dma_quiescent = mga_driver_dma_quiescent,
+       .device_is_agp = mga_driver_device_is_agp,
        .vblank_wait = mga_driver_vblank_wait,
        .irq_preinstall = mga_driver_irq_preinstall,
        .irq_postinstall = mga_driver_irq_postinstall,
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL and additional rights");
+
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * In addition to the usual tests performed by \c drm_device_is_agp, this
+ * function detects PCI G450 cards that appear to the system exactly like
+ * AGP G450 cards.
+ *
+ * \param dev   The device to be tested.
+ *
+ * \returns
+ * If the device is a PCI G450, zero is returned.  Otherwise 2 is returned.
+ */
+int mga_driver_device_is_agp(drm_device_t * dev)
+{
+       const struct pci_dev * const pdev = dev->pdev;
+
+
+       /* There are PCI versions of the G450.  These cards have the
+        * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
+        * bridge chip.  We detect these cards, which are not currently
+        * supported by this driver, by looking at the device ID of the
+        * bus the "card" is on.  If vendor is 0x3388 (Hint Corp) and the
+        * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
+        * device.
+        */
+       
+       if ( (pdev->device == 0x0525)
+            && (pdev->bus->self->vendor == 0x3388)
+            && (pdev->bus->self->device == 0x0021) ) {
+               return 0;
+       }
+
+       return 2;
+}
 
 
 #define DRIVER_NAME            "mga"
 #define DRIVER_DESC            "Matrox G200/G400"
-#define DRIVER_DATE            "20021029"
+#define DRIVER_DATE            "20051013"
 
 #define DRIVER_MAJOR           3
 #define DRIVER_MINOR           1
-#define DRIVER_PATCHLEVEL      0
+#define DRIVER_PATCHLEVEL      1
 
 typedef struct drm_mga_primary_buffer {
        u8 *start;