Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / char / drm / mga_drv.c
index 22dab3e..9f7ed0e 100644 (file)
 #include "mga_drm.h"
 #include "mga_drv.h"
 
-  
 #include "drm_pciids.h"
 
-static int postinit( struct drm_device *dev, unsigned long flags )
-{
-       dev->counters += 3;
-       dev->types[6] = _DRM_STAT_IRQ;
-       dev->types[7] = _DRM_STAT_PRIMARY;
-       dev->types[8] = _DRM_STAT_SECONDARY;
-
-       DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
-               DRIVER_NAME,
-               DRIVER_MAJOR,
-               DRIVER_MINOR,
-               DRIVER_PATCHLEVEL,
-               DRIVER_DATE,
-               dev->primary.minor,
-               pci_pretty_name(dev->pdev)
-               );
-       return 0;
-}
-
-static int version( drm_version_t *version )
-{
-       int len;
-
-       version->version_major = DRIVER_MAJOR;
-       version->version_minor = DRIVER_MINOR;
-       version->version_patchlevel = DRIVER_PATCHLEVEL;
-       DRM_COPY( version->name, DRIVER_NAME );
-       DRM_COPY( version->date, DRIVER_DATE );
-       DRM_COPY( version->desc, DRIVER_DESC );
-       return 0;
-}
+static int mga_driver_device_is_agp(drm_device_t * dev);
 
 static struct pci_device_id pciidlist[] = {
        mga_PCI_IDS
 };
 
-extern drm_ioctl_desc_t mga_ioctls[];
-extern int mga_max_ioctl;
-
 static struct drm_driver driver = {
-       .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,
+       .driver_features =
+           DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
+           DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+           DRIVER_IRQ_VBL,
+       .load = mga_driver_load,
+       .unload = mga_driver_unload,
+       .lastclose = mga_driver_lastclose,
        .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,
@@ -89,23 +61,31 @@ static struct drm_driver driver = {
        .reclaim_buffers = drm_core_reclaim_buffers,
        .get_map_ofs = drm_core_get_map_ofs,
        .get_reg_ofs = drm_core_get_reg_ofs,
-       .postinit = postinit,
-       .version = version,
        .ioctls = mga_ioctls,
        .dma_ioctl = mga_dma_buffers,
        .fops = {
-               .owner = THIS_MODULE,
-               .open = drm_open,
-               .release = drm_release,
-               .ioctl = drm_ioctl,
-               .mmap = drm_mmap,
-               .poll = drm_poll,
-               .fasync = drm_fasync,
-       },
+                .owner = THIS_MODULE,
+                .open = drm_open,
+                .release = drm_release,
+                .ioctl = drm_ioctl,
+                .mmap = drm_mmap,
+                .poll = drm_poll,
+                .fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+                .compat_ioctl = mga_compat_ioctl,
+#endif
+                },
        .pci_driver = {
-               .name = DRIVER_NAME,
-               .id_table = pciidlist,
-       }
+                .name = DRIVER_NAME,
+                .id_table = pciidlist,
+       },
+
+       .name = DRIVER_NAME,
+       .desc = DRIVER_DESC,
+       .date = DRIVER_DATE,
+       .major = DRIVER_MAJOR,
+       .minor = DRIVER_MINOR,
+       .patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init mga_init(void)
@@ -122,6 +102,40 @@ static void __exit mga_exit(void)
 module_init(mga_init);
 module_exit(mga_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+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.
+ */
+static 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
+           && (pdev->bus->self->vendor == 0x3388)
+           && (pdev->bus->self->device == 0x0021)) {
+               return 0;
+       }
+
+       return 2;
+}