summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/mga_dma.c
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-04-06 23:28:01 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-04-06 23:28:01 +0000
commite83491fb40cebf2a318b94a7bfc52ab98ab9760b (patch)
tree026104064c20ef047dfa9ee6b2a8818e6b066151 /sys/dev/pci/drm/mga_dma.c
parent3554ae2b5a63062c498b682afaa3cc761d6b2332 (diff)
Convert the mgadrm freelist code from handrolled lists to TAILQs,
simplifying while I do it.
Diffstat (limited to 'sys/dev/pci/drm/mga_dma.c')
-rw-r--r--sys/dev/pci/drm/mga_dma.c161
1 files changed, 45 insertions, 116 deletions
diff --git a/sys/dev/pci/drm/mga_dma.c b/sys/dev/pci/drm/mga_dma.c
index 4684eefcfd8..fea770d41c5 100644
--- a/sys/dev/pci/drm/mga_dma.c
+++ b/sys/dev/pci/drm/mga_dma.c
@@ -225,8 +225,8 @@ void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv)
#if MGA_FREELIST_DEBUG
static void mga_freelist_print(struct drm_device * dev)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_freelist_t *entry;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct mgadrm_buf_priv *entry;
DRM_INFO("\n");
DRM_INFO("current dispatch: last=0x%x done=0x%x\n",
@@ -235,7 +235,7 @@ static void mga_freelist_print(struct drm_device * dev)
dev_priv->primary->offset));
DRM_INFO("current freelist:\n");
- for (entry = dev_priv->head->next; entry; entry = entry->next) {
+ TAILQ_FOREACH(entry, &dev_priv->freelist, link) {
DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n",
entry, entry->buf->idx, entry->age.head,
entry->age.head - dev_priv->primary->offset);
@@ -244,144 +244,77 @@ static void mga_freelist_print(struct drm_device * dev)
}
#endif
-static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv)
+static int
+mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv)
{
- struct drm_device_dma *dma = dev->dma;
- struct drm_buf *buf;
- drm_mga_buf_priv_t *buf_priv;
- drm_mga_freelist_t *entry;
- int i;
- DRM_DEBUG("count=%d\n", dma->buf_count);
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf *buf;
+ struct mgadrm_buf_priv *buf_priv;
+ int i;
- dev_priv->head = drm_calloc(1, sizeof(*(dev_priv->head)));
- if (dev_priv->head == NULL)
- return ENOMEM;
+ DRM_DEBUG("count=%d\n", dma->buf_count);
- SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0);
+ /* if we have a freelist lying around, this'll nuke them. */
+ TAILQ_INIT(&dev_priv->freelist);
for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i];
- buf_priv = (drm_mga_buf_priv_t *)buf;
-
- entry = drm_calloc(1, sizeof(*entry));
- if (entry == NULL)
- return ENOMEM;
-
- entry->next = dev_priv->head->next;
- entry->prev = dev_priv->head;
- SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
-
- if (dev_priv->head->next != NULL)
- dev_priv->head->next->prev = entry;
- if (entry->next == NULL)
- dev_priv->tail = entry;
+ buf_priv = buf->dev_private;
- buf_priv->list_entry = entry;
+ TAILQ_INSERT_HEAD(&dev_priv->freelist, buf_priv, link);
+ SET_AGE(&buf_priv->age, MGA_BUFFER_FREE, 0);
buf_priv->discard = 0;
buf_priv->dispatched = 0;
-
- dev_priv->head->next = entry;
- }
-
- return 0;
-}
-
-static void mga_freelist_cleanup(struct drm_device * dev)
-{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_freelist_t *entry;
- drm_mga_freelist_t *next;
- DRM_DEBUG("\n");
-
- entry = dev_priv->head;
- while (entry) {
- next = entry->next;
- drm_free(entry);
- entry = next;
}
- dev_priv->head = dev_priv->tail = NULL;
+ return (0);
}
-#if 0
-/* FIXME: Still needed?
- */
-static void mga_freelist_reset(struct drm_device * dev)
+static struct drm_buf *
+mga_freelist_get(struct drm_device *dev)
{
- struct drm_device_dma *dma = dev->dma;
- struct drm_buf *buf;
- drm_mga_buf_priv_t *buf_priv;
- int i;
-
- for (i = 0; i < dma->buf_count; i++) {
- buf = dma->buflist[i];
- buf_priv = buf->dev_private;
- SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0);
- }
-}
-#endif
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct mgadrm_buf_priv *entry;
+ u_int32_t head, wrap;
-static struct drm_buf *mga_freelist_get(struct drm_device * dev)
-{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_freelist_t *next;
- drm_mga_freelist_t *prev;
- drm_mga_freelist_t *tail = dev_priv->tail;
- u32 head, wrap;
DRM_DEBUG("\n");
head = MGA_READ(MGA_PRIMADDRESS);
wrap = dev_priv->sarea_priv->last_wrap;
- DRM_DEBUG(" tail=0x%06lx %d\n",
- tail->age.head ?
- tail->age.head - dev_priv->primary->offset : 0,
- tail->age.wrap);
- DRM_DEBUG(" head=0x%06lx %d\n",
- head - dev_priv->primary->offset, wrap);
-
- if (TEST_AGE(&tail->age, head, wrap)) {
- prev = dev_priv->tail->prev;
- next = dev_priv->tail;
- prev->next = NULL;
- next->prev = next->next = NULL;
- dev_priv->tail = prev;
- SET_AGE(&next->age, MGA_BUFFER_USED, 0);
- return next->buf;
+ DRM_DEBUG(" tail=0x%06lx %d\n", tail->age.head ?
+ tail->age.head - dev_priv->primary->offset : 0, tail->age.wrap);
+ DRM_DEBUG(" head=0x%06lx %d\n", head - dev_priv->primary->offset,
+ wrap);
+
+ if ((entry = TAILQ_LAST(&dev_priv->freelist, mga_freelist)) != NULL &&
+ TEST_AGE(&entry->age, head, wrap)) {
+ TAILQ_REMOVE(&dev_priv->freelist, entry, link);
+ SET_AGE(&entry->age, MGA_BUFFER_USED, 0);
+ return (entry->buf);
}
DRM_DEBUG("returning NULL!\n");
- return NULL;
+ return (NULL);
}
-int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
+int
+mga_freelist_put(struct drm_device *dev, struct drm_buf *buf)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = (drm_mga_buf_priv_t *)buf;
- drm_mga_freelist_t *head, *entry, *prev;
-
- DRM_DEBUG("age=0x%06lx wrap=%d\n",
- buf_priv->list_entry->age.head -
- dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
-
- entry = buf_priv->list_entry;
- head = dev_priv->head;
-
- if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) {
- SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
- prev = dev_priv->tail;
- prev->next = entry;
- entry->prev = prev;
- entry->next = NULL;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct mgadrm_buf_priv *buf_priv = buf->dev_private;
+
+ DRM_DEBUG("age=0x%06lx wrap=%d\n", buf_priv->list_entry->age.head -
+ dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
+
+ if (buf_priv->age.head == MGA_BUFFER_USED) {
+ SET_AGE(&buf_priv->age, MGA_BUFFER_FREE, 0);
+ TAILQ_INSERT_TAIL(&dev_priv->freelist, buf_priv, link);
} else {
- prev = head->next;
- head->next = entry;
- prev->prev = entry;
- entry->prev = head;
- entry->next = prev;
+ TAILQ_INSERT_HEAD(&dev_priv->freelist, buf_priv, link);
}
- return 0;
+ return (0);
}
/* ================================================================
@@ -921,10 +854,6 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
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);
- }
-
return err;
}