void drmSetServerInfo(drmServerInfoPtr info)
{
- drm_server_info = info;
+ drm_server_info = info;
}
/**
static int drmDebugPrint(const char *format, va_list ap)
{
- return vfprintf(stderr, format, ap);
+ return vfprintf(stderr, format, ap);
}
static int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint;
void
drmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap))
{
- drm_debug_print = debug_msg_ptr;
+ drm_debug_print = debug_msg_ptr;
}
static void *drmHashTable = NULL; /* Context switch callbacks */
void *drmGetHashTable(void)
{
- return drmHashTable;
+ return drmHashTable;
}
void *drmMalloc(int size)
{
void *pt;
- if ((pt = malloc(size))) memset(pt, 0, size);
+ if ((pt = malloc(size)))
+ memset(pt, 0, size);
return pt;
}
void drmFree(void *pt)
{
- if (pt) free(pt);
+ if (pt)
+ free(pt);
}
/* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
void *value;
drmHashEntry *entry;
- if (!drmHashTable) drmHashTable = drmHashCreate();
+ if (!drmHashTable)
+ drmHashTable = drmHashCreate();
if (drmHashLookup(drmHashTable, key, &value)) {
entry = drmMalloc(sizeof(*entry));
drmMsg("drmOpenDevice: node name is %s\n", buf);
if (drm_server_info) {
- drm_server_info->get_perms(&serv_group, &serv_mode);
- devmode = serv_mode ? serv_mode : DRM_DEV_MODE;
- devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
- group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
+ drm_server_info->get_perms(&serv_group, &serv_mode);
+ devmode = serv_mode ? serv_mode : DRM_DEV_MODE;
+ devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+ group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
}
if (stat(DRM_DIR_NAME, &st)) {
- if (!isroot) return DRM_ERR_NOT_ROOT;
+ if (!isroot)
+ return DRM_ERR_NOT_ROOT;
mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
chown(DRM_DIR_NAME, 0, 0); /* root:root */
chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
/* Check if the device node exists and create it if necessary. */
if (stat(buf, &st)) {
- if (!isroot) return DRM_ERR_NOT_ROOT;
+ if (!isroot)
+ return DRM_ERR_NOT_ROOT;
remove(buf);
mknod(buf, S_IFCHR | devmode, dev);
}
if (drm_server_info) {
- chown(buf, user, group);
- chmod(buf, devmode);
+ chown(buf, user, group);
+ chmod(buf, devmode);
}
fd = open(buf, O_RDWR, 0);
drmMsg("drmOpenDevice: open result is %d, (%s)\n",
fd, fd < 0 ? strerror(errno) : "OK");
- if (fd >= 0) return fd;
+ if (fd >= 0)
+ return fd;
/* Check if the device node is not what we expect it to be, and recreate it
* and try again if so.
*/
if (st.st_rdev != dev) {
- if (!isroot) return DRM_ERR_NOT_ROOT;
+ if (!isroot)
+ return DRM_ERR_NOT_ROOT;
remove(buf);
mknod(buf, S_IFCHR | devmode, dev);
if (drm_server_info) {
- chown(buf, user, group);
- chmod(buf, devmode);
+ chown(buf, user, group);
+ chmod(buf, devmode);
}
}
fd = open(buf, O_RDWR, 0);
drmMsg("drmOpenDevice: open result is %d, (%s)\n",
fd, fd < 0 ? strerror(errno) : "OK");
- if (fd >= 0) return fd;
+ if (fd >= 0)
+ return fd;
drmMsg("drmOpenDevice: Open failed\n");
remove(buf);
int fd;
char buf[64];
- if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
+ if (create)
+ return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
- if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+ if ((fd = open(buf, O_RDWR, 0)) >= 0)
+ return fd;
return -errno;
}
if ((fd = drmOpenMinor(0, 1)) < 0) {
#ifdef __linux__
/* Try proc for backward Linux compatibility */
- if (!access("/proc/dri/0", R_OK)) return 1;
+ if (!access("/proc/dri/0", R_OK))
+ return 1;
#endif
return 0;
}
drmFreeBusid(buf);
return fd;
}
- if (buf) drmFreeBusid(buf);
+ if (buf)
+ drmFreeBusid(buf);
close(fd);
}
}
char * id;
if (!drmAvailable()) {
- if (!drm_server_info)
- return -1;
- else {
- /* try to load the kernel module now */
- if (!drm_server_info->load_module(name)) {
- drmMsg("[drm] failed to load kernel module \"%s\"\n",
- name);
- return -1;
- }
- }
+ if (!drm_server_info) {
+ return -1;
+ }
+ else {
+ /* try to load the kernel module now */
+ if (!drm_server_info->load_module(name)) {
+ drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
+ return -1;
+ }
+ }
}
/*
if (!drmAvailable() && name != NULL && drm_server_info) {
/* try to load the kernel */
if (!drm_server_info->load_module(name)) {
- drmMsg("[drm] failed to load kernel module \"%s\"\n",
- name);
+ drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
return -1;
}
}
if (busid) {
- int fd;
-
- fd = drmOpenByBusid(busid);
+ int fd = drmOpenByBusid(busid);
if (fd >= 0)
return fd;
}
*/
void drmFreeVersion(drmVersionPtr v)
{
- if (!v) return;
+ if (!v)
+ return;
drmFree(v->name);
drmFree(v->date);
drmFree(v->desc);
*/
static void drmFreeKernelVersion(drm_version_t *v)
{
- if (!v) return;
+ if (!v)
+ return;
drmFree(v->name);
drmFree(v->date);
drmFree(v->desc);
u.unique_len = 0;
u.unique = NULL;
- if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
+ return NULL;
u.unique = drmMalloc(u.unique_len + 1);
- if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
+ return NULL;
u.unique[u.unique_len] = '\0';
return u.unique;
drm_auth_t auth;
*magic = 0;
- if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
+ return -errno;
*magic = auth.magic;
return 0;
}
drm_auth_t auth;
auth.magic = magic;
- if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
+ return -errno;
return 0;
}
map.handle = 0;
map.type = type;
map.flags = flags;
- if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno;
- if (handle) *handle = (drm_handle_t)map.handle;
+ if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map))
+ return -errno;
+ if (handle)
+ *handle = (drm_handle_t)map.handle;
return 0;
}
map.handle = (void *)handle;
- if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno;
+ if(ioctl(fd, DRM_IOCTL_RM_MAP, &map))
+ return -errno;
return 0;
}
request.flags = flags;
request.agp_start = agp_offset;
- if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request))
+ return -errno;
return request.count;
}
info.count = 0;
info.list = NULL;
- if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info))
+ return -EINVAL;
- if (!info.count) return -EINVAL;
+ if (!info.count)
+ return -EINVAL;
if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
return -ENOMEM;
request.count = count;
request.list = list;
- if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request))
+ return -errno;
return 0;
}
{
static unsigned long pagesize_mask = 0;
- if (fd < 0) return -EINVAL;
+ if (fd < 0)
+ return -EINVAL;
if (!pagesize_mask)
pagesize_mask = getpagesize() - 1;
size = (size + pagesize_mask) & ~pagesize_mask;
*address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
- if (*address == MAP_FAILED) return -errno;
+ if (*address == MAP_FAILED)
+ return -errno;
return 0;
}
info.count = 0;
info.list = NULL;
- if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL;
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info))
+ return NULL;
if (info.count) {
if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
bufs.count = 0;
bufs.list = NULL;
bufs.virtual = NULL;
- if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
+ return NULL;
- if (!bufs.count) return NULL;
+ if (!bufs.count)
+ return NULL;
if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
return NULL;
res.count = 0;
res.contexts = NULL;
- if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res))
+ return NULL;
- if (!res.count) return NULL;
+ if (!res.count)
+ return NULL;
- if (!(list = drmMalloc(res.count * sizeof(*list)))) return NULL;
+ if (!(list = drmMalloc(res.count * sizeof(*list))))
+ return NULL;
if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
drmFree(list);
return NULL;
}
res.contexts = list;
- if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res))
+ return NULL;
- for (i = 0; i < res.count; i++) retval[i] = list[i].handle;
+ for (i = 0; i < res.count; i++)
+ retval[i] = list[i].handle;
drmFree(list);
*count = res.count;
drm_ctx_t ctx;
ctx.flags = 0; /* Modified with functions below */
- if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
+ return -errno;
*handle = ctx.handle;
return 0;
}
drm_ctx_t ctx;
ctx.handle = context;
- if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
+ return -errno;
return 0;
}
*/
ctx.handle = context;
ctx.flags = 0;
- if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED;
- if (flags & DRM_CONTEXT_2DONLY) ctx.flags |= _DRM_CONTEXT_2DONLY;
- if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno;
+ if (flags & DRM_CONTEXT_PRESERVED)
+ ctx.flags |= _DRM_CONTEXT_PRESERVED;
+ if (flags & DRM_CONTEXT_2DONLY)
+ ctx.flags |= _DRM_CONTEXT_2DONLY;
+ if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
+ return -errno;
return 0;
}
drm_ctx_t ctx;
ctx.handle = context;
- if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx))
+ return -errno;
*flags = 0;
- if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED;
- if (ctx.flags & _DRM_CONTEXT_2DONLY) *flags |= DRM_CONTEXT_2DONLY;
+ if (ctx.flags & _DRM_CONTEXT_PRESERVED)
+ *flags |= DRM_CONTEXT_PRESERVED;
+ if (ctx.flags & _DRM_CONTEXT_2DONLY)
+ *flags |= DRM_CONTEXT_2DONLY;
return 0;
}
{
drm_ctx_t ctx;
ctx.handle = handle;
- if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx))
+ return -errno;
return 0;
}
int drmCreateDrawable(int fd, drm_drawable_t *handle)
{
drm_draw_t draw;
- if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
+ return -errno;
*handle = draw.handle;
return 0;
}
{
drm_draw_t draw;
draw.handle = handle;
- if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw))
+ return -errno;
return 0;
}
update.num = num;
update.data = (unsigned long long)(unsigned long)data;
- if (ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
+ return -errno;
return 0;
}
*/
int drmAgpAcquire(int fd)
{
- if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
+ return -errno;
return 0;
}
*/
int drmAgpRelease(int fd)
{
- if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
+ return -errno;
return 0;
}
drm_agp_mode_t m;
m.mode = mode;
- if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
+ return -errno;
return 0;
}
b.size = size;
b.handle = 0;
b.type = type;
- if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno;
- if (address != 0UL) *address = b.physical;
+ if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
+ return -errno;
+ if (address != 0UL)
+ *address = b.physical;
*handle = b.handle;
return 0;
}
b.size = 0;
b.handle = handle;
- if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b))
+ return -errno;
return 0;
}
b.handle = handle;
b.offset = offset;
- if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b))
+ return -errno;
return 0;
}
b.handle = handle;
b.offset = 0;
- if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
+ return -errno;
return 0;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return -errno;
return i.agp_version_major;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return -errno;
return i.agp_version_minor;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.mode;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.aperture_base;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.aperture_size;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.memory_used;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.memory_allowed;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.id_vendor;
}
{
drm_agp_info_t i;
- if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+ return 0;
return i.id_device;
}
*handle = 0;
sg.size = size;
sg.handle = 0;
- if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
+ return -errno;
*handle = sg.handle;
return 0;
}
sg.size = 0;
sg.handle = handle;
- if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg))
+ return -errno;
return 0;
}
int drmError(int err, const char *label)
{
switch (err) {
- case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label); break;
- case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label); break;
- case DRM_ERR_NOT_ROOT: fprintf(stderr, "%s: not root\n", label); break;
- case DRM_ERR_INVALID: fprintf(stderr, "%s: invalid args\n", label);break;
+ case DRM_ERR_NO_DEVICE:
+ fprintf(stderr, "%s: no device\n", label);
+ break;
+ case DRM_ERR_NO_ACCESS:
+ fprintf(stderr, "%s: no access\n", label);
+ break;
+ case DRM_ERR_NOT_ROOT:
+ fprintf(stderr, "%s: not root\n", label);
+ break;
+ case DRM_ERR_INVALID:
+ fprintf(stderr, "%s: invalid args\n", label);
+ break;
default:
- if (err < 0) err = -err;
+ if (err < 0)
+ err = -err;
fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
break;
}
ctl.func = DRM_INST_HANDLER;
ctl.irq = irq;
- if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl))
+ return -errno;
return 0;
}
ctl.func = DRM_UNINST_HANDLER;
ctl.irq = 0;
- if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl))
+ return -errno;
return 0;
}
if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
- if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_FINISH, &lock))
+ return -errno;
return 0;
}
p.busnum = busnum;
p.devnum = devnum;
p.funcnum = funcnum;
- if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
+ return -errno;
return p.irq;
}
drmHashEntry *entry = drmGetEntry(fd);
void *value;
- if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
+ if (drmHashLookup(entry->tagTable, context, &value))
+ return NULL;
return value;
}
map.ctx_id = ctx_id;
map.handle = (void *)handle;
- if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
+ return -errno;
return 0;
}
map.ctx_id = ctx_id;
- if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno;
- if (handle) *handle = (drm_handle_t)map.handle;
+ if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
+ return -errno;
+ if (handle)
+ *handle = (drm_handle_t)map.handle;
return 0;
}
drm_map_t map;
map.offset = idx;
- if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_GET_MAP, &map))
+ return -errno;
*offset = map.offset;
*size = map.size;
*type = map.type;
drm_client_t client;
client.idx = idx;
- if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client))
+ return -errno;
*auth = client.auth;
*pid = client.pid;
*uid = client.uid;
drm_stats_t s;
int i;
- if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
+ if (ioctl(fd, DRM_IOCTL_GET_STATS, &s))
+ return -errno;
stats->count = 0;
memset(stats, 0, sizeof(*stats));
arg.flags = flags;
arg.type = type;
arg.class = class;
- arg.op = drm_fence_create;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ if (ioctl(fd, DRM_IOCTL_FENCE_CREATE, &arg))
return -errno;
fence->handle = arg.handle;
fence->class = arg.class;
int drmFenceBuffers(int fd, unsigned flags, drmFence *fence)
{
drm_fence_arg_t arg;
-
+
memset(&arg, 0, sizeof(arg));
arg.flags = flags;
- arg.op = drm_fence_buffers;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_BUFFERS, &arg))
return -errno;
fence->handle = arg.handle;
fence->class = arg.class;
int drmFenceDestroy(int fd, const drmFence *fence)
{
drm_fence_arg_t arg;
-
+
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
- arg.op = drm_fence_destroy;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_DESTROY, &arg))
return -errno;
return 0;
}
int drmFenceReference(int fd, unsigned handle, drmFence *fence)
{
drm_fence_arg_t arg;
-
+
memset(&arg, 0, sizeof(arg));
arg.handle = handle;
- arg.op = drm_fence_reference;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_REFERENCE, &arg))
return -errno;
fence->handle = arg.handle;
fence->class = arg.class;
int drmFenceUnreference(int fd, const drmFence *fence)
{
drm_fence_arg_t arg;
-
+
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
- arg.op = drm_fence_unreference;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_UNREFERENCE, &arg))
return -errno;
return 0;
}
int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type)
{
drm_fence_arg_t arg;
-
+
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
arg.type = flush_type;
- arg.op = drm_fence_flush;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_FLUSH, &arg))
return -errno;
fence->class = arg.class;
fence->type = arg.type;
int drmFenceUpdate(int fd, drmFence *fence)
{
- drm_fence_arg_t arg;
-
+ drm_fence_arg_t arg;
+
memset(&arg, 0, sizeof(arg));
arg.handle = fence->handle;
- arg.op = drm_fence_signaled;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_SIGNALED, &arg))
return -errno;
fence->class = arg.class;
fence->type = arg.type;
int drmFenceSignaled(int fd, drmFence *fence, unsigned fenceType,
int *signaled)
{
- int
- ret;
-
if ((fence->flags & DRM_FENCE_FLAG_SHAREABLE) ||
((fenceType & fence->signaled) != fenceType)) {
-
- ret = drmFenceFlush(fd, fence, fenceType);
+ int ret = drmFenceFlush(fd, fence, fenceType);
if (ret)
return ret;
}
arg.flags = flags;
arg.handle = fence->handle;
arg.type = emit_type;
- arg.op = drm_fence_emit;
- if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+
+ if (ioctl(fd, DRM_IOCTL_FENCE_EMIT, &arg))
return -errno;
fence->class = arg.class;
fence->type = arg.type;
arg.handle = fence->handle;
arg.type = flush_type;
arg.flags = flags;
- arg.op = drm_fence_wait;
+
do {
- ret = ioctl(fd, DRM_IOCTL_FENCE, &arg);
+ ret = ioctl(fd, DRM_IOCTL_FENCE_WAIT, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret)
}
}
- int drmBOResetList(drmBOList *list) {
-
+ int drmBOResetList(drmBOList *list)
+ {
drmMMListHead *l;
int ret;
return ret;
l = list->list.next;
- while(l != &list->list) {
+ while (l != &list->list) {
DRMLISTDEL(l);
DRMLISTADD(l, &list->free);
list->numOnList--;
return NULL;
}
list->numCurrent++;
- } else {
+ }
+ else {
DRMLISTDEL(l);
node = DRMLISTENTRY(drmBONode, l, head);
}
drmBONode *node;
drmMMListHead *l = (drmMMListHead *) iterator;
node = DRMLISTENTRY(drmBONode, l, head);
-
return node->buf;
}
return drmAdjustListNodes(list);
}
- static void drmBOCopyReply(struct drm_bo_info_rep *rep,
- drmBO *buf)
-static void drmBOCopyReply(const drm_bo_arg_reply_t *rep, drmBO *buf)
++static void drmBOCopyReply(const struct drm_bo_info_rep *rep, drmBO *buf)
{
buf->handle = rep->handle;
buf->flags = rep->flags;
buf->fenceFlags = rep->fence_flags;
buf->replyFlags = rep->rep_flags;
buf->pageAlignment = rep->page_alignment;
+ buf->tileInfo = rep->tile_info;
+ buf->hwTileStride = rep->hw_tile_stride;
+ buf->desiredTileStride = rep->desired_tile_stride;
}
-int drmBOCreate(int fd, unsigned long start, unsigned long size,
- unsigned pageAlignment, void *user_buffer, drm_bo_type_t type,
- unsigned mask,
+
+
+int drmBOCreate(int fd, unsigned long start, unsigned long size,
+ unsigned pageAlignment, void *user_buffer, drm_bo_type_t type,
+ drm_u64_t mask,
unsigned hint, drmBO *buf)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_create_arg arg;
+ struct drm_bo_create_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
int ret;
memset(buf, 0, sizeof(*buf));
default:
return -EINVAL;
}
- req->op = drm_bo_create;
do {
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ ret = ioctl(fd, DRM_IOCTL_BO_CREATE, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret)
return -errno;
- if (!arg.handled) {
- return -EFAULT;
- }
- if (rep->ret) {
- fprintf(stderr, "Error %d\n", rep->ret);
- return rep->ret;
- }
drmBOCopyReply(rep, buf);
buf->mapVirtual = NULL;
int drmBODestroy(int fd, drmBO *buf)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_handle_arg arg;
if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
}
memset(&arg, 0, sizeof(arg));
- req->handle = buf->handle;
- req->op = drm_bo_destroy;
+ arg.handle = buf->handle;
- if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+ if (ioctl(fd, DRM_IOCTL_BO_DESTROY, &arg))
return -errno;
- if (!arg.handled) {
- return -EFAULT;
- }
- if (rep->ret) {
- return rep->ret;
- }
buf->handle = 0;
return 0;
}
-
+
int drmBOReference(int fd, unsigned handle, drmBO *buf)
{
-
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_reference_info_arg arg;
+ struct drm_bo_handle_arg *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
memset(&arg, 0, sizeof(arg));
req->handle = handle;
- req->op = drm_bo_reference;
- if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+ if (ioctl(fd, DRM_IOCTL_BO_REFERENCE, &arg))
return -errno;
- if (!arg.handled) {
- return -EFAULT;
- }
- if (rep->ret) {
- return rep->ret;
- }
drmBOCopyReply(rep, buf);
buf->type = drm_bo_type_dc;
int drmBOUnReference(int fd, drmBO *buf)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_handle_arg arg;
if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
(void) munmap(buf->mapVirtual, buf->start + buf->size);
}
memset(&arg, 0, sizeof(arg));
- req->handle = buf->handle;
- req->op = drm_bo_unreference;
+ arg.handle = buf->handle;
- if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+ if (ioctl(fd, DRM_IOCTL_BO_UNREFERENCE, &arg))
return -errno;
- if (!arg.handled) {
- return -EFAULT;
- }
- if (rep->ret) {
- return rep->ret;
- }
buf->handle = 0;
return 0;
}
+
/*
* 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
int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
void **address)
{
-
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_map_wait_idle_arg arg;
+ struct drm_bo_info_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
int ret = 0;
/*
req->handle = buf->handle;
req->mask = mapFlags;
req->hint = mapHint;
- req->op = drm_bo_map;
/*
* May hang if the buffer object is busy.
*/
do {
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ ret = ioctl(fd, DRM_IOCTL_BO_MAP, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret)
return -errno;
- if (!arg.handled)
- return -EFAULT;
- if (rep->ret)
- return rep->ret;
drmBOCopyReply(rep, buf);
buf->mapFlags = mapFlags;
return 0;
}
+
int drmBOUnmap(int fd, drmBO *buf)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_handle_arg arg;
-
+
memset(&arg, 0, sizeof(arg));
- req->handle = buf->handle;
- req->op = drm_bo_unmap;
+ arg.handle = buf->handle;
- if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
+ if (ioctl(fd, DRM_IOCTL_BO_UNMAP, &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,
+
+int drmBOValidate(int fd, drmBO *buf,
+ drm_u64_t flags, drm_u64_t mask,
unsigned hint)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_op_arg arg;
+ struct drm_bo_op_req *req = &arg.d.req;
+ struct drm_bo_arg_rep *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
- req->handle = buf->handle;
- req->mask = flags;
- req->hint = hint;
- req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
+ req->bo_req.handle = buf->handle;
+ req->bo_req.flags = flags;
+ req->bo_req.mask = mask;
+ req->bo_req.hint = hint;
+ req->bo_req.fence_class = 0; /* Backwards compatibility. */
req->op = drm_bo_validate;
do{
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg);
} while (ret && errno == EAGAIN);
-
+
if (ret)
return -errno;
if (!arg.handled)
if (rep->ret)
return rep->ret;
- drmBOCopyReply(rep, buf);
+ drmBOCopyReply(&rep->bo_info, buf);
return 0;
}
int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_op_arg arg;
+ struct drm_bo_op_req *req = &arg.d.req;
+ struct drm_bo_arg_rep *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
- req->handle = buf->handle;
- req->mask = flags;
+ req->bo_req.handle = buf->handle;
+ req->bo_req.flags = flags;
req->arg_handle = fenceHandle;
req->op = drm_bo_fence;
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
-
+ ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg);
-
if (ret)
return -errno;
if (!arg.handled)
int drmBOInfo(int fd, drmBO *buf)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_reference_info_arg arg;
+ struct drm_bo_handle_arg *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
- req->op = drm_bo_info;
-
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
-
+ ret = ioctl(fd, DRM_IOCTL_BO_INFO, &arg);
if (ret)
return -errno;
- if (!arg.handled)
- return -EFAULT;
- if (rep->ret)
- return rep->ret;
+
drmBOCopyReply(rep, buf);
return 0;
}
int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint)
{
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t *rep = &arg.d.rep;
+ struct drm_bo_map_wait_idle_arg arg;
+ struct drm_bo_info_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
int ret = 0;
if ((buf->flags & DRM_BO_FLAG_SHAREABLE) ||
(buf->replyFlags & DRM_BO_REP_BUSY)) {
memset(&arg, 0, sizeof(arg));
req->handle = buf->handle;
- req->op = drm_bo_wait_idle;
req->hint = hint;
do {
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ ret = ioctl(fd, DRM_IOCTL_BO_WAIT_IDLE, &arg);
} while (ret && errno == EAGAIN);
if (ret)
return -errno;
- if (!arg.handled)
- return -EFAULT;
- if (rep->ret)
- return rep->ret;
+
drmBOCopyReply(rep, buf);
}
return 0;
!(buf->replyFlags & DRM_BO_REP_BUSY)) {
*busy = 0;
return 0;
- } else {
+ }
+ else {
int ret = drmBOInfo(fd, buf);
if (ret)
return ret;
}
}
-
int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
unsigned mask,
int *newItem)
*newItem = 1;
cur->arg0 = flags;
cur->arg1 = mask;
- } else {
+ }
+ else {
unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
unsigned memFlags = cur->arg0 & flags & memMask;
int drmBOValidateList(int fd, drmBOList *list)
{
-
- drmBONode *node;
- drmMMListHead *l;
- struct drm_bo_op_arg *arg, *first;
- struct drm_bo_op_req *req;
- struct drm_bo_arg_rep *rep;
- drm_u64_t *prevNext = NULL;
- drmBO *buf;
- int ret;
+ drmBONode *node;
+ drmMMListHead *l;
- drm_bo_arg_t *arg, *first;
- drm_bo_arg_request_t *req;
- drm_bo_arg_reply_t *rep;
++ struct drm_bo_op_arg *arg, *first;
++ struct drm_bo_op_req *req;
++ struct drm_bo_arg_rep *rep;
+ drm_u64_t *prevNext = NULL;
+ drmBO *buf;
+ int ret;
- first = NULL;
+ first = NULL;
- for (l = list->list.next; l != &list->list; l = l->next) {
- node = DRMLISTENTRY(drmBONode, l, head);
+ for (l = list->list.next; l != &list->list; l = l->next) {
- node = DRMLISTENTRY(drmBONode, l, head);
++ node = DRMLISTENTRY(drmBONode, l, head);
- arg = &node->bo_arg;
- req = &arg->d.req;
- arg = &node->bo_arg;
- req = &arg->d.req;
++ arg = &node->bo_arg;
++ req = &arg->d.req;
- if (!first)
- first = arg;
- if (!first)
- first = arg;
++ if (!first)
++ first = arg;
- if (prevNext)
- *prevNext = (unsigned long) arg;
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
- memset(arg, 0, sizeof(*arg));
- prevNext = &arg->next;
- req->bo_req.handle = node->buf->handle;
- req->op = drm_bo_validate;
- req->bo_req.flags = node->arg0;
- req->bo_req.hint = 0;
- req->bo_req.mask = node->arg1;
- req->bo_req.fence_class = 0; /* Backwards compat. */
- }
+ memset(arg, 0, sizeof(*arg));
+ prevNext = &arg->next;
- req->handle = node->buf->handle;
++ req->bo_req.handle = node->buf->handle;
+ req->op = drm_bo_validate;
- req->mask = node->arg0;
- req->hint = 0;
- req->arg_handle = node->arg1;
++ req->bo_req.flags = node->arg0;
++ req->bo_req.hint = 0;
++ req->bo_req.mask = node->arg1;
++ req->bo_req.fence_class = 0; /* Backwards compat. */
+ }
-
- if (!first)
+
- if (!first)
- return 0;
++ if (!first)
+ return 0;
- do{
- ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
- } while (ret && errno == EAGAIN);
- do {
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
++ do{
++ ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
+ } while (ret && errno == EAGAIN);
-
+ if (ret)
+ return -errno;
- 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->d.rep;
+
-
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ arg = &node->bo_arg;
+ rep = &arg->d.rep;
- if (!arg->handled) {
- drmMsg("Unhandled request\n");
- return -EFAULT;
- }
- if (rep->ret)
- return rep->ret;
-
- buf = node->buf;
- drmBOCopyReply(&rep->bo_info, buf);
- }
-
- return 0;
+
-
+ if (!arg->handled) {
+ drmMsg("Unhandled request\n");
+ return -EFAULT;
+ }
+ if (rep->ret)
+ return rep->ret;
- drmBOCopyReply(rep, buf);
++
+ buf = node->buf;
-
++ drmBOCopyReply(&rep->bo_info, buf);
+ }
++
+ return 0;
}
--
int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
{
-
- drmBONode *node;
- drmMMListHead *l;
- struct drm_bo_op_arg *arg, *first;
- struct drm_bo_op_req *req;
- struct drm_bo_arg_rep *rep;
- drm_u64_t *prevNext = NULL;
- drmBO *buf;
- unsigned fence_flags;
- 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->d.req;
-
- if (!first)
- first = arg;
-
- if (prevNext)
- *prevNext = (unsigned long) arg;
-
- memset(arg, 0, sizeof(*arg));
- prevNext = &arg->next;
- req->bo_req.handle = node->buf->handle;
- req->op = drm_bo_fence;
- req->bo_req.mask = node->arg0;
- req->arg_handle = fenceHandle;
- }
+ drmBONode *node;
+ drmMMListHead *l;
- drm_bo_arg_t *arg, *first;
- drm_bo_arg_request_t *req;
- drm_bo_arg_reply_t *rep;
++ struct drm_bo_op_arg *arg, *first;
++ struct drm_bo_op_req *req;
++ struct drm_bo_arg_rep *rep;
+ drm_u64_t *prevNext = NULL;
+ drmBO *buf;
+ unsigned fence_flags;
+ int ret;
+
+ first = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
- node = DRMLISTENTRY(drmBONode, l, head);
-
++ node = DRMLISTENTRY(drmBONode, l, head);
++
+ arg = &node->bo_arg;
+ req = &arg->d.req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
+
+ memset(arg, 0, sizeof(*arg));
+ prevNext = &arg->next;
- req->handle = node->buf->handle;
++ req->bo_req.handle = node->buf->handle;
+ req->op = drm_bo_fence;
- req->mask = node->arg0;
++ req->bo_req.mask = node->arg0;
+ req->arg_handle = fenceHandle;
+ }
- if (!first)
- return 0;
+ if (!first)
+ return 0;
- ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
- ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
++ ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
- if (ret)
- return -errno;
+ if (ret)
+ return -errno;
- for (l = list->list.next; l != &list->list; l = l->next) {
- node = DRMLISTENTRY(drmBONode, l, head);
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
- arg = &node->bo_arg;
- rep = &arg->d.rep;
-
- if (!arg->handled)
- return -EFAULT;
- if (rep->ret)
- return rep->ret;
- drmBOCopyReply(&rep->bo_info, node->buf);
- }
+ arg = &node->bo_arg;
+ rep = &arg->d.rep;
++
+ if (!arg->handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
- drmBOCopyReply(rep, node->buf);
++ drmBOCopyReply(&rep->bo_info, node->buf);
+ }
- return 0;
+ return 0;
}
int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
unsigned memType)
{
- drm_mm_init_arg_t arg;
+ struct drm_mm_init_arg arg;
-
+
memset(&arg, 0, sizeof(arg));
- arg.req.op = mm_init;
- arg.req.p_offset = pOffset;
- arg.req.p_size = pSize;
- arg.req.mem_type = memType;
+
+ arg.magic = DRM_BO_INIT_MAGIC;
+ arg.major = DRM_BO_INIT_MAJOR;
+ arg.minor = DRM_BO_INIT_MINOR;
+ arg.p_offset = pOffset;
+ arg.p_size = pSize;
+ arg.mem_type = memType;
if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
return -errno;
-
return 0;
}
int drmMMTakedown(int fd, unsigned memType)
{
- drm_mm_init_arg_t arg;
+ struct drm_mm_type_arg arg;
memset(&arg, 0, sizeof(arg));
- arg.req.op = mm_takedown;
- arg.req.mem_type = memType;
+ arg.mem_type = memType;
- if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
+ if (ioctl(fd, DRM_IOCTL_MM_TAKEDOWN, &arg))
return -errno;
-
return 0;
}
int drmMMLock(int fd, unsigned memType)
{
- drm_mm_init_arg_t arg;
+ struct drm_mm_type_arg arg;
int ret;
memset(&arg, 0, sizeof(arg));
- arg.req.op = mm_lock;
- arg.req.mem_type = memType;
+ arg.mem_type = memType;
do{
- ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
+ ret = ioctl(fd, DRM_IOCTL_MM_LOCK, &arg);
} while (ret && errno == EAGAIN);
-
- return -errno;
+
+ return (ret) ? -errno : 0;
}
int drmMMUnlock(int fd, unsigned memType)
{
- drm_mm_init_arg_t arg;
+ struct drm_mm_type_arg arg;
int ret;
memset(&arg, 0, sizeof(arg));
- arg.req.op = mm_unlock;
- arg.req.mem_type = memType;
+
+ arg.mem_type = memType;
do{
- ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
+ ret = ioctl(fd, DRM_IOCTL_MM_UNLOCK, &arg);
} while (ret && errno == EAGAIN);
-
- return -errno;
+
+ return (ret) ? -errno : 0;
}
#define DRM_MAX_FDS 16
static struct {
- char *BusID;
- int fd;
- int refcount;
+ char *BusID;
+ int fd;
+ int refcount;
} connection[DRM_MAX_FDS];
static int nr_fds = 0;
const char *BusID,
int *newlyopened)
{
- int i;
- int fd;
+ int i;
+ int fd;
- for (i = 0; i < nr_fds; i++)
- if (strcmp(BusID, connection[i].BusID) == 0) {
- connection[i].refcount++;
- *newlyopened = 0;
- return connection[i].fd;
- }
-
- fd = drmOpen(unused, BusID);
- if (fd <= 0 || nr_fds == DRM_MAX_FDS)
- return fd;
+ for (i = 0; i < nr_fds; i++)
+ if (strcmp(BusID, connection[i].BusID) == 0) {
+ connection[i].refcount++;
+ *newlyopened = 0;
+ return connection[i].fd;
+ }
+
+ fd = drmOpen(unused, BusID);
+ if (fd <= 0 || nr_fds == DRM_MAX_FDS)
+ return fd;
- connection[nr_fds].BusID = strdup(BusID);
- connection[nr_fds].fd = fd;
- connection[nr_fds].refcount = 1;
- *newlyopened = 1;
+ connection[nr_fds].BusID = strdup(BusID);
+ connection[nr_fds].fd = fd;
+ connection[nr_fds].refcount = 1;
+ *newlyopened = 1;
- if (0)
- fprintf(stderr, "saved connection %d for %s %d\n",
- nr_fds, connection[nr_fds].BusID,
- strcmp(BusID, connection[nr_fds].BusID));
+ if (0)
+ fprintf(stderr, "saved connection %d for %s %d\n",
+ nr_fds, connection[nr_fds].BusID,
+ strcmp(BusID, connection[nr_fds].BusID));
- nr_fds++;
+ nr_fds++;
- return fd;
+ return fd;
}
void drmCloseOnce(int fd)
{
- int i;
+ int i;
- for (i = 0; i < nr_fds; i++) {
- if (fd == connection[i].fd) {
- if (--connection[i].refcount == 0) {
- drmClose(connection[i].fd);
- free(connection[i].BusID);
+ for (i = 0; i < nr_fds; i++) {
+ if (fd == connection[i].fd) {
+ if (--connection[i].refcount == 0) {
+ drmClose(connection[i].fd);
+ free(connection[i].BusID);
- if (i < --nr_fds)
- connection[i] = connection[nr_fds];
+ if (i < --nr_fds)
+ connection[i] = connection[nr_fds];
- return;
- }
- }
- }
+ return;
+ }
+ }
+ }
}
(__item)->next = (__item); \
} while (0)
- #define DRMLISTADD(__item, __list) \
+ #define DRMLISTADD(__item, __list) \
do { \
(__item)->prev = (__list); \
(__item)->next = (__list)->next; \
#define DRMLISTENTRY(__type, __item, __field) \
((__type *)(((char *) (__item)) - offsetof(__type, __field)))
- typedef struct _drmFence{
- unsigned handle;
- int class;
- unsigned type;
- unsigned flags;
- unsigned signaled;
- unsigned pad[4]; /* for future expansion */
+ typedef struct _drmFence
+ {
+ unsigned handle;
+ int class;
+ unsigned type;
+ unsigned flags;
+ unsigned signaled;
+ unsigned pad[4]; /* for future expansion */
} drmFence;
- typedef struct _drmBO{
+ typedef struct _drmBO
+ {
drm_bo_type_t type;
unsigned handle;
drm_u64_t mapHandle;
- unsigned flags;
- unsigned mask;
+ drm_u64_t flags;
+ drm_u64_t mask;
unsigned mapFlags;
unsigned long size;
unsigned long offset;
unsigned replyFlags;
unsigned fenceFlags;
unsigned pageAlignment;
+ unsigned tileInfo;
+ unsigned hwTileStride;
+ unsigned desiredTileStride;
void *virtual;
void *mapVirtual;
int mapCount;
unsigned pad[8]; /* for future expansion */
} drmBO;
-
- typedef struct _drmBONode {
+ typedef struct _drmBONode
+ {
drmMMListHead head;
drmBO *buf;
- drm_bo_arg_t bo_arg;
+ struct drm_bo_op_arg bo_arg;
unsigned long arg0;
unsigned long arg1;
} drmBONode;
drmMMListHead free;
} drmBOList;
- /* Fencing */
-
- extern int drmFenceCreate(int fd, unsigned flags, int class,
- unsigned type,
- drmFence *fence);
- extern int drmFenceDestroy(int fd, const drmFence *fence);
- extern int drmFenceReference(int fd, unsigned handle, drmFence *fence);
- extern int drmFenceUnreference(int fd, const drmFence *fence);
- extern int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
- extern int drmFenceSignaled(int fd, drmFence *fence,
- unsigned fenceType, int *signaled);
- extern int drmFenceWait(int fd, unsigned flags, drmFence *fence,
- unsigned flush_type);
- extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence,
- unsigned emit_type);
- extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
+
+ /*
+ * Fence functions.
+ */
+
+ extern int drmFenceCreate(int fd, unsigned flags, int class,
+ unsigned type, drmFence *fence);
+ extern int drmFenceDestroy(int fd, const drmFence *fence);
+ extern int drmFenceReference(int fd, unsigned handle, drmFence *fence);
+ extern int drmFenceUnreference(int fd, const drmFence *fence);
+ extern int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
+ extern int drmFenceSignaled(int fd, drmFence *fence,
+ unsigned fenceType, int *signaled);
+ extern int drmFenceWait(int fd, unsigned flags, drmFence *fence,
+ unsigned flush_type);
+ extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence,
+ unsigned emit_type);
+ extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
/*
*/
extern int drmBOCreate(int fd, unsigned long start, unsigned long size,
- unsigned pageAlignment,void *user_buffer,
- drm_bo_type_t type, unsigned mask,
+ unsigned pageAlignment,void *user_buffer,
+ drm_bo_type_t type, drm_u64_t mask,
unsigned hint, drmBO *buf);
extern int drmBODestroy(int fd, drmBO *buf);
extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
extern int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
void **address);
extern int drmBOUnmap(int fd, drmBO *buf);
-extern int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
- unsigned hint);
+extern int drmBOValidate(int fd, drmBO *buf, drm_u64_t flags,
+ drm_u64_t mask, unsigned hint);
+
extern int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle);
extern int drmBOInfo(int fd, drmBO *buf);
extern int drmBOBusy(int fd, drmBO *buf, int *busy);
-
-extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
+extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
unsigned mask,
int *newItem);
extern int drmBOValidateList(int fd, drmBOList *list);
{
drm_mem_type_manager_t *man;
+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
+ DRM_ASSERT_LOCKED(&bo->mutex);
+
man = &bo->dev->bm.man[bo->pinned_mem_type];
list_add_tail(&bo->pinned_lru, &man->pinned);
}
{
drm_mem_type_manager_t *man;
+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
+
if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))
|| bo->mem.mem_type != bo->pinned_mem_type) {
man = &bo->dev->bm.man[bo->mem.mem_type];
int ret = 0;
bo->ttm = NULL;
+ DRM_ASSERT_LOCKED(&bo->mutex);
+
switch (bo->type) {
case drm_bo_type_dc:
bo->ttm = drm_ttm_init(dev, bo->mem.num_pages << PAGE_SHIFT);
if ((bo->mem.mem_type == DRM_BO_MEM_LOCAL) && bo->ttm == NULL) {
drm_bo_mem_reg_t *old_mem = &bo->mem;
- uint32_t save_flags = old_mem->flags;
- uint32_t save_mask = old_mem->mask;
+ uint64_t save_flags = old_mem->flags;
+ uint64_t save_mask = old_mem->mask;
*old_mem = *mem;
mem->mm_node = NULL;
int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
int no_wait)
{
-
- drm_fence_object_t *fence = bo->fence;
int ret;
- if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ DRM_ASSERT_LOCKED(&bo->mutex);
+
+ if (bo->fence) {
+ if (drm_fence_object_signaled(bo->fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
if (no_wait) {
return -EBUSY;
}
ret =
- drm_fence_object_wait(dev, fence, lazy, ignore_signals,
+ drm_fence_object_wait(bo->fence, lazy, ignore_signals,
bo->fence_type);
if (ret)
return ret;
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
-
+ drm_fence_usage_deref_unlocked(&bo->fence);
}
return 0;
}
"Evicting buffer.\n");
}
}
- if (bo->fence) {
- drm_fence_usage_deref_unlocked(dev, bo->fence);
- bo->fence = NULL;
- }
+ if (bo->fence)
+ drm_fence_usage_deref_unlocked(&bo->fence);
}
return 0;
}
drm_device_t *dev = bo->dev;
drm_buffer_manager_t *bm = &dev->bm;
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
+
atomic_inc(&bo->usage);
mutex_unlock(&dev->struct_mutex);
mutex_lock(&bo->mutex);
DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
- if (bo->fence && drm_fence_object_signaled(bo->fence, bo->fence_type)) {
- drm_fence_usage_deref_locked(dev, bo->fence);
- bo->fence = NULL;
- }
+ if (bo->fence && drm_fence_object_signaled(bo->fence,
+ bo->fence_type, 0))
+ drm_fence_usage_deref_unlocked(&bo->fence);
if (bo->fence && remove_all)
(void)drm_bo_expire_fence(bo, 0);
}
if (list_empty(&bo->ddestroy)) {
- drm_fence_object_flush(dev, bo->fence, bo->fence_type);
+ drm_fence_object_flush(bo->fence, bo->fence_type);
list_add_tail(&bo->ddestroy, &bm->ddestroy);
schedule_delayed_work(&bm->wq,
((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
drm_device_t *dev = bo->dev;
drm_buffer_manager_t *bm = &dev->bm;
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
+
if (list_empty(&bo->lru) && bo->mem.mm_node == NULL &&
list_empty(&bo->pinned_lru) && bo->pinned_node == NULL &&
list_empty(&bo->ddestroy) && atomic_read(&bo->usage) == 0) {
atomic_dec(&bm->count);
+ BUG_ON(!list_empty(&bo->base.list));
drm_ctl_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);
return;
mutex_unlock(&dev->struct_mutex);
}
- void drm_bo_usage_deref_locked(drm_buffer_object_t * bo)
+ void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo)
{
- if (atomic_dec_and_test(&bo->usage)) {
- drm_bo_destroy_locked(bo);
+ struct drm_buffer_object *tmp_bo = *bo;
+ bo = NULL;
+
+ DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex);
+
+ if (atomic_dec_and_test(&tmp_bo->usage)) {
+ drm_bo_destroy_locked(tmp_bo);
}
}
drm_buffer_object_t *bo =
drm_user_object_entry(uo, drm_buffer_object_t, base);
+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
+
drm_bo_takedown_vm_locked(bo);
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
}
- static void drm_bo_usage_deref_unlocked(drm_buffer_object_t * bo)
+ static void drm_bo_usage_deref_unlocked(drm_buffer_object_t ** bo)
{
- drm_device_t *dev = bo->dev;
+ struct drm_buffer_object *tmp_bo = *bo;
+ drm_device_t *dev = tmp_bo->dev;
- if (atomic_dec_and_test(&bo->usage)) {
+ *bo = NULL;
+ if (atomic_dec_and_test(&tmp_bo->usage)) {
mutex_lock(&dev->struct_mutex);
- if (atomic_read(&bo->usage) == 0)
- drm_bo_destroy_locked(bo);
+ if (atomic_read(&tmp_bo->usage) == 0)
+ drm_bo_destroy_locked(tmp_bo);
mutex_unlock(&dev->struct_mutex);
}
}
if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
count++;
if (entry->fence)
- drm_fence_usage_deref_locked(dev, entry->fence);
- entry->fence = fence;
+ drm_fence_usage_deref_locked(&entry->fence);
+ entry->fence = drm_fence_reference_locked(fence);
DRM_FLAG_MASKED(entry->priv_flags, 0,
_DRM_BO_FLAG_UNFENCED);
DRM_WAKEUP(&entry->event_queue);
drm_bo_add_to_lru(entry);
}
mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_locked(entry);
+ drm_bo_usage_deref_locked(&entry);
l = f_list.next;
}
- atomic_add(count, &fence->usage);
DRM_DEBUG("Fenced %d buffers\n", count);
out:
mutex_unlock(&dev->struct_mutex);
ret = drm_bo_evict(entry, mem_type, no_wait);
mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_unlocked(entry);
+ drm_bo_usage_deref_unlocked(&entry);
if (ret)
return ret;
mutex_lock(&dev->struct_mutex);
EXPORT_SYMBOL(drm_bo_mem_space);
static int drm_bo_new_mask(drm_buffer_object_t * bo,
- uint32_t new_mask, uint32_t hint)
+ uint64_t new_mask, uint32_t hint)
{
uint32_t new_props;
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
return 1;
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
- drm_fence_object_flush(dev, fence, DRM_FENCE_TYPE_EXE);
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE);
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
return 1;
*/
static void drm_bo_fill_rep_arg(drm_buffer_object_t * bo,
- drm_bo_arg_reply_t * rep)
+ struct drm_bo_info_rep *rep)
{
rep->handle = bo->base.hash.key;
rep->flags = bo->mem.flags;
static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
uint32_t map_flags, unsigned hint,
- drm_bo_arg_reply_t * rep)
+ struct drm_bo_info_rep *rep)
{
drm_buffer_object_t *bo;
drm_device_t *dev = priv->head->dev;
drm_bo_fill_rep_arg(bo, rep);
out:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
}
drm_remove_ref_object(priv, ro);
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
out:
mutex_unlock(&dev->struct_mutex);
return ret;
return 0;
}
- DRM_ERROR("Illegal fake buffer flags 0x%08x\n", mem->mask);
+ DRM_ERROR("Illegal fake buffer flags 0x%016llx\n",
+ (unsigned long long) mem->mask);
return -EINVAL;
}
*/
static int drm_buffer_object_validate(drm_buffer_object_t * bo,
+ uint32_t fence_class,
int move_unfenced, int no_wait)
{
drm_device_t *dev = bo->dev;
drm_buffer_manager_t *bm = &dev->bm;
drm_bo_driver_t *driver = dev->driver->bo_driver;
+ uint32_t ftype;
int ret;
- DRM_DEBUG("New flags 0x%08x, Old flags 0x%08x\n", bo->mem.mask,
- bo->mem.flags);
- ret =
- driver->fence_type(bo, &bo->fence_class, &bo->fence_type);
+ DRM_DEBUG("New flags 0x%016llx, Old flags 0x%016llx\n",
+ (unsigned long long) bo->mem.mask,
+ (unsigned long long) bo->mem.flags);
+
+ ret = driver->fence_type(bo, &ftype);
+
if (ret) {
DRM_ERROR("Driver did not support given buffer permissions\n");
return ret;
}
+ /*
+ * We're switching command submission mechanism,
+ * or cannot simply rely on the hardware serializing for us.
+ *
+ * Wait for buffer idle.
+ */
+
+ if ((fence_class != bo->fence_class) ||
+ ((ftype ^ bo->fence_type) & bo->fence_type)) {
+
+ ret = drm_bo_wait(bo, 0, 0, no_wait);
+
+ if (ret)
+ return ret;
+
+ }
+
+ bo->fence_class = fence_class;
+ bo->fence_type = ftype;
ret = drm_bo_wait_unmapped(bo, no_wait);
if (ret)
return ret;
return 0;
}
-static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
- uint32_t flags, uint32_t mask, uint32_t hint,
- drm_bo_arg_reply_t * rep)
+static int drm_bo_handle_validate(drm_file_t * priv,
+ uint32_t handle,
+ uint32_t fence_class,
+ uint64_t flags, uint64_t mask, uint32_t hint,
+ struct drm_bo_info_rep *rep)
{
+ struct drm_device *dev = priv->head->dev;
drm_buffer_object_t *bo;
int ret;
int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
+ mutex_lock(&dev->struct_mutex);
bo = drm_lookup_buffer_object(priv, handle, 1);
+ mutex_unlock(&dev->struct_mutex);
if (!bo) {
return -EINVAL;
}
goto out;
ret =
- drm_buffer_object_validate(bo, !(hint & DRM_BO_HINT_DONT_FENCE),
+ drm_buffer_object_validate(bo, fence_class,
+ !(hint & DRM_BO_HINT_DONT_FENCE),
no_wait);
drm_bo_fill_rep_arg(bo, rep);
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
-static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
- drm_bo_arg_reply_t * rep)
+static int drm_bo_handle_info(drm_file_t *priv, uint32_t handle,
+ struct drm_bo_info_rep *rep)
{
+ struct drm_device *dev = priv->head->dev;
drm_buffer_object_t *bo;
+ mutex_lock(&dev->struct_mutex);
bo = drm_lookup_buffer_object(priv, handle, 1);
+ mutex_unlock(&dev->struct_mutex);
+
if (!bo) {
return -EINVAL;
}
(void)drm_bo_busy(bo);
drm_bo_fill_rep_arg(bo, rep);
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return 0;
}
-static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
- uint32_t hint, drm_bo_arg_reply_t * rep)
+static int drm_bo_handle_wait(drm_file_t *priv, uint32_t handle,
+ uint32_t hint,
+ struct drm_bo_info_rep *rep)
{
+ struct drm_device *dev = priv->head->dev;
drm_buffer_object_t *bo;
int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
int ret;
+ mutex_lock(&dev->struct_mutex);
bo = drm_lookup_buffer_object(priv, handle, 1);
+ mutex_unlock(&dev->struct_mutex);
+
if (!bo) {
return -EINVAL;
}
out:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
int drm_buffer_object_create(drm_device_t *dev,
unsigned long size,
drm_bo_type_t type,
- uint32_t mask,
+ uint64_t mask,
uint32_t hint,
uint32_t page_alignment,
unsigned long buffer_start,
bo->buffer_start = buffer_start;
}
bo->priv_flags = 0;
- bo->mem.flags = 0;
- bo->mem.mask = 0;
+ bo->mem.flags = 0ULL;
+ bo->mem.mask = 0ULL;
atomic_inc(&bm->count);
ret = drm_bo_new_mask(bo, mask, hint);
if (ret)
goto out_err;
}
- ret = drm_buffer_object_validate(bo, 0, hint & DRM_BO_HINT_DONT_BLOCK);
+ ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK);
if (ret)
goto out_err;
out_err:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
return 0;
}
-int drm_bo_ioctl(DRM_IOCTL_ARGS)
+int drm_bo_op_ioctl(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t rep;
+ struct drm_bo_op_arg arg;
+ struct drm_bo_op_req *req = &arg.d.req;
+ struct drm_bo_info_rep rep;
unsigned long next;
- drm_user_object_t *uo;
- drm_buffer_object_t *entry;
+ int ret;
if (!dev->bm.initialized) {
DRM_ERROR("Buffer object manager is not initialized.\n");
continue;
}
- rep.ret = 0;
+ ret = 0;
switch (req->op) {
- case drm_bo_create:
- rep.ret = drm_bo_lock_test(dev, filp);
- if (rep.ret)
- break;
- rep.ret =
- drm_buffer_object_create(priv->head->dev,
- req->size,
- req->type,
- req->mask,
- req->hint,
- req->page_alignment,
- req->buffer_start, &entry);
- if (rep.ret)
- break;
-
- rep.ret =
- drm_bo_add_user_object(priv, entry,
- req->
- mask &
- DRM_BO_FLAG_SHAREABLE);
- if (rep.ret)
- drm_bo_usage_deref_unlocked(&entry);
-
- if (rep.ret)
- break;
-
- mutex_lock(&entry->mutex);
- drm_bo_fill_rep_arg(entry, &rep);
- mutex_unlock(&entry->mutex);
- break;
- case drm_bo_unmap:
- rep.ret = drm_buffer_object_unmap(priv, req->handle);
- break;
- case drm_bo_map:
- rep.ret = drm_buffer_object_map(priv, req->handle,
- req->mask,
- req->hint, &rep);
- break;
- case drm_bo_destroy:
- mutex_lock(&dev->struct_mutex);
- uo = drm_lookup_user_object(priv, req->handle);
- if (!uo || (uo->type != drm_buffer_type)
- || uo->owner != priv) {
- mutex_unlock(&dev->struct_mutex);
- rep.ret = -EINVAL;
- break;
- }
- rep.ret = drm_remove_user_object(priv, uo);
- mutex_unlock(&dev->struct_mutex);
- break;
- case drm_bo_reference:
- rep.ret = drm_user_object_ref(priv, req->handle,
- drm_buffer_type, &uo);
- if (rep.ret)
- break;
-
- rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
- break;
- case drm_bo_unreference:
- rep.ret = drm_user_object_unref(priv, req->handle,
- drm_buffer_type);
- break;
case drm_bo_validate:
- rep.ret = drm_bo_lock_test(dev, filp);
-
- if (rep.ret)
+ ret = drm_bo_lock_test(dev, filp);
+ if (ret)
break;
- rep.ret =
- drm_bo_handle_validate(priv, req->handle, req->mask,
- req->arg_handle, req->hint,
- &rep);
+ ret = drm_bo_handle_validate(priv, req->bo_req.handle,
+ req->bo_req.fence_class,
+ req->bo_req.flags,
+ req->bo_req.mask,
+ req->bo_req.hint,
+ &rep);
break;
case drm_bo_fence:
- rep.ret = drm_bo_lock_test(dev, filp);
- if (rep.ret)
- break;
- /**/ break;
- case drm_bo_info:
- rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
- break;
- case drm_bo_wait_idle:
- rep.ret = drm_bo_handle_wait(priv, req->handle,
- req->hint, &rep);
+ ret = -EINVAL;
+ DRM_ERROR("Function is not implemented yet.\n");
break;
case drm_bo_ref_fence:
- rep.ret = -EINVAL;
+ ret = -EINVAL;
DRM_ERROR("Function is not implemented yet.\n");
+ break;
default:
- rep.ret = -EINVAL;
+ ret = -EINVAL;
}
next = arg.next;
* A signal interrupted us. Make sure the ioctl is restartable.
*/
- if (rep.ret == -EAGAIN)
+ if (ret == -EAGAIN)
return -EAGAIN;
arg.handled = 1;
- arg.d.rep = rep;
+ arg.d.rep.ret = ret;
+ arg.d.rep.bo_info = rep;
DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
data = next;
} while (data);
return 0;
}
- drm_bo_usage_deref_unlocked(entry);
+int drm_bo_create_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_create_arg arg;
+ struct drm_bo_create_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
+ drm_buffer_object_t *entry;
+ int ret = 0;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_bo_lock_test(dev, filp);
+ if (ret)
+ goto out;
+
+ ret = drm_buffer_object_create(priv->head->dev,
+ req->size, req->type, req->mask,
+ req->hint, req->page_alignment,
+ req->buffer_start, &entry);
+ if (ret)
+ goto out;
+
+ ret = drm_bo_add_user_object(priv, entry,
+ req->mask & DRM_BO_FLAG_SHAREABLE);
+ if (ret) {
++ drm_bo_usage_deref_unlocked(&entry);
+ goto out;
+ }
+
+ mutex_lock(&entry->mutex);
+ drm_bo_fill_rep_arg(entry, rep);
+ mutex_unlock(&entry->mutex);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+out:
+ return ret;
+}
+
+
+int drm_bo_destroy_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_handle_arg arg;
+ drm_user_object_t *uo;
+ int ret = 0;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ mutex_lock(&dev->struct_mutex);
+ uo = drm_lookup_user_object(priv, arg.handle);
+ if (!uo || (uo->type != drm_buffer_type) || uo->owner != priv) {
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+ ret = drm_remove_user_object(priv, uo);
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+int drm_bo_map_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_map_wait_idle_arg arg;
+ struct drm_bo_info_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_buffer_object_map(priv, req->handle, req->mask,
+ req->hint, rep);
+ if (ret)
+ return ret;
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_bo_unmap_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_handle_arg arg;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_buffer_object_unmap(priv, arg.handle);
+ return ret;
+}
+
+
+int drm_bo_reference_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_reference_info_arg arg;
+ struct drm_bo_handle_arg *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
+ drm_user_object_t *uo;
+ int ret;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_user_object_ref(priv, req->handle,
+ drm_buffer_type, &uo);
+ if (ret)
+ return ret;
+
+ ret = drm_bo_handle_info(priv, req->handle, rep);
+ if (ret)
+ return ret;
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_bo_unreference_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_handle_arg arg;
+ int ret = 0;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_user_object_unref(priv, arg.handle, drm_buffer_type);
+ return ret;
+}
+
+int drm_bo_info_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_reference_info_arg arg;
+ struct drm_bo_handle_arg *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
+ int ret;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_bo_handle_info(priv, req->handle, rep);
+ if (ret)
+ return ret;
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_bo_wait_idle_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_bo_map_wait_idle_arg arg;
+ struct drm_bo_info_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ ret = drm_bo_handle_wait(priv, req->handle,
+ req->hint, rep);
+ if (ret)
+ return ret;
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+
+
/**
*Clean the unfenced list and put on regular LRU.
*This is part of the memory manager cleanup and should only be
allow_errors);
mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(entry);
+ drm_bo_usage_deref_locked(&entry);
if (ret)
return ret;
do_restart = ((next->prev != list) && (next->prev != prev));
- if (nentry != NULL && do_restart) {
- drm_bo_usage_deref_locked(nentry);
- nentry = NULL;
- }
+ if (nentry != NULL && do_restart)
+ drm_bo_usage_deref_locked(&nentry);
if (do_restart)
goto restart;
int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
+ struct drm_mm_init_arg arg;
+ drm_buffer_manager_t *bm = &dev->bm;
+ drm_bo_driver_t *driver = dev->driver->bo_driver;
+ int ret;
- int ret = 0;
- drm_mm_init_arg_t arg;
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ ret = -EINVAL;
+ if (arg.magic != DRM_BO_INIT_MAGIC) {
+ DRM_ERROR("You are using an old libdrm that is not compatible with\n"
+ "\tthe kernel DRM module. Please upgrade your libdrm.\n");
+ return -EINVAL;
+ }
+ if (arg.major != DRM_BO_INIT_MAJOR) {
+ DRM_ERROR("libdrm and kernel DRM buffer object interface major\n"
+ "\tversion don't match. Got %d, expected %d,\n",
+ arg.major, DRM_BO_INIT_MAJOR);
+ return -EINVAL;
+ }
+ if (arg.minor > DRM_BO_INIT_MINOR) {
+ DRM_ERROR("libdrm expects a newer DRM buffer object interface.\n"
+ "\tlibdrm buffer object interface version is %d.%d.\n"
+ "\tkernel DRM buffer object interface version is %d.%d\n",
+ arg.major, arg.minor, DRM_BO_INIT_MAJOR, DRM_BO_INIT_MINOR);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->bm.init_mutex);
+ mutex_lock(&dev->struct_mutex);
+ if (!bm->initialized) {
+ DRM_ERROR("DRM memory manager was not initialized.\n");
+ goto out;
+ }
+ if (arg.mem_type == 0) {
+ DRM_ERROR("System memory buffers already initialized.\n");
+ goto out;
+ }
+ ret = drm_bo_init_mm(dev, arg.mem_type,
+ arg.p_offset, arg.p_size);
+
+out:
+ mutex_unlock(&dev->struct_mutex);
+ mutex_unlock(&dev->bm.init_mutex);
+ if (ret)
+ return ret;
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_mm_takedown_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_mm_type_arg arg;
drm_buffer_manager_t *bm = &dev->bm;
drm_bo_driver_t *driver = dev->driver->bo_driver;
+ int ret;
if (!driver) {
DRM_ERROR("Buffer objects are not supported by this driver\n");
DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
- switch (arg.req.op) {
- case mm_init:
- ret = -EINVAL;
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized.\n");
- break;
- }
- if (arg.req.mem_type == 0) {
- DRM_ERROR
- ("System memory buffers already initialized.\n");
- break;
- }
- ret = drm_bo_init_mm(dev, arg.req.mem_type,
- arg.req.p_offset, arg.req.p_size);
- break;
- case mm_takedown:
- LOCK_TEST_WITH_RETURN(dev, filp);
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- ret = -EINVAL;
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized\n");
- break;
- }
- if (arg.req.mem_type == 0) {
- DRM_ERROR("No takedown for System memory buffers.\n");
- break;
- }
- ret = 0;
- if (drm_bo_clean_mm(dev, arg.req.mem_type)) {
- DRM_ERROR("Memory manager type %d not clean. "
- "Delaying takedown\n", arg.req.mem_type);
- }
- break;
- case mm_lock:
- LOCK_TEST_WITH_RETURN(dev, filp);
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- ret = drm_bo_lock_mm(dev, arg.req.mem_type);
- break;
- case mm_unlock:
- LOCK_TEST_WITH_RETURN(dev, filp);
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- ret = 0;
- break;
- default:
- DRM_ERROR("Function not implemented yet\n");
+ LOCK_TEST_WITH_RETURN(dev, filp);
+ mutex_lock(&dev->bm.init_mutex);
+ mutex_lock(&dev->struct_mutex);
+ ret = -EINVAL;
+ if (!bm->initialized) {
+ DRM_ERROR("DRM memory manager was not initialized\n");
+ goto out;
+ }
+ if (arg.mem_type == 0) {
+ DRM_ERROR("No takedown for System memory buffers.\n");
+ goto out;
+ }
+ ret = 0;
+ if (drm_bo_clean_mm(dev, arg.mem_type)) {
+ DRM_ERROR("Memory manager type %d not clean. "
+ "Delaying takedown\n", arg.mem_type);
+ }
+out:
+ mutex_unlock(&dev->struct_mutex);
+ mutex_unlock(&dev->bm.init_mutex);
+ if (ret)
+ return ret;
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_mm_lock_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_mm_type_arg arg;
+ drm_bo_driver_t *driver = dev->driver->bo_driver;
+ int ret;
+
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ LOCK_TEST_WITH_RETURN(dev, filp);
+ mutex_lock(&dev->bm.init_mutex);
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_bo_lock_mm(dev, arg.mem_type);
+ mutex_unlock(&dev->struct_mutex);
+ mutex_unlock(&dev->bm.init_mutex);
+ if (ret)
+ return ret;
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_mm_unlock_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ struct drm_mm_type_arg arg;
+ drm_bo_driver_t *driver = dev->driver->bo_driver;
+ int ret;
+
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
return -EINVAL;
}
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ LOCK_TEST_WITH_RETURN(dev, filp);
+ mutex_lock(&dev->bm.init_mutex);
+ mutex_lock(&dev->struct_mutex);
+ ret = 0;
+
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&dev->bm.init_mutex);
if (ret)
drm_local_map_t *map;
drm_device_t *dev = bo->dev;
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
if (list->user_token) {
drm_ht_remove_item(&dev->map_hash, &list->hash);
list->user_token = 0;
drm_ctl_free(map, sizeof(*map), DRM_MEM_BUFOBJ);
list->map = NULL;
list->user_token = 0ULL;
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
}
static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo)
drm_local_map_t *map;
drm_device_t *dev = bo->dev;
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
list->map = drm_ctl_calloc(1, sizeof(*map), DRM_MEM_BUFOBJ);
if (!list->map)
return -ENOMEM;
return ret;
}
-static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
+
+static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
struct fault_data *data)
{
unsigned long address = data->address;
#endif
+ #ifdef DRM_IDR_COMPAT_FN
+ /* only called when idp->lock is held */
+ static void __free_layer(struct idr *idp, struct idr_layer *p)
+ {
+ p->ary[0] = idp->id_free;
+ idp->id_free = p;
+ idp->id_free_cnt++;
+ }
+
+ static void free_layer(struct idr *idp, struct idr_layer *p)
+ {
+ unsigned long flags;
+
+ /*
+ * Depends on the return element being zeroed.
+ */
+ spin_lock_irqsave(&idp->lock, flags);
+ __free_layer(idp, p);
+ spin_unlock_irqrestore(&idp->lock, flags);
+ }
+
+ /**
+ * idr_for_each - iterate through all stored pointers
+ * @idp: idr handle
+ * @fn: function to be called for each pointer
+ * @data: data passed back to callback function
+ *
+ * Iterate over the pointers registered with the given idr. The
+ * callback function will be called for each pointer currently
+ * registered, passing the id, the pointer and the data pointer passed
+ * to this function. It is not safe to modify the idr tree while in
+ * the callback, so functions such as idr_get_new and idr_remove are
+ * not allowed.
+ *
+ * We check the return of @fn each time. If it returns anything other
+ * than 0, we break out and return that value.
+ *
+ * The caller must serialize idr_find() vs idr_get_new() and idr_remove().
+ */
+ int idr_for_each(struct idr *idp,
+ int (*fn)(int id, void *p, void *data), void *data)
+ {
+ int n, id, max, error = 0;
+ struct idr_layer *p;
+ struct idr_layer *pa[MAX_LEVEL];
+ struct idr_layer **paa = &pa[0];
+
+ n = idp->layers * IDR_BITS;
+ p = idp->top;
+ max = 1 << n;
+
+ id = 0;
+ while (id < max) {
+ while (n > 0 && p) {
+ n -= IDR_BITS;
+ *paa++ = p;
+ p = p->ary[(id >> n) & IDR_MASK];
+ }
+
+ if (p) {
+ error = fn(id, (void *)p, data);
+ if (error)
+ break;
+ }
+
+ id += 1 << n;
+ while (n < fls(id)) {
+ n += IDR_BITS;
+ p = *--paa;
+ }
+ }
+
+ return error;
+ }
+ EXPORT_SYMBOL(idr_for_each);
+
+ /**
+ * idr_remove_all - remove all ids from the given idr tree
+ * @idp: idr handle
+ *
+ * idr_destroy() only frees up unused, cached idp_layers, but this
+ * function will remove all id mappings and leave all idp_layers
+ * unused.
+ *
+ * A typical clean-up sequence for objects stored in an idr tree, will
+ * use idr_for_each() to free all objects, if necessay, then
+ * idr_remove_all() to remove all ids, and idr_destroy() to free
+ * up the cached idr_layers.
+ */
+ void idr_remove_all(struct idr *idp)
+ {
+ int n, id, max, error = 0;
+ struct idr_layer *p;
+ struct idr_layer *pa[MAX_LEVEL];
+ struct idr_layer **paa = &pa[0];
+
+ n = idp->layers * IDR_BITS;
+ p = idp->top;
+ max = 1 << n;
+
+ id = 0;
+ while (id < max && !error) {
+ while (n > IDR_BITS && p) {
+ n -= IDR_BITS;
+ *paa++ = p;
+ p = p->ary[(id >> n) & IDR_MASK];
+ }
+
+ id += 1 << n;
+ while (n < fls(id)) {
+ if (p) {
+ memset(p, 0, sizeof *p);
+ free_layer(idp, p);
+ }
+ n += IDR_BITS;
+ p = *--paa;
+ }
+ }
+ idp->top = NULL;
+ idp->layers = 0;
+ }
+ EXPORT_SYMBOL(idr_remove_all);
+ #endif
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_FENCE)] = {drm_fence_ioctl, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
+
+ // [DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+
+
[DRM_IOCTL_NR(DRM_IOCTL_MM_INIT)] = {drm_mm_init_ioctl,
DRM_AUTH },
+ [DRM_IOCTL_NR(DRM_IOCTL_MM_TAKEDOWN)] = {drm_mm_takedown_ioctl,
+ DRM_AUTH },
+ [DRM_IOCTL_NR(DRM_IOCTL_MM_LOCK)] = {drm_mm_lock_ioctl,
+ DRM_AUTH },
+ [DRM_IOCTL_NR(DRM_IOCTL_MM_UNLOCK)] = {drm_mm_unlock_ioctl,
+ DRM_AUTH },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_CREATE)] = {drm_fence_create_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_DESTROY)] = {drm_fence_destroy_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_REFERENCE)] = {drm_fence_reference_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_UNREFERENCE)] = {drm_fence_unreference_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_SIGNALED)] = {drm_fence_signaled_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_FLUSH)] = {drm_fence_flush_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_WAIT)] = {drm_fence_wait_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_EMIT)] = {drm_fence_emit_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_FENCE_BUFFERS)] = {drm_fence_buffers_ioctl, DRM_AUTH},
+
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_CREATE)] = {drm_bo_create_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_DESTROY)] = {drm_bo_destroy_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_MAP)] = {drm_bo_map_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_UNMAP)] = {drm_bo_unmap_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_REFERENCE)] = {drm_bo_reference_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_UNREFERENCE)] = {drm_bo_unreference_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_OP)] = {drm_bo_op_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_INFO)] = {drm_bo_info_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_BO_WAIT_IDLE)] = {drm_bo_wait_idle_ioctl, DRM_AUTH},
+
+
- [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
int drm_lastclose(drm_device_t * dev)
{
drm_magic_entry_t *pt, *next;
- drm_map_list_t *r_list;
- drm_vma_entry_t *vma, *vma_next;
+ drm_map_list_t *r_list, *list_t;
+ drm_vma_entry_t *vma, *vma_temp;
int i;
DRM_DEBUG("\n");
drm_irq_uninstall(dev);
/* Free drawable information memory */
- for (i = 0; i < dev->drw_bitfield_length / sizeof(*dev->drw_bitfield);
- i++) {
- drm_drawable_info_t *info = drm_get_drawable_info(dev, i);
-
- if (info) {
- drm_free(info->rects, info->num_rects *
- sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
- drm_free(info, sizeof(*info), DRM_MEM_BUFS);
- }
- }
-
mutex_lock(&dev->struct_mutex);
+
+ drm_drawable_free_all(dev);
del_timer(&dev->timer);
if (dev->unique) {
/* Clear AGP information */
if (drm_core_has_AGP(dev) && dev->agp) {
- drm_agp_mem_t *entry;
- drm_agp_mem_t *nexte;
+ drm_agp_mem_t *entry, *tempe;
/* Remove AGP resources, but leave dev->agp
intact until drv_cleanup is called. */
- for (entry = dev->agp->memory; entry; entry = nexte) {
- nexte = entry->next;
+ list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
if (entry->bound)
drm_unbind_agp(entry->memory);
drm_free_agp(entry->memory, entry->pages);
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
}
- dev->agp->memory = NULL;
+ INIT_LIST_HEAD(&dev->agp->memory);
if (dev->agp->acquired)
drm_agp_release(dev);
}
/* Clear vma list (only built for debugging) */
- if (dev->vmalist) {
- for (vma = dev->vmalist; vma; vma = vma_next) {
- vma_next = vma->next;
- drm_ctl_free(vma, sizeof(*vma), DRM_MEM_VMAS);
- }
- dev->vmalist = NULL;
+ list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
+ list_del(&vma->head);
+ drm_ctl_free(vma, sizeof(*vma), DRM_MEM_VMAS);
}
-
- if (dev->maplist) {
- while (!list_empty(&dev->maplist->head)) {
- struct list_head *list = dev->maplist->head.next;
- r_list = list_entry(list, drm_map_list_t, head);
- drm_rmmap_locked(dev, r_list->map);
- }
+
+ list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
+ drm_rmmap_locked(dev, r_list->map);
+ r_list = NULL;
}
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
}
if (!drm_fb_loaded)
- pci_register_driver(&driver->pci_driver);
+ return pci_register_driver(&driver->pci_driver);
else {
for (i = 0; pciidlist[i].vendor != 0; i++) {
pid = &pciidlist[i];
drm_lastclose(dev);
drm_fence_manager_takedown(dev);
- if (dev->maplist) {
- drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
- dev->maplist = NULL;
- drm_ht_remove(&dev->map_hash);
- drm_mm_takedown(&dev->offset_manager);
- drm_ht_remove(&dev->object_hash);
- }
+ drm_ht_remove(&dev->map_hash);
+ drm_mm_takedown(&dev->offset_manager);
+ drm_ht_remove(&dev->object_hash);
if (!drm_fb_loaded)
pci_disable_device(dev->pdev);
goto err_i1;
if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
&& (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
- ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+ ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
ioctl = &drm_ioctls[nr];
else
}
EXPORT_SYMBOL(drm_ioctl);
- int drm_wait_on(drm_device_t *dev, wait_queue_head_t *queue, int timeout,
- int (*fn)(drm_device_t *dev, void *priv), void *priv)
- {
- DECLARE_WAITQUEUE(entry, current);
- unsigned long end = jiffies + (timeout);
- int ret = 0;
- add_wait_queue(queue, &entry);
-
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- if ((*fn)(dev, priv))
- break;
- if (time_after_eq(jiffies, end)) {
- ret = -EBUSY;
- break;
- }
- schedule_timeout((HZ/100 > 1) ? HZ/100 : 1);
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
- }
- }
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(queue, &entry);
- return ret;
- }
- EXPORT_SYMBOL(drm_wait_on);
-
drm_local_map_t *drm_getsarea(struct drm_device *dev)
{
drm_map_list_t *entry;
- list_for_each_entry(entry, &dev->maplist->head, head) {
+ list_for_each_entry(entry, &dev->maplist, head) {
if (entry->map && entry->map->type == _DRM_SHM &&
(entry->map->flags & _DRM_CONTAINS_LOCK)) {
return entry->map;
write_unlock_irqrestore(&fm->lock, flags);
}
- void drm_fence_usage_deref_locked(drm_device_t * dev,
- drm_fence_object_t * fence)
+ void drm_fence_usage_deref_locked(drm_fence_object_t ** fence)
{
+ struct drm_fence_object *tmp_fence = *fence;
+ struct drm_device *dev = tmp_fence->dev;
drm_fence_manager_t *fm = &dev->fm;
- if (atomic_dec_and_test(&fence->usage)) {
- drm_fence_unring(dev, &fence->ring);
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
+ *fence = NULL;
+ if (atomic_dec_and_test(&tmp_fence->usage)) {
+ drm_fence_unring(dev, &tmp_fence->ring);
DRM_DEBUG("Destroyed a fence object 0x%08lx\n",
- fence->base.hash.key);
+ tmp_fence->base.hash.key);
atomic_dec(&fm->count);
- drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE);
+ BUG_ON(!list_empty(&tmp_fence->base.list));
+ drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
}
}
- void drm_fence_usage_deref_unlocked(drm_device_t * dev,
- drm_fence_object_t * fence)
+ void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence)
{
+ struct drm_fence_object *tmp_fence = *fence;
+ struct drm_device *dev = tmp_fence->dev;
drm_fence_manager_t *fm = &dev->fm;
- if (atomic_dec_and_test(&fence->usage)) {
+ *fence = NULL;
+ if (atomic_dec_and_test(&tmp_fence->usage)) {
mutex_lock(&dev->struct_mutex);
- if (atomic_read(&fence->usage) == 0) {
- drm_fence_unring(dev, &fence->ring);
+ if (atomic_read(&tmp_fence->usage) == 0) {
+ drm_fence_unring(dev, &tmp_fence->ring);
atomic_dec(&fm->count);
- drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE);
+ BUG_ON(!list_empty(&tmp_fence->base.list));
+ drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
}
mutex_unlock(&dev->struct_mutex);
}
}
- static void drm_fence_object_destroy(drm_file_t * priv,
- drm_user_object_t * base)
+ struct drm_fence_object
+ *drm_fence_reference_locked(struct drm_fence_object *src)
+ {
+ DRM_ASSERT_LOCKED(&src->dev->struct_mutex);
+
+ atomic_inc(&src->usage);
+ return src;
+ }
+
+ void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+ struct drm_fence_object *src)
+ {
+ mutex_lock(&src->dev->struct_mutex);
+ *dst = src;
+ atomic_inc(&src->usage);
+ mutex_unlock(&src->dev->struct_mutex);
+ }
+
+
+ static void drm_fence_object_destroy(drm_file_t *priv, drm_user_object_t * base)
{
- drm_device_t *dev = priv->head->dev;
drm_fence_object_t *fence =
drm_user_object_entry(base, drm_fence_object_t, base);
- drm_fence_usage_deref_locked(dev, fence);
+ drm_fence_usage_deref_locked(&fence);
}
- static int fence_signaled(drm_device_t * dev,
- drm_fence_object_t * fence,
- uint32_t mask, int poke_flush)
+ int drm_fence_object_signaled(drm_fence_object_t * fence,
+ uint32_t mask, int poke_flush)
{
unsigned long flags;
int signaled;
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
}
}
- int drm_fence_object_signaled(drm_fence_object_t * fence,
- uint32_t type)
- {
- return ((fence->signaled & type) == type);
- }
-
- int drm_fence_object_flush(drm_device_t * dev,
- drm_fence_object_t * fence,
+ int drm_fence_object_flush(drm_fence_object_t * fence,
uint32_t type)
{
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
drm_fence_driver_t *driver = dev->driver->fence_driver;
mutex_unlock(&dev->struct_mutex);
return;
}
- fence = list_entry(fc->ring.next, drm_fence_object_t, ring);
- atomic_inc(&fence->usage);
+ fence = drm_fence_reference_locked(list_entry(fc->ring.next, drm_fence_object_t, ring));
mutex_unlock(&dev->struct_mutex);
diff = (old_sequence - fence->sequence) & driver->sequence_mask;
read_unlock_irqrestore(&fm->lock, flags);
if (diff < driver->wrap_diff) {
- drm_fence_object_flush(dev, fence, fence->type);
+ drm_fence_object_flush(fence, fence->type);
}
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
}
EXPORT_SYMBOL(drm_fence_flush_old);
- static int drm_fence_lazy_wait(drm_device_t *dev,
- drm_fence_object_t *fence,
+ static int drm_fence_lazy_wait(drm_fence_object_t *fence,
int ignore_signals,
uint32_t mask)
{
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
int signaled;
do {
DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ,
- (signaled = fence_signaled(dev, fence, mask, 1)));
+ (signaled = drm_fence_object_signaled(fence, mask, 1)));
if (signaled)
return 0;
if (time_after_eq(jiffies, _end))
break;
} while (ret == -EINTR && ignore_signals);
- if (fence_signaled(dev, fence, mask, 0))
+ if (drm_fence_object_signaled(fence, mask, 0))
return 0;
if (time_after_eq(jiffies, _end))
ret = -EBUSY;
return 0;
}
- int drm_fence_object_wait(drm_device_t * dev,
- drm_fence_object_t * fence,
+ int drm_fence_object_wait(drm_fence_object_t * fence,
int lazy, int ignore_signals, uint32_t mask)
{
+ struct drm_device *dev = fence->dev;
drm_fence_driver_t *driver = dev->driver->fence_driver;
int ret = 0;
unsigned long _end;
return -EINVAL;
}
- if (fence_signaled(dev, fence, mask, 0))
+ if (drm_fence_object_signaled(fence, mask, 0))
return 0;
_end = jiffies + 3 * DRM_HZ;
- drm_fence_object_flush(dev, fence, mask);
+ drm_fence_object_flush(fence, mask);
if (lazy && driver->lazy_capable) {
- ret = drm_fence_lazy_wait(dev, fence, ignore_signals, mask);
+ ret = drm_fence_lazy_wait(fence, ignore_signals, mask);
if (ret)
return ret;
if (driver->has_irq(dev, fence->class,
DRM_FENCE_TYPE_EXE)) {
- ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+ ret = drm_fence_lazy_wait(fence, ignore_signals,
DRM_FENCE_TYPE_EXE);
if (ret)
return ret;
if (driver->has_irq(dev, fence->class,
mask & ~DRM_FENCE_TYPE_EXE)) {
- ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+ ret = drm_fence_lazy_wait(fence, ignore_signals,
mask);
if (ret)
return ret;
}
}
- if (drm_fence_object_signaled(fence, mask))
+ if (drm_fence_object_signaled(fence, mask, 0))
return 0;
/*
#endif
do {
schedule();
- signaled = fence_signaled(dev, fence, mask, 1);
+ signaled = drm_fence_object_signaled(fence, mask, 1);
} while (!signaled && !time_after_eq(jiffies, _end));
if (!signaled)
return 0;
}
- int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
+ int drm_fence_object_emit(drm_fence_object_t * fence,
uint32_t fence_flags, uint32_t class, uint32_t type)
{
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
write_lock_irqsave(&fm->lock, flags);
INIT_LIST_HEAD(&fence->ring);
+
+ /*
+ * Avoid hitting BUG() for kernel-only fence objects.
+ */
+
+ INIT_LIST_HEAD(&fence->base.list);
fence->class = class;
fence->type = type;
fence->flush_mask = 0;
fence->submitted_flush = 0;
fence->signaled = 0;
fence->sequence = 0;
+ fence->dev = dev;
write_unlock_irqrestore(&fm->lock, flags);
if (fence_flags & DRM_FENCE_FLAG_EMIT) {
- ret = drm_fence_object_emit(dev, fence, fence_flags,
+ ret = drm_fence_object_emit(fence, fence_flags,
fence->class, type);
}
return ret;
mutex_lock(&dev->struct_mutex);
ret = drm_add_user_object(priv, &fence->base, shareable);
- mutex_unlock(&dev->struct_mutex);
if (ret)
- return ret;
+ goto out;
+ atomic_inc(&fence->usage);
fence->base.type = drm_fence_type;
fence->base.remove = &drm_fence_object_destroy;
DRM_DEBUG("Fence 0x%08lx created\n", fence->base.hash.key);
- return 0;
+ out:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
-
EXPORT_SYMBOL(drm_fence_add_user_object);
int drm_fence_object_create(drm_device_t * dev, uint32_t class, uint32_t type,
int ret;
drm_fence_manager_t *fm = &dev->fm;
- fence = drm_ctl_alloc(sizeof(*fence), DRM_MEM_FENCE);
+ fence = drm_ctl_calloc(1, sizeof(*fence), DRM_MEM_FENCE);
if (!fence)
return -ENOMEM;
ret = drm_fence_object_init(dev, class, type, flags, fence);
if (ret) {
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
return ret;
}
*c_fence = fence;
mutex_unlock(&dev->struct_mutex);
return NULL;
}
- fence = drm_user_object_entry(uo, drm_fence_object_t, base);
- atomic_inc(&fence->usage);
+ fence = drm_fence_reference_locked(drm_user_object_entry(uo, drm_fence_object_t, base));
mutex_unlock(&dev->struct_mutex);
return fence;
}
-int drm_fence_ioctl(DRM_IOCTL_ARGS)
+int drm_fence_create_ioctl(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
int ret;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_arg_t arg;
drm_fence_object_t *fence;
- drm_user_object_t *uo;
unsigned long flags;
ret = 0;
}
DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
-
- switch (arg.op) {
- case drm_fence_create:
- if (arg.flags & DRM_FENCE_FLAG_EMIT)
- LOCK_TEST_WITH_RETURN(dev, filp);
- ret = drm_fence_object_create(dev, arg.class,
- arg.type, arg.flags, &fence);
- if (ret)
- return ret;
- ret = drm_fence_add_user_object(priv, fence,
- arg.flags &
- DRM_FENCE_FLAG_SHAREABLE);
- if (ret) {
- drm_fence_usage_deref_unlocked(&fence);
- return ret;
- }
- arg.handle = fence->base.hash.key;
+ if (arg.flags & DRM_FENCE_FLAG_EMIT)
+ LOCK_TEST_WITH_RETURN(dev, filp);
+ ret = drm_fence_object_create(dev, arg.class,
+ arg.type, arg.flags, &fence);
+ if (ret)
+ return ret;
+ ret = drm_fence_add_user_object(priv, fence,
+ arg.flags &
+ DRM_FENCE_FLAG_SHAREABLE);
+ if (ret) {
- drm_fence_usage_deref_unlocked(dev, fence);
++ drm_fence_usage_deref_unlocked(&fence);
+ return ret;
+ }
+
+ /*
+ * usage > 0. No need to lock dev->struct_mutex;
+ */
+
+ atomic_inc(&fence->usage);
+ arg.handle = fence->base.hash.key;
- break;
- case drm_fence_destroy:
- mutex_lock(&dev->struct_mutex);
- uo = drm_lookup_user_object(priv, arg.handle);
- if (!uo || (uo->type != drm_fence_type) || uo->owner != priv) {
- mutex_unlock(&dev->struct_mutex);
- return -EINVAL;
- }
- ret = drm_remove_user_object(priv, uo);
+ read_lock_irqsave(&fm->lock, flags);
+ arg.class = fence->class;
+ arg.type = fence->type;
+ arg.signaled = fence->signaled;
+ read_unlock_irqrestore(&fm->lock, flags);
- drm_fence_usage_deref_unlocked(dev, fence);
++ drm_fence_usage_deref_unlocked(&fence);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return ret;
+}
+
+int drm_fence_destroy_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_user_object_t *uo;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ mutex_lock(&dev->struct_mutex);
+ uo = drm_lookup_user_object(priv, arg.handle);
+ if (!uo || (uo->type != drm_fence_type) || uo->owner != priv) {
mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+ ret = drm_remove_user_object(priv, uo);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
+
+int drm_fence_reference_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_fence_object_t *fence;
+ drm_user_object_t *uo;
+ unsigned long flags;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ ret = drm_user_object_ref(priv, arg.handle, drm_fence_type, &uo);
+ if (ret)
return ret;
- case drm_fence_reference:
- ret =
- drm_user_object_ref(priv, arg.handle, drm_fence_type, &uo);
- if (ret)
- return ret;
- fence = drm_lookup_fence_object(priv, arg.handle);
- break;
- case drm_fence_unreference:
- ret = drm_user_object_unref(priv, arg.handle, drm_fence_type);
- return ret;
- case drm_fence_signaled:
- fence = drm_lookup_fence_object(priv, arg.handle);
- if (!fence)
- return -EINVAL;
- break;
- case drm_fence_flush:
- fence = drm_lookup_fence_object(priv, arg.handle);
- if (!fence)
- return -EINVAL;
- ret = drm_fence_object_flush(fence, arg.type);
- break;
- case drm_fence_wait:
- fence = drm_lookup_fence_object(priv, arg.handle);
- if (!fence)
- return -EINVAL;
- ret =
- drm_fence_object_wait(fence,
- arg.flags & DRM_FENCE_FLAG_WAIT_LAZY,
- 0, arg.type);
- break;
- case drm_fence_emit:
- LOCK_TEST_WITH_RETURN(dev, filp);
- fence = drm_lookup_fence_object(priv, arg.handle);
- if (!fence)
- return -EINVAL;
- ret = drm_fence_object_emit(fence, arg.flags, arg.class,
- arg.type);
- break;
- case drm_fence_buffers:
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized\n");
- return -EINVAL;
- }
- LOCK_TEST_WITH_RETURN(dev, filp);
- ret = drm_fence_buffer_objects(priv, NULL, arg.flags,
- NULL, &fence);
- if (ret)
- return ret;
- ret = drm_fence_add_user_object(priv, fence,
- arg.flags &
- DRM_FENCE_FLAG_SHAREABLE);
- if (ret)
- return ret;
- arg.handle = fence->base.hash.key;
- break;
- default:
+ fence = drm_lookup_fence_object(priv, arg.handle);
+
+ read_lock_irqsave(&fm->lock, flags);
+ arg.class = fence->class;
+ arg.type = fence->type;
+ arg.signaled = fence->signaled;
+ read_unlock_irqrestore(&fm->lock, flags);
- drm_fence_usage_deref_unlocked(dev, fence);
++ drm_fence_usage_deref_unlocked(&fence);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return ret;
+}
+
+
+int drm_fence_unreference_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ return drm_user_object_unref(priv, arg.handle, drm_fence_type);
+}
+
+int drm_fence_signaled_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_fence_object_t *fence;
+ unsigned long flags;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ fence = drm_lookup_fence_object(priv, arg.handle);
+ if (!fence)
+ return -EINVAL;
+
+ read_lock_irqsave(&fm->lock, flags);
+ arg.class = fence->class;
+ arg.type = fence->type;
+ arg.signaled = fence->signaled;
+ read_unlock_irqrestore(&fm->lock, flags);
- drm_fence_usage_deref_unlocked(dev, fence);
++ drm_fence_usage_deref_unlocked(&fence);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return ret;
+}
+
+int drm_fence_flush_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_fence_object_t *fence;
+ unsigned long flags;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
return -EINVAL;
}
- ret = drm_fence_object_flush(dev, fence, arg.type);
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ fence = drm_lookup_fence_object(priv, arg.handle);
+ if (!fence)
+ return -EINVAL;
- drm_fence_usage_deref_unlocked(dev, fence);
++ ret = drm_fence_object_flush(fence, arg.type);
+
+ read_lock_irqsave(&fm->lock, flags);
+ arg.class = fence->class;
+ arg.type = fence->type;
+ arg.signaled = fence->signaled;
+ read_unlock_irqrestore(&fm->lock, flags);
- ret = drm_fence_object_wait(dev, fence,
++ drm_fence_usage_deref_unlocked(&fence);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return ret;
+}
+
+
+int drm_fence_wait_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_fence_object_t *fence;
+ unsigned long flags;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ fence = drm_lookup_fence_object(priv, arg.handle);
+ if (!fence)
+ return -EINVAL;
- drm_fence_usage_deref_unlocked(dev, fence);
++ ret = drm_fence_object_wait(fence,
+ arg.flags & DRM_FENCE_FLAG_WAIT_LAZY,
+ 0, arg.type);
+
+ read_lock_irqsave(&fm->lock, flags);
+ arg.class = fence->class;
+ arg.type = fence->type;
+ arg.signaled = fence->signaled;
+ read_unlock_irqrestore(&fm->lock, flags);
- ret = drm_fence_object_emit(dev, fence, arg.flags, arg.class,
++ drm_fence_usage_deref_unlocked(&fence);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return ret;
+}
+
+
+int drm_fence_emit_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_fence_object_t *fence;
+ unsigned long flags;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ LOCK_TEST_WITH_RETURN(dev, filp);
+ fence = drm_lookup_fence_object(priv, arg.handle);
+ if (!fence)
+ return -EINVAL;
- drm_fence_usage_deref_unlocked(dev, fence);
++ ret = drm_fence_object_emit(fence, arg.flags, arg.class,
+ arg.type);
+
+ read_lock_irqsave(&fm->lock, flags);
+ arg.class = fence->class;
+ arg.type = fence->type;
+ arg.signaled = fence->signaled;
+ read_unlock_irqrestore(&fm->lock, flags);
++ drm_fence_usage_deref_unlocked(&fence);
+
+ DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return ret;
+}
+
+int drm_fence_buffers_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ int ret;
+ drm_fence_manager_t *fm = &dev->fm;
+ drm_fence_arg_t arg;
+ drm_fence_object_t *fence;
+ unsigned long flags;
+ ret = 0;
+
+ if (!fm->initialized) {
+ DRM_ERROR("The DRM driver does not support fencing.\n");
+ return -EINVAL;
+ }
+
+ DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized\n");
+ return -EINVAL;
+ }
+ LOCK_TEST_WITH_RETURN(dev, filp);
+ ret = drm_fence_buffer_objects(priv, NULL, arg.flags,
+ NULL, &fence);
+ if (ret)
+ return ret;
+ ret = drm_fence_add_user_object(priv, fence,
+ arg.flags &
+ DRM_FENCE_FLAG_SHAREABLE);
+ if (ret)
+ return ret;
+ atomic_inc(&fence->usage);
+ arg.handle = fence->base.hash.key;
+
read_lock_irqsave(&fm->lock, flags);
arg.class = fence->class;
arg.type = fence->type;
arg.signaled = fence->signaled;
read_unlock_irqrestore(&fm->lock, flags);
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
return ret;
*/
#ifndef _DRM_OBJECTS_H
- #define _DRM_OJBECTS_H
+ #define _DRM_OBJECTS_H
struct drm_device;
typedef struct drm_fence_object {
drm_user_object_t base;
+ struct drm_device *dev;
atomic_t usage;
/*
extern void drm_fence_manager_takedown(struct drm_device *dev);
extern void drm_fence_flush_old(struct drm_device *dev, uint32_t class,
uint32_t sequence);
- extern int drm_fence_object_flush(struct drm_device *dev,
- drm_fence_object_t * fence, uint32_t type);
- extern int drm_fence_object_signaled(drm_fence_object_t * fence, uint32_t type);
- extern void drm_fence_usage_deref_locked(struct drm_device *dev,
- drm_fence_object_t * fence);
- extern void drm_fence_usage_deref_unlocked(struct drm_device *dev,
- drm_fence_object_t * fence);
- extern int drm_fence_object_wait(struct drm_device *dev,
- drm_fence_object_t * fence,
+ extern int drm_fence_object_flush(drm_fence_object_t * fence, uint32_t type);
+ extern int drm_fence_object_signaled(drm_fence_object_t * fence,
+ uint32_t type, int flush);
+ extern void drm_fence_usage_deref_locked(drm_fence_object_t ** fence);
+ extern void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence);
+ extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src);
+ extern void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+ struct drm_fence_object *src);
+ extern int drm_fence_object_wait(drm_fence_object_t * fence,
int lazy, int ignore_signals, uint32_t mask);
extern int drm_fence_object_create(struct drm_device *dev, uint32_t type,
uint32_t fence_flags, uint32_t class,
drm_fence_object_t ** c_fence);
extern int drm_fence_add_user_object(drm_file_t * priv,
drm_fence_object_t * fence, int shareable);
-extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_create_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_destroy_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_reference_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_unreference_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_signaled_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_flush_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_wait_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_emit_ioctl(DRM_IOCTL_ARGS);
+extern int drm_fence_buffers_ioctl(DRM_IOCTL_ARGS);
/**************************************************
*TTMs
*/
unsigned long num_pages;
uint32_t page_alignment;
uint32_t mem_type;
- uint32_t flags;
- uint32_t mask;
+ uint64_t flags;
+ uint64_t mask;
} drm_bo_mem_reg_t;
typedef struct drm_buffer_object {
uint32_t num_mem_busy_prio;
drm_ttm_backend_t *(*create_ttm_backend_entry)
(struct drm_device * dev);
- int (*fence_type) (struct drm_buffer_object *bo, uint32_t * class, uint32_t * type);
- int (*invalidate_caches) (struct drm_device * dev, uint32_t flags);
+ int (*fence_type) (struct drm_buffer_object *bo, uint32_t * type);
+ int (*invalidate_caches) (struct drm_device * dev, uint64_t flags);
int (*init_mem_type) (struct drm_device * dev, uint32_t type,
drm_mem_type_manager_t * man);
uint32_t(*evict_mask) (struct drm_buffer_object *bo);
* buffer objects (drm_bo.c)
*/
-extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_create_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_destroy_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_map_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_unmap_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_reference_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_unreference_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_wait_idle_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_info_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_op_ioctl(DRM_IOCTL_ARGS);
+
+
extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
+extern int drm_mm_takedown_ioctl(DRM_IOCTL_ARGS);
+extern int drm_mm_lock_ioctl(DRM_IOCTL_ARGS);
+extern int drm_mm_unlock_ioctl(DRM_IOCTL_ARGS);
extern int drm_bo_driver_finish(struct drm_device *dev);
extern int drm_bo_driver_init(struct drm_device *dev);
extern int drm_bo_pci_offset(struct drm_device *dev,
unsigned long *bus_size);
extern int drm_mem_reg_is_pci(struct drm_device *dev, drm_bo_mem_reg_t * mem);
- extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo);
+ extern void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo);
extern int drm_fence_buffer_objects(drm_file_t * priv,
struct list_head *list,
uint32_t fence_flags,
uint32_t fence_flags,
drm_bo_mem_reg_t * new_mem);
+ #ifdef CONFIG_DEBUG_MUTEXES
+ #define DRM_ASSERT_LOCKED(_mutex) \
+ BUG_ON(!mutex_is_locked(_mutex) || \
+ ((_mutex)->owner != current_thread_info()))
+ #else
+ #define DRM_ASSERT_LOCKED(_mutex)
+ #endif
+
#endif
void *hw_status_page;
dma_addr_t dma_status_page;
uint32_t counter;
+ unsigned int status_gfx_addr;
+ drm_local_map_t hws_map;
unsigned int cpp;
int use_mi_batchbuffer_start;
#ifdef I915_HAVE_BUFFER
/* i915_buffer.c */
extern drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t *dev);
-extern int i915_fence_types(drm_buffer_object_t *bo, uint32_t *class, uint32_t *type);
-extern int i915_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags);
+extern int i915_fence_types(drm_buffer_object_t *bo, uint32_t *type);
+extern int i915_invalidate_caches(drm_device_t *dev, uint64_t buffer_flags);
extern int i915_init_mem_type(drm_device_t *dev, uint32_t type,
drm_mem_type_manager_t *man);
extern uint32_t i915_evict_mask(drm_buffer_object_t *bo);
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
+ #define BREADCRUMB_BITS 31
+ #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
+
#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
#endif