summaryrefslogtreecommitdiff
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
parent3554ae2b5a63062c498b682afaa3cc761d6b2332 (diff)
Convert the mgadrm freelist code from handrolled lists to TAILQs,
simplifying while I do it.
-rw-r--r--sys/dev/pci/drm/mga_dma.c161
-rw-r--r--sys/dev/pci/drm/mga_drv.c2
-rw-r--r--sys/dev/pci/drm/mga_drv.h31
-rw-r--r--sys/dev/pci/drm/mga_state.c63
4 files changed, 90 insertions, 167 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;
}
diff --git a/sys/dev/pci/drm/mga_drv.c b/sys/dev/pci/drm/mga_drv.c
index 2995536feaf..8915f10b7d4 100644
--- a/sys/dev/pci/drm/mga_drv.c
+++ b/sys/dev/pci/drm/mga_drv.c
@@ -56,7 +56,7 @@ const static struct drm_pcidev mgadrm_pciidlist[] = {
};
static const struct drm_driver_info mga_driver = {
- .buf_priv_size = sizeof(drm_mga_buf_priv_t),
+ .buf_priv_size = sizeof(struct mgadrm_buf_priv),
.ioctl = mgadrm_ioctl,
.lastclose = mga_driver_lastclose,
.vblank_pipes = 1,
diff --git a/sys/dev/pci/drm/mga_drv.h b/sys/dev/pci/drm/mga_drv.h
index 198b1366a43..c753b9e209e 100644
--- a/sys/dev/pci/drm/mga_drv.h
+++ b/sys/dev/pci/drm/mga_drv.h
@@ -61,18 +61,13 @@ typedef struct drm_mga_primary_buffer {
u32 high_mark;
} drm_mga_primary_buffer_t;
-typedef struct drm_mga_freelist {
- struct drm_mga_freelist *next;
- struct drm_mga_freelist *prev;
- drm_mga_age_t age;
- struct drm_buf *buf;
-} drm_mga_freelist_t;
-
-typedef struct {
- drm_mga_freelist_t *list_entry;
- int discard;
- int dispatched;
-} drm_mga_buf_priv_t;
+struct mgadrm_buf_priv {
+ TAILQ_ENTRY(mgadrm_buf_priv) link;
+ drm_mga_age_t age;
+ struct drm_buf *buf;
+ int discard;
+ int dispatched;
+};
typedef struct drm_mga_private {
struct device dev;
@@ -87,8 +82,7 @@ typedef struct drm_mga_private {
drm_mga_primary_buffer_t prim;
drm_mga_sarea_t *sarea_priv;
- drm_mga_freelist_t *head;
- drm_mga_freelist_t *tail;
+ TAILQ_HEAD(mga_freelist, mgadrm_buf_priv) freelist;
unsigned int warp_pipe;
unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES];
@@ -372,14 +366,13 @@ do { \
#define AGE_BUFFER( buf_priv ) \
do { \
- drm_mga_freelist_t *entry = (buf_priv)->list_entry; \
if ( (buf_priv)->dispatched ) { \
- entry->age.head = (dev_priv->prim.tail + \
+ buf_priv->age.head = (dev_priv->prim.tail + \
dev_priv->primary->offset); \
- entry->age.wrap = dev_priv->sarea_priv->last_wrap; \
+ buf_priv->age.wrap = dev_priv->sarea_priv->last_wrap; \
} else { \
- entry->age.head = 0; \
- entry->age.wrap = 0; \
+ buf_priv->age.head = 0; \
+ buf_priv->age.wrap = 0; \
} \
} while (0)
diff --git a/sys/dev/pci/drm/mga_state.c b/sys/dev/pci/drm/mga_state.c
index d9ad1f4e5ca..92062e836a8 100644
--- a/sys/dev/pci/drm/mga_state.c
+++ b/sys/dev/pci/drm/mga_state.c
@@ -649,12 +649,12 @@ static void mga_dma_dispatch_swap(struct drm_device * dev)
static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- u32 address = (u32) buf->bus_address;
- u32 length = (u32) buf->used;
- int i = 0;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct mgadrm_buf_priv *buf_priv = buf->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ u_int32_t address = (u_int32_t) buf->bus_address;
+ u_int32_t length = (u_int32_t) buf->used;
+ int i = 0;
DMA_LOCALS;
DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
@@ -697,11 +697,11 @@ static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * bu
static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf,
unsigned int start, unsigned int end)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- u32 address = (u32) buf->bus_address;
- int i = 0;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct mgadrm_buf_priv *buf_priv = buf->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ u_int32_t address = (u_int32_t) buf->bus_address;
+ int i = 0;
DMA_LOCALS;
DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end);
@@ -746,14 +746,15 @@ static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * b
static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf,
unsigned int dstorg, unsigned int length)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
- u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
- u32 y2;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct mgadrm_buf_priv *buf_priv = buf->dev_private;
+ drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
+ u_int32_t srcorg, y2;
DMA_LOCALS;
DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
+ srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
+
y2 = length / 64;
BEGIN_DMA(5);
@@ -906,11 +907,11 @@ int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- struct drm_device_dma *dma = dev->dma;
- struct drm_buf *buf;
- drm_mga_buf_priv_t *buf_priv;
- drm_mga_vertex_t *vertex = data;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf *buf;
+ struct mgadrm_buf_priv *buf_priv;
+ drm_mga_vertex_t *vertex = data;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -941,11 +942,11 @@ int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_pri
int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- struct drm_device_dma *dma = dev->dma;
- struct drm_buf *buf;
- drm_mga_buf_priv_t *buf_priv;
- drm_mga_indices_t *indices = data;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf *buf;
+ struct mgadrm_buf_priv *buf_priv;
+ drm_mga_indices_t *indices = data;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -976,11 +977,11 @@ int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_pr
int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- struct drm_device_dma *dma = dev->dma;
- drm_mga_private_t *dev_priv = dev->dev_private;
- struct drm_buf *buf;
- drm_mga_buf_priv_t *buf_priv;
- drm_mga_iload_t *iload = data;
+ struct drm_device_dma *dma = dev->dma;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ struct drm_buf *buf;
+ struct mgadrm_buf_priv *buf_priv;
+ drm_mga_iload_t *iload = data;
DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);