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. :(
main
Ian Romanick 2005-05-21 02:27:51 +00:00
parent fced784140
commit a686be5bc8
5 changed files with 29 additions and 38 deletions

View File

@ -52,7 +52,8 @@ static void mga_configure(drm_device_t *dev)
{ {
dev->dev_priv_size = sizeof(drm_mga_buf_priv_t); dev->dev_priv_size = sizeof(drm_mga_buf_priv_t);
/* XXX dev->prerelease = mga_driver_prerelease; */ /* 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->vblank_wait = mga_driver_vblank_wait;
dev->irq_preinstall = mga_driver_irq_preinstall; dev->irq_preinstall = mga_driver_irq_preinstall;
dev->irq_postinstall = mga_driver_irq_postinstall; dev->irq_postinstall = mga_driver_irq_postinstall;

View File

@ -81,7 +81,8 @@ static struct drm_driver driver = {
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_IRQ_VBL, DRIVER_IRQ_VBL,
.pretakedown = mga_driver_pretakedown, .preinit = mga_driver_preinit,
.postcleanup = mga_driver_postcleanup,
.dma_quiescent = mga_driver_dma_quiescent, .dma_quiescent = mga_driver_dma_quiescent,
.device_is_agp = mga_driver_device_is_agp, .device_is_agp = mga_driver_device_is_agp,
.vblank_wait = mga_driver_vblank_wait, .vblank_wait = mga_driver_vblank_wait,

View File

@ -110,9 +110,9 @@
0x1002 0x5452 0 "ATI Rage 128 Pro Ultra TR (AGP)" 0x1002 0x5452 0 "ATI Rage 128 Pro Ultra TR (AGP)"
[mga] [mga]
0x102b 0x0521 0 "Matrox G200 (AGP)" 0x102b 0x0521 MGA_CARD_TYPE_G200 "Matrox G200 (AGP)"
0x102b 0x0525 0 "Matrox G400/G450 (AGP)" 0x102b 0x0525 MGA_CARD_TYPE_G400 "Matrox G400/G450 (AGP)"
0x102b 0x2527 0 "Matrox G550 (AGP)" 0x102b 0x2527 MGA_CARD_TYPE_G400 "Matrox G550 (AGP)"
[mach64] [mach64]
0x1002 0x4749 0 "3D Rage Pro" 0x1002 0x4749 0 "3D Rage Pro"

View File

@ -388,21 +388,31 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
* DMA initialization, cleanup * DMA initialization, cleanup
*/ */
int mga_driver_preinit(drm_device_t *dev, unsigned long flags)
{
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->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) static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
{ {
drm_mga_private_t *dev_priv; drm_mga_private_t *dev_priv;
int ret; int ret;
DRM_DEBUG("\n"); DRM_DEBUG("\n");
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
if (!dev_priv)
return DRM_ERR(ENOMEM);
memset(dev_priv, 0, sizeof(drm_mga_private_t)); dev_priv = dev->dev_private;
dev_priv->chipset = init->chipset;
dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
if (init->sgram) { if (init->sgram) {
dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; 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) { if (!dev_priv->sarea) {
DRM_ERROR("failed to find sarea!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(EINVAL); 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); dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
if (!dev_priv->mmio) { if (!dev_priv->mmio) {
DRM_ERROR("failed to find mmio region!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
dev_priv->status = drm_core_findmap(dev, init->status_offset); dev_priv->status = drm_core_findmap(dev, init->status_offset);
if (!dev_priv->status) { if (!dev_priv->status) {
DRM_ERROR("failed to find status page!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
dev_priv->warp = drm_core_findmap(dev, init->warp_offset); dev_priv->warp = drm_core_findmap(dev, init->warp_offset);
if (!dev_priv->warp) { if (!dev_priv->warp) {
DRM_ERROR("failed to find warp microcode region!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
dev_priv->primary = drm_core_findmap(dev, init->primary_offset); dev_priv->primary = drm_core_findmap(dev, init->primary_offset);
if (!dev_priv->primary) { if (!dev_priv->primary) {
DRM_ERROR("failed to find primary dma region!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) { if (!dev->agp_buffer_map) {
DRM_ERROR("failed to find dma buffer region!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(EINVAL); 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 || if (!dev_priv->warp->handle ||
!dev_priv->primary->handle || !dev->agp_buffer_map->handle) { !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
DRM_ERROR("failed to ioremap agp regions!\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(ENOMEM); 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); ret = mga_warp_install_microcode(dev_priv);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to install WARP ucode!\n"); 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); mga_do_cleanup_dma(dev);
return ret; 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); ret = mga_warp_init(dev_priv);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to init WARP engine!\n"); 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); mga_do_cleanup_dma(dev);
return ret; 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) { if (mga_freelist_init(dev, dev_priv) < 0) {
DRM_ERROR("could not initialize freelist\n"); 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); mga_do_cleanup_dma(dev);
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
/* Make dev_private visable to others. */
dev->dev_private = (void *)dev_priv;
return 0; return 0;
} }
@ -733,9 +721,9 @@ int mga_dma_buffers(DRM_IOCTL_ARGS)
return ret; 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) int mga_driver_dma_quiescent(drm_device_t * dev)

View File

@ -113,11 +113,12 @@ typedef struct drm_mga_private {
} drm_mga_private_t; } drm_mga_private_t;
/* mga_dma.c */ /* 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_init(DRM_IOCTL_ARGS);
extern int mga_dma_flush(DRM_IOCTL_ARGS); extern int mga_dma_flush(DRM_IOCTL_ARGS);
extern int mga_dma_reset(DRM_IOCTL_ARGS); extern int mga_dma_reset(DRM_IOCTL_ARGS);
extern int mga_dma_buffers(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_driver_dma_quiescent(drm_device_t * dev);
extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);