diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-03-13 14:51:55 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-03-13 14:55:54 +1100 |
commit | 90f8c691a57a79a6a9652b7d2a01c59acc127b3f (patch) | |
tree | d32ff97d902c30fd3e09062f1ee3c5a10ebce0a3 | |
parent | 1775202cf96c51018bf369b1b4d08023d622513c (diff) |
nouveau: make sure cmdbuf object gets destroyed
-rw-r--r-- | shared-core/nouveau_drv.h | 2 | ||||
-rw-r--r-- | shared-core/nouveau_fifo.c | 47 | ||||
-rw-r--r-- | shared-core/nouveau_object.c | 10 | ||||
-rw-r--r-- | shared-core/nouveau_state.c | 1 |
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); } |