From a686be5bc8c5d8a260513b680f322e3b790aadf7 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Sat, 21 May 2005 02:27:51 +0000 Subject: Change the MGA initialization and cleanup a bit. The dev_private structure 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. :( --- shared-core/drm_pciids.txt | 6 +++--- shared-core/mga_dma.c | 48 +++++++++++++++++----------------------------- shared-core/mga_drv.h | 3 ++- 3 files changed, 23 insertions(+), 34 deletions(-) (limited to 'shared-core') diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index d9b42e01..82cbdd46 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -110,9 +110,9 @@ 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" diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c index be96161e..2adb30ac 100644 --- a/shared-core/mga_dma.c +++ b/shared-core/mga_dma.c @@ -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) diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h index f1c3cf3e..54373cc7 100644 --- a/shared-core/mga_drv.h +++ b/shared-core/mga_drv.h @@ -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); -- cgit v1.2.3