Change the MGA initialization and cleanup a bit. The dev_private structure
authorIan Romanick <idr@us.ibm.com>
Sat, 21 May 2005 02:27:51 +0000 (02:27 +0000)
committerIan Romanick <idr@us.ibm.com>
Sat, 21 May 2005 02:27:51 +0000 (02:27 +0000)
    is now allocated (and partially filled in) by the new
    mga_driver_preinit function.
This allows the driver to detect the type of card (i.e., G200 class vs.
    G400 class) on its own. The chipset value passed to mga_dma_init is now
    ignored. This same technique is used by the radeon DRM.
As a result of this, mga_driver_pretakedown was converted to
    mga_driver_postcleanup. This routine gets called in some other places
    than might be expected, and it sets the dev_private pointer to NULL.
    That little gem took over an hour to track down. :(

bsd-core/mga_drv.c
linux-core/mga_drv.c
shared-core/drm_pciids.txt
shared-core/mga_dma.c
shared-core/mga_drv.h

index 1dd4c81..e088cec 100644 (file)
@@ -52,7 +52,8 @@ static void mga_configure(drm_device_t *dev)
 {
        dev->dev_priv_size = sizeof(drm_mga_buf_priv_t);
        /* XXX dev->prerelease = mga_driver_prerelease; */
-       dev->pretakedown = mga_driver_pretakedown;
+       dev->preinit = mga_driver_preinit;
+       dev->postcleanup = mga_driver_postcleanup;
        dev->vblank_wait = mga_driver_vblank_wait;
        dev->irq_preinstall = mga_driver_irq_preinstall;
        dev->irq_postinstall = mga_driver_irq_postinstall;
index e0f1ab3..c04de5a 100644 (file)
@@ -81,7 +81,8 @@ static struct drm_driver driver = {
            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,
+       .preinit = mga_driver_preinit,
+       .postcleanup = mga_driver_postcleanup,
        .dma_quiescent = mga_driver_dma_quiescent,
        .device_is_agp = mga_driver_device_is_agp,
        .vblank_wait = mga_driver_vblank_wait,
index d9b42e0..82cbdd4 100644 (file)
 0x1002 0x5452 0 "ATI Rage 128 Pro Ultra TR (AGP)"
 
 [mga]
-0x102b 0x0521 0 "Matrox G200 (AGP)"
-0x102b 0x0525 0 "Matrox G400/G450 (AGP)"
-0x102b 0x2527 0 "Matrox G550 (AGP)"
+0x102b 0x0521 MGA_CARD_TYPE_G200 "Matrox G200 (AGP)"
+0x102b 0x0525 MGA_CARD_TYPE_G400 "Matrox G400/G450 (AGP)"
+0x102b 0x2527 MGA_CARD_TYPE_G400 "Matrox G550 (AGP)"
 
 [mach64]
 0x1002 0x4749 0 "3D Rage Pro"
index be96161..2adb30a 100644 (file)
@@ -388,21 +388,31 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
  * DMA initialization, cleanup
  */
 
-static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
+int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
 {
-       drm_mga_private_t *dev_priv;
-       int ret;
-       DRM_DEBUG("\n");
+       drm_mga_private_t * dev_priv;
 
        dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
        if (!dev_priv)
                return DRM_ERR(ENOMEM);
 
+       dev->dev_private = (void *)dev_priv;
        memset(dev_priv, 0, sizeof(drm_mga_private_t));
 
-       dev_priv->chipset = init->chipset;
-
        dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
+       dev_priv->chipset = flags;
+
+       return 0;
+}
+
+static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
+{
+       drm_mga_private_t *dev_priv;
+       int ret;
+       DRM_DEBUG("\n");
+
+
+       dev_priv = dev->dev_private;
 
        if (init->sgram) {
                dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
@@ -430,8 +440,6 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
 
        if (!dev_priv->sarea) {
                DRM_ERROR("failed to find sarea!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(EINVAL);
        }
@@ -439,40 +447,30 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
        dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
        if (!dev_priv->mmio) {
                DRM_ERROR("failed to find mmio region!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(EINVAL);
        }
        dev_priv->status = drm_core_findmap(dev, init->status_offset);
        if (!dev_priv->status) {
                DRM_ERROR("failed to find status page!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(EINVAL);
        }
        dev_priv->warp = drm_core_findmap(dev, init->warp_offset);
        if (!dev_priv->warp) {
                DRM_ERROR("failed to find warp microcode region!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(EINVAL);
        }
        dev_priv->primary = drm_core_findmap(dev, init->primary_offset);
        if (!dev_priv->primary) {
                DRM_ERROR("failed to find primary dma region!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(EINVAL);
        }
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                DRM_ERROR("failed to find dma buffer region!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(EINVAL);
        }
@@ -488,8 +486,6 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
        if (!dev_priv->warp->handle ||
            !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
                DRM_ERROR("failed to ioremap agp regions!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(ENOMEM);
        }
@@ -497,8 +493,6 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
        ret = mga_warp_install_microcode(dev_priv);
        if (ret < 0) {
                DRM_ERROR("failed to install WARP ucode!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return ret;
        }
@@ -506,8 +500,6 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
        ret = mga_warp_init(dev_priv);
        if (ret < 0) {
                DRM_ERROR("failed to init WARP engine!\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return ret;
        }
@@ -547,14 +539,10 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
 
        if (mga_freelist_init(dev, dev_priv) < 0) {
                DRM_ERROR("could not initialize freelist\n");
-               /* Assign dev_private so we can do cleanup. */
-               dev->dev_private = (void *)dev_priv;
                mga_do_cleanup_dma(dev);
                return DRM_ERR(ENOMEM);
        }
 
-       /* Make dev_private visable to others. */
-       dev->dev_private = (void *)dev_priv;
        return 0;
 }
 
@@ -733,9 +721,9 @@ int mga_dma_buffers(DRM_IOCTL_ARGS)
        return ret;
 }
 
-void mga_driver_pretakedown(drm_device_t * dev)
+int mga_driver_postcleanup(drm_device_t * dev)
 {
-       mga_do_cleanup_dma(dev);
+       return mga_do_cleanup_dma(dev);
 }
 
 int mga_driver_dma_quiescent(drm_device_t * dev)
index f1c3cf3..54373cc 100644 (file)
@@ -113,11 +113,12 @@ typedef struct drm_mga_private {
 } drm_mga_private_t;
 
                                /* mga_dma.c */
+extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
 extern int mga_dma_init(DRM_IOCTL_ARGS);
 extern int mga_dma_flush(DRM_IOCTL_ARGS);
 extern int mga_dma_reset(DRM_IOCTL_ARGS);
 extern int mga_dma_buffers(DRM_IOCTL_ARGS);
-extern void mga_driver_pretakedown(drm_device_t * dev);
+extern int mga_driver_postcleanup(drm_device_t * dev);
 extern int mga_driver_dma_quiescent(drm_device_t * dev);
 
 extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);