diff options
-rw-r--r-- | bsd-core/mga_drv.c | 1 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 1 | ||||
-rw-r--r-- | shared-core/mga_dma.c | 57 | ||||
-rw-r--r-- | shared-core/mga_drv.h | 6 | ||||
-rw-r--r-- | shared-core/mga_irq.c | 2 |
5 files changed, 40 insertions, 27 deletions
diff --git a/bsd-core/mga_drv.c b/bsd-core/mga_drv.c index 6034212c..efb7cc99 100644 --- a/bsd-core/mga_drv.c +++ b/bsd-core/mga_drv.c @@ -60,6 +60,7 @@ static void mga_configure(drm_device_t *dev) dev->irq_uninstall = mga_driver_irq_uninstall; dev->irq_handler = mga_driver_irq_handler; dev->dma_ioctl = mga_dma_buffers; + dev->pretakedown = mga_driver_pretakedown; dev->dma_quiescent = mga_driver_dma_quiescent; dev->device_is_agp = mga_driver_device_is_agp; diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index c8bb042d..43877597 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -83,6 +83,7 @@ static struct drm_driver driver = { DRIVER_IRQ_VBL, .preinit = mga_driver_preinit, .postcleanup = mga_driver_postcleanup, + .pretakedown = mga_driver_pretakedown, .dma_quiescent = mga_driver_dma_quiescent, .device_is_agp = mga_driver_device_is_agp, .vblank_wait = mga_driver_vblank_wait, diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c index 367c670e..4c0be4cc 100644 --- a/shared-core/mga_dma.c +++ b/shared-core/mga_dma.c @@ -440,38 +440,32 @@ 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"); - mga_do_cleanup_dma(dev); return DRM_ERR(EINVAL); } dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio) { DRM_ERROR("failed to find mmio region!\n"); - 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"); - 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"); - 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"); - 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"); - mga_do_cleanup_dma(dev); return DRM_ERR(EINVAL); } @@ -486,21 +480,18 @@ 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"); - mga_do_cleanup_dma(dev); return DRM_ERR(ENOMEM); } ret = mga_warp_install_microcode(dev_priv); if (ret < 0) { DRM_ERROR("failed to install WARP ucode!\n"); - mga_do_cleanup_dma(dev); return ret; } ret = mga_warp_init(dev_priv); if (ret < 0) { DRM_ERROR("failed to init WARP engine!\n"); - mga_do_cleanup_dma(dev); return ret; } @@ -539,7 +530,6 @@ 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"); - mga_do_cleanup_dma(dev); return DRM_ERR(ENOMEM); } @@ -564,10 +554,20 @@ static int mga_do_cleanup_dma(drm_device_t * dev) drm_core_ioremapfree(dev_priv->warp, dev); if (dev_priv->primary != NULL) drm_core_ioremapfree(dev_priv->primary, dev); - if (dev->agp_buffer_map != NULL) { + if (dev->agp_buffer_map != NULL) drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } + + dev_priv->warp = NULL; + dev_priv->primary = NULL; + dev_priv->mmio = NULL; + dev_priv->status = NULL; + dev_priv->sarea = NULL; + dev_priv->sarea_priv = NULL; + dev->agp_buffer_map = NULL; + + memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); + dev_priv->warp_pipe = 0; + memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); if (dev_priv->head != NULL) { mga_freelist_cleanup(dev); @@ -581,6 +581,7 @@ int mga_dma_init(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mga_init_t init; + int err; LOCK_TEST_WITH_RETURN(dev, filp); @@ -589,7 +590,11 @@ int mga_dma_init(DRM_IOCTL_ARGS) switch (init.func) { case MGA_INIT_DMA: - return mga_do_init_dma(dev, &init); + err = mga_do_init_dma(dev, &init); + if (err) { + (void) mga_do_cleanup_dma(dev); + } + return err; case MGA_CLEANUP_DMA: return mga_do_cleanup_dma(dev); } @@ -717,19 +722,23 @@ int mga_dma_buffers(DRM_IOCTL_ARGS) return ret; } +/** + * Called just before the module is unloaded. + */ int mga_driver_postcleanup(drm_device_t * dev) { - int err; - - - err = mga_do_cleanup_dma(dev); - if (!err) { - drm_free(dev->dev_private, sizeof(drm_mga_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; - } + drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); + dev->dev_private = NULL; + + return 0; +} - return err; +/** + * Called when the last opener of the device is closed. + */ +void mga_driver_pretakedown(drm_device_t * dev) +{ + 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 e12dbd42..180c1235 100644 --- a/shared-core/mga_drv.h +++ b/shared-core/mga_drv.h @@ -38,11 +38,11 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20050520" +#define DRIVER_DATE "20050606" #define DRIVER_MAJOR 3 #define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 2 +#define DRIVER_PATCHLEVEL 3 typedef struct drm_mga_primary_buffer { u8 *start; @@ -108,7 +108,6 @@ typedef struct drm_mga_private { drm_local_map_t *status; drm_local_map_t *warp; drm_local_map_t *primary; - drm_local_map_t *buffers; drm_local_map_t *agp_textures; } drm_mga_private_t; @@ -119,6 +118,7 @@ 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 int mga_driver_postcleanup(drm_device_t * dev); +extern void mga_driver_pretakedown(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); diff --git a/shared-core/mga_irq.c b/shared-core/mga_irq.c index 704652d3..99a23fe1 100644 --- a/shared-core/mga_irq.c +++ b/shared-core/mga_irq.c @@ -98,4 +98,6 @@ void mga_driver_irq_uninstall(drm_device_t * dev) /* Disable *all* interrupts */ MGA_WRITE(MGA_IEN, 0); + + dev->irq_enabled = 0; } |