summaryrefslogtreecommitdiff
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
parent1775202cf96c51018bf369b1b4d08023d622513c (diff)
nouveau: make sure cmdbuf object gets destroyed
-rw-r--r--shared-core/nouveau_drv.h2
-rw-r--r--shared-core/nouveau_fifo.c47
-rw-r--r--shared-core/nouveau_object.c10
-rw-r--r--shared-core/nouveau_state.c1
4 files changed, 33 insertions, 27 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index a4b05895..c27c93ea 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -191,7 +191,7 @@ extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp);
extern void nouveau_fifo_free(drm_device_t *dev, int channel);
/* nouveau_object.c */
-extern void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp);
+extern void nouveau_object_cleanup(drm_device_t *dev, int channel);
extern struct nouveau_object *
nouveau_object_gr_create(drm_device_t *dev, int channel, int class);
extern struct nouveau_object *
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--;
}
diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c
index c5cf8496..83f039db 100644
--- a/shared-core/nouveau_object.c
+++ b/shared-core/nouveau_object.c
@@ -461,17 +461,13 @@ nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj)
drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER);
}
-void nouveau_object_cleanup(drm_device_t *dev, DRMFILE filp)
+void nouveau_object_cleanup(drm_device_t *dev, int channel)
{
drm_nouveau_private_t *dev_priv=dev->dev_private;
- int channel;
-
- channel = nouveau_fifo_id_get(dev, filp);
- if (channel == -1)
- return;
- while (dev_priv->fifos[channel].objs)
+ while (dev_priv->fifos[channel].objs) {
nouveau_object_free(dev, dev_priv->fifos[channel].objs);
+ }
}
int nouveau_ioctl_object_init(DRM_IOCTL_ARGS)
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index e1fc6330..ed45c166 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -34,7 +34,6 @@ void nouveau_preclose(drm_device_t * dev, DRMFILE filp)
nouveau_mem_release(filp,dev_priv->fb_heap);
nouveau_mem_release(filp,dev_priv->agp_heap);
- nouveau_object_cleanup(dev, filp);
nouveau_fifo_cleanup(dev, filp);
}