summaryrefslogtreecommitdiff
path: root/shared-core/nouveau_fifo.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-03-13 14:51:55 +1100
committerBen Skeggs <skeggsb@gmail.com>2007-03-13 14:55:54 +1100
commit90f8c691a57a79a6a9652b7d2a01c59acc127b3f (patch)
treed32ff97d902c30fd3e09062f1ee3c5a10ebce0a3 /shared-core/nouveau_fifo.c
parent1775202cf96c51018bf369b1b4d08023d622513c (diff)
nouveau: make sure cmdbuf object gets destroyed
Diffstat (limited to 'shared-core/nouveau_fifo.c')
-rw-r--r--shared-core/nouveau_fifo.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 8c4e8309..3ffb0516 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -527,15 +527,20 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
if (i==nouveau_fifo_number(dev))
return DRM_ERR(EINVAL);
+ /* that fifo is used */
+ dev_priv->fifos[i].used = 1;
+ dev_priv->fifos[i].filp = filp;
+ /* FIFO has no objects yet */
+ dev_priv->fifos[i].objs = NULL;
+
/* allocate a command buffer, and create a dma object for the gpu */
ret = nouveau_fifo_cmdbuf_alloc(dev, i);
- if (ret) return ret;
+ if (ret) {
+ nouveau_fifo_free(dev, i);
+ return ret;
+ }
cb_obj = dev_priv->fifos[i].cmdbuf_obj;
- /* that fifo is used */
- dev_priv->fifos[i].used=1;
- dev_priv->fifos[i].filp=filp;
-
init->channel = i;
init->put_base = 0;
dev_priv->cur_fifo = init->channel;
@@ -638,8 +643,6 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
init->cmdbuf = dev_priv->fifos[init->channel].cmdbuf_mem->start;
init->cmdbuf_size = dev_priv->fifos[init->channel].cmdbuf_mem->size;
- /* FIFO has no objects yet */
- dev_priv->fifos[init->channel].objs = NULL;
dev_priv->fifo_alloc_count++;
DRM_INFO("%s: initialised FIFO %d\n", __func__, init->channel);
@@ -647,43 +650,51 @@ static int nouveau_fifo_alloc(drm_device_t* dev,drm_nouveau_fifo_alloc_t* init,
}
/* stops a fifo */
-void nouveau_fifo_free(drm_device_t* dev,int n)
+void nouveau_fifo_free(drm_device_t* dev, int channel)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
+ struct nouveau_fifo *chan = &dev_priv->fifos[channel];
int i;
int ctx_size = nouveau_fifo_ctx_size(dev);
- dev_priv->fifos[n].used=0;
- DRM_INFO("%s: freeing fifo %d\n", __func__, n);
+ chan->used = 0;
+ DRM_INFO("%s: freeing fifo %d\n", __func__, channel);
/* disable the fifo caches */
NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
- NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)&~(1<<n));
+ NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<channel));
// FIXME XXX needs more code
/* Clean RAMFC */
for (i=0;i<ctx_size;i+=4) {
DRM_DEBUG("RAMFC +%02x: 0x%08x\n", i, NV_READ(NV_RAMIN +
- dev_priv->ramfc_offset + n*ctx_size + i));
- NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + n*ctx_size + i, 0);
+ dev_priv->ramfc_offset +
+ channel*ctx_size + i));
+ NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset +
+ channel*ctx_size + i, 0);
}
+ /* Cleanup PGRAPH state */
if (dev_priv->card_type >= NV_40)
- nouveau_instmem_free(dev, dev_priv->fifos[n].ramin_grctx);
+ nouveau_instmem_free(dev, chan->ramin_grctx);
else if (dev_priv->card_type >= NV_30) {
}
else if (dev_priv->card_type >= NV_20) {
/* clear ctx table */
- INSTANCE_WR(dev_priv->ctx_table, n, 0);
- nouveau_instmem_free(dev, dev_priv->fifos[n].ramin_grctx);
+ INSTANCE_WR(dev_priv->ctx_table, channel, 0);
+ nouveau_instmem_free(dev, chan->ramin_grctx);
}
/* reenable the fifo caches */
NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
- /* Deallocate command buffer, and dma object */
- nouveau_mem_free(dev, dev_priv->fifos[n].cmdbuf_mem);
+ /* Deallocate command buffer */
+ if (chan->cmdbuf_mem)
+ nouveau_mem_free(dev, chan->cmdbuf_mem);
+
+ /* Destroy objects belonging to the channel */
+ nouveau_object_cleanup(dev, channel);
dev_priv->fifo_alloc_count--;
}