summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-31 14:10:13 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-31 14:10:13 +0200
commitec8c79b79de6544cc09b5a2c85213a5f30e0d906 (patch)
treea9e4f337533bd02b17efa356b5acef8d7e948a96
parented9de124cc88cee398b7013de6b822bfaa3f397e (diff)
More mapping synchronization.
libdrm validate and fencing functions.
-rw-r--r--libdrm/xf86drm.c340
-rw-r--r--libdrm/xf86mm.h2
-rw-r--r--linux-core/drmP.h1
-rw-r--r--linux-core/drm_bo.c163
-rw-r--r--shared-core/drm.h35
5 files changed, 445 insertions, 96 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index 1763b89a..a99c979d 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -2501,7 +2501,9 @@ int drmResetList(drmBOList *list) {
return drmAdjustListNodes(list);
}
-static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
+static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
+ unsigned long arg0,
+ unsigned long arg1)
{
drmBONode *node;
drmMMListHead *l;
@@ -2510,7 +2512,7 @@ static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
if (l == &list->free) {
node = (drmBONode *) malloc(sizeof(*node));
if (!node) {
- return -ENOMEM;
+ return NULL;
}
list->numCurrent++;
} else {
@@ -2518,45 +2520,51 @@ static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
node = DRMLISTENTRY(drmBONode, l, head);
}
node->buf = item;
+ node->arg0 = arg0;
+ node->arg1 = arg1;
DRMLISTADD(&node->head, &list->list);
list->numOnList++;
- return 0;
+ return node;
}
-int drmCreateBufList(int numTarget, drmBOList *list)
+void *drmBOListIterator(drmBOList *list)
{
- DRMINITLISTHEAD(&list->list);
- DRMINITLISTHEAD(&list->free);
- list->numTarget = numTarget;
- list->numCurrent = 0;
- list->numOnList = 0;
- return drmAdjustListNodes(list);
-}
+ void *ret = list->list.next;
-/*
- * Prepare list for IOCTL submission.
- */
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
-static drm_bo_arg_t *drmPrepareList(drmBOList *list)
+void *drmBOListNext(drmBOList *list, void *iterator)
{
- drmMMListHead *cur, *next;
- drmBONode *first, *curNode, *nextNode;
+ void *ret;
- cur = list->list.next;
- if (cur == &list->list)
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ ret = l->next;
+ if (ret == &list->list)
return NULL;
+ return ret;
+}
- first = DRMLISTENTRY(drmBONode, cur, head);
- curNode = DRMLISTENTRY(drmBONode, cur, head);
+void drmBOListBuf(void *iterator, drmBO **buf)
+{
+ drmBONode *node;
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ *buf = node->buf;
+}
- for (next = cur->next; next != &list->list;
- cur = next, next = cur->next) {
- nextNode = DRMLISTENTRY(drmBONode, next, head);
- curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req);
- curNode = nextNode;
- }
- curNode->bo_arg.req.next = 0;
- return &first->bo_arg;
+
+int drmCreateBufList(int numTarget, drmBOList *list)
+{
+ DRMINITLISTHEAD(&list->list);
+ DRMINITLISTHEAD(&list->free);
+ list->numTarget = numTarget;
+ list->numCurrent = 0;
+ list->numOnList = 0;
+ return drmAdjustListNodes(list);
}
int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
@@ -2567,6 +2575,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
+ arg.handled = 0;
req->mask = mask;
req->hint = hint;
req->size = size;
@@ -2595,7 +2604,8 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
- if (!rep->handled) {
+ if (!arg.handled) {
+ fprintf(stderr, "Not handled\n");
return -EFAULT;
}
if (rep->ret) {
@@ -2607,7 +2617,6 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
buf->size = rep->size;
buf->offset = rep->offset;
buf->mapHandle = rep->arg_handle;
- buf->mapFlags = rep->map_flags;
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
@@ -2623,13 +2632,14 @@ int drmBODestroy(int fd, drmBO *buf)
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
+ arg.handled = 0;
req->handle = buf->handle;
req->op = drm_bo_destroy;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
- if (!rep->handled) {
+ if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
@@ -2647,13 +2657,14 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
+ arg.handled = 0;
req->handle = handle;
req->op = drm_bo_reference;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
- if (!rep->handled) {
+ if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
@@ -2666,7 +2677,6 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
buf->size = rep->size;
buf->offset = rep->offset;
buf->mapHandle = rep->arg_handle;
- buf->mapFlags = rep->map_flags;
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
@@ -2681,13 +2691,14 @@ int drmBOUnReference(int fd, drmBO *buf)
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
+ arg.handled = 0;
req->handle = buf->handle;
req->op = drm_bo_unreference;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
- if (!rep->handled) {
+ if (!arg.handled) {
return -EFAULT;
}
if (rep->ret) {
@@ -2699,10 +2710,13 @@ int drmBOUnReference(int fd, drmBO *buf)
}
/*
- *
+ * Flags can be DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE or'ed together
+ * Hint currently be DRM_BO_HINT_DONT_BLOCK, which makes the
+ * call return an -EBUSY if it can' immediately honor the mapping request.
*/
-int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
+int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
+ void **address)
{
drm_bo_arg_t arg;
@@ -2714,6 +2728,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
* Make sure we have a virtual address of the buffer.
*/
+ fprintf(stderr, "Address is 0x%08x\n", address);
if (!buf->mapVirtual) {
if (buf->mapCount == 0) {
drmAddress virtual;
@@ -2728,8 +2743,11 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
}
}
+ fprintf(stderr, "Address is 0x%08x\n", address);
+ arg.handled = 0;
req->handle = buf->handle;
- req->hint = mapFlags;
+ req->mask = mapFlags;
+ req->hint = mapHint;
req->op = drm_bo_map;
req->next = 0;
@@ -2738,23 +2756,26 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
* This IOCTL synchronizes the buffer.
*/
+ fprintf(stderr, "Address is 0x%08x\n", address);
do {
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
} while (ret != 0 && errno == EAGAIN);
- if (ret || !rep->handled || rep->ret) {
+ fprintf(stderr, "Address is 0x%08x\n", address);
+ if (ret || !arg.handled || rep->ret) {
if (--buf->mapCount == 0) {
(void )drmUnmap(buf->mapVirtual, buf->start + buf->size);
}
}
if (ret)
return ret;
- if (!rep->handled)
+ if (!arg.handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
buf->mapFlags = mapFlags;
+ fprintf(stderr, "Address is 0x%08x\n", address);
*address = buf->virtual;
return 0;
@@ -2764,6 +2785,7 @@ int drmBOUnmap(int fd, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.req;
+ drm_bo_arg_reply_t *rep = &arg.rep;
if (buf->mapCount == 0) {
return -EINVAL;
@@ -2773,6 +2795,7 @@ int drmBOUnmap(int fd, drmBO *buf)
(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
}
+ arg.handled = 0;
req->handle = buf->handle;
req->op = drm_bo_unmap;
req->next = 0;
@@ -2780,10 +2803,247 @@ int drmBOUnmap(int fd, drmBO *buf)
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
return -errno;
}
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+
+ return 0;
+}
+
+int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
+ unsigned hint)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.req;
+ drm_bo_arg_reply_t *rep = &arg.rep;
+ int ret = 0;
+
+ arg.handled = 0;
+ req->handle = buf->handle;
+ req->mask = flags;
+ req->hint = hint;
+ req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
+ req->op = drm_bo_validate;
+ req->next = 0;
+
+ do{
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ } while (ret && errno == -EAGAIN);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+
+ buf->offset = rep->offset;
+ buf->flags = rep->flags;
+ buf->mask = rep->mask;
+ return 0;
+}
+
+
+int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.req;
+ drm_bo_arg_reply_t *rep = &arg.rep;
+ int ret = 0;
+
+ arg.handled = 0;
+ req->handle = buf->handle;
+ req->mask = flags;
+ req->arg_handle = fenceHandle;
+ req->op = drm_bo_validate;
+ req->next = 0;
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
return 0;
}
+
+
+int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
+ unsigned mask,
+ int *newItem)
+{
+ drmBONode *node, *cur;
+ unsigned oldFlags, newFlags;
+ drmMMListHead *l;
+
+ *newItem = 0;
+ cur = NULL;
+
+ mask &= ~DRM_BO_MASK_MEM;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ if (node->buf == buf) {
+ cur = node;
+ break;
+ }
+ }
+ if (!cur) {
+ cur = drmAddListItem(list, buf, flags, mask);
+ if (!cur) {
+ drmMsg("Out of memory creating validate list node.\n");
+ return -ENOMEM;
+ }
+ *newItem = 1;
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ } else {
+ unsigned memFlags = cur->arg0 & DRM_BO_MASK_MEM;
+
+ if (!(memFlags & flags)) {
+ drmMsg("Incompatible memory location requests "
+ "on validate list.\n");
+ return -EINVAL;
+ }
+ if ((cur->arg1 | mask) & (cur->arg0 ^ flags)) {
+ drmMsg("Incompatible buffer flag requests "
+ " on validate list.\n");
+ return -EINVAL;
+ }
+ cur->arg1 |= mask;
+ cur->arg0 = (memFlags & flags) | ((cur->arg0 | flags) & cur->arg1);
+ }
+}
+
+
+int drmBOValidateList(int fd, drmBOList *list)
+{
+
+ drmBONode *node;
+ drmMMListHead *l;
+ drm_bo_arg_t *arg, *first;
+ drm_bo_arg_request_t *req;
+ drm_bo_arg_reply_t *rep;
+ drm_u64_t *prevNext = NULL;
+ drmBO *buf;
+ int ret;
+
+ first = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
+
+ req->next = 0;
+ prevNext = &req->next;
+ arg->handled = 0;
+ req->handle = node->buf->handle;
+ req->op = drm_bo_validate;
+ req->mask = node->arg0;
+ req->hint = 0;
+ req->arg_handle = node->arg1;
+ }
+
+ if (!first)
+ return 0;
+
+ do{
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ } while (ret && errno == -EAGAIN);
+
+ if (ret)
+ return -errno;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ rep = &arg->rep;
+
+ if (!arg->handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+
+ buf = node->buf;
+ buf->offset = rep->offset;
+ buf->flags = rep->flags;
+ buf->mask = rep->mask;
+ }
+
+ return 0;
+}
+
+
+int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
+{
+
+ drmBONode *node;
+ drmMMListHead *l;
+ drm_bo_arg_t *arg, *first;
+ drm_bo_arg_request_t *req;
+ drm_bo_arg_reply_t *rep;
+ drm_u64_t *prevNext = NULL;
+ drmBO *buf;
+ int ret;
+
+ first = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
+
+ req->next = 0;
+ prevNext = &req->next;
+ arg->handled = 0;
+ req->handle = node->buf->handle;
+ req->op = drm_bo_fence;
+ req->mask = node->arg0;
+ req->arg_handle = fenceHandle;
+ }
+
+ if (!first)
+ return 0;
+
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+
+ if (ret)
+ return -errno;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ rep = &arg->rep;
+
+ if (!arg->handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+ }
+
+ return 0;
+}
int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize,
unsigned long ttPOffset, unsigned long ttPSize)
diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h
index 21fed6cf..aaee3c0b 100644
--- a/libdrm/xf86mm.h
+++ b/libdrm/xf86mm.h
@@ -103,6 +103,8 @@ typedef struct _drmBONode {
drmMMListHead head;
drmBO *buf;
drm_bo_arg_t bo_arg;
+ unsigned long arg0;
+ unsigned long arg1;
} drmBONode;
typedef struct _drmBOList {
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index bbf9da0b..fde89c30 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -966,7 +966,6 @@ typedef struct drm_buffer_object{
unsigned long offset;
atomic_t mapped;
- uint32_t map_flags;
uint32_t flags;
uint32_t mask;
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index faa2e007..232120a4 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -256,11 +256,11 @@ static int drm_bo_evict(drm_buffer_object_t * bo, int tt, int no_wait)
int ret = 0;
/*
- * Someone might have taken out the buffer before we took the buffer mutex.
+ * Someone might have modified the buffer before we took the buffer mutex.
*/
mutex_lock(&bo->mutex);
- if (bo->unfenced)
+ if (bo->unfenced || (bo->flags & DRM_BO_FLAG_NO_EVICT))
goto out;
if (tt && !bo->tt)
goto out;
@@ -371,17 +371,46 @@ static int drm_move_local_to_tt(drm_buffer_object_t * bo, int no_wait)
static int drm_bo_new_flags(drm_bo_driver_t * driver,
uint32_t flags, uint32_t new_mask, uint32_t hint,
- int init, uint32_t * n_flags)
+ int init, uint32_t * n_flags,
+ uint32_t *n_mask)
{
- uint32_t new_flags;
+ uint32_t new_flags = 0;
uint32_t new_props;
- if (!(flags & new_mask & DRM_BO_MASK_MEM) || init) {
+ /*
+ * First adjust the mask. Vram is not supported yet.
+ */
- /*
- * We need to move memory. Default preferences are hard-coded
- * here.
- */
+ new_mask &= ~DRM_BO_FLAG_MEM_VRAM;
+
+ if (new_mask & DRM_BO_FLAG_BIND_CACHED) {
+ if (((new_mask & DRM_BO_FLAG_MEM_TT) && !driver->cached_tt) &&
+ ((new_mask & DRM_BO_FLAG_MEM_VRAM) && !driver->cached_vram)) {
+ new_mask &= ~DRM_BO_FLAG_BIND_CACHED;
+ } else {
+ if (!driver->cached_tt)
+ new_flags &= DRM_BO_FLAG_MEM_TT;
+ if (!driver->cached_vram)
+ new_flags &= DRM_BO_FLAG_MEM_VRAM;
+ }
+ }
+
+ if ((new_mask & DRM_BO_FLAG_READ_CACHED) &&
+ !(new_mask & DRM_BO_FLAG_BIND_CACHED)) {
+ if ((new_mask & DRM_BO_FLAG_NO_EVICT) &&
+ !(new_mask & DRM_BO_FLAG_MEM_LOCAL)) {
+ DRM_ERROR("Cannot read cached from a pinned VRAM / TT buffer\n");
+ return -EINVAL;
+ }
+ new_mask &= ~(DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM);
+ }
+
+ /*
+ * Determine new memory location:
+ */
+
+
+ if (!(flags & new_mask & DRM_BO_MASK_MEM) || init) {
new_flags = new_mask & DRM_BO_MASK_MEM;
@@ -421,17 +450,10 @@ static int drm_bo_new_flags(drm_bo_driver_t * driver,
new_flags |= new_mask & ~DRM_BO_MASK_MEM;
- if (new_mask & DRM_BO_FLAG_BIND_CACHED) {
- new_flags |= DRM_BO_FLAG_CACHED;
- if (((new_flags & DRM_BO_FLAG_MEM_TT) && !driver->cached_tt) ||
- ((new_flags & DRM_BO_FLAG_MEM_VRAM)
- && !driver->cached_vram))
- new_flags &= ~DRM_BO_FLAG_CACHED;
- }
-
- if ((new_flags & DRM_BO_FLAG_NO_EVICT) &&
- ((flags ^ new_flags) & DRM_BO_FLAG_CACHED)) {
- if (flags & DRM_BO_FLAG_CACHED) {
+ if (((flags ^ new_flags) & DRM_BO_FLAG_BIND_CACHED) &&
+ (new_flags & DRM_BO_FLAG_NO_EVICT) &&
+ (flags & (DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM))) {
+ if (!(flags & DRM_BO_FLAG_CACHED)) {
DRM_ERROR
("Cannot change caching policy of pinned buffer\n");
return -EINVAL;
@@ -441,6 +463,7 @@ static int drm_bo_new_flags(drm_bo_driver_t * driver,
}
*n_flags = new_flags;
+ *n_mask = new_mask;
return 0;
}
@@ -498,6 +521,12 @@ static int drm_bo_busy(drm_buffer_object_t * bo)
return 0;
}
+
+static int drm_bo_read_cached(drm_buffer_object_t *bo) {
+ return 0;
+}
+
+
/*
* Wait for buffer idle and register that we've mapped the buffer.
* Mapping is registered as a drm_ref_object with type _DRM_REF_TYPE1,
@@ -505,11 +534,12 @@ static int drm_bo_busy(drm_buffer_object_t * bo)
* unregistered.
*/
-static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle, int wait)
+static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
+ uint32_t map_flags, int no_wait)
{
drm_buffer_object_t *bo;
drm_device_t *dev = priv->head->dev;
- int ret;
+ int ret = 0;
mutex_lock(&dev->struct_mutex);
bo = drm_lookup_buffer_object(priv, handle, 1);
@@ -526,14 +556,46 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle, int wait)
* be done without the bo->mutex held.
*/
- if (atomic_inc_and_test(&bo->mapped)) {
- ret = drm_bo_wait(bo, 0, !wait);
- if (ret) {
- atomic_dec(&bo->mapped);
- goto out;
+ while(1) {
+ if (atomic_inc_and_test(&bo->mapped)) {
+ ret = drm_bo_wait(bo, 0, no_wait);
+ if (ret) {
+ atomic_dec(&bo->mapped);
+ goto out;
+ }
+
+ if ((map_flags & DRM_BO_FLAG_READ) &&
+ (bo->flags & DRM_BO_FLAG_READ_CACHED) &&
+ (!(bo->flags & DRM_BO_FLAG_CACHED))) {
+
+ drm_bo_read_cached(bo);
+ }
+ break;
+ } else {
+ if ((map_flags & DRM_BO_FLAG_READ) &&
+ (bo->flags & DRM_BO_FLAG_READ_CACHED) &&
+ (!(bo->flags & DRM_BO_FLAG_CACHED))) {
+
+ /*
+ * We are already mapped with different flags.
+ * need to wait for unmap.
+ */
+
+ if (no_wait) {
+ ret = -EBUSY;
+ goto out;
+ }
+ DRM_WAIT_ON(ret, bo->validate_queue, 3 * DRM_HZ,
+ atomic_read(&bo->mapped) == -1);
+ if (ret == -EINTR)
+ ret = -EAGAIN;
+ if (ret)
+ goto out;
+ continue;
+ }
}
}
-
+
mutex_lock(&dev->struct_mutex);
ret = drm_add_ref_object(priv, &bo->base, _DRM_REF_TYPE1);
mutex_unlock(&dev->struct_mutex);
@@ -729,7 +791,7 @@ static int drm_buffer_object_validate(drm_buffer_object_t * bo,
*/
static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
- uint32_t mask, uint32_t ttm_handle)
+ uint32_t ttm_handle)
{
drm_device_t *dev = bo->dev;
drm_ttm_object_t *to = NULL;
@@ -774,7 +836,7 @@ static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
ttm = drm_ttm_from_object(to);
ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
bo->num_pages,
- mask & DRM_BO_FLAG_BIND_CACHED,
+ bo->mask & DRM_BO_FLAG_BIND_CACHED,
&bo->ttm_region);
if (ret) {
drm_ttm_object_deref_unlocked(dev, to);
@@ -827,17 +889,19 @@ int drm_buffer_object_create(drm_file_t * priv,
bo->buffer_start = buffer_start;
ret = drm_bo_new_flags(dev->driver->bo_driver, bo->flags, mask, hint,
- 1, &new_flags);
+ 1, &new_flags, &bo->mask);
if (ret)
goto out_err;
- ret = drm_bo_add_ttm(priv, bo, mask, ttm_handle);
+ ret = drm_bo_add_ttm(priv, bo, ttm_handle);
if (ret)
goto out_err;
- bo->mask = mask;
-
+#if 0
ret = drm_buffer_object_validate(bo, new_flags, 0,
hint & DRM_BO_HINT_DONT_BLOCK);
+#else
+ bo->flags = new_flags;
+#endif
if (ret)
goto out_err;
@@ -886,7 +950,6 @@ static void drm_bo_fill_rep_arg(const drm_buffer_object_t * bo,
rep->arg_handle = 0;
}
- rep->map_flags = bo->map_flags;
rep->mask = bo->mask;
rep->buffer_start = bo->buffer_start;
}
@@ -902,9 +965,15 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
drm_buffer_object_t *entry;
do {
- DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data,
+ sizeof(arg));
+
+ if (arg.handled) {
+ data = req->next;
+ continue;
+ }
+
rep.ret = 0;
- rep.handled = 0;
switch (req->op) {
case drm_bo_create:{
unsigned long buffer_start = req->buffer_start;
@@ -937,8 +1006,9 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
break;
case drm_bo_map:
rep.ret = drm_buffer_object_map(priv, req->handle,
- !(req->hint &
- DRM_BO_HINT_DONT_BLOCK));
+ req->mask,
+ req->hint &
+ DRM_BO_HINT_DONT_BLOCK);
break;
case drm_bo_destroy:
mutex_lock(&dev->struct_mutex);
@@ -976,16 +1046,25 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
rep.ret = -EINVAL;
}
next = req->next;
- rep.handled = 1;
+
+ /*
+ * A signal interrupted us. Make sure the ioctl is restartable.
+ */
+
+ if (rep.ret == -EAGAIN)
+ return -EAGAIN;
+
+ arg.handled = 1;
arg.rep = rep;
DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
data = next;
} while (data);
return 0;
-
}
+
+
static void drm_bo_clean_mm(drm_file_t * priv)
{
}
@@ -1008,10 +1087,12 @@ int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
switch (arg.req.op) {
case mm_init:
+#if 0
if (bm->initialized) {
DRM_ERROR("Memory manager already initialized\n");
return -EINVAL;
}
+#endif
mutex_init(&bm->mutex);
mutex_lock(&bm->mutex);
bm->has_vram = 0;
diff --git a/shared-core/drm.h b/shared-core/drm.h
index d992621b..9640855c 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -688,22 +688,28 @@ typedef struct drm_ttm_arg {
#define DRM_BO_FLAG_WRITE 0x00000002
#define DRM_BO_FLAG_EXE 0x00000004
+/*
+ * Status flags. Can be read to determine the actual state of a buffer.
+ */
+
/* Pinned buffer. */
-#define DRM_BO_FLAG_NO_EVICT 0x00000010
+#define DRM_BO_FLAG_NO_EVICT 0x00000001
/* Always keep a system memory shadow to a vram buffer */
-#define DRM_BO_FLAG_SHADOW_VRAM 0x00000020
+#define DRM_BO_FLAG_SHADOW_VRAM 0x00000002
/* When mapped for reading, make sure the buffer is cached even
if it means moving the buffer to system memory */
-#define DRM_BO_FLAG_READ_CACHED 0x00000040
-/* The buffer is currently cached */
-#define DRM_BO_FLAG_CACHED 0x00000080
-/* The buffer is shareable with other processes */
-#define DRM_BO_FLAG_SHAREABLE 0x00000100
+#define DRM_BO_FLAG_SHAREABLE 0x00000004
/* When there is a choice between VRAM and TT, prefer VRAM.
The default behaviour is to prefer TT. */
-#define DRM_BO_FLAG_PREFER_VRAM 0x00000200
+#define DRM_BO_FLAG_CACHED 0x00000008
+/* The buffer is shareable with other processes */
+
+
+#define DRM_BO_FLAG_READ_CACHED 0x00001000
+/* The buffer is currently cached */
+#define DRM_BO_FLAG_PREFER_VRAM 0x00002000
/* Bind this buffer cached if the hardware supports it. */
-#define DRM_BO_FLAG_BIND_CACHED 0x00000400
+#define DRM_BO_FLAG_BIND_CACHED 0x00004000
/* Translation table aperture */
#define DRM_BO_FLAG_MEM_TT 0x01000000
@@ -750,21 +756,22 @@ typedef struct drm_bo_arg_request {
typedef struct drm_bo_arg_reply {
int ret;
- int handled;
unsigned handle;
unsigned flags;
drm_u64_t size;
drm_u64_t offset;
unsigned arg_handle;
- unsigned map_flags;
unsigned mask;
drm_u64_t buffer_start;
}drm_bo_arg_reply_t;
-typedef union drm_bo_arg{
- drm_bo_arg_request_t req;
- drm_bo_arg_reply_t rep;
+typedef struct drm_bo_arg{
+ int handled;
+ union {
+ drm_bo_arg_request_t req;
+ drm_bo_arg_reply_t rep;
+ };
} drm_bo_arg_t;
typedef union drm_mm_init_arg{