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
parent
fced784140
commit
a686be5bc8
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue