Merge branch 'master' into vblank-rework, fixup remaining drivers
Conflicts: linux-core/drmP.h linux-core/drm_drv.c linux-core/drm_irq.c shared-core/i915_drv.h shared-core/i915_irq.c shared-core/mga_drv.h shared-core/mga_irq.c shared-core/radeon_drv.h shared-core/radeon_irq.c Merge in the latest master bits and update the remaining drivers (except mach64 which math_b is working on). Also remove the 9xx hack from the i915 driver; it seems to be correct.main
commit
91aae7e683
|
@ -1,55 +1,5 @@
|
|||
bsd-core/linux
|
||||
bsd-core/drm.h
|
||||
bsd-core/drm_sarea.h
|
||||
bsd-core/i915_dma.c
|
||||
bsd-core/i915_drm.h
|
||||
bsd-core/i915_drv.h
|
||||
bsd-core/i915_irq.c
|
||||
bsd-core/i915_mem.c
|
||||
bsd-core/mach64_dma.c
|
||||
bsd-core/mach64_drm.h
|
||||
bsd-core/mach64_drv.h
|
||||
bsd-core/mach64_irq.c
|
||||
bsd-core/mach64_state.c
|
||||
bsd-core/mga_dma.c
|
||||
bsd-core/mga_drm.h
|
||||
bsd-core/mga_drv.h
|
||||
bsd-core/mga_irq.c
|
||||
bsd-core/mga_state.c
|
||||
bsd-core/mga_ucode.h
|
||||
bsd-core/mga_warp.c
|
||||
bsd-core/nv_drv.h
|
||||
bsd-core/r128_cce.c
|
||||
bsd-core/r128_drm.h
|
||||
bsd-core/r128_drv.h
|
||||
bsd-core/r128_irq.c
|
||||
bsd-core/r128_state.c
|
||||
bsd-core/r300_cmdbuf.c
|
||||
bsd-core/r300_reg.h
|
||||
bsd-core/radeon_cp.c
|
||||
bsd-core/radeon_drm.h
|
||||
bsd-core/radeon_drv.h
|
||||
bsd-core/radeon_irq.c
|
||||
bsd-core/radeon_mem.c
|
||||
bsd-core/radeon_state.c
|
||||
bsd-core/savage_bci.c
|
||||
bsd-core/savage_drm.h
|
||||
bsd-core/savage_drv.h
|
||||
bsd-core/savage_state.c
|
||||
bsd-core/sis_drm.h
|
||||
bsd-core/sis_drv.h
|
||||
bsd-core/tdfx_drv.h
|
||||
bsd-core/via_3d_reg.h
|
||||
bsd-core/via_dma.c
|
||||
bsd-core/via_drm.h
|
||||
bsd-core/via_drv.c
|
||||
bsd-core/via_drv.h
|
||||
bsd-core/via_irq.c
|
||||
bsd-core/via_map.c
|
||||
bsd-core/via_verifier.c
|
||||
bsd-core/via_verifier.h
|
||||
bsd-core/via_video.c
|
||||
*~
|
||||
bsd-core/*/@
|
||||
bsd-core/*/machine
|
||||
*.flags
|
||||
*.ko
|
||||
*.ko.cmd
|
||||
|
@ -75,6 +25,7 @@ config.log
|
|||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.lineno
|
||||
cscope.*
|
||||
depcomp
|
||||
device_if.h
|
||||
|
@ -100,3 +51,13 @@ sis.kld
|
|||
stamp-h1
|
||||
tdfx.kld
|
||||
via.kld
|
||||
tests/auth
|
||||
tests/dristat
|
||||
tests/drmstat
|
||||
tests/getclient
|
||||
tests/getstats
|
||||
tests/getversion
|
||||
tests/lock
|
||||
tests/openclose
|
||||
tests/setversion
|
||||
tests/updatedraw
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
# here too, but let's just do libdrm for now
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = libdrm shared-core
|
||||
SUBDIRS = libdrm shared-core tests
|
||||
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
pkgconfig_DATA = libdrm.pc
|
||||
|
|
|
@ -1,71 +1,11 @@
|
|||
SHARED= ../shared-core
|
||||
SHAREDFILES= drm.h \
|
||||
drm_sarea.h \
|
||||
i915_dma.c \
|
||||
i915_drm.h \
|
||||
i915_drv.h \
|
||||
i915_irq.c \
|
||||
i915_mem.c \
|
||||
mach64_dma.c \
|
||||
mach64_drm.h \
|
||||
mach64_drv.h \
|
||||
mach64_irq.c \
|
||||
mach64_state.c \
|
||||
mga_dma.c \
|
||||
mga_drm.h \
|
||||
mga_drv.h \
|
||||
mga_irq.c \
|
||||
mga_state.c \
|
||||
mga_ucode.h \
|
||||
mga_warp.c \
|
||||
r128_cce.c \
|
||||
r128_drm.h \
|
||||
r128_drv.h \
|
||||
r128_irq.c \
|
||||
r128_state.c \
|
||||
radeon_cp.c \
|
||||
radeon_drm.h \
|
||||
radeon_drv.h \
|
||||
radeon_irq.c \
|
||||
radeon_mem.c \
|
||||
radeon_state.c \
|
||||
r300_cmdbuf.c \
|
||||
r300_reg.h \
|
||||
savage_bci.c \
|
||||
savage_drm.h \
|
||||
savage_drv.h \
|
||||
savage_state.c \
|
||||
sis_drm.h \
|
||||
sis_drv.h \
|
||||
sis_ds.c \
|
||||
sis_ds.h \
|
||||
sis_mm.c \
|
||||
tdfx_drv.h \
|
||||
via_3d_reg.h \
|
||||
via_dma.c \
|
||||
via_drm.h \
|
||||
via_drv.h \
|
||||
via_ds.c \
|
||||
via_ds.h \
|
||||
via_irq.c \
|
||||
via_map.c \
|
||||
via_mm.c \
|
||||
via_mm.h \
|
||||
via_verifier.c \
|
||||
via_verifier.h \
|
||||
via_video.c
|
||||
|
||||
SUBDIR = drm mach64 mga r128 radeon savage sis tdfx i915 # via
|
||||
|
||||
CLEANFILES+= ${SHAREDFILES}
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
|
||||
depend: drm_pciids.h ${SHAREDFILES}
|
||||
all: drm_pciids.h ${SHAREDFILES}
|
||||
depend: drm_pciids.h
|
||||
all: drm_pciids.h
|
||||
|
||||
drm_pciids.h: ${SHARED}/drm_pciids.txt
|
||||
sh ../scripts/create_bsd_pci_lists.sh < ${SHARED}/drm_pciids.txt
|
||||
|
||||
${SHAREDFILES}:
|
||||
ln -sf ${SHARED}/$@ $@
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* ati_pcigart.h -- ATI PCI GART support -*- linux-c -*-
|
||||
* Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
* All Rights Reserved.
|
||||
|
@ -29,6 +26,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file ati_pcigart.c
|
||||
* Implementation of ATI's PCIGART, which provides an aperture in card virtual
|
||||
* address space with addresses remapped to system memory.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../shared-core/drm.h
|
198
bsd-core/drmP.h
198
bsd-core/drmP.h
|
@ -59,6 +59,8 @@ typedef struct drm_file drm_file_t;
|
|||
#include <sys/bus.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/tree.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
@ -152,6 +154,7 @@ typedef struct drm_file drm_file_t;
|
|||
#define DRM_MEM_CTXBITMAP 17
|
||||
#define DRM_MEM_STUB 18
|
||||
#define DRM_MEM_SGLISTS 19
|
||||
#define DRM_MEM_DRAWABLE 20
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||
|
||||
|
@ -184,10 +187,15 @@ MALLOC_DECLARE(M_DRM);
|
|||
#define DRM_CURPROC curthread
|
||||
#define DRM_STRUCTPROC struct thread
|
||||
#define DRM_SPINTYPE struct mtx
|
||||
#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
|
||||
#define DRM_SPINUNINIT(l) mtx_destroy(&l)
|
||||
#define DRM_SPININIT(l,name) mtx_init(l, name, NULL, MTX_DEF)
|
||||
#define DRM_SPINUNINIT(l) mtx_destroy(l)
|
||||
#define DRM_SPINLOCK(l) mtx_lock(l)
|
||||
#define DRM_SPINUNLOCK(u) mtx_unlock(u);
|
||||
#define DRM_SPINUNLOCK(u) mtx_unlock(u)
|
||||
#define DRM_SPINLOCK_IRQSAVE(l, irqflags) do { \
|
||||
mtx_lock(l); \
|
||||
(void)irqflags; \
|
||||
} while (0)
|
||||
#define DRM_SPINUNLOCK_IRQRESTORE(u, irqflags) mtx_unlock(u)
|
||||
#define DRM_SPINLOCK_ASSERT(l) mtx_assert(l, MA_OWNED)
|
||||
#define DRM_CURRENTPID curthread->td_proc->p_pid
|
||||
#define DRM_LOCK() mtx_lock(&dev->dev_lock)
|
||||
|
@ -209,10 +217,6 @@ MALLOC_DECLARE(M_DRM);
|
|||
#define spldrm() spltty()
|
||||
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
/* Currently our DRMFILE (filp) is a void * which is actually the pid
|
||||
* of the current process. It should be a per-open unique pointer, but
|
||||
* code for that is not yet written */
|
||||
#define DRMFILE void *
|
||||
#define DRM_IRQ_ARGS void *arg
|
||||
typedef void irqreturn_t;
|
||||
#define IRQ_HANDLED /* nothing */
|
||||
|
@ -226,11 +230,15 @@ enum {
|
|||
#define DRM_AGP_MEM struct agp_memory_info
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define DRM_DEVICE \
|
||||
drm_device_t *dev = kdev->si_drv1
|
||||
#define DRM_IOCTL_ARGS struct cdev *kdev, u_long cmd, caddr_t data, \
|
||||
int flags, DRM_STRUCTPROC *p, DRMFILE filp
|
||||
#define drm_get_device_from_kdev(_kdev) (_kdev->si_drv1)
|
||||
#elif defined(__NetBSD__)
|
||||
#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, minor(_kdev))
|
||||
#elif defined(__OpenBSD__)
|
||||
#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, \
|
||||
minor(_kdev)))->dv_cfdata->cf_driver->cd_devs[minor(_kdev)]
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define PAGE_ALIGN(addr) round_page(addr)
|
||||
/* DRM_SUSER returns true if the user is superuser */
|
||||
#if __FreeBSD_version >= 700000
|
||||
|
@ -244,17 +252,6 @@ enum {
|
|||
|
||||
#else /* __FreeBSD__ */
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
#define DRM_DEVICE \
|
||||
drm_device_t *dev = device_lookup(&drm_cd, minor(kdev))
|
||||
#elif defined(__OpenBSD__)
|
||||
#define DRM_DEVICE \
|
||||
drm_device_t *dev = (device_lookup(&drm_cd, \
|
||||
minor(kdev)))->dv_cfdata->cf_driver->cd_devs[minor(kdev)]
|
||||
#endif /* __OpenBSD__ */
|
||||
#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, \
|
||||
int flags, DRM_STRUCTPROC *p, DRMFILE filp
|
||||
|
||||
#define CDEV_MAJOR 34
|
||||
#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
|
||||
/* DRM_SUSER returns true if the user is superuser */
|
||||
|
@ -342,14 +339,6 @@ typedef vaddr_t vm_offset_t;
|
|||
(!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
||||
#endif /* !__FreeBSD__ */
|
||||
|
||||
#define DRM_COPY_TO_USER_IOCTL(user, kern, size) \
|
||||
if ( IOCPARM_LEN(cmd) != size) \
|
||||
return EINVAL; \
|
||||
*user = kern;
|
||||
#define DRM_COPY_FROM_USER_IOCTL(kern, user, size) \
|
||||
if ( IOCPARM_LEN(cmd) != size) \
|
||||
return EINVAL; \
|
||||
kern = *user;
|
||||
#define DRM_COPY_TO_USER(user, kern, size) \
|
||||
copyout(kern, user, size)
|
||||
#define DRM_COPY_FROM_USER(kern, user, size) \
|
||||
|
@ -369,7 +358,6 @@ typedef vaddr_t vm_offset_t;
|
|||
#define cpu_to_le32(x) htole32(x)
|
||||
#define le32_to_cpu(x) le32toh(x)
|
||||
|
||||
#define DRM_ERR(v) v
|
||||
#define DRM_HZ hz
|
||||
#define DRM_UDELAY(udelay) DELAY(udelay)
|
||||
#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
|
||||
|
@ -378,23 +366,10 @@ typedef vaddr_t vm_offset_t;
|
|||
(_map) = (_dev)->context_sareas[_ctx]; \
|
||||
} while(0)
|
||||
|
||||
#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) \
|
||||
do { \
|
||||
if (_filp != (DRMFILE)(intptr_t)DRM_CURRENTPID) { \
|
||||
DRM_ERROR("filp doesn't match curproc\n"); \
|
||||
return EINVAL; \
|
||||
} \
|
||||
_priv = drm_find_file_by_proc(dev, DRM_CURPROC); \
|
||||
if (_priv == NULL) { \
|
||||
DRM_ERROR("can't find authenticator\n"); \
|
||||
return EINVAL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOCK_TEST_WITH_RETURN(dev, filp) \
|
||||
#define LOCK_TEST_WITH_RETURN(dev, file_priv) \
|
||||
do { \
|
||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \
|
||||
dev->lock.filp != filp) { \
|
||||
dev->lock.file_priv != file_priv) { \
|
||||
DRM_ERROR("%s called without lock held\n", \
|
||||
__FUNCTION__); \
|
||||
return EINVAL; \
|
||||
|
@ -402,22 +377,24 @@ do { \
|
|||
} while (0)
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version > 500000
|
||||
/* Returns -errno to shared code */
|
||||
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
|
||||
for ( ret = 0 ; !ret && !(condition) ; ) { \
|
||||
DRM_UNLOCK(); \
|
||||
mtx_lock(&dev->irq_lock); \
|
||||
if (!(condition)) \
|
||||
ret = msleep(&(queue), &dev->irq_lock, \
|
||||
ret = -msleep(&(queue), &dev->irq_lock, \
|
||||
PZERO | PCATCH, "drmwtq", (timeout)); \
|
||||
mtx_unlock(&dev->irq_lock); \
|
||||
DRM_LOCK(); \
|
||||
}
|
||||
#else
|
||||
/* Returns -errno to shared code */
|
||||
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
|
||||
for ( ret = 0 ; !ret && !(condition) ; ) { \
|
||||
int s = spldrm(); \
|
||||
if (!(condition)) \
|
||||
ret = tsleep( &(queue), PZERO | PCATCH, \
|
||||
ret = -tsleep( &(queue), PZERO | PCATCH, \
|
||||
"drmwtq", (timeout) ); \
|
||||
splx(s); \
|
||||
}
|
||||
|
@ -447,9 +424,16 @@ typedef struct drm_pci_id_list
|
|||
#define DRM_MASTER 0x2
|
||||
#define DRM_ROOT_ONLY 0x4
|
||||
typedef struct drm_ioctl_desc {
|
||||
int (*func)(DRM_IOCTL_ARGS);
|
||||
unsigned long cmd;
|
||||
int (*func)(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int flags;
|
||||
} drm_ioctl_desc_t;
|
||||
/**
|
||||
* Creates a driver or general drm_ioctl_desc array entry for the given
|
||||
* ioctl, for use by drm_ioctl().
|
||||
*/
|
||||
#define DRM_IOCTL_DEF(ioctl, func, flags) \
|
||||
[DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags}
|
||||
|
||||
typedef struct drm_magic_entry {
|
||||
drm_magic_t magic;
|
||||
|
@ -472,7 +456,7 @@ typedef struct drm_buf {
|
|||
unsigned long bus_address; /* Bus address of buffer */
|
||||
struct drm_buf *next; /* Kernel-only: used for free list */
|
||||
__volatile__ int pending; /* On hardware DMA queue */
|
||||
DRMFILE filp; /* Unique identifier of holding process */
|
||||
struct drm_file *file_priv; /* Unique identifier of holding process */
|
||||
int context; /* Kernel queue for this buffer */
|
||||
enum {
|
||||
DRM_LIST_NONE = 0,
|
||||
|
@ -534,7 +518,7 @@ struct drm_file {
|
|||
|
||||
typedef struct drm_lock_data {
|
||||
drm_hw_lock_t *hw_lock; /* Hardware lock */
|
||||
DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/
|
||||
struct drm_file *file_priv; /* Unique identifier of holding process (NULL is kernel)*/
|
||||
int lock_queue; /* Queue of blocked processes */
|
||||
unsigned long lock_time; /* Time of last lock in jiffies */
|
||||
} drm_lock_data_t;
|
||||
|
@ -638,12 +622,13 @@ struct drm_driver_info {
|
|||
int (*load)(struct drm_device *, unsigned long flags);
|
||||
int (*firstopen)(struct drm_device *);
|
||||
int (*open)(struct drm_device *, drm_file_t *);
|
||||
void (*preclose)(struct drm_device *, void *filp);
|
||||
void (*preclose)(struct drm_device *, struct drm_file *file_priv);
|
||||
void (*postclose)(struct drm_device *, drm_file_t *);
|
||||
void (*lastclose)(struct drm_device *);
|
||||
int (*unload)(struct drm_device *);
|
||||
void (*reclaim_buffers_locked)(struct drm_device *, void *filp);
|
||||
int (*dma_ioctl)(DRM_IOCTL_ARGS);
|
||||
void (*reclaim_buffers_locked)(struct drm_device *,
|
||||
struct drm_file *file_priv);
|
||||
int (*dma_ioctl)(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
void (*dma_ready)(struct drm_device *);
|
||||
int (*dma_quiescent)(struct drm_device *);
|
||||
int (*dma_flush_block_and_flush)(struct drm_device *, int context,
|
||||
|
@ -732,6 +717,8 @@ struct drm_device {
|
|||
struct mtx irq_lock; /* protects irq condition checks */
|
||||
struct mtx dev_lock; /* protects everything else */
|
||||
#endif
|
||||
DRM_SPINTYPE drw_lock;
|
||||
|
||||
/* Usage Counters */
|
||||
int open_count; /* Outstanding files open */
|
||||
int buf_use; /* Buffers in use -- cannot alloc */
|
||||
|
@ -780,6 +767,7 @@ struct drm_device {
|
|||
int last_context; /* Last current context */
|
||||
int vbl_queue; /* vbl wait channel */
|
||||
atomic_t vbl_received;
|
||||
atomic_t vbl_received2;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
struct sigio *buf_sigio; /* Processes waiting for SIGIO */
|
||||
|
@ -796,6 +784,13 @@ struct drm_device {
|
|||
void *dev_private;
|
||||
unsigned int agp_buffer_token;
|
||||
drm_local_map_t *agp_buffer_map;
|
||||
|
||||
struct unrhdr *drw_unrhdr;
|
||||
/* RB tree of drawable infos */
|
||||
RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head;
|
||||
|
||||
struct task locked_task;
|
||||
void (*locked_task_call)(drm_device_t *dev);
|
||||
};
|
||||
|
||||
extern int drm_debug_flag;
|
||||
|
@ -883,7 +878,7 @@ int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
|
|||
int drm_dma_setup(drm_device_t *dev);
|
||||
void drm_dma_takedown(drm_device_t *dev);
|
||||
void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
|
||||
void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp);
|
||||
void drm_reclaim_buffers(drm_device_t *dev, struct drm_file *file_priv);
|
||||
#define drm_core_reclaim_buffers drm_reclaim_buffers
|
||||
|
||||
/* IRQ support (drm_irq.c) */
|
||||
|
@ -915,6 +910,7 @@ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
|
|||
|
||||
/* Scatter Gather Support (drm_scatter.c) */
|
||||
void drm_sg_cleanup(drm_sg_mem_t *entry);
|
||||
int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* sysctl support (drm_sysctl.h) */
|
||||
|
@ -929,68 +925,72 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev,
|
|||
drm_ati_pcigart_info *gart_info);
|
||||
|
||||
/* Locking IOCTL support (drm_drv.c) */
|
||||
int drm_lock(DRM_IOCTL_ARGS);
|
||||
int drm_unlock(DRM_IOCTL_ARGS);
|
||||
int drm_version(DRM_IOCTL_ARGS);
|
||||
int drm_setversion(DRM_IOCTL_ARGS);
|
||||
int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_version(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_setversion(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* Misc. IOCTL support (drm_ioctl.c) */
|
||||
int drm_irq_by_busid(DRM_IOCTL_ARGS);
|
||||
int drm_getunique(DRM_IOCTL_ARGS);
|
||||
int drm_setunique(DRM_IOCTL_ARGS);
|
||||
int drm_getmap(DRM_IOCTL_ARGS);
|
||||
int drm_getclient(DRM_IOCTL_ARGS);
|
||||
int drm_getstats(DRM_IOCTL_ARGS);
|
||||
int drm_noop(DRM_IOCTL_ARGS);
|
||||
int drm_irq_by_busid(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_getunique(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_setunique(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_getmap(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_getclient(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_getstats(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_noop(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* Context IOCTL support (drm_context.c) */
|
||||
int drm_resctx(DRM_IOCTL_ARGS);
|
||||
int drm_addctx(DRM_IOCTL_ARGS);
|
||||
int drm_modctx(DRM_IOCTL_ARGS);
|
||||
int drm_getctx(DRM_IOCTL_ARGS);
|
||||
int drm_switchctx(DRM_IOCTL_ARGS);
|
||||
int drm_newctx(DRM_IOCTL_ARGS);
|
||||
int drm_rmctx(DRM_IOCTL_ARGS);
|
||||
int drm_setsareactx(DRM_IOCTL_ARGS);
|
||||
int drm_getsareactx(DRM_IOCTL_ARGS);
|
||||
int drm_resctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_addctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_modctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_getctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_switchctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_newctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_rmctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_setsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_getsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* Drawable IOCTL support (drm_drawable.c) */
|
||||
int drm_adddraw(DRM_IOCTL_ARGS);
|
||||
int drm_rmdraw(DRM_IOCTL_ARGS);
|
||||
int drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
struct drm_drawable_info *drm_get_drawable_info(drm_device_t *dev, int handle);
|
||||
|
||||
/* Authentication IOCTL support (drm_auth.c) */
|
||||
int drm_getmagic(DRM_IOCTL_ARGS);
|
||||
int drm_authmagic(DRM_IOCTL_ARGS);
|
||||
int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* Buffer management support (drm_bufs.c) */
|
||||
int drm_addmap_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_rmmap_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_addbufs_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_infobufs(DRM_IOCTL_ARGS);
|
||||
int drm_markbufs(DRM_IOCTL_ARGS);
|
||||
int drm_freebufs(DRM_IOCTL_ARGS);
|
||||
int drm_mapbufs(DRM_IOCTL_ARGS);
|
||||
int drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_rmmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_addbufs_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_infobufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_markbufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_freebufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* DMA support (drm_dma.c) */
|
||||
int drm_dma(DRM_IOCTL_ARGS);
|
||||
int drm_dma(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* IRQ support (drm_irq.c) */
|
||||
int drm_control(DRM_IOCTL_ARGS);
|
||||
int drm_wait_vblank(DRM_IOCTL_ARGS);
|
||||
int drm_control(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
void drm_locked_tasklet(drm_device_t *dev,
|
||||
void (*tasklet)(drm_device_t *dev));
|
||||
|
||||
/* AGP/GART support (drm_agpsupport.c) */
|
||||
int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_release_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_enable_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_info_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_free_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_bind_ioctl(DRM_IOCTL_ARGS);
|
||||
int drm_agp_acquire_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_release_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_enable_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_info_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_free_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_unbind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_agp_bind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* Scatter Gather Support (drm_scatter.c) */
|
||||
int drm_sg_alloc(DRM_IOCTL_ARGS);
|
||||
int drm_sg_free(DRM_IOCTL_ARGS);
|
||||
int drm_sg_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int drm_sg_free(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
|
||||
/* consistent PCI memory functions (drm_pci.c) */
|
||||
drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_agpsupport.h -- DRM support for AGP/GART backend -*- linux-c -*-
|
||||
* Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_agpsupport.c
|
||||
* Support code for tying the kernel AGP support to DRM drivers and
|
||||
* the DRM's AGP ioctls.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -125,11 +127,10 @@ int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_agp_info_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_info_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int err;
|
||||
drm_agp_info_t info;
|
||||
DRM_DEVICE;
|
||||
|
||||
err = drm_agp_info(dev, &info);
|
||||
if (err != 0)
|
||||
|
@ -139,9 +140,8 @@ int drm_agp_info_ioctl(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_acquire_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
|
||||
return drm_agp_acquire(dev);
|
||||
}
|
||||
|
@ -161,9 +161,8 @@ int drm_agp_acquire(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_agp_release_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_release_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
|
||||
return drm_agp_release(dev);
|
||||
}
|
||||
|
@ -185,15 +184,13 @@ int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
|
|||
|
||||
dev->agp->mode = mode.mode;
|
||||
agp_enable(dev->agp->agpdev, mode.mode);
|
||||
dev->agp->base = dev->agp->info.ai_aperture_base;
|
||||
dev->agp->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_agp_enable_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_enable_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_agp_mode_t mode;
|
||||
DRM_DEVICE;
|
||||
|
||||
mode = *(drm_agp_mode_t *) data;
|
||||
|
||||
|
@ -243,9 +240,8 @@ int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_agp_buffer_t request;
|
||||
int retcode;
|
||||
|
||||
|
@ -292,9 +288,8 @@ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_unbind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_agp_binding_t request;
|
||||
int retcode;
|
||||
|
||||
|
@ -333,9 +328,8 @@ int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int drm_agp_bind_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_bind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_agp_binding_t request;
|
||||
int retcode;
|
||||
|
||||
|
@ -378,9 +372,8 @@ int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
|
|||
|
||||
}
|
||||
|
||||
int drm_agp_free_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_agp_free_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_agp_buffer_t request;
|
||||
int retcode;
|
||||
|
||||
|
@ -411,6 +404,7 @@ drm_agp_head_t *drm_agp_init(void)
|
|||
return NULL;
|
||||
head->agpdev = agpdev;
|
||||
agp_get_info(agpdev, &head->info);
|
||||
head->base = head->info.ai_aperture_base;
|
||||
head->memory = NULL;
|
||||
DRM_INFO("AGP at 0x%08lx %dMB\n",
|
||||
(long)head->info.ai_aperture_base,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_auth.h -- IOCTLs for authentication -*- linux-c -*-
|
||||
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_auth.c
|
||||
* Implementation of the get/authmagic ioctls implementing the authentication
|
||||
* scheme between the master and clients.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
static int drm_hash_magic(drm_magic_t magic)
|
||||
|
@ -38,25 +40,29 @@ static int drm_hash_magic(drm_magic_t magic)
|
|||
return magic & (DRM_HASH_SIZE-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file private associated with the given magic number.
|
||||
*/
|
||||
static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
||||
{
|
||||
drm_file_t *retval = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
int hash;
|
||||
int hash = drm_hash_magic(magic);
|
||||
|
||||
hash = drm_hash_magic(magic);
|
||||
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
|
||||
|
||||
DRM_LOCK();
|
||||
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
|
||||
if (pt->magic == magic) {
|
||||
retval = pt->priv;
|
||||
break;
|
||||
return pt->priv;
|
||||
}
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
return retval;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the given magic number into the hash table of used magic number
|
||||
* lists.
|
||||
*/
|
||||
static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
||||
{
|
||||
int hash;
|
||||
|
@ -64,9 +70,11 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
|||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
|
||||
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
|
||||
|
||||
hash = drm_hash_magic(magic);
|
||||
entry = malloc(sizeof(*entry), M_DRM, M_ZERO | M_NOWAIT);
|
||||
if (!entry) return DRM_ERR(ENOMEM);
|
||||
if (!entry) return ENOMEM;
|
||||
entry->magic = magic;
|
||||
entry->priv = priv;
|
||||
entry->next = NULL;
|
||||
|
@ -84,16 +92,21 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given magic number from the hash table of used magic number
|
||||
* lists.
|
||||
*/
|
||||
static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
|
||||
{
|
||||
drm_magic_entry_t *prev = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
int hash;
|
||||
|
||||
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
hash = drm_hash_magic(magic);
|
||||
|
||||
DRM_LOCK();
|
||||
for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
|
||||
if (pt->magic == magic) {
|
||||
if (dev->magiclist[hash].head == pt) {
|
||||
|
@ -105,68 +118,69 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
|
|||
if (prev) {
|
||||
prev->next = pt->next;
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
|
||||
free(pt, M_DRM);
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int drm_getmagic(DRM_IOCTL_ARGS)
|
||||
/**
|
||||
* Called by the client, this returns a unique magic number to be authorized
|
||||
* by the master.
|
||||
*
|
||||
* The master may use its own knowledge of the client (such as the X
|
||||
* connection that the magic is passed over) to determine if the magic number
|
||||
* should be authenticated.
|
||||
*/
|
||||
int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
static drm_magic_t sequence = 0;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *priv;
|
||||
|
||||
DRM_LOCK();
|
||||
priv = drm_find_file_by_proc(dev, p);
|
||||
DRM_UNLOCK();
|
||||
if (priv == NULL) {
|
||||
DRM_ERROR("can't find authenticator\n");
|
||||
return EINVAL;
|
||||
}
|
||||
drm_auth_t *auth = data;
|
||||
|
||||
/* Find unique magic */
|
||||
if (priv->magic) {
|
||||
auth.magic = priv->magic;
|
||||
if (file_priv->magic) {
|
||||
auth->magic = file_priv->magic;
|
||||
} else {
|
||||
DRM_LOCK();
|
||||
do {
|
||||
int old = sequence;
|
||||
|
||||
auth.magic = old+1;
|
||||
auth->magic = old+1;
|
||||
|
||||
if (!atomic_cmpset_int(&sequence, old, auth.magic))
|
||||
if (!atomic_cmpset_int(&sequence, old, auth->magic))
|
||||
continue;
|
||||
} while (drm_find_file(dev, auth.magic));
|
||||
priv->magic = auth.magic;
|
||||
drm_add_magic(dev, priv, auth.magic);
|
||||
} while (drm_find_file(dev, auth->magic));
|
||||
file_priv->magic = auth->magic;
|
||||
drm_add_magic(dev, file_priv, auth->magic);
|
||||
DRM_UNLOCK();
|
||||
}
|
||||
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_auth_t *)data, auth, sizeof(auth));
|
||||
DRM_DEBUG("%u\n", auth->magic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_authmagic(DRM_IOCTL_ARGS)
|
||||
/**
|
||||
* Marks the client associated with the given magic number as authenticated.
|
||||
*/
|
||||
int drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_auth_t auth;
|
||||
drm_file_t *file;
|
||||
DRM_DEVICE;
|
||||
drm_auth_t *auth = data;
|
||||
drm_file_t *priv;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth));
|
||||
DRM_DEBUG("%u\n", auth->magic);
|
||||
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
|
||||
if ((file = drm_find_file(dev, auth.magic))) {
|
||||
file->authenticated = 1;
|
||||
drm_remove_magic(dev, auth.magic);
|
||||
DRM_LOCK();
|
||||
priv = drm_find_file(dev, auth->magic);
|
||||
if (priv != NULL) {
|
||||
priv->authenticated = 1;
|
||||
drm_remove_magic(dev, auth->magic);
|
||||
DRM_UNLOCK();
|
||||
return 0;
|
||||
} else {
|
||||
DRM_UNLOCK();
|
||||
return EINVAL;
|
||||
}
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_bufs.h -- Generic buffer template -*- linux-c -*-
|
||||
* Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_bufs.c
|
||||
* Implementation of the ioctls for setup of DRM mappings and DMA buffers.
|
||||
*/
|
||||
|
||||
#include "dev/pci/pcireg.h"
|
||||
|
||||
#include "drmP.h"
|
||||
|
@ -149,7 +150,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
*/
|
||||
map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT);
|
||||
if ( !map )
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
|
||||
map->offset = offset;
|
||||
map->size = size;
|
||||
|
@ -172,7 +173,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
map->size, drm_order(map->size), map->handle );
|
||||
if ( !map->handle ) {
|
||||
free(map, M_DRM);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
map->offset = (unsigned long)map->handle;
|
||||
if ( map->flags & _DRM_CONTAINS_LOCK ) {
|
||||
|
@ -182,7 +183,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
DRM_UNLOCK();
|
||||
free(map->handle, M_DRM);
|
||||
free(map, M_DRM);
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
dev->lock.hw_lock = map->handle; /* Pointer to lock */
|
||||
DRM_UNLOCK();
|
||||
|
@ -190,7 +191,17 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
break;
|
||||
case _DRM_AGP:
|
||||
/*valid = 0;*/
|
||||
map->offset += dev->agp->base;
|
||||
/* In some cases (i810 driver), user space may have already
|
||||
* added the AGP base itself, because dev->agp->base previously
|
||||
* only got set during AGP enable. So, only add the base
|
||||
* address if the map's offset isn't already within the
|
||||
* aperture.
|
||||
*/
|
||||
if (map->offset < dev->agp->base ||
|
||||
map->offset > dev->agp->base +
|
||||
dev->agp->info.ai_aperture_size - 1) {
|
||||
map->offset += dev->agp->base;
|
||||
}
|
||||
map->mtrr = dev->agp->mtrr; /* for getmap */
|
||||
/*for (entry = dev->agp->memory; entry; entry = entry->next) {
|
||||
if ((map->offset >= entry->bound) &&
|
||||
|
@ -202,13 +213,13 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
}
|
||||
if (!valid) {
|
||||
free(map, M_DRM);
|
||||
return DRM_ERR(EACCES);
|
||||
return EACCES;
|
||||
}*/
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
if (!dev->sg) {
|
||||
free(map, M_DRM);
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
map->offset = map->offset + dev->sg->handle;
|
||||
break;
|
||||
|
@ -225,7 +236,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful);
|
||||
if (map->dmah == NULL) {
|
||||
free(map, M_DRM);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
map->handle = map->dmah->vaddr;
|
||||
map->offset = map->dmah->busaddr;
|
||||
|
@ -233,7 +244,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
|
|||
default:
|
||||
DRM_ERROR("Bad map type %d\n", map->type);
|
||||
free(map, M_DRM);
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
DRM_LOCK();
|
||||
|
@ -250,39 +261,35 @@ done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_addmap_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_map_t request;
|
||||
drm_map_t *request = data;
|
||||
drm_local_map_t *map;
|
||||
int err;
|
||||
DRM_DEVICE;
|
||||
|
||||
if (!(dev->flags & (FREAD|FWRITE)))
|
||||
return DRM_ERR(EACCES); /* Require read/write */
|
||||
return EACCES; /* Require read/write */
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(request, (drm_map_t *)data, sizeof(drm_map_t));
|
||||
|
||||
if (!DRM_SUSER(p) && request.type != _DRM_AGP)
|
||||
return DRM_ERR(EACCES);
|
||||
if (!DRM_SUSER(DRM_CURPROC) && request->type != _DRM_AGP)
|
||||
return EACCES;
|
||||
|
||||
DRM_LOCK();
|
||||
err = drm_addmap(dev, request.offset, request.size, request.type,
|
||||
request.flags, &map);
|
||||
err = drm_addmap(dev, request->offset, request->size, request->type,
|
||||
request->flags, &map);
|
||||
DRM_UNLOCK();
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
request.offset = map->offset;
|
||||
request.size = map->size;
|
||||
request.type = map->type;
|
||||
request.flags = map->flags;
|
||||
request.mtrr = map->mtrr;
|
||||
request.handle = map->handle;
|
||||
request->offset = map->offset;
|
||||
request->size = map->size;
|
||||
request->type = map->type;
|
||||
request->flags = map->flags;
|
||||
request->mtrr = map->mtrr;
|
||||
request->handle = map->handle;
|
||||
|
||||
if (request.type != _DRM_SHM) {
|
||||
request.handle = (void *)request.offset;
|
||||
if (request->type != _DRM_SHM) {
|
||||
request->handle = (void *)request->offset;
|
||||
}
|
||||
DRM_COPY_TO_USER_IOCTL((drm_map_t *)data, request, sizeof(drm_map_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -333,17 +340,14 @@ void drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
|
|||
* isn't in use.
|
||||
*/
|
||||
|
||||
int drm_rmmap_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_rmmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_local_map_t *map;
|
||||
drm_map_t request;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) );
|
||||
drm_map_t *request = data;
|
||||
|
||||
DRM_LOCK();
|
||||
TAILQ_FOREACH(map, &dev->maplist, link) {
|
||||
if (map->handle == request.handle &&
|
||||
if (map->handle == request->handle &&
|
||||
map->flags & _DRM_REMOVABLE)
|
||||
break;
|
||||
}
|
||||
|
@ -351,7 +355,7 @@ int drm_rmmap_ioctl(DRM_IOCTL_ARGS)
|
|||
/* No match found. */
|
||||
if (map == NULL) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
drm_rmmap(dev, map);
|
||||
|
@ -441,7 +445,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
}
|
||||
if (!valid) {
|
||||
DRM_DEBUG("zone invalid\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}*/
|
||||
|
||||
entry = &dma->bufs[order];
|
||||
|
@ -449,7 +453,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if ( !entry->buflist ) {
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
entry->buf_size = size;
|
||||
|
@ -469,7 +473,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
buf->address = (void *)(agp_offset + offset);
|
||||
buf->next = NULL;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver.buf_priv_size;
|
||||
buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
|
||||
|
@ -478,7 +482,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
/* Set count correctly so we free the proper amount. */
|
||||
entry->buf_count = count;
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
offset += alignment;
|
||||
|
@ -494,7 +498,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
if (temp_buflist == NULL) {
|
||||
/* Free the entry because it isn't valid */
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
dma->buflist = temp_buflist;
|
||||
|
||||
|
@ -563,7 +567,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
temp_pagelist == NULL) {
|
||||
free(entry->buflist, M_DRM);
|
||||
free(entry->seglist, M_DRM);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(temp_pagelist, dma->pagelist, dma->page_count *
|
||||
|
@ -586,7 +590,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
entry->seg_count = count;
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
free(temp_pagelist, M_DRM);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
entry->seglist[entry->seg_count++] = dmah;
|
||||
|
@ -610,7 +614,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
buf->bus_address = dmah->busaddr + offset;
|
||||
buf->next = NULL;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver.buf_priv_size;
|
||||
buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
|
||||
|
@ -621,7 +625,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
entry->seg_count = count;
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
free(temp_pagelist, M_DRM);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "buffer %d @ %p\n",
|
||||
|
@ -637,7 +641,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
/* Free the entry because it isn't valid */
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
free(temp_pagelist, M_DRM);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
dma->buflist = temp_buflist;
|
||||
|
||||
|
@ -705,7 +709,7 @@ static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (entry->buflist == NULL)
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
|
||||
entry->buf_size = size;
|
||||
entry->page_order = page_order;
|
||||
|
@ -724,7 +728,7 @@ static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
buf->address = (void *)(agp_offset + offset + dev->sg->handle);
|
||||
buf->next = NULL;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver.buf_priv_size;
|
||||
buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
|
||||
|
@ -733,7 +737,7 @@ static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
/* Set count correctly so we free the proper amount. */
|
||||
entry->buf_count = count;
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "buffer %d @ %p\n",
|
||||
|
@ -752,7 +756,7 @@ static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
if (temp_buflist == NULL) {
|
||||
/* Free the entry because it isn't valid */
|
||||
drm_cleanup_buf_error(dev, entry);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
dma->buflist = temp_buflist;
|
||||
|
||||
|
@ -781,21 +785,21 @@ int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
|
||||
if (request->count < 0 || request->count > 4096)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
order = drm_order(request->size);
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
/* No more allocations after first buffer-using ioctl. */
|
||||
if (dev->buf_use != 0) {
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
/* No more than one allocation per order */
|
||||
if (dev->dma->bufs[order].buf_count != 0) {
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = drm_do_addbufs_agp(dev, request);
|
||||
|
@ -812,24 +816,24 @@ int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
|
||||
if (!DRM_SUSER(DRM_CURPROC))
|
||||
return DRM_ERR(EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (request->count < 0 || request->count > 4096)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
order = drm_order(request->size);
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
/* No more allocations after first buffer-using ioctl. */
|
||||
if (dev->buf_use != 0) {
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
/* No more than one allocation per order */
|
||||
if (dev->dma->bufs[order].buf_count != 0) {
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = drm_do_addbufs_sg(dev, request);
|
||||
|
@ -846,24 +850,24 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
|
||||
if (!DRM_SUSER(DRM_CURPROC))
|
||||
return DRM_ERR(EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (request->count < 0 || request->count > 4096)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
order = drm_order(request->size);
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
/* No more allocations after first buffer-using ioctl. */
|
||||
if (dev->buf_use != 0) {
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
/* No more than one allocation per order */
|
||||
if (dev->dma->bufs[order].buf_count != 0) {
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = drm_do_addbufs_pci(dev, request);
|
||||
|
@ -873,39 +877,29 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int drm_addbufs_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_addbufs_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_buf_desc_t request;
|
||||
drm_buf_desc_t *request = data;
|
||||
int err;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(request, (drm_buf_desc_t *)data,
|
||||
sizeof(request));
|
||||
|
||||
if (request.flags & _DRM_AGP_BUFFER)
|
||||
err = drm_addbufs_agp(dev, &request);
|
||||
else if (request.flags & _DRM_SG_BUFFER)
|
||||
err = drm_addbufs_sg(dev, &request);
|
||||
if (request->flags & _DRM_AGP_BUFFER)
|
||||
err = drm_addbufs_agp(dev, request);
|
||||
else if (request->flags & _DRM_SG_BUFFER)
|
||||
err = drm_addbufs_sg(dev, request);
|
||||
else
|
||||
err = drm_addbufs_pci(dev, &request);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request,
|
||||
sizeof(request));
|
||||
err = drm_addbufs_pci(dev, request);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int drm_infobufs(DRM_IOCTL_ARGS)
|
||||
int drm_infobufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_info_t request;
|
||||
drm_buf_info_t *request = data;
|
||||
int i;
|
||||
int count;
|
||||
int retcode = 0;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) );
|
||||
|
||||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
++dev->buf_use; /* Can't allocate more after this call */
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
|
@ -916,7 +910,7 @@ int drm_infobufs(DRM_IOCTL_ARGS)
|
|||
|
||||
DRM_DEBUG( "count = %d\n", count );
|
||||
|
||||
if ( request.count >= count ) {
|
||||
if ( request->count >= count ) {
|
||||
for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
|
||||
if ( dma->bufs[i].buf_count ) {
|
||||
drm_buf_desc_t from;
|
||||
|
@ -926,9 +920,9 @@ int drm_infobufs(DRM_IOCTL_ARGS)
|
|||
from.low_mark = dma->bufs[i].freelist.low_mark;
|
||||
from.high_mark = dma->bufs[i].freelist.high_mark;
|
||||
|
||||
if (DRM_COPY_TO_USER(&request.list[count], &from,
|
||||
if (DRM_COPY_TO_USER(&request->list[count], &from,
|
||||
sizeof(drm_buf_desc_t)) != 0) {
|
||||
retcode = DRM_ERR(EFAULT);
|
||||
retcode = EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -942,76 +936,68 @@ int drm_infobufs(DRM_IOCTL_ARGS)
|
|||
}
|
||||
}
|
||||
}
|
||||
request.count = count;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) );
|
||||
request->count = count;
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int drm_markbufs(DRM_IOCTL_ARGS)
|
||||
int drm_markbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
drm_buf_desc_t *request = data;
|
||||
int order;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) );
|
||||
|
||||
DRM_DEBUG( "%d, %d, %d\n",
|
||||
request.size, request.low_mark, request.high_mark );
|
||||
request->size, request->low_mark, request->high_mark );
|
||||
|
||||
|
||||
order = drm_order(request.size);
|
||||
order = drm_order(request->size);
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ||
|
||||
request.low_mark < 0 || request.high_mark < 0) {
|
||||
return DRM_ERR(EINVAL);
|
||||
request->low_mark < 0 || request->high_mark < 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
if (request.low_mark > dma->bufs[order].buf_count ||
|
||||
request.high_mark > dma->bufs[order].buf_count) {
|
||||
return DRM_ERR(EINVAL);
|
||||
if (request->low_mark > dma->bufs[order].buf_count ||
|
||||
request->high_mark > dma->bufs[order].buf_count) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
dma->bufs[order].freelist.low_mark = request.low_mark;
|
||||
dma->bufs[order].freelist.high_mark = request.high_mark;
|
||||
dma->bufs[order].freelist.low_mark = request->low_mark;
|
||||
dma->bufs[order].freelist.high_mark = request->high_mark;
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_freebufs(DRM_IOCTL_ARGS)
|
||||
int drm_freebufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_free_t request;
|
||||
drm_buf_free_t *request = data;
|
||||
int i;
|
||||
int idx;
|
||||
drm_buf_t *buf;
|
||||
int retcode = 0;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) );
|
||||
|
||||
DRM_DEBUG( "%d\n", request.count );
|
||||
DRM_DEBUG( "%d\n", request->count );
|
||||
|
||||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
for ( i = 0 ; i < request.count ; i++ ) {
|
||||
if (DRM_COPY_FROM_USER(&idx, &request.list[i], sizeof(idx))) {
|
||||
retcode = DRM_ERR(EFAULT);
|
||||
for ( i = 0 ; i < request->count ; i++ ) {
|
||||
if (DRM_COPY_FROM_USER(&idx, &request->list[i], sizeof(idx))) {
|
||||
retcode = EFAULT;
|
||||
break;
|
||||
}
|
||||
if ( idx < 0 || idx >= dma->buf_count ) {
|
||||
DRM_ERROR( "Index %d (of %d max)\n",
|
||||
idx, dma->buf_count - 1 );
|
||||
retcode = DRM_ERR(EINVAL);
|
||||
retcode = EINVAL;
|
||||
break;
|
||||
}
|
||||
buf = dma->buflist[idx];
|
||||
if ( buf->filp != filp ) {
|
||||
if ( buf->file_priv != file_priv ) {
|
||||
DRM_ERROR("Process %d freeing buffer not owned\n",
|
||||
DRM_CURRENTPID);
|
||||
retcode = DRM_ERR(EINVAL);
|
||||
retcode = EINVAL;
|
||||
break;
|
||||
}
|
||||
drm_free_buffer(dev, buf);
|
||||
|
@ -1021,9 +1007,8 @@ int drm_freebufs(DRM_IOCTL_ARGS)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int drm_mapbufs(DRM_IOCTL_ARGS)
|
||||
int drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int retcode = 0;
|
||||
const int zero = 0;
|
||||
|
@ -1040,27 +1025,25 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
|
|||
vaddr_t vaddr;
|
||||
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
drm_buf_map_t request;
|
||||
drm_buf_map_t *request = data;
|
||||
int i;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) );
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
if (!vfinddev(kdev, VCHR, &vn))
|
||||
return 0; /* FIXME: Shouldn't this be EINVAL or something? */
|
||||
#endif /* __NetBSD__ || __OpenBSD */
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
vms = p->td_proc->p_vmspace;
|
||||
vms = DRM_CURPROC->td_proc->p_vmspace;
|
||||
#else
|
||||
vms = p->p_vmspace;
|
||||
vms = DRM_CURPROC->p_vmspace;
|
||||
#endif
|
||||
|
||||
DRM_SPINLOCK(&dev->dma_lock);
|
||||
dev->buf_use++; /* Can't allocate more after this call */
|
||||
DRM_SPINUNLOCK(&dev->dma_lock);
|
||||
|
||||
if (request.count < dma->buf_count)
|
||||
if (request->count < dma->buf_count)
|
||||
goto done;
|
||||
|
||||
if ((dev->driver.use_agp && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
||||
|
@ -1082,10 +1065,11 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
|
|||
vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ);
|
||||
#if __FreeBSD_version >= 600023
|
||||
retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
|
||||
VM_PROT_ALL, MAP_SHARED, OBJT_DEVICE, kdev, foff );
|
||||
VM_PROT_ALL, MAP_SHARED, OBJT_DEVICE, dev->devnode, foff);
|
||||
#else
|
||||
retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
|
||||
VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), foff );
|
||||
VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&dev->devnode->si_hlist),
|
||||
foff);
|
||||
#endif
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
|
||||
|
@ -1096,26 +1080,26 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
|
|||
if (retcode)
|
||||
goto done;
|
||||
|
||||
request.virtual = (void *)vaddr;
|
||||
request->virtual = (void *)vaddr;
|
||||
|
||||
for ( i = 0 ; i < dma->buf_count ; i++ ) {
|
||||
if (DRM_COPY_TO_USER(&request.list[i].idx,
|
||||
&dma->buflist[i]->idx, sizeof(request.list[0].idx))) {
|
||||
if (DRM_COPY_TO_USER(&request->list[i].idx,
|
||||
&dma->buflist[i]->idx, sizeof(request->list[0].idx))) {
|
||||
retcode = EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (DRM_COPY_TO_USER(&request.list[i].total,
|
||||
&dma->buflist[i]->total, sizeof(request.list[0].total))) {
|
||||
if (DRM_COPY_TO_USER(&request->list[i].total,
|
||||
&dma->buflist[i]->total, sizeof(request->list[0].total))) {
|
||||
retcode = EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (DRM_COPY_TO_USER(&request.list[i].used, &zero,
|
||||
if (DRM_COPY_TO_USER(&request->list[i].used, &zero,
|
||||
sizeof(zero))) {
|
||||
retcode = EFAULT;
|
||||
goto done;
|
||||
}
|
||||
address = vaddr + dma->buflist[i]->offset; /* *** */
|
||||
if (DRM_COPY_TO_USER(&request.list[i].address, &address,
|
||||
if (DRM_COPY_TO_USER(&request->list[i].address, &address,
|
||||
sizeof(address))) {
|
||||
retcode = EFAULT;
|
||||
goto done;
|
||||
|
@ -1123,11 +1107,9 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
|
|||
}
|
||||
|
||||
done:
|
||||
request.count = dma->buf_count;
|
||||
request->count = dma->buf_count;
|
||||
|
||||
DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
|
||||
DRM_DEBUG( "%d buffers, retcode = %d\n", request->count, retcode );
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_buf_map_t *)data, request, sizeof(request));
|
||||
|
||||
return DRM_ERR(retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
|
||||
* Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_context.c
|
||||
* Implementation of the context management ioctls.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
/* ================================================================
|
||||
|
@ -109,7 +110,7 @@ int drm_ctxbitmap_init(drm_device_t *dev)
|
|||
dev->ctx_bitmap = malloc(PAGE_SIZE, M_DRM, M_NOWAIT | M_ZERO);
|
||||
if ( dev->ctx_bitmap == NULL ) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
dev->context_sareas = NULL;
|
||||
dev->max_context = -1;
|
||||
|
@ -136,48 +137,39 @@ void drm_ctxbitmap_cleanup(drm_device_t *dev)
|
|||
* Per Context SAREA Support
|
||||
*/
|
||||
|
||||
int drm_getsareactx( DRM_IOCTL_ARGS )
|
||||
int drm_getsareactx( drm_device_t *dev, void *data, struct drm_file *file_priv )
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_ctx_priv_map_t *request = data;
|
||||
drm_local_map_t *map;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
||||
sizeof(request) );
|
||||
|
||||
DRM_LOCK();
|
||||
if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
|
||||
if (dev->max_context < 0 ||
|
||||
request->ctx_id >= (unsigned) dev->max_context) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
map = dev->context_sareas[request.ctx_id];
|
||||
map = dev->context_sareas[request->ctx_id];
|
||||
DRM_UNLOCK();
|
||||
|
||||
request.handle = map->handle;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_ctx_priv_map_t *)data, request, sizeof(request) );
|
||||
request->handle = map->handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_setsareactx( DRM_IOCTL_ARGS )
|
||||
int drm_setsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_ctx_priv_map_t *request = data;
|
||||
drm_local_map_t *map = NULL;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
||||
sizeof(request) );
|
||||
|
||||
DRM_LOCK();
|
||||
TAILQ_FOREACH(map, &dev->maplist, link) {
|
||||
if (map->handle == request.handle) {
|
||||
if (map->handle == request->handle) {
|
||||
if (dev->max_context < 0)
|
||||
goto bad;
|
||||
if (request.ctx_id >= (unsigned) dev->max_context)
|
||||
if (request->ctx_id >= (unsigned) dev->max_context)
|
||||
goto bad;
|
||||
dev->context_sareas[request.ctx_id] = map;
|
||||
dev->context_sareas[request->ctx_id] = map;
|
||||
DRM_UNLOCK();
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,7 +177,7 @@ int drm_setsareactx( DRM_IOCTL_ARGS )
|
|||
|
||||
bad:
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
|
@ -196,7 +188,7 @@ int drm_context_switch(drm_device_t *dev, int old, int new)
|
|||
{
|
||||
if ( test_and_set_bit( 0, &dev->context_flag ) ) {
|
||||
DRM_ERROR( "Reentering -- FIXME\n" );
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "Context switch from %d to %d\n", old, new );
|
||||
|
@ -225,120 +217,98 @@ int drm_context_switch_complete(drm_device_t *dev, int new)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_resctx(DRM_IOCTL_ARGS)
|
||||
int drm_resctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_ctx_res_t res;
|
||||
drm_ctx_res_t *res = data;
|
||||
drm_ctx_t ctx;
|
||||
int i;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) );
|
||||
|
||||
if ( res.count >= DRM_RESERVED_CONTEXTS ) {
|
||||
if ( res->count >= DRM_RESERVED_CONTEXTS ) {
|
||||
bzero(&ctx, sizeof(ctx));
|
||||
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
|
||||
ctx.handle = i;
|
||||
if ( DRM_COPY_TO_USER( &res.contexts[i],
|
||||
if ( DRM_COPY_TO_USER( &res->contexts[i],
|
||||
&ctx, sizeof(ctx) ) )
|
||||
return DRM_ERR(EFAULT);
|
||||
return EFAULT;
|
||||
}
|
||||
}
|
||||
res.count = DRM_RESERVED_CONTEXTS;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) );
|
||||
res->count = DRM_RESERVED_CONTEXTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_addctx(DRM_IOCTL_ARGS)
|
||||
int drm_addctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_ctx_t ctx;
|
||||
drm_ctx_t *ctx = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
|
||||
|
||||
ctx.handle = drm_ctxbitmap_next(dev);
|
||||
if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
|
||||
ctx->handle = drm_ctxbitmap_next(dev);
|
||||
if ( ctx->handle == DRM_KERNEL_CONTEXT ) {
|
||||
/* Skip kernel's context and get a new one. */
|
||||
ctx.handle = drm_ctxbitmap_next(dev);
|
||||
ctx->handle = drm_ctxbitmap_next(dev);
|
||||
}
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
if ( ctx.handle == -1 ) {
|
||||
DRM_DEBUG( "%d\n", ctx->handle );
|
||||
if ( ctx->handle == -1 ) {
|
||||
DRM_DEBUG( "Not enough free contexts.\n" );
|
||||
/* Should this return -EBUSY instead? */
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (dev->driver.context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
if (dev->driver.context_ctor && ctx->handle != DRM_KERNEL_CONTEXT) {
|
||||
DRM_LOCK();
|
||||
dev->driver.context_ctor(dev, ctx.handle);
|
||||
dev->driver.context_ctor(dev, ctx->handle);
|
||||
DRM_UNLOCK();
|
||||
}
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_modctx(DRM_IOCTL_ARGS)
|
||||
int drm_modctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
/* This does nothing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_getctx(DRM_IOCTL_ARGS)
|
||||
int drm_getctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_ctx_t ctx;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
|
||||
drm_ctx_t *ctx = data;
|
||||
|
||||
/* This is 0, because we don't handle any context flags */
|
||||
ctx.flags = 0;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) );
|
||||
ctx->flags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_switchctx(DRM_IOCTL_ARGS)
|
||||
int drm_switchctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_ctx_t ctx;
|
||||
drm_ctx_t *ctx = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
|
||||
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
return drm_context_switch(dev, dev->last_context, ctx.handle);
|
||||
DRM_DEBUG( "%d\n", ctx->handle );
|
||||
return drm_context_switch(dev, dev->last_context, ctx->handle);
|
||||
}
|
||||
|
||||
int drm_newctx(DRM_IOCTL_ARGS)
|
||||
int drm_newctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_ctx_t ctx;
|
||||
drm_ctx_t *ctx = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
|
||||
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
drm_context_switch_complete(dev, ctx.handle);
|
||||
DRM_DEBUG( "%d\n", ctx->handle );
|
||||
drm_context_switch_complete(dev, ctx->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_rmctx(DRM_IOCTL_ARGS)
|
||||
int drm_rmctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_ctx_t ctx;
|
||||
drm_ctx_t *ctx = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
|
||||
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
|
||||
DRM_DEBUG( "%d\n", ctx->handle );
|
||||
if ( ctx->handle != DRM_KERNEL_CONTEXT ) {
|
||||
if (dev->driver.context_dtor) {
|
||||
DRM_LOCK();
|
||||
dev->driver.context_dtor(dev, ctx.handle);
|
||||
dev->driver.context_dtor(dev, ctx->handle);
|
||||
DRM_UNLOCK();
|
||||
}
|
||||
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
drm_ctxbitmap_free(dev, ctx->handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_dma.c -- DMA IOCTL and function support -*- linux-c -*-
|
||||
* Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_dma.c
|
||||
* Support code for DMA buffer management.
|
||||
*
|
||||
* The implementation used to be significantly more complicated, but the
|
||||
* complexity has been moved into the drivers as different buffer management
|
||||
* schemes evolved.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
int drm_dma_setup(drm_device_t *dev)
|
||||
|
@ -38,9 +43,9 @@ int drm_dma_setup(drm_device_t *dev)
|
|||
|
||||
dev->dma = malloc(sizeof(*dev->dma), M_DRM, M_NOWAIT | M_ZERO);
|
||||
if (dev->dma == NULL)
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
|
||||
DRM_SPININIT(dev->dma_lock, "drmdma");
|
||||
DRM_SPININIT(&dev->dma_lock, "drmdma");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,7 +85,7 @@ void drm_dma_takedown(drm_device_t *dev)
|
|||
free(dma->pagelist, M_DRM);
|
||||
free(dev->dma, M_DRM);
|
||||
dev->dma = NULL;
|
||||
DRM_SPINUNINIT(dev->dma_lock);
|
||||
DRM_SPINUNINIT(&dev->dma_lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,18 +94,18 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
|
|||
if (!buf) return;
|
||||
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->file_priv= NULL;
|
||||
buf->used = 0;
|
||||
}
|
||||
|
||||
void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
|
||||
void drm_reclaim_buffers(drm_device_t *dev, struct drm_file *file_priv)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i;
|
||||
|
||||
if (!dma) return;
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (dma->buflist[i]->filp == filp) {
|
||||
if (dma->buflist[i]->file_priv == file_priv) {
|
||||
switch (dma->buflist[i]->list) {
|
||||
case DRM_LIST_NONE:
|
||||
drm_free_buffer(dev, dma->buflist[i]);
|
||||
|
@ -117,12 +122,12 @@ void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
|
|||
}
|
||||
|
||||
/* Call into the driver-specific DMA handler */
|
||||
int drm_dma(DRM_IOCTL_ARGS)
|
||||
int drm_dma(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
|
||||
if (dev->driver.dma_ioctl) {
|
||||
return dev->driver.dma_ioctl(kdev, cmd, data, flags, p, filp);
|
||||
/* shared code returns -errno */
|
||||
return -dev->driver.dma_ioctl(dev, data, file_priv);
|
||||
} else {
|
||||
DRM_DEBUG("DMA ioctl on driver with no dma handler\n");
|
||||
return EINVAL;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_drawable.h -- IOCTLs for drawables -*- linux-c -*-
|
||||
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,21 +28,123 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_drawable.c
|
||||
* This file implements ioctls to store information along with DRM drawables,
|
||||
* such as the current set of cliprects for vblank-synced buffer swaps.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
int drm_adddraw(DRM_IOCTL_ARGS)
|
||||
struct bsd_drm_drawable_info {
|
||||
struct drm_drawable_info info;
|
||||
int handle;
|
||||
RB_ENTRY(bsd_drm_drawable_info) tree;
|
||||
};
|
||||
|
||||
static int
|
||||
drm_drawable_compare(struct bsd_drm_drawable_info *a,
|
||||
struct bsd_drm_drawable_info *b)
|
||||
{
|
||||
drm_draw_t draw;
|
||||
if (a->handle > b->handle)
|
||||
return 1;
|
||||
if (a->handle < b->handle)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
draw.handle = 0; /* NOOP */
|
||||
DRM_DEBUG("%d\n", draw.handle);
|
||||
RB_GENERATE_STATIC(drawable_tree, bsd_drm_drawable_info, tree,
|
||||
drm_drawable_compare);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) );
|
||||
struct drm_drawable_info *
|
||||
drm_get_drawable_info(drm_device_t *dev, int handle)
|
||||
{
|
||||
struct bsd_drm_drawable_info find, *result;
|
||||
|
||||
find.handle = handle;
|
||||
result = RB_FIND(drawable_tree, &dev->drw_head, &find);
|
||||
|
||||
return &result->info;
|
||||
}
|
||||
|
||||
int drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_draw_t *draw = data;
|
||||
struct bsd_drm_drawable_info *info;
|
||||
|
||||
info = drm_calloc(1, sizeof(struct bsd_drm_drawable_info),
|
||||
DRM_MEM_DRAWABLE);
|
||||
if (info == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
info->handle = alloc_unr(dev->drw_unrhdr);
|
||||
DRM_SPINLOCK(&dev->drw_lock);
|
||||
RB_INSERT(drawable_tree, &dev->drw_head, info);
|
||||
draw->handle = info->handle;
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
|
||||
DRM_DEBUG("%d\n", draw->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_rmdraw(DRM_IOCTL_ARGS)
|
||||
int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
return 0; /* NOOP */
|
||||
drm_draw_t *draw = (drm_draw_t *)data;
|
||||
struct drm_drawable_info *info;
|
||||
|
||||
DRM_SPINLOCK(&dev->drw_lock);
|
||||
info = drm_get_drawable_info(dev, draw->handle);
|
||||
if (info != NULL) {
|
||||
RB_REMOVE(drawable_tree, &dev->drw_head,
|
||||
(struct bsd_drm_drawable_info *)info);
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
free_unr(dev->drw_unrhdr, draw->handle);
|
||||
drm_free(info, sizeof(struct bsd_drm_drawable_info),
|
||||
DRM_MEM_DRAWABLE);
|
||||
return 0;
|
||||
} else {
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_drawable_info *info;
|
||||
struct drm_update_draw *update = (struct drm_update_draw *)data;
|
||||
int ret;
|
||||
|
||||
info = drm_get_drawable_info(dev, update->handle);
|
||||
if (info == NULL)
|
||||
return EINVAL;
|
||||
|
||||
switch (update->type) {
|
||||
case DRM_DRAWABLE_CLIPRECTS:
|
||||
DRM_SPINLOCK(&dev->drw_lock);
|
||||
if (update->num != info->num_rects) {
|
||||
drm_free(info->rects,
|
||||
sizeof(*info->rects) * info->num_rects,
|
||||
DRM_MEM_DRAWABLE);
|
||||
info->rects = NULL;
|
||||
info->num_rects = 0;
|
||||
}
|
||||
if (update->num == 0) {
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
return 0;
|
||||
}
|
||||
if (info->rects == NULL) {
|
||||
info->rects = drm_alloc(sizeof(*info->rects) *
|
||||
update->num, DRM_MEM_DRAWABLE);
|
||||
if (info->rects == NULL)
|
||||
return ENOMEM;
|
||||
info->num_rects = update->num;
|
||||
}
|
||||
/* For some reason the pointer arg is unsigned long long. */
|
||||
ret = copyin((void *)(intptr_t)update->data, info->rects,
|
||||
sizeof(*info->rects) * info->num_rects);
|
||||
DRM_SPINUNLOCK(&dev->drw_lock);
|
||||
return ret;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_drv.h -- Generic driver template -*- linux-c -*-
|
||||
* Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_drv.c
|
||||
* The catch-all file for DRM device support, including module setup/teardown,
|
||||
* open/close, and ioctl dispatch.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/limits.h>
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "drm_sarea.h"
|
||||
|
@ -64,63 +68,64 @@ MODULE_DEPEND(drm, mem, 1, 1, 1);
|
|||
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
static drm_ioctl_desc_t drm_ioctls[256] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, DRM_MASTER|DRM_ROOT_ONLY },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, DRM_AUTH },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, DRM_AUTH },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, DRM_AUTH },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, DRM_AUTH },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, DRM_AUTH|DRM_MASTER },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { drm_dma, DRM_AUTH },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, DRM_AUTH },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 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_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(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_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
};
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -198,6 +203,7 @@ int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist)
|
|||
"dri/card%d", unit);
|
||||
#if __FreeBSD_version >= 500000
|
||||
mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF);
|
||||
mtx_init(&dev->drw_lock, "drmdrw", NULL, MTX_DEF);
|
||||
#endif
|
||||
|
||||
id_entry = drm_find_description(pci_get_vendor(dev->device),
|
||||
|
@ -496,7 +502,7 @@ static int drm_lastclose(drm_device_t *dev)
|
|||
drm_dma_takedown(dev);
|
||||
if ( dev->lock.hw_lock ) {
|
||||
dev->lock.hw_lock = NULL; /* SHM removed */
|
||||
dev->lock.filp = NULL;
|
||||
dev->lock.file_priv = NULL;
|
||||
DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
|
||||
}
|
||||
|
||||
|
@ -510,8 +516,11 @@ static int drm_load(drm_device_t *dev)
|
|||
DRM_DEBUG( "\n" );
|
||||
|
||||
dev->irq = pci_get_irq(dev->device);
|
||||
/* XXX Fix domain number (alpha hoses) */
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 700053
|
||||
dev->pci_domain = pci_get_domain(dev->device);
|
||||
#else
|
||||
dev->pci_domain = 0;
|
||||
#endif
|
||||
dev->pci_bus = pci_get_bus(dev->device);
|
||||
dev->pci_slot = pci_get_slot(dev->device);
|
||||
dev->pci_func = pci_get_function(dev->device);
|
||||
|
@ -529,7 +538,9 @@ static int drm_load(drm_device_t *dev)
|
|||
|
||||
if (dev->driver.load != NULL) {
|
||||
DRM_LOCK();
|
||||
retcode = dev->driver.load(dev, dev->id_entry->driver_private);
|
||||
/* Shared code returns -errno. */
|
||||
retcode = -dev->driver.load(dev,
|
||||
dev->id_entry->driver_private);
|
||||
DRM_UNLOCK();
|
||||
if (retcode != 0)
|
||||
goto error;
|
||||
|
@ -541,7 +552,7 @@ static int drm_load(drm_device_t *dev)
|
|||
if (dev->driver.require_agp && dev->agp == NULL) {
|
||||
DRM_ERROR("Card isn't AGP, or couldn't initialize "
|
||||
"AGP.\n");
|
||||
retcode = DRM_ERR(ENOMEM);
|
||||
retcode = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
if (dev->agp != NULL) {
|
||||
|
@ -557,6 +568,12 @@ static int drm_load(drm_device_t *dev)
|
|||
goto error;
|
||||
}
|
||||
|
||||
dev->drw_unrhdr = new_unrhdr(1, INT_MAX, NULL);
|
||||
if (dev->drw_unrhdr == NULL) {
|
||||
DRM_ERROR("Couldn't allocate drawable number allocator\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s\n",
|
||||
dev->driver.name,
|
||||
dev->driver.major,
|
||||
|
@ -628,6 +645,8 @@ static void drm_unload(drm_device_t *dev)
|
|||
if (dev->driver.unload != NULL)
|
||||
dev->driver.unload(dev);
|
||||
|
||||
delete_unrhdr(dev->drw_unrhdr);
|
||||
|
||||
drm_mem_uninit();
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
mtx_destroy(&dev->dev_lock);
|
||||
|
@ -635,32 +654,27 @@ static void drm_unload(drm_device_t *dev)
|
|||
}
|
||||
|
||||
|
||||
int drm_version(DRM_IOCTL_ARGS)
|
||||
int drm_version(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_version_t version;
|
||||
drm_version_t *version = data;
|
||||
int len;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( version, (drm_version_t *)data, sizeof(version) );
|
||||
|
||||
#define DRM_COPY( name, value ) \
|
||||
len = strlen( value ); \
|
||||
if ( len > name##_len ) len = name##_len; \
|
||||
name##_len = strlen( value ); \
|
||||
if ( len && name ) { \
|
||||
if ( DRM_COPY_TO_USER( name, value, len ) ) \
|
||||
return DRM_ERR(EFAULT); \
|
||||
return EFAULT; \
|
||||
}
|
||||
|
||||
version.version_major = dev->driver.major;
|
||||
version.version_minor = dev->driver.minor;
|
||||
version.version_patchlevel = dev->driver.patchlevel;
|
||||
version->version_major = dev->driver.major;
|
||||
version->version_minor = dev->driver.minor;
|
||||
version->version_patchlevel = dev->driver.patchlevel;
|
||||
|
||||
DRM_COPY(version.name, dev->driver.name);
|
||||
DRM_COPY(version.date, dev->driver.date);
|
||||
DRM_COPY(version.desc, dev->driver.desc);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) );
|
||||
DRM_COPY(version->name, dev->driver.name);
|
||||
DRM_COPY(version->date, dev->driver.date);
|
||||
DRM_COPY(version->desc, dev->driver.desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -692,24 +706,26 @@ int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
|
||||
int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
||||
{
|
||||
drm_file_t *priv;
|
||||
DRM_DEVICE;
|
||||
drm_device_t *dev = drm_get_device_from_kdev(kdev);
|
||||
drm_file_t *file_priv;
|
||||
int retcode = 0;
|
||||
DRMFILE filp = (void *)(uintptr_t)(DRM_CURRENTPID);
|
||||
|
||||
DRM_DEBUG( "open_count = %d\n", dev->open_count );
|
||||
|
||||
DRM_LOCK();
|
||||
|
||||
priv = drm_find_file_by_proc(dev, p);
|
||||
if (!priv) {
|
||||
file_priv = drm_find_file_by_proc(dev, p);
|
||||
if (!file_priv) {
|
||||
DRM_UNLOCK();
|
||||
DRM_ERROR("can't find authenticator\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (--file_priv->refs != 0)
|
||||
goto done;
|
||||
|
||||
if (dev->driver.preclose != NULL)
|
||||
dev->driver.preclose(dev, filp);
|
||||
dev->driver.preclose(dev, file_priv);
|
||||
|
||||
/* ========================================================
|
||||
* Begin inline drm_release
|
||||
|
@ -724,12 +740,12 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
#endif
|
||||
|
||||
if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
|
||||
&& dev->lock.filp == filp) {
|
||||
&& dev->lock.file_priv == file_priv) {
|
||||
DRM_DEBUG("Process %d dead, freeing lock for context %d\n",
|
||||
DRM_CURRENTPID,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
|
||||
if (dev->driver.reclaim_buffers_locked != NULL)
|
||||
dev->driver.reclaim_buffers_locked(dev, filp);
|
||||
dev->driver.reclaim_buffers_locked(dev, file_priv);
|
||||
|
||||
drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
|
||||
|
@ -744,12 +760,12 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
for (;;) {
|
||||
if ( !dev->lock.hw_lock ) {
|
||||
/* Device has been unregistered */
|
||||
retcode = DRM_ERR(EINTR);
|
||||
retcode = EINTR;
|
||||
break;
|
||||
}
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT)) {
|
||||
dev->lock.filp = filp;
|
||||
dev->lock.file_priv = file_priv;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
||||
break; /* Got lock */
|
||||
|
@ -766,14 +782,14 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
break;
|
||||
}
|
||||
if (retcode == 0) {
|
||||
dev->driver.reclaim_buffers_locked(dev, filp);
|
||||
dev->driver.reclaim_buffers_locked(dev, file_priv);
|
||||
drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->driver.use_dma && !dev->driver.reclaim_buffers_locked)
|
||||
drm_reclaim_buffers(dev, filp);
|
||||
drm_reclaim_buffers(dev, file_priv);
|
||||
|
||||
#if defined (__FreeBSD__) && (__FreeBSD_version >= 500000)
|
||||
funsetown(&dev->buf_sigio);
|
||||
|
@ -783,17 +799,16 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
dev->buf_pgid = 0;
|
||||
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
if (--priv->refs == 0) {
|
||||
if (dev->driver.postclose != NULL)
|
||||
dev->driver.postclose(dev, priv);
|
||||
TAILQ_REMOVE(&dev->files, priv, link);
|
||||
free(priv, M_DRM);
|
||||
}
|
||||
if (dev->driver.postclose != NULL)
|
||||
dev->driver.postclose(dev, file_priv);
|
||||
TAILQ_REMOVE(&dev->files, file_priv, link);
|
||||
free(file_priv, M_DRM);
|
||||
|
||||
/* ========================================================
|
||||
* End inline drm_release
|
||||
*/
|
||||
|
||||
done:
|
||||
atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
|
@ -812,32 +827,33 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags,
|
||||
DRM_STRUCTPROC *p)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_device_t *dev = drm_get_device_from_kdev(kdev);
|
||||
int retcode = 0;
|
||||
drm_ioctl_desc_t *ioctl;
|
||||
int (*func)(DRM_IOCTL_ARGS);
|
||||
int (*func)(drm_device_t *dev, void *data, struct drm_file *file_priv);
|
||||
int nr = DRM_IOCTL_NR(cmd);
|
||||
int is_driver_ioctl = 0;
|
||||
drm_file_t *priv;
|
||||
DRMFILE filp = (DRMFILE)(uintptr_t)DRM_CURRENTPID;
|
||||
drm_file_t *file_priv;
|
||||
|
||||
DRM_LOCK();
|
||||
priv = drm_find_file_by_proc(dev, p);
|
||||
file_priv = drm_find_file_by_proc(dev, p);
|
||||
DRM_UNLOCK();
|
||||
if (priv == NULL) {
|
||||
if (file_priv == NULL) {
|
||||
DRM_ERROR("can't find authenticator\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
|
||||
++priv->ioctl_count;
|
||||
++file_priv->ioctl_count;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
DRM_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated );
|
||||
DRM_CURRENTPID, cmd, nr, (long)dev->device,
|
||||
file_priv->authenticated );
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
DRM_CURRENTPID, cmd, nr, (long)&dev->device, priv->authenticated );
|
||||
DRM_CURRENTPID, cmd, nr, (long)&dev->device,
|
||||
file_priv->authenticated );
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -892,24 +908,25 @@ int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags,
|
|||
DRM_DEBUG( "no function\n" );
|
||||
return EINVAL;
|
||||
}
|
||||
/* ioctl->master check should be against something in the filp set up
|
||||
* for the first opener, but it doesn't matter yet.
|
||||
*/
|
||||
|
||||
if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) ||
|
||||
((ioctl->flags & DRM_AUTH) && !priv->authenticated) ||
|
||||
((ioctl->flags & DRM_MASTER) && !priv->master))
|
||||
((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
|
||||
((ioctl->flags & DRM_MASTER) && !file_priv->master))
|
||||
return EACCES;
|
||||
|
||||
if (is_driver_ioctl)
|
||||
if (is_driver_ioctl) {
|
||||
DRM_LOCK();
|
||||
retcode = func(kdev, cmd, data, flags, p, filp);
|
||||
if (is_driver_ioctl)
|
||||
/* shared code returns -errno */
|
||||
retcode = -func(dev, data, file_priv);
|
||||
DRM_UNLOCK();
|
||||
} else {
|
||||
retcode = func(dev, data, file_priv);
|
||||
}
|
||||
|
||||
if (retcode != 0)
|
||||
DRM_DEBUG(" returning %d\n", retcode);
|
||||
|
||||
return DRM_ERR(retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
drm_local_map_t *drm_getsarea(drm_device_t *dev)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_fops.h -- File operations for DRM -*- linux-c -*-
|
||||
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -32,6 +29,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_fops.c
|
||||
* Support code for dealing with the file privates associated with each
|
||||
* open of the DRM device.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
drm_file_t *drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p)
|
||||
|
@ -75,7 +77,7 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
|
|||
priv = malloc(sizeof(*priv), M_DRM, M_NOWAIT | M_ZERO);
|
||||
if (priv == NULL) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
}
|
||||
#if __FreeBSD_version >= 500000
|
||||
priv->uid = p->td_ucred->cr_svuid;
|
||||
|
@ -93,7 +95,8 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
|
|||
priv->authenticated = DRM_SUSER(p);
|
||||
|
||||
if (dev->driver.open) {
|
||||
retcode = dev->driver.open(dev, priv);
|
||||
/* shared code returns -errno */
|
||||
retcode = -dev->driver.open(dev, priv);
|
||||
if (retcode != 0) {
|
||||
free(priv, M_DRM);
|
||||
DRM_UNLOCK();
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_ioctl.h -- IOCTL processing for DRM -*- linux-c -*-
|
||||
* Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_ioctl.c
|
||||
* Varios minor DRM ioctls not applicable to other files, such as versioning
|
||||
* information and reporting DRM information to userland.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
/*
|
||||
|
@ -39,20 +41,15 @@
|
|||
* before setunique has been called. The format for the bus-specific part of
|
||||
* the unique is not defined for any other bus.
|
||||
*/
|
||||
int drm_getunique(DRM_IOCTL_ARGS)
|
||||
int drm_getunique(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_unique_t u;
|
||||
drm_unique_t *u = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) );
|
||||
|
||||
if (u.unique_len >= dev->unique_len) {
|
||||
if (DRM_COPY_TO_USER(u.unique, dev->unique, dev->unique_len))
|
||||
return DRM_ERR(EFAULT);
|
||||
if (u->unique_len >= dev->unique_len) {
|
||||
if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len))
|
||||
return EFAULT;
|
||||
}
|
||||
u.unique_len = dev->unique_len;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_unique_t *)data, u, sizeof(u) );
|
||||
u->unique_len = dev->unique_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -60,28 +57,25 @@ int drm_getunique(DRM_IOCTL_ARGS)
|
|||
/* Deprecated in DRM version 1.1, and will return EBUSY when setversion has
|
||||
* requested version 1.1 or greater.
|
||||
*/
|
||||
int drm_setunique(DRM_IOCTL_ARGS)
|
||||
int drm_setunique(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_unique_t u;
|
||||
drm_unique_t *u = data;
|
||||
int domain, bus, slot, func, ret;
|
||||
char *busid;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) );
|
||||
|
||||
/* Check and copy in the submitted Bus ID */
|
||||
if (!u.unique_len || u.unique_len > 1024)
|
||||
return DRM_ERR(EINVAL);
|
||||
if (!u->unique_len || u->unique_len > 1024)
|
||||
return EINVAL;
|
||||
|
||||
busid = malloc(u.unique_len + 1, M_DRM, M_WAITOK);
|
||||
busid = malloc(u->unique_len + 1, M_DRM, M_WAITOK);
|
||||
if (busid == NULL)
|
||||
return DRM_ERR(ENOMEM);
|
||||
return ENOMEM;
|
||||
|
||||
if (DRM_COPY_FROM_USER(busid, u.unique, u.unique_len)) {
|
||||
if (DRM_COPY_FROM_USER(busid, u->unique, u->unique_len)) {
|
||||
free(busid, M_DRM);
|
||||
return DRM_ERR(EFAULT);
|
||||
return EFAULT;
|
||||
}
|
||||
busid[u.unique_len] = '\0';
|
||||
busid[u->unique_len] = '\0';
|
||||
|
||||
/* Return error if the busid submitted doesn't match the device's actual
|
||||
* busid.
|
||||
|
@ -89,7 +83,7 @@ int drm_setunique(DRM_IOCTL_ARGS)
|
|||
ret = sscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func);
|
||||
if (ret != 3) {
|
||||
free(busid, M_DRM);
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
domain = bus >> 8;
|
||||
bus &= 0xff;
|
||||
|
@ -99,17 +93,17 @@ int drm_setunique(DRM_IOCTL_ARGS)
|
|||
(slot != dev->pci_slot) ||
|
||||
(func != dev->pci_func)) {
|
||||
free(busid, M_DRM);
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Actually set the device's busid now. */
|
||||
DRM_LOCK();
|
||||
if (dev->unique_len || dev->unique) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
dev->unique_len = u.unique_len;
|
||||
dev->unique_len = u->unique_len;
|
||||
dev->unique = busid;
|
||||
DRM_UNLOCK();
|
||||
|
||||
|
@ -143,32 +137,29 @@ drm_set_busid(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_getmap(DRM_IOCTL_ARGS)
|
||||
int drm_getmap(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_map_t map;
|
||||
drm_map_t *map = data;
|
||||
drm_local_map_t *mapinlist;
|
||||
int idx;
|
||||
int i = 0;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( map, (drm_map_t *)data, sizeof(map) );
|
||||
|
||||
idx = map.offset;
|
||||
idx = map->offset;
|
||||
|
||||
DRM_LOCK();
|
||||
if (idx < 0) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(mapinlist, &dev->maplist, link) {
|
||||
if (i==idx) {
|
||||
map.offset = mapinlist->offset;
|
||||
map.size = mapinlist->size;
|
||||
map.type = mapinlist->type;
|
||||
map.flags = mapinlist->flags;
|
||||
map.handle = mapinlist->handle;
|
||||
map.mtrr = mapinlist->mtrr;
|
||||
map->offset = mapinlist->offset;
|
||||
map->size = mapinlist->size;
|
||||
map->type = mapinlist->type;
|
||||
map->flags = mapinlist->flags;
|
||||
map->handle = mapinlist->handle;
|
||||
map->mtrr = mapinlist->mtrr;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
|
@ -179,100 +170,89 @@ int drm_getmap(DRM_IOCTL_ARGS)
|
|||
if (mapinlist == NULL)
|
||||
return EINVAL;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, map, sizeof(map) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_getclient(DRM_IOCTL_ARGS)
|
||||
int drm_getclient(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_client_t client;
|
||||
drm_client_t *client = data;
|
||||
drm_file_t *pt;
|
||||
int idx;
|
||||
int i = 0;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( client, (drm_client_t *)data, sizeof(client) );
|
||||
|
||||
idx = client.idx;
|
||||
idx = client->idx;
|
||||
DRM_LOCK();
|
||||
TAILQ_FOREACH(pt, &dev->files, link) {
|
||||
if (i==idx)
|
||||
{
|
||||
client.auth = pt->authenticated;
|
||||
client.pid = pt->pid;
|
||||
client.uid = pt->uid;
|
||||
client.magic = pt->magic;
|
||||
client.iocs = pt->ioctl_count;
|
||||
client->auth = pt->authenticated;
|
||||
client->pid = pt->pid;
|
||||
client->uid = pt->uid;
|
||||
client->magic = pt->magic;
|
||||
client->iocs = pt->ioctl_count;
|
||||
DRM_UNLOCK();
|
||||
|
||||
*(drm_client_t *)data = client;
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_client_t *)data, client, sizeof(client) );
|
||||
|
||||
return 0;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int drm_getstats(DRM_IOCTL_ARGS)
|
||||
int drm_getstats(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_stats_t stats;
|
||||
drm_stats_t *stats = data;
|
||||
int i;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
memset(stats, 0, sizeof(drm_stats_t));
|
||||
|
||||
DRM_LOCK();
|
||||
|
||||
for (i = 0; i < dev->counters; i++) {
|
||||
if (dev->types[i] == _DRM_STAT_LOCK)
|
||||
stats.data[i].value
|
||||
stats->data[i].value
|
||||
= (dev->lock.hw_lock
|
||||
? dev->lock.hw_lock->lock : 0);
|
||||
else
|
||||
stats.data[i].value = atomic_read(&dev->counts[i]);
|
||||
stats.data[i].type = dev->types[i];
|
||||
stats->data[i].value = atomic_read(&dev->counts[i]);
|
||||
stats->data[i].type = dev->types[i];
|
||||
}
|
||||
|
||||
stats.count = dev->counters;
|
||||
stats->count = dev->counters;
|
||||
|
||||
DRM_UNLOCK();
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_stats_t *)data, stats, sizeof(stats) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DRM_IF_MAJOR 1
|
||||
#define DRM_IF_MINOR 2
|
||||
|
||||
int drm_setversion(DRM_IOCTL_ARGS)
|
||||
int drm_setversion(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_set_version_t sv;
|
||||
drm_set_version_t retv;
|
||||
drm_set_version_t *sv = data;
|
||||
drm_set_version_t ver;
|
||||
int if_version;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(sv, (drm_set_version_t *)data, sizeof(sv));
|
||||
/* Save the incoming data, and set the response before continuing
|
||||
* any further.
|
||||
*/
|
||||
ver = *sv;
|
||||
sv->drm_di_major = DRM_IF_MAJOR;
|
||||
sv->drm_di_minor = DRM_IF_MINOR;
|
||||
sv->drm_dd_major = dev->driver.major;
|
||||
sv->drm_dd_minor = dev->driver.minor;
|
||||
|
||||
retv.drm_di_major = DRM_IF_MAJOR;
|
||||
retv.drm_di_minor = DRM_IF_MINOR;
|
||||
retv.drm_dd_major = dev->driver.major;
|
||||
retv.drm_dd_minor = dev->driver.minor;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_set_version_t *)data, retv, sizeof(sv));
|
||||
|
||||
if (sv.drm_di_major != -1) {
|
||||
if (sv.drm_di_major != DRM_IF_MAJOR ||
|
||||
sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
|
||||
if (ver.drm_di_major != -1) {
|
||||
if (ver.drm_di_major != DRM_IF_MAJOR ||
|
||||
ver.drm_di_minor < 0 || ver.drm_di_minor > DRM_IF_MINOR) {
|
||||
return EINVAL;
|
||||
if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
|
||||
}
|
||||
if_version = DRM_IF_VERSION(ver.drm_di_major,
|
||||
ver.drm_dd_minor);
|
||||
dev->if_version = DRM_MAX(if_version, dev->if_version);
|
||||
if (sv.drm_di_minor >= 1) {
|
||||
if (ver.drm_di_minor >= 1) {
|
||||
/*
|
||||
* Version 1.1 includes tying of DRM to specific device
|
||||
*/
|
||||
|
@ -280,16 +260,20 @@ int drm_setversion(DRM_IOCTL_ARGS)
|
|||
}
|
||||
}
|
||||
|
||||
if (sv.drm_dd_major != -1) {
|
||||
if (sv.drm_dd_major != dev->driver.major ||
|
||||
sv.drm_dd_minor < 0 || sv.drm_dd_minor > dev->driver.minor)
|
||||
if (ver.drm_dd_major != -1) {
|
||||
if (ver.drm_dd_major != dev->driver.major ||
|
||||
ver.drm_dd_minor < 0 ||
|
||||
ver.drm_dd_minor > dev->driver.minor)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drm_noop(DRM_IOCTL_ARGS)
|
||||
int drm_noop(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEBUG("\n");
|
||||
return 0;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_irq.c -- IRQ IOCTL and function support
|
||||
* Created: Fri Oct 18 2003 by anholt@FreeBSD.org
|
||||
*/
|
||||
/*-
|
||||
* Copyright 2003 Eric Anholt
|
||||
* All Rights Reserved.
|
||||
|
@ -28,28 +25,30 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_irq.c
|
||||
* Support code for handling setup/teardown of interrupt handlers and
|
||||
* handing interrupt handlers off to the drivers.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
||||
int drm_irq_by_busid(DRM_IOCTL_ARGS)
|
||||
static void drm_locked_task(void *context, int pending __unused);
|
||||
|
||||
int drm_irq_by_busid(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_irq_busid_t irq;
|
||||
drm_irq_busid_t *irq = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(irq, (drm_irq_busid_t *)data, sizeof(irq));
|
||||
|
||||
if ((irq.busnum >> 8) != dev->pci_domain ||
|
||||
(irq.busnum & 0xff) != dev->pci_bus ||
|
||||
irq.devnum != dev->pci_slot ||
|
||||
irq.funcnum != dev->pci_func)
|
||||
if ((irq->busnum >> 8) != dev->pci_domain ||
|
||||
(irq->busnum & 0xff) != dev->pci_bus ||
|
||||
irq->devnum != dev->pci_slot ||
|
||||
irq->funcnum != dev->pci_func)
|
||||
return EINVAL;
|
||||
|
||||
irq.irq = dev->irq;
|
||||
irq->irq = dev->irq;
|
||||
|
||||
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
|
||||
irq.busnum, irq.devnum, irq.funcnum, irq.irq);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_irq_busid_t *)data, irq, sizeof(irq) );
|
||||
irq->busnum, irq->devnum, irq->funcnum, irq->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,20 +73,20 @@ int drm_irq_install(drm_device_t *dev)
|
|||
#endif
|
||||
|
||||
if (dev->irq == 0 || dev->dev_private == NULL)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
|
||||
|
||||
DRM_LOCK();
|
||||
if (dev->irq_enabled) {
|
||||
DRM_UNLOCK();
|
||||
return DRM_ERR(EBUSY);
|
||||
return EBUSY;
|
||||
}
|
||||
dev->irq_enabled = 1;
|
||||
|
||||
dev->context_flag = 0;
|
||||
|
||||
DRM_SPININIT(dev->irq_lock, "DRM IRQ lock");
|
||||
DRM_SPININIT(&dev->irq_lock, "DRM IRQ lock");
|
||||
|
||||
/* Before installing handler */
|
||||
dev->driver.irq_preinstall(dev);
|
||||
|
@ -131,6 +130,7 @@ int drm_irq_install(drm_device_t *dev)
|
|||
dev->driver.irq_postinstall(dev);
|
||||
DRM_UNLOCK();
|
||||
|
||||
TASK_INIT(&dev->locked_task, 0, drm_locked_task, dev);
|
||||
return 0;
|
||||
err:
|
||||
DRM_LOCK();
|
||||
|
@ -142,7 +142,7 @@ err:
|
|||
dev->irqrid = 0;
|
||||
}
|
||||
#endif
|
||||
DRM_SPINUNINIT(dev->irq_lock);
|
||||
DRM_SPINUNINIT(&dev->irq_lock);
|
||||
DRM_UNLOCK();
|
||||
return retcode;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ int drm_irq_uninstall(drm_device_t *dev)
|
|||
#endif
|
||||
|
||||
if (!dev->irq_enabled)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
dev->irq_enabled = 0;
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -174,20 +174,17 @@ int drm_irq_uninstall(drm_device_t *dev)
|
|||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
|
||||
#endif
|
||||
DRM_SPINUNINIT(dev->irq_lock);
|
||||
DRM_SPINUNINIT(&dev->irq_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_control(DRM_IOCTL_ARGS)
|
||||
int drm_control(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_control_t ctl;
|
||||
drm_control_t *ctl = data;
|
||||
int err;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
|
||||
|
||||
switch ( ctl.func ) {
|
||||
switch ( ctl->func ) {
|
||||
case DRM_INST_HANDLER:
|
||||
/* Handle drivers whose DRM used to require IRQ setup but the
|
||||
* no longer does.
|
||||
|
@ -195,8 +192,8 @@ int drm_control(DRM_IOCTL_ARGS)
|
|||
if (!dev->driver.use_irq)
|
||||
return 0;
|
||||
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
|
||||
ctl.irq != dev->irq)
|
||||
return DRM_ERR(EINVAL);
|
||||
ctl->irq != dev->irq)
|
||||
return EINVAL;
|
||||
return drm_irq_install(dev);
|
||||
case DRM_UNINST_HANDLER:
|
||||
if (!dev->driver.use_irq)
|
||||
|
@ -206,29 +203,25 @@ int drm_control(DRM_IOCTL_ARGS)
|
|||
DRM_UNLOCK();
|
||||
return err;
|
||||
default:
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||
int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_wait_vblank_t vblwait;
|
||||
drm_wait_vblank_t *vblwait = data;
|
||||
struct timeval now;
|
||||
int ret;
|
||||
int ret, flags;
|
||||
|
||||
if (!dev->irq_enabled)
|
||||
return DRM_ERR(EINVAL);
|
||||
return EINVAL;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
|
||||
sizeof(vblwait) );
|
||||
|
||||
if (vblwait.request.type & _DRM_VBLANK_RELATIVE) {
|
||||
vblwait.request.sequence += atomic_read(&dev->vbl_received);
|
||||
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
||||
if (vblwait->request.type & _DRM_VBLANK_RELATIVE) {
|
||||
vblwait->request.sequence += atomic_read(&dev->vbl_received);
|
||||
vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
|
||||
}
|
||||
|
||||
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
|
||||
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
|
||||
if (flags & _DRM_VBLANK_SIGNAL) {
|
||||
#if 0 /* disabled */
|
||||
drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t), M_DRM,
|
||||
|
@ -236,11 +229,11 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
|||
if (vbl_sig == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
vbl_sig->sequence = vblwait.request.sequence;
|
||||
vbl_sig->signo = vblwait.request.signal;
|
||||
vbl_sig->sequence = vblwait->request.sequence;
|
||||
vbl_sig->signo = vblwait->request.signal;
|
||||
vbl_sig->pid = DRM_CURRENTPID;
|
||||
|
||||
vblwait.reply.sequence = atomic_read(&dev->vbl_received);
|
||||
vblwait->reply.sequence = atomic_read(&dev->vbl_received);
|
||||
|
||||
DRM_SPINLOCK(&dev->irq_lock);
|
||||
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
|
||||
|
@ -250,17 +243,16 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
|||
ret = EINVAL;
|
||||
} else {
|
||||
DRM_LOCK();
|
||||
ret = dev->driver.vblank_wait(dev, &vblwait.request.sequence);
|
||||
/* shared code returns -errno */
|
||||
ret = -dev->driver.vblank_wait(dev,
|
||||
&vblwait->request.sequence);
|
||||
DRM_UNLOCK();
|
||||
|
||||
microtime(&now);
|
||||
vblwait.reply.tval_sec = now.tv_sec;
|
||||
vblwait.reply.tval_usec = now.tv_usec;
|
||||
vblwait->reply.tval_sec = now.tv_sec;
|
||||
vblwait->reply.tval_usec = now.tv_usec;
|
||||
}
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
|
||||
sizeof(vblwait) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -291,3 +283,45 @@ void drm_vbl_send_signals( drm_device_t *dev )
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drm_locked_task(void *context, int pending __unused)
|
||||
{
|
||||
drm_device_t *dev = context;
|
||||
|
||||
DRM_LOCK();
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT))
|
||||
{
|
||||
dev->lock.file_priv = NULL; /* kernel owned */
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version > 500000
|
||||
ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock,
|
||||
PZERO | PCATCH, "drmlk2", 0);
|
||||
#else
|
||||
ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH,
|
||||
"drmlk2", 0);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return;
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
|
||||
dev->locked_task_call(dev);
|
||||
|
||||
drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
|
||||
}
|
||||
|
||||
void
|
||||
drm_locked_tasklet(drm_device_t *dev, void (*tasklet)(drm_device_t *dev))
|
||||
{
|
||||
dev->locked_task_call = tasklet;
|
||||
taskqueue_enqueue(taskqueue_swi, &dev->locked_task);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* lock.c -- IOCTLs for locking -*- linux-c -*-
|
||||
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,25 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_lock.c
|
||||
* Implementation of the ioctls and other support code for dealing with the
|
||||
* hardware lock.
|
||||
*
|
||||
* The DRM hardware lock is a shared structure between the kernel and userland.
|
||||
*
|
||||
* On uncontended access where the new context was the last context, the
|
||||
* client may take the lock without dropping down into the kernel, using atomic
|
||||
* compare-and-set.
|
||||
*
|
||||
* If the client finds during compare-and-set that it was not the last owner
|
||||
* of the lock, it calls the DRM lock ioctl, which may sleep waiting for the
|
||||
* lock, and may have side-effects of kernel-managed context switching.
|
||||
*
|
||||
* When the client releases the lock, if the lock is marked as being contended
|
||||
* by another client, then the DRM unlock ioctl is called so that the
|
||||
* contending client may be woken up.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
||||
|
@ -66,7 +82,7 @@ int drm_lock_transfer(drm_device_t *dev,
|
|||
{
|
||||
unsigned int old, new;
|
||||
|
||||
dev->lock.filp = NULL;
|
||||
dev->lock.file_priv = NULL;
|
||||
do {
|
||||
old = *lock;
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
|
@ -80,7 +96,7 @@ int drm_lock_free(drm_device_t *dev,
|
|||
{
|
||||
unsigned int old, new;
|
||||
|
||||
dev->lock.filp = NULL;
|
||||
dev->lock.file_priv = NULL;
|
||||
do {
|
||||
old = *lock;
|
||||
new = 0;
|
||||
|
@ -95,30 +111,28 @@ int drm_lock_free(drm_device_t *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_lock(DRM_IOCTL_ARGS)
|
||||
int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_lock_t lock;
|
||||
drm_lock_t *lock = data;
|
||||
int ret = 0;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock));
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
if (lock->context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
DRM_CURRENTPID, lock.context);
|
||||
DRM_CURRENTPID, lock->context);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags);
|
||||
lock->context, DRM_CURRENTPID, dev->lock.hw_lock->lock,
|
||||
lock->flags);
|
||||
|
||||
if (dev->driver.use_dma_queue && lock.context < 0)
|
||||
if (dev->driver.use_dma_queue && lock->context < 0)
|
||||
return EINVAL;
|
||||
|
||||
DRM_LOCK();
|
||||
for (;;) {
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
|
||||
dev->lock.filp = (void *)(uintptr_t)DRM_CURRENTPID;
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock, lock->context)) {
|
||||
dev->lock.file_priv = file_priv;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||
break; /* Got lock */
|
||||
|
@ -136,7 +150,7 @@ int drm_lock(DRM_IOCTL_ARGS)
|
|||
break;
|
||||
}
|
||||
DRM_UNLOCK();
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
DRM_DEBUG("%d %s\n", lock->context, ret ? "interrupted" : "has lock");
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
@ -144,24 +158,27 @@ int drm_lock(DRM_IOCTL_ARGS)
|
|||
/* XXX: Add signal blocking here */
|
||||
|
||||
if (dev->driver.dma_quiescent != NULL &&
|
||||
(lock.flags & _DRM_LOCK_QUIESCENT))
|
||||
(lock->flags & _DRM_LOCK_QUIESCENT))
|
||||
dev->driver.dma_quiescent(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_unlock(DRM_IOCTL_ARGS)
|
||||
int drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_lock_t lock;
|
||||
drm_lock_t *lock = data;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock));
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
if (lock->context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
DRM_CURRENTPID, lock.context);
|
||||
DRM_CURRENTPID, lock->context);
|
||||
return EINVAL;
|
||||
}
|
||||
/* Check that the context unlock being requested actually matches
|
||||
* who currently holds the lock.
|
||||
*/
|
||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) != lock->context)
|
||||
return EINVAL;
|
||||
|
||||
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
|
||||
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
|
||||
*/
|
||||
/*-
|
||||
*Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
|
@ -31,6 +28,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_memory.c
|
||||
* Wrappers for kernel memory allocation routines, and MTRR management support.
|
||||
*
|
||||
* This file previously implemented a memory consumption tracking system using
|
||||
* the "area" argument for various different types of allocations, but that
|
||||
* has been stripped out for now.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures");
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
/**
|
||||
* \file drm_pci.h
|
||||
* \brief PCI consistent, DMA-accessible memory functions.
|
||||
*
|
||||
* \author Eric Anholt <anholt@FreeBSD.org>
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright 2003 Eric Anholt.
|
||||
* All Rights Reserved.
|
||||
|
@ -28,6 +21,13 @@
|
|||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file drm_pci.h
|
||||
* \brief PCI consistent, DMA-accessible memory allocation.
|
||||
*
|
||||
* \author Eric Anholt <anholt@FreeBSD.org>
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
/**********************************************************************/
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../shared-core/drm_sarea.h
|
|
@ -1,5 +1,3 @@
|
|||
/* drm_scatter.h -- IOCTLs to manage scatter/gather memory -*- linux-c -*-
|
||||
* Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com */
|
||||
/*-
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
* All Rights Reserved.
|
||||
|
@ -29,6 +27,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/** @file drm_scatter.c
|
||||
* Allocation of memory for scatter-gather mappings by the graphics chip.
|
||||
*
|
||||
* The memory allocated here is then made into an aperture in the card
|
||||
* by drm_ati_pcigart_init().
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
#define DEBUG_SCATTER 0
|
||||
|
@ -40,28 +45,21 @@ void drm_sg_cleanup(drm_sg_mem_t *entry)
|
|||
free(entry, M_DRM);
|
||||
}
|
||||
|
||||
int drm_sg_alloc(DRM_IOCTL_ARGS)
|
||||
int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_scatter_gather_t request;
|
||||
drm_sg_mem_t *entry;
|
||||
unsigned long pages;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( dev->sg )
|
||||
return EINVAL;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data,
|
||||
sizeof(request) );
|
||||
|
||||
entry = malloc(sizeof(*entry), M_DRM, M_WAITOK | M_ZERO);
|
||||
if ( !entry )
|
||||
return ENOMEM;
|
||||
|
||||
pages = round_page(request.size) / PAGE_SIZE;
|
||||
DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
|
||||
pages = round_page(request->size) / PAGE_SIZE;
|
||||
DRM_DEBUG( "sg size=%ld pages=%ld\n", request->size, pages );
|
||||
|
||||
entry->pages = pages;
|
||||
|
||||
|
@ -86,11 +84,7 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
|
|||
DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
|
||||
|
||||
entry->virtual = (void *)entry->handle;
|
||||
request.handle = entry->handle;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data,
|
||||
request,
|
||||
sizeof(request) );
|
||||
request->handle = entry->handle;
|
||||
|
||||
DRM_LOCK();
|
||||
if (dev->sg) {
|
||||
|
@ -104,21 +98,28 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_sg_free(DRM_IOCTL_ARGS)
|
||||
int drm_sg_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_scatter_gather_t request;
|
||||
drm_sg_mem_t *entry;
|
||||
drm_scatter_gather_t *request = data;
|
||||
int ret;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
|
||||
sizeof(request) );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
ret = drm_sg_alloc(dev, request);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_sg_free(drm_device_t *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_scatter_gather_t *request = data;
|
||||
drm_sg_mem_t *entry;
|
||||
|
||||
DRM_LOCK();
|
||||
entry = dev->sg;
|
||||
dev->sg = NULL;
|
||||
DRM_UNLOCK();
|
||||
|
||||
if ( !entry || entry->handle != request.handle )
|
||||
if ( !entry || entry->handle != request->handle )
|
||||
return EINVAL;
|
||||
|
||||
DRM_DEBUG( "sg free virtual = 0x%lx\n", entry->handle );
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/** @file drm_sysctl.c
|
||||
* Implementation of various sysctls for controlling DRM behavior and reporting
|
||||
* debug information.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/** @file drm_vm.c
|
||||
* Support code for mmaping of DRM maps.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
||||
|
@ -33,7 +37,7 @@ int drm_mmap(dev_t kdev, vm_offset_t offset, int prot)
|
|||
paddr_t drm_mmap(dev_t kdev, off_t offset, int prot)
|
||||
#endif
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_device_t *dev = drm_get_device_from_kdev(kdev);
|
||||
drm_local_map_t *map;
|
||||
drm_file_t *priv;
|
||||
drm_map_type_t type;
|
||||
|
@ -52,7 +56,7 @@ paddr_t drm_mmap(dev_t kdev, off_t offset, int prot)
|
|||
}
|
||||
|
||||
if (!priv->authenticated)
|
||||
return DRM_ERR(EACCES);
|
||||
return EACCES;
|
||||
|
||||
if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) {
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../shared-core/i915_dma.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/i915_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/i915_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/i915_irq.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/i915_mem.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mach64_dma.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mach64_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mach64_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mach64_irq.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mach64_state.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_dma.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_irq.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_state.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_ucode.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/mga_warp.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r128_cce.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r128_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r128_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r128_irq.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r128_state.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r300_cmdbuf.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/r300_reg.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_cp.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_irq.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_mem.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/radeon_state.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/savage_bci.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/savage_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/savage_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/savage_state.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/sis_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/sis_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/sis_ds.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/sis_ds.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/sis_mm.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/tdfx_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_3d_reg.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_dma.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_drm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_drv.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_ds.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_ds.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_irq.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_map.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_mm.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_mm.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_verifier.c
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_verifier.h
|
|
@ -0,0 +1 @@
|
|||
../shared-core/via_video.c
|
|
@ -35,4 +35,9 @@ AC_SYS_LARGEFILE
|
|||
pkgconfigdir=${libdir}/pkgconfig
|
||||
AC_SUBST(pkgconfigdir)
|
||||
|
||||
AC_OUTPUT([Makefile libdrm/Makefile shared-core/Makefile libdrm.pc])
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
libdrm/Makefile
|
||||
shared-core/Makefile
|
||||
tests/Makefile
|
||||
libdrm.pc])
|
||||
|
|
689
libdrm/xf86drm.c
689
libdrm/xf86drm.c
|
@ -49,7 +49,6 @@
|
|||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdarg.h>
|
||||
#include "drm.h"
|
||||
|
||||
/* Not all systems have MAP_FAILED defined */
|
||||
#ifndef MAP_FAILED
|
||||
|
@ -2346,7 +2345,7 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
|
|||
* DRM_FENCE_MASK_DRIVER
|
||||
*/
|
||||
|
||||
int drmFenceCreate(int fd, unsigned flags, int class, unsigned type,
|
||||
int drmFenceCreate(int fd, unsigned flags, int fence_class, unsigned type,
|
||||
drmFence *fence)
|
||||
{
|
||||
drm_fence_arg_t arg;
|
||||
|
@ -2354,12 +2353,12 @@ int drmFenceCreate(int fd, unsigned flags, int class, unsigned type,
|
|||
memset(&arg, 0, sizeof(arg));
|
||||
arg.flags = flags;
|
||||
arg.type = type;
|
||||
arg.class = class;
|
||||
arg.op = drm_fence_create;
|
||||
if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
|
||||
arg.fence_class = fence_class;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_FENCE_CREATE, &arg))
|
||||
return -errno;
|
||||
fence->handle = arg.handle;
|
||||
fence->class = arg.class;
|
||||
fence->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->flags = arg.flags;
|
||||
fence->signaled = 0;
|
||||
|
@ -2372,46 +2371,36 @@ int drmFenceCreate(int fd, unsigned flags, int class, unsigned type,
|
|||
* DRM_FENCE_MASK_DRIVER
|
||||
*/
|
||||
|
||||
int drmFenceBuffers(int fd, unsigned flags, drmFence *fence)
|
||||
int drmFenceBuffers(int fd, unsigned flags, uint32_t fence_class, 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))
|
||||
arg.fence_class = fence_class;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_FENCE_BUFFERS, &arg))
|
||||
return -errno;
|
||||
fence->handle = arg.handle;
|
||||
fence->class = arg.class;
|
||||
fence->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->flags = arg.flags;
|
||||
fence->sequence = arg.sequence;
|
||||
fence->signaled = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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))
|
||||
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;
|
||||
fence->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->flags = arg.flags;
|
||||
fence->signaled = arg.signaled;
|
||||
|
@ -2424,8 +2413,8 @@ int drmFenceUnreference(int fd, const drmFence *fence)
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -2437,10 +2426,10 @@ int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type)
|
|||
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->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->signaled = arg.signaled;
|
||||
return 0;
|
||||
|
@ -2452,10 +2441,10 @@ int drmFenceUpdate(int fd, drmFence *fence)
|
|||
|
||||
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->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->signaled = arg.signaled;
|
||||
return 0;
|
||||
|
@ -2488,14 +2477,14 @@ int drmFenceEmit(int fd, unsigned flags, drmFence *fence, unsigned emit_type)
|
|||
drm_fence_arg_t arg;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.class = fence->class;
|
||||
arg.fence_class = fence->fence_class;
|
||||
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->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->signaled = arg.signaled;
|
||||
return 0;
|
||||
|
@ -2526,159 +2515,21 @@ int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_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)
|
||||
return -errno;
|
||||
|
||||
fence->class = arg.class;
|
||||
fence->fence_class = arg.fence_class;
|
||||
fence->type = arg.type;
|
||||
fence->signaled = arg.signaled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drmAdjustListNodes(drmBOList *list)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
int ret = 0;
|
||||
|
||||
while(list->numCurrent < list->numTarget) {
|
||||
node = (drmBONode *) malloc(sizeof(*node));
|
||||
if (!node) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
list->numCurrent++;
|
||||
DRMLISTADD(&node->head, &list->free);
|
||||
}
|
||||
|
||||
while(list->numCurrent > list->numTarget) {
|
||||
l = list->free.next;
|
||||
if (l == &list->free)
|
||||
break;
|
||||
DRMLISTDEL(l);
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
free(node);
|
||||
list->numCurrent--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void drmBOFreeList(drmBOList *list)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
|
||||
l = list->list.next;
|
||||
while(l != &list->list) {
|
||||
DRMLISTDEL(l);
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
free(node);
|
||||
l = list->list.next;
|
||||
list->numCurrent--;
|
||||
list->numOnList--;
|
||||
}
|
||||
|
||||
l = list->free.next;
|
||||
while(l != &list->free) {
|
||||
DRMLISTDEL(l);
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
free(node);
|
||||
l = list->free.next;
|
||||
list->numCurrent--;
|
||||
}
|
||||
}
|
||||
|
||||
int drmBOResetList(drmBOList *list)
|
||||
{
|
||||
drmMMListHead *l;
|
||||
int ret;
|
||||
|
||||
ret = drmAdjustListNodes(list);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
l = list->list.next;
|
||||
while (l != &list->list) {
|
||||
DRMLISTDEL(l);
|
||||
DRMLISTADD(l, &list->free);
|
||||
list->numOnList--;
|
||||
l = list->list.next;
|
||||
}
|
||||
return drmAdjustListNodes(list);
|
||||
}
|
||||
|
||||
static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
|
||||
unsigned long arg0,
|
||||
unsigned long arg1)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
|
||||
l = list->free.next;
|
||||
if (l == &list->free) {
|
||||
node = (drmBONode *) malloc(sizeof(*node));
|
||||
if (!node) {
|
||||
return NULL;
|
||||
}
|
||||
list->numCurrent++;
|
||||
}
|
||||
else {
|
||||
DRMLISTDEL(l);
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
}
|
||||
node->buf = item;
|
||||
node->arg0 = arg0;
|
||||
node->arg1 = arg1;
|
||||
DRMLISTADD(&node->head, &list->list);
|
||||
list->numOnList++;
|
||||
return node;
|
||||
}
|
||||
|
||||
void *drmBOListIterator(drmBOList *list)
|
||||
{
|
||||
void *ret = list->list.next;
|
||||
|
||||
if (ret == &list->list)
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *drmBOListNext(drmBOList *list, void *iterator)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
drmMMListHead *l = (drmMMListHead *) iterator;
|
||||
ret = l->next;
|
||||
if (ret == &list->list)
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
drmBO *drmBOListBuf(void *iterator)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l = (drmMMListHead *) iterator;
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
return node->buf;
|
||||
}
|
||||
|
||||
|
||||
int drmBOCreateList(int numTarget, drmBOList *list)
|
||||
{
|
||||
DRMINITLISTHEAD(&list->list);
|
||||
DRMINITLISTHEAD(&list->free);
|
||||
list->numTarget = numTarget;
|
||||
list->numCurrent = 0;
|
||||
list->numOnList = 0;
|
||||
return drmAdjustListNodes(list);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -2690,16 +2541,21 @@ static void drmBOCopyReply(const drm_bo_arg_reply_t *rep, drmBO *buf)
|
|||
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 size,
|
||||
unsigned pageAlignment, void *user_buffer,
|
||||
uint64_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));
|
||||
|
@ -2707,40 +2563,17 @@ int drmBOCreate(int fd, unsigned long start, unsigned long size,
|
|||
req->mask = mask;
|
||||
req->hint = hint;
|
||||
req->size = size;
|
||||
req->type = type;
|
||||
req->page_alignment = pageAlignment;
|
||||
req->buffer_start = (unsigned long) user_buffer;
|
||||
|
||||
buf->virtual = NULL;
|
||||
|
||||
switch(type) {
|
||||
case drm_bo_type_dc:
|
||||
req->buffer_start = start;
|
||||
break;
|
||||
case drm_bo_type_user:
|
||||
req->buffer_start = (unsigned long) user_buffer;
|
||||
buf->virtual = user_buffer;
|
||||
break;
|
||||
case drm_bo_type_fake:
|
||||
req->buffer_start = start;
|
||||
break;
|
||||
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;
|
||||
|
@ -2749,56 +2582,19 @@ int drmBOCreate(int fd, unsigned long start, unsigned long size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
|
||||
(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
|
||||
buf->mapVirtual = NULL;
|
||||
buf->virtual = NULL;
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
req->handle = buf->handle;
|
||||
req->op = drm_bo_destroy;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &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;
|
||||
buf->mapVirtual = NULL;
|
||||
buf->mapCount = 0;
|
||||
buf->virtual = NULL;
|
||||
|
@ -2806,35 +2602,27 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drmBOUnReference(int fd, drmBO *buf)
|
||||
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)) {
|
||||
if (buf->mapVirtual) {
|
||||
(void) munmap(buf->mapVirtual, buf->start + buf->size);
|
||||
buf->mapVirtual = NULL;
|
||||
buf->virtual = NULL;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -2844,16 +2632,16 @@ int drmBOUnReference(int fd, drmBO *buf)
|
|||
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;
|
||||
|
||||
/*
|
||||
* Make sure we have a virtual address of the buffer.
|
||||
*/
|
||||
|
||||
if (!buf->virtual && buf->type != drm_bo_type_fake) {
|
||||
if (!buf->virtual) {
|
||||
drmAddress virtual;
|
||||
virtual = mmap(0, buf->size + buf->start,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
|
@ -2871,7 +2659,6 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
|
|||
req->handle = buf->handle;
|
||||
req->mask = mapFlags;
|
||||
req->hint = mapHint;
|
||||
req->op = drm_bo_map;
|
||||
|
||||
/*
|
||||
* May hang if the buffer object is busy.
|
||||
|
@ -2879,15 +2666,11 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
|
|||
*/
|
||||
|
||||
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;
|
||||
|
@ -2897,129 +2680,90 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
|
|||
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;
|
||||
|
||||
buf->mapCount--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
|
||||
unsigned hint)
|
||||
int drmBOSetStatus(int fd, drmBO *buf,
|
||||
uint64_t flags, uint64_t mask,
|
||||
unsigned int hint,
|
||||
unsigned int desired_tile_stride,
|
||||
unsigned int tile_info)
|
||||
{
|
||||
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;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
req->mask = mask;
|
||||
req->flags = flags;
|
||||
req->handle = buf->handle;
|
||||
req->mask = flags;
|
||||
req->hint = hint;
|
||||
req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
|
||||
req->op = drm_bo_validate;
|
||||
req->desired_tile_stride = desired_tile_stride;
|
||||
req->tile_info = tile_info;
|
||||
|
||||
do{
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
do {
|
||||
ret = ioctl(fd, DRM_IOCTL_BO_SETSTATUS, &arg);
|
||||
} while (ret && errno == EAGAIN);
|
||||
|
||||
if (ret)
|
||||
return -errno;
|
||||
if (!arg.handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
return -errno;
|
||||
|
||||
drmBOCopyReply(rep, 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;
|
||||
int ret = 0;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
req->handle = buf->handle;
|
||||
req->mask = flags;
|
||||
req->arg_handle = fenceHandle;
|
||||
req->op = drm_bo_fence;
|
||||
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
|
||||
if (ret)
|
||||
return -errno;
|
||||
if (!arg.handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -3041,194 +2785,19 @@ int drmBOBusy(int fd, drmBO *buf, int *busy)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
|
||||
unsigned mask,
|
||||
int *newItem)
|
||||
{
|
||||
drmBONode *node, *cur;
|
||||
drmMMListHead *l;
|
||||
|
||||
*newItem = 0;
|
||||
cur = NULL;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
if (node->buf == buf) {
|
||||
cur = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cur) {
|
||||
cur = drmAddListItem(list, buf, flags, mask);
|
||||
if (!cur) {
|
||||
drmMsg("Out of memory creating validate list node.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
*newItem = 1;
|
||||
cur->arg0 = flags;
|
||||
cur->arg1 = mask;
|
||||
}
|
||||
else {
|
||||
unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
|
||||
unsigned memFlags = cur->arg0 & flags & memMask;
|
||||
|
||||
if (!memFlags) {
|
||||
drmMsg("Incompatible memory location requests "
|
||||
"on validate list.\n");
|
||||
drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
|
||||
cur->arg0, cur->arg1);
|
||||
drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
|
||||
flags, mask);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
|
||||
drmMsg("Incompatible buffer flag requests "
|
||||
"on validate list.\n");
|
||||
drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
|
||||
cur->arg0, cur->arg1);
|
||||
drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
|
||||
flags, mask);
|
||||
return -EINVAL;
|
||||
}
|
||||
cur->arg1 |= mask;
|
||||
cur->arg0 = memFlags | ((cur->arg0 | flags) &
|
||||
cur->arg1 & ~DRM_BO_MASK_MEM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drmBOValidateList(int fd, drmBOList *list)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
drm_bo_arg_t *arg, *first;
|
||||
drm_bo_arg_request_t *req;
|
||||
drm_bo_arg_reply_t *rep;
|
||||
drm_u64_t *prevNext = NULL;
|
||||
drmBO *buf;
|
||||
int ret;
|
||||
|
||||
first = NULL;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
|
||||
arg = &node->bo_arg;
|
||||
req = &arg->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->op = drm_bo_validate;
|
||||
req->mask = node->arg0;
|
||||
req->hint = 0;
|
||||
req->arg_handle = node->arg1;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
|
||||
} while (ret && errno == EAGAIN);
|
||||
|
||||
if (ret)
|
||||
return -errno;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
arg = &node->bo_arg;
|
||||
rep = &arg->d.rep;
|
||||
|
||||
if (!arg->handled) {
|
||||
drmMsg("Unhandled request\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
|
||||
buf = node->buf;
|
||||
drmBOCopyReply(rep, buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
drm_bo_arg_t *arg, *first;
|
||||
drm_bo_arg_request_t *req;
|
||||
drm_bo_arg_reply_t *rep;
|
||||
drm_u64_t *prevNext = NULL;
|
||||
drmBO *buf;
|
||||
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->handle = node->buf->handle;
|
||||
req->op = drm_bo_fence;
|
||||
req->mask = node->arg0;
|
||||
req->arg_handle = fenceHandle;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
return 0;
|
||||
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
|
||||
|
||||
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;
|
||||
if (!arg->handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
drmBOCopyReply(rep, node->buf);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -3237,47 +2806,79 @@ int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
|
|||
|
||||
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)
|
||||
/*
|
||||
* If this function returns an error, and lockBM was set to 1,
|
||||
* the buffer manager is NOT locked.
|
||||
*/
|
||||
|
||||
int drmMMLock(int fd, unsigned memType, int lockBM, int ignoreNoEvict)
|
||||
{
|
||||
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;
|
||||
arg.lock_flags |= (lockBM) ? DRM_BO_LOCK_UNLOCK_BM : 0;
|
||||
arg.lock_flags |= (ignoreNoEvict) ? DRM_BO_LOCK_IGNORE_NO_EVICT : 0;
|
||||
|
||||
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)
|
||||
int drmMMUnlock(int fd, unsigned memType, int unlockBM)
|
||||
{
|
||||
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;
|
||||
arg.lock_flags |= (unlockBM) ? DRM_BO_LOCK_UNLOCK_BM : 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int drmBOVersion(int fd, unsigned int *major,
|
||||
unsigned int *minor,
|
||||
unsigned int *patchlevel)
|
||||
{
|
||||
struct drm_bo_version_arg arg;
|
||||
int ret;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
ret = ioctl(fd, DRM_IOCTL_BO_VERSION, &arg);
|
||||
if (ret)
|
||||
return -errno;
|
||||
|
||||
if (major)
|
||||
*major = arg.major;
|
||||
if (minor)
|
||||
*minor = arg.minor;
|
||||
if (patchlevel)
|
||||
*patchlevel = arg.patchlevel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define DRM_MAX_FDS 16
|
||||
static struct {
|
||||
char *BusID;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <drm.h>
|
||||
|
||||
/* Defaults, if nothing set in xf86config */
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
#define HASH_MAIN 0
|
||||
|
||||
#if !HASH_MAIN
|
||||
# include "drm.h"
|
||||
# include "xf86drm.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -77,7 +77,6 @@
|
|||
#define RANDOM_MAIN 0
|
||||
|
||||
#if !RANDOM_MAIN
|
||||
# include "drm.h"
|
||||
# include "xf86drm.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#define SL_MAIN 0
|
||||
|
||||
#if !SL_MAIN
|
||||
# include "drm.h"
|
||||
# include "xf86drm.h"
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#ifndef _XF86MM_H_
|
||||
#define _XF86MM_H_
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "drm.h"
|
||||
|
||||
/*
|
||||
|
@ -37,7 +38,7 @@
|
|||
* be protected using an external mutex.
|
||||
*
|
||||
* Note: Don't protect the following functions, as it may lead to deadlocks:
|
||||
* drmBOUnmap(), drmFenceBuffers().
|
||||
* drmBOUnmap().
|
||||
* The kernel is synchronizing and refcounting buffer maps.
|
||||
* User space only needs to refcount object usage within the same application.
|
||||
*/
|
||||
|
@ -96,20 +97,20 @@ typedef struct _drmMMListHead
|
|||
typedef struct _drmFence
|
||||
{
|
||||
unsigned handle;
|
||||
int class;
|
||||
int fence_class;
|
||||
unsigned type;
|
||||
unsigned flags;
|
||||
unsigned signaled;
|
||||
uint32_t sequence;
|
||||
unsigned pad[4]; /* for future expansion */
|
||||
} drmFence;
|
||||
|
||||
typedef struct _drmBO
|
||||
{
|
||||
drm_bo_type_t type;
|
||||
unsigned handle;
|
||||
drm_u64_t mapHandle;
|
||||
unsigned flags;
|
||||
unsigned mask;
|
||||
uint64_t mapHandle;
|
||||
uint64_t flags;
|
||||
uint64_t mask;
|
||||
unsigned mapFlags;
|
||||
unsigned long size;
|
||||
unsigned long offset;
|
||||
|
@ -117,37 +118,21 @@ typedef struct _drmBO
|
|||
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
|
||||
{
|
||||
drmMMListHead head;
|
||||
drmBO *buf;
|
||||
drm_bo_arg_t bo_arg;
|
||||
unsigned long arg0;
|
||||
unsigned long arg1;
|
||||
} drmBONode;
|
||||
|
||||
typedef struct _drmBOList {
|
||||
unsigned numTarget;
|
||||
unsigned numCurrent;
|
||||
unsigned numOnList;
|
||||
drmMMListHead list;
|
||||
drmMMListHead free;
|
||||
} drmBOList;
|
||||
|
||||
|
||||
/*
|
||||
* Fence functions.
|
||||
*/
|
||||
|
||||
extern int drmFenceCreate(int fd, unsigned flags, int class,
|
||||
extern int drmFenceCreate(int fd, unsigned flags, int fence_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);
|
||||
|
@ -157,46 +142,25 @@ 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 drmFenceBuffers(int fd, unsigned flags, uint32_t fence_class, drmFence *fence);
|
||||
|
||||
|
||||
/*
|
||||
* Buffer object list functions.
|
||||
*/
|
||||
|
||||
extern void drmBOFreeList(drmBOList *list);
|
||||
extern int drmBOResetList(drmBOList *list);
|
||||
extern void *drmBOListIterator(drmBOList *list);
|
||||
extern void *drmBOListNext(drmBOList *list, void *iterator);
|
||||
extern drmBO *drmBOListBuf(void *iterator);
|
||||
extern int drmBOCreateList(int numTarget, drmBOList *list);
|
||||
|
||||
/*
|
||||
* Buffer object functions.
|
||||
*/
|
||||
|
||||
extern int drmBOCreate(int fd, unsigned long start, unsigned long size,
|
||||
unsigned pageAlignment,void *user_buffer,
|
||||
drm_bo_type_t type, unsigned mask,
|
||||
unsigned hint, drmBO *buf);
|
||||
extern int drmBODestroy(int fd, drmBO *buf);
|
||||
extern int drmBOCreate(int fd, unsigned long size,
|
||||
unsigned pageAlignment, void *user_buffer,
|
||||
uint64_t mask, unsigned hint, drmBO *buf);
|
||||
extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
|
||||
extern int drmBOUnReference(int fd, drmBO *buf);
|
||||
extern int drmBOUnreference(int fd, 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 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,
|
||||
unsigned mask,
|
||||
int *newItem);
|
||||
extern int drmBOValidateList(int fd, drmBOList *list);
|
||||
extern int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle);
|
||||
extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint);
|
||||
|
||||
/*
|
||||
|
@ -206,8 +170,16 @@ extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint);
|
|||
extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
|
||||
unsigned memType);
|
||||
extern int drmMMTakedown(int fd, unsigned memType);
|
||||
extern int drmMMLock(int fd, unsigned memType);
|
||||
extern int drmMMUnlock(int fd, unsigned memType);
|
||||
extern int drmMMLock(int fd, unsigned memType, int lockBM, int ignoreNoEvict);
|
||||
extern int drmMMUnlock(int fd, unsigned memType, int unlockBM);
|
||||
extern int drmBOSetStatus(int fd, drmBO *buf,
|
||||
uint64_t flags, uint64_t mask,
|
||||
unsigned int hint,
|
||||
unsigned int desired_tile_stride,
|
||||
unsigned int tile_info);
|
||||
extern int drmBOVersion(int fd, unsigned int *major,
|
||||
unsigned int *minor,
|
||||
unsigned int *patchlevel);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -58,7 +58,7 @@ endif
|
|||
|
||||
# Modules for all architectures
|
||||
MODULE_LIST := drm.o tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o \
|
||||
mach64.o nv.o nouveau.o
|
||||
mach64.o nv.o nouveau.o xgi.o
|
||||
|
||||
# Modules only for ix86 architectures
|
||||
ifneq (,$(findstring 86,$(MACHINE)))
|
||||
|
@ -91,6 +91,7 @@ MACH64HEADERS = mach64_drv.h mach64_drm.h $(DRMHEADERS)
|
|||
NVHEADERS = nv_drv.h $(DRMHEADERS)
|
||||
FFBHEADERS = ffb_drv.h $(DRMHEADERS)
|
||||
NOUVEAUHEADERS = nouveau_drv.h nouveau_drm.h nouveau_reg.h $(DRMHEADERS)
|
||||
XGIHEADERS = xgi_cmdlist.h xgi_drv.h xgi_misc.h xgi_regs.h $(DRMHEADERS)
|
||||
|
||||
PROGS = dristat drmstat
|
||||
|
||||
|
@ -162,7 +163,7 @@ endif
|
|||
all: modules
|
||||
|
||||
modules: includes
|
||||
make -C $(LINUXDIR) $(GETCONFIG) SUBDIRS=`pwd` DRMSRCDIR=`pwd` modules
|
||||
+make -C $(LINUXDIR) $(GETCONFIG) SUBDIRS=`pwd` DRMSRCDIR=`pwd` modules
|
||||
|
||||
ifeq ($(HEADERFROMBOOT),1)
|
||||
|
||||
|
@ -284,6 +285,7 @@ CONFIG_DRM_VIA := n
|
|||
CONFIG_DRM_MACH64 := n
|
||||
CONFIG_DRM_NV := n
|
||||
CONFIG_DRM_NOUVEAU := n
|
||||
CONFIG_DRM_XGI := n
|
||||
|
||||
# Enable module builds for the modules requested/supported.
|
||||
|
||||
|
@ -320,6 +322,9 @@ endif
|
|||
ifneq (,$(findstring nouveau,$(DRM_MODULES)))
|
||||
CONFIG_DRM_NOUVEAU := m
|
||||
endif
|
||||
ifneq (,$(findstring xgi,$(DRM_MODULES)))
|
||||
CONFIG_DRM_XGI := m
|
||||
endif
|
||||
|
||||
# These require AGP support
|
||||
|
||||
|
@ -347,6 +352,7 @@ $(via-objs): $(VIAHEADERS)
|
|||
$(mach64-objs): $(MACH64HEADERS)
|
||||
$(nv-objs): $(NVHEADERS)
|
||||
$(nouveau-objs): $(NOUVEAUHEADERS)
|
||||
$(xgi-objs): $(XGIHEADERS)
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
|
|||
drm_sysfs.o drm_pci.o drm_agpsupport.o drm_scatter.o \
|
||||
drm_memory_debug.o ati_pcigart.o drm_sman.o \
|
||||
drm_hashtab.o drm_mm.o drm_object.o drm_compat.o \
|
||||
drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o
|
||||
drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o
|
||||
tdfx-objs := tdfx_drv.o
|
||||
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
|
||||
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
|
||||
|
@ -21,12 +21,15 @@ i810-objs := i810_drv.o i810_dma.o
|
|||
i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \
|
||||
i915_buffer.o
|
||||
nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
|
||||
nouveau_object.o nouveau_irq.o \
|
||||
nouveau_object.o nouveau_irq.o nouveau_notifier.o nouveau_swmthd.o \
|
||||
nouveau_sgdma.o nouveau_dma.o \
|
||||
nv04_timer.o \
|
||||
nv04_mc.o nv40_mc.o \
|
||||
nv04_mc.o nv40_mc.o nv50_mc.o \
|
||||
nv04_fb.o nv10_fb.o nv40_fb.o \
|
||||
nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \
|
||||
nv40_graph.o
|
||||
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
|
||||
nv04_graph.o nv10_graph.o nv20_graph.o \
|
||||
nv40_graph.o nv50_graph.o \
|
||||
nv04_instmem.o nv50_instmem.o
|
||||
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
|
||||
sis-objs := sis_drv.o sis_mm.o
|
||||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
|
@ -35,6 +38,8 @@ via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o \
|
|||
via_video.o via_dmablit.o via_fence.o via_buffer.o
|
||||
mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o
|
||||
nv-objs := nv_drv.o
|
||||
xgi-objs := xgi_cmdlist.o xgi_drv.o xgi_fb.o xgi_misc.o xgi_pcie.o \
|
||||
xgi_fence.o
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
drm-objs += drm_ioc32.o
|
||||
|
@ -43,6 +48,7 @@ mga-objs += mga_ioc32.o
|
|||
r128-objs += r128_ioc32.o
|
||||
i915-objs += i915_ioc32.o
|
||||
nouveau-objs += nouveau_ioc32.o
|
||||
xgi-objs += xgi_ioc32.o
|
||||
endif
|
||||
|
||||
obj-m += drm.o
|
||||
|
@ -59,3 +65,4 @@ obj-$(CONFIG_DRM_VIA) += via.o
|
|||
obj-$(CONFIG_DRM_MACH64)+= mach64.o
|
||||
obj-$(CONFIG_DRM_NV) += nv.o
|
||||
obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o
|
||||
obj-$(CONFIG_DRM_XGI) += xgi.o
|
||||
|
|
|
@ -81,9 +81,9 @@ static void drm_ati_free_pcigart_table(void *address, int order)
|
|||
free_pages((unsigned long)address, order);
|
||||
}
|
||||
|
||||
int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
|
||||
int drm_ati_pcigart_cleanup(struct drm_device *dev, struct ati_pcigart_info *gart_info)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
struct drm_sg_mem *entry = dev->sg;
|
||||
unsigned long pages;
|
||||
int i;
|
||||
int order;
|
||||
|
@ -132,9 +132,9 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
|
||||
|
||||
int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
|
||||
int drm_ati_pcigart_init(struct drm_device *dev, struct ati_pcigart_info *gart_info)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
struct drm_sg_mem *entry = dev->sg;
|
||||
void *address = NULL;
|
||||
unsigned long pages;
|
||||
u32 *pci_gart, page_base, bus_address = 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -40,7 +40,7 @@
|
|||
* Get AGP information.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a (output) drm_agp_info structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -48,7 +48,7 @@
|
|||
* Verifies the AGP device has been initialized and acquired and fills in the
|
||||
* drm_agp_info structure with the information in drm_agp_head::agp_info.
|
||||
*/
|
||||
int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info)
|
||||
int drm_agp_info(struct drm_device * dev, struct drm_agp_info *info)
|
||||
{
|
||||
DRM_AGP_KERN *kern;
|
||||
|
||||
|
@ -70,20 +70,16 @@ int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_agp_info);
|
||||
|
||||
int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_info_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_info_t info;
|
||||
struct drm_agp_info *info = data;
|
||||
int err;
|
||||
|
||||
err = drm_agp_info(dev, &info);
|
||||
err = drm_agp_info(dev, info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -96,7 +92,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
|||
* Verifies the AGP device hasn't been acquired before and calls
|
||||
* \c agp_backend_acquire.
|
||||
*/
|
||||
int drm_agp_acquire(drm_device_t * dev)
|
||||
int drm_agp_acquire(struct drm_device * dev)
|
||||
{
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)
|
||||
int retcode;
|
||||
|
@ -123,7 +119,7 @@ EXPORT_SYMBOL(drm_agp_acquire);
|
|||
* Acquire the AGP device (ioctl).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -131,12 +127,10 @@ EXPORT_SYMBOL(drm_agp_acquire);
|
|||
* Verifies the AGP device hasn't been acquired before and calls
|
||||
* \c agp_backend_acquire.
|
||||
*/
|
||||
int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
|
||||
return drm_agp_acquire( (drm_device_t *) priv->head->dev );
|
||||
return drm_agp_acquire( (struct drm_device *) file_priv->head->dev );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,7 +141,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Verifies the AGP device has been acquired and calls \c agp_backend_release.
|
||||
*/
|
||||
int drm_agp_release(drm_device_t *dev)
|
||||
int drm_agp_release(struct drm_device *dev)
|
||||
{
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
@ -162,12 +156,9 @@ int drm_agp_release(drm_device_t *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_agp_release);
|
||||
|
||||
int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_release_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
||||
return drm_agp_release(dev);
|
||||
}
|
||||
|
||||
|
@ -181,7 +172,7 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
|||
* Verifies the AGP device has been acquired but not enabled, and calls
|
||||
* \c agp_enable.
|
||||
*/
|
||||
int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
|
||||
int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode)
|
||||
{
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
@ -192,31 +183,24 @@ int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
|
|||
#else
|
||||
agp_enable(dev->agp->bridge, mode.mode);
|
||||
#endif
|
||||
dev->agp->base = dev->agp->agp_info.aper_base;
|
||||
dev->agp->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_agp_enable);
|
||||
|
||||
int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_enable_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_mode_t mode;
|
||||
struct drm_agp_mode *mode = data;
|
||||
|
||||
|
||||
if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode)))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_agp_enable(dev, mode);
|
||||
return drm_agp_enable(dev, *mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate AGP memory.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv file private pointer.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_agp_buffer structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -224,9 +208,9 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
|
|||
* Verifies the AGP device is present and has been acquired, allocates the
|
||||
* memory via alloc_agp() and creates a drm_agp_mem entry for it.
|
||||
*/
|
||||
int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
|
||||
int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
struct drm_agp_mem *entry;
|
||||
DRM_AGP_MEM *memory;
|
||||
unsigned long pages;
|
||||
u32 type;
|
||||
|
@ -259,35 +243,12 @@ int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
|
|||
EXPORT_SYMBOL(drm_agp_alloc);
|
||||
|
||||
|
||||
int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_alloc_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_buffer_t request;
|
||||
drm_agp_buffer_t __user *argp = (void __user *)arg;
|
||||
int err;
|
||||
struct drm_agp_buffer *request = data;
|
||||
|
||||
if (copy_from_user(&request, argp, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_agp_alloc(dev, &request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request))) {
|
||||
drm_agp_mem_t *entry;
|
||||
list_for_each_entry(entry, &dev->agp->memory, head) {
|
||||
if (entry->handle == request.handle)
|
||||
break;
|
||||
}
|
||||
list_del(&entry->head);
|
||||
drm_free_agp(entry->memory, entry->pages);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return drm_agp_alloc(dev, request);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,10 +260,10 @@ int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Walks through drm_agp_head::memory until finding a matching handle.
|
||||
*/
|
||||
static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
|
||||
static struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device * dev,
|
||||
unsigned long handle)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
struct drm_agp_mem *entry;
|
||||
|
||||
list_for_each_entry(entry, &dev->agp->memory, head) {
|
||||
if (entry->handle == handle)
|
||||
|
@ -315,7 +276,7 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
|
|||
* Unbind AGP memory from the GATT (ioctl).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_agp_binding structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -323,9 +284,9 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
|
|||
* Verifies the AGP device is present and acquired, looks-up the AGP memory
|
||||
* entry and passes it to the unbind_agp() function.
|
||||
*/
|
||||
int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
|
||||
int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
struct drm_agp_mem *entry;
|
||||
int ret;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
|
@ -342,18 +303,12 @@ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
|
|||
EXPORT_SYMBOL(drm_agp_unbind);
|
||||
|
||||
|
||||
int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_unbind_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_binding_t request;
|
||||
struct drm_agp_binding *request = data;
|
||||
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_agp_unbind(dev, &request);
|
||||
return drm_agp_unbind(dev, request);
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,7 +316,7 @@ int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
|
|||
* Bind AGP memory into the GATT (ioctl)
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_agp_binding structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -370,9 +325,9 @@ int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
|
|||
* is currently bound into the GATT. Looks-up the AGP memory entry and passes
|
||||
* it to bind_agp() function.
|
||||
*/
|
||||
int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
|
||||
int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
struct drm_agp_mem *entry;
|
||||
int retcode;
|
||||
int page;
|
||||
|
||||
|
@ -393,18 +348,12 @@ int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
|
|||
EXPORT_SYMBOL(drm_agp_bind);
|
||||
|
||||
|
||||
int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_bind_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_binding_t request;
|
||||
struct drm_agp_binding *request = data;
|
||||
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_agp_bind(dev, &request);
|
||||
return drm_agp_bind(dev, request);
|
||||
}
|
||||
|
||||
|
||||
|
@ -412,7 +361,7 @@ int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
|
|||
* Free AGP memory (ioctl).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_agp_buffer structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -422,9 +371,9 @@ int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
|
|||
* unbind_agp(). Frees it via free_agp() as well as the entry itself
|
||||
* and unlinks from the doubly linked list it's inserted in.
|
||||
*/
|
||||
int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
|
||||
int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
struct drm_agp_mem *entry;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
@ -443,18 +392,12 @@ EXPORT_SYMBOL(drm_agp_free);
|
|||
|
||||
|
||||
|
||||
int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_agp_free_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_buffer_t request;
|
||||
struct drm_agp_buffer *request = data;
|
||||
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_agp_free(dev, &request);
|
||||
return drm_agp_free(dev, request);
|
||||
}
|
||||
|
||||
|
||||
|
@ -467,9 +410,9 @@ int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
|
|||
* via the inter_module_* functions. Creates and initializes a drm_agp_head
|
||||
* structure.
|
||||
*/
|
||||
drm_agp_head_t *drm_agp_init(drm_device_t *dev)
|
||||
struct drm_agp_head *drm_agp_init(struct drm_device *dev)
|
||||
{
|
||||
drm_agp_head_t *head = NULL;
|
||||
struct drm_agp_head *head = NULL;
|
||||
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
|
@ -497,6 +440,7 @@ drm_agp_head_t *drm_agp_init(drm_device_t *dev)
|
|||
INIT_LIST_HEAD(&head->memory);
|
||||
head->cant_use_aperture = head->agp_info.cant_use_aperture;
|
||||
head->page_mask = head->agp_info.page_mask;
|
||||
head->base = head->agp_info.aper_base;
|
||||
return head;
|
||||
}
|
||||
|
||||
|
@ -554,16 +498,16 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
|
|||
#define AGP_REQUIRED_MAJOR 0
|
||||
#define AGP_REQUIRED_MINOR 102
|
||||
|
||||
static int drm_agp_needs_unbind_cache_adjust(drm_ttm_backend_t *backend) {
|
||||
static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend) {
|
||||
return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
|
||||
}
|
||||
|
||||
|
||||
static int drm_agp_populate(drm_ttm_backend_t *backend, unsigned long num_pages,
|
||||
static int drm_agp_populate(struct drm_ttm_backend *backend, unsigned long num_pages,
|
||||
struct page **pages) {
|
||||
|
||||
drm_agp_ttm_backend_t *agp_be =
|
||||
container_of(backend, drm_agp_ttm_backend_t, backend);
|
||||
struct drm_agp_ttm_backend *agp_be =
|
||||
container_of(backend, struct drm_agp_ttm_backend, backend);
|
||||
struct page **cur_page, **last_page = pages + num_pages;
|
||||
DRM_AGP_MEM *mem;
|
||||
|
||||
|
@ -590,32 +534,32 @@ static int drm_agp_populate(drm_ttm_backend_t *backend, unsigned long num_pages,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_agp_bind_ttm(drm_ttm_backend_t *backend,
|
||||
unsigned long offset,
|
||||
int cached)
|
||||
static int drm_agp_bind_ttm(struct drm_ttm_backend *backend,
|
||||
struct drm_bo_mem_reg *bo_mem)
|
||||
{
|
||||
drm_agp_ttm_backend_t *agp_be =
|
||||
container_of(backend, drm_agp_ttm_backend_t, backend);
|
||||
struct drm_agp_ttm_backend *agp_be =
|
||||
container_of(backend, struct drm_agp_ttm_backend, backend);
|
||||
DRM_AGP_MEM *mem = agp_be->mem;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG("drm_agp_bind_ttm\n");
|
||||
mem->is_flushed = TRUE;
|
||||
mem->type = (cached) ? AGP_USER_CACHED_MEMORY :
|
||||
mem->type = (bo_mem->flags & DRM_BO_FLAG_CACHED) ? AGP_USER_CACHED_MEMORY :
|
||||
AGP_USER_MEMORY;
|
||||
ret = drm_agp_bind_memory(mem, offset);
|
||||
ret = drm_agp_bind_memory(mem, bo_mem->mm_node->start);
|
||||
if (ret) {
|
||||
DRM_ERROR("AGP Bind memory failed\n");
|
||||
}
|
||||
DRM_FLAG_MASKED(backend->flags, (cached) ? DRM_BE_FLAG_BOUND_CACHED : 0,
|
||||
DRM_FLAG_MASKED(backend->flags, (bo_mem->flags & DRM_BO_FLAG_CACHED) ?
|
||||
DRM_BE_FLAG_BOUND_CACHED : 0,
|
||||
DRM_BE_FLAG_BOUND_CACHED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int drm_agp_unbind_ttm(drm_ttm_backend_t *backend) {
|
||||
static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend) {
|
||||
|
||||
drm_agp_ttm_backend_t *agp_be =
|
||||
container_of(backend, drm_agp_ttm_backend_t, backend);
|
||||
struct drm_agp_ttm_backend *agp_be =
|
||||
container_of(backend, struct drm_agp_ttm_backend, backend);
|
||||
|
||||
DRM_DEBUG("drm_agp_unbind_ttm\n");
|
||||
if (agp_be->mem->is_bound)
|
||||
|
@ -624,10 +568,10 @@ static int drm_agp_unbind_ttm(drm_ttm_backend_t *backend) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void drm_agp_clear_ttm(drm_ttm_backend_t *backend) {
|
||||
static void drm_agp_clear_ttm(struct drm_ttm_backend *backend) {
|
||||
|
||||
drm_agp_ttm_backend_t *agp_be =
|
||||
container_of(backend, drm_agp_ttm_backend_t, backend);
|
||||
struct drm_agp_ttm_backend *agp_be =
|
||||
container_of(backend, struct drm_agp_ttm_backend, backend);
|
||||
DRM_AGP_MEM *mem = agp_be->mem;
|
||||
|
||||
DRM_DEBUG("drm_agp_clear_ttm\n");
|
||||
|
@ -640,13 +584,13 @@ static void drm_agp_clear_ttm(drm_ttm_backend_t *backend) {
|
|||
agp_be->mem = NULL;
|
||||
}
|
||||
|
||||
static void drm_agp_destroy_ttm(drm_ttm_backend_t *backend) {
|
||||
static void drm_agp_destroy_ttm(struct drm_ttm_backend *backend) {
|
||||
|
||||
drm_agp_ttm_backend_t *agp_be;
|
||||
struct drm_agp_ttm_backend *agp_be;
|
||||
|
||||
if (backend) {
|
||||
DRM_DEBUG("drm_agp_destroy_ttm\n");
|
||||
agp_be = container_of(backend, drm_agp_ttm_backend_t, backend);
|
||||
agp_be = container_of(backend, struct drm_agp_ttm_backend, backend);
|
||||
if (agp_be) {
|
||||
if (agp_be->mem) {
|
||||
backend->func->clear(backend);
|
||||
|
@ -656,7 +600,7 @@ static void drm_agp_destroy_ttm(drm_ttm_backend_t *backend) {
|
|||
}
|
||||
}
|
||||
|
||||
static drm_ttm_backend_func_t agp_ttm_backend =
|
||||
static struct drm_ttm_backend_func agp_ttm_backend =
|
||||
{
|
||||
.needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust,
|
||||
.populate = drm_agp_populate,
|
||||
|
@ -666,10 +610,10 @@ static drm_ttm_backend_func_t agp_ttm_backend =
|
|||
.destroy = drm_agp_destroy_ttm,
|
||||
};
|
||||
|
||||
drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev)
|
||||
struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev)
|
||||
{
|
||||
|
||||
drm_agp_ttm_backend_t *agp_be;
|
||||
struct drm_agp_ttm_backend *agp_be;
|
||||
struct agp_kern_info *info;
|
||||
|
||||
if (!dev->agp) {
|
||||
|
@ -699,7 +643,8 @@ drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev)
|
|||
agp_be->bridge = dev->agp->bridge;
|
||||
agp_be->populated = FALSE;
|
||||
agp_be->backend.func = &agp_ttm_backend;
|
||||
agp_be->backend.mem_type = DRM_BO_MEM_TT;
|
||||
// agp_be->backend.mem_type = DRM_BO_MEM_TT;
|
||||
agp_be->backend.dev = dev;
|
||||
|
||||
return &agp_be->backend;
|
||||
}
|
||||
|
|
|
@ -45,15 +45,15 @@
|
|||
* the one with matching magic number, while holding the drm_device::struct_mutex
|
||||
* lock.
|
||||
*/
|
||||
static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
|
||||
static struct drm_file *drm_find_file(struct drm_device * dev, drm_magic_t magic)
|
||||
{
|
||||
drm_file_t *retval = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
drm_hash_item_t *hash;
|
||||
struct drm_file *retval = NULL;
|
||||
struct drm_magic_entry *pt;
|
||||
struct drm_hash_item *hash;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (!drm_ht_find_item(&dev->magiclist, (unsigned long) magic, &hash)) {
|
||||
pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item);
|
||||
if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
|
||||
pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item);
|
||||
retval = pt->priv;
|
||||
}
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -71,10 +71,10 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
|
|||
* associated the magic number hash key in drm_device::magiclist, while holding
|
||||
* the drm_device::struct_mutex lock.
|
||||
*/
|
||||
static int drm_add_magic(drm_device_t *dev, drm_file_t *priv,
|
||||
static int drm_add_magic(struct drm_device * dev, struct drm_file * priv,
|
||||
drm_magic_t magic)
|
||||
{
|
||||
drm_magic_entry_t *entry;
|
||||
struct drm_magic_entry *entry;
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
|
||||
|
@ -101,10 +101,10 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv,
|
|||
* Searches and unlinks the entry in drm_device::magiclist with the magic
|
||||
* number hash key, while holding the drm_device::struct_mutex lock.
|
||||
*/
|
||||
static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
|
||||
static int drm_remove_magic(struct drm_device * dev, drm_magic_t magic)
|
||||
{
|
||||
drm_magic_entry_t *pt;
|
||||
drm_hash_item_t *hash;
|
||||
struct drm_magic_entry *pt;
|
||||
struct drm_hash_item *hash;
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
|
||||
|
@ -113,7 +113,7 @@ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
|
|||
mutex_unlock(&dev->struct_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item);
|
||||
pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item);
|
||||
drm_ht_remove_item(&dev->magiclist, hash);
|
||||
list_del(&pt->head);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -127,42 +127,38 @@ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
|
|||
* Get a unique magic number (ioctl).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a resulting drm_auth structure.
|
||||
* \return zero on success, or a negative number on failure.
|
||||
*
|
||||
* If there is a magic number in drm_file::magic then use it, otherwise
|
||||
* searches an unique non-zero magic number and add it associating it with \p
|
||||
* filp.
|
||||
* file_priv.
|
||||
*/
|
||||
int drm_getmagic(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
static drm_magic_t sequence = 0;
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
struct drm_auth *auth = data;
|
||||
|
||||
/* Find unique magic */
|
||||
if (priv->magic) {
|
||||
auth.magic = priv->magic;
|
||||
if (file_priv->magic) {
|
||||
auth->magic = file_priv->magic;
|
||||
} else {
|
||||
do {
|
||||
spin_lock(&lock);
|
||||
if (!sequence)
|
||||
++sequence; /* reserve 0 */
|
||||
auth.magic = sequence++;
|
||||
auth->magic = sequence++;
|
||||
spin_unlock(&lock);
|
||||
} while (drm_find_file(dev, auth.magic));
|
||||
priv->magic = auth.magic;
|
||||
drm_add_magic(dev, priv, auth.magic);
|
||||
} while (drm_find_file(dev, auth->magic));
|
||||
file_priv->magic = auth->magic;
|
||||
drm_add_magic(dev, file_priv, auth->magic);
|
||||
}
|
||||
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
if (copy_to_user((drm_auth_t __user *) arg, &auth, sizeof(auth)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%u\n", auth->magic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -170,27 +166,23 @@ int drm_getmagic(struct inode *inode, struct file *filp,
|
|||
* Authenticate with a magic.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_auth structure.
|
||||
* \return zero if authentication successed, or a negative number otherwise.
|
||||
*
|
||||
* Checks if \p filp is associated with the magic number passed in \arg.
|
||||
* Checks if \p file_priv is associated with the magic number passed in \arg.
|
||||
*/
|
||||
int drm_authmagic(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_authmagic(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *file;
|
||||
struct drm_auth *auth = data;
|
||||
struct drm_file *file;
|
||||
|
||||
if (copy_from_user(&auth, (drm_auth_t __user *) arg, sizeof(auth)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
if ((file = drm_find_file(dev, auth.magic))) {
|
||||
DRM_DEBUG("%u\n", auth->magic);
|
||||
if ((file = drm_find_file(dev, auth->magic))) {
|
||||
file->authenticated = 1;
|
||||
drm_remove_magic(dev, auth.magic);
|
||||
drm_remove_magic(dev, auth->magic);
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
|
|
1378
linux-core/drm_bo.c
1378
linux-core/drm_bo.c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,178 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file implements a simple replacement for the buffer manager use
|
||||
* of the heavyweight hardware lock.
|
||||
* The lock is a read-write lock. Taking it in read mode is fast, and
|
||||
* intended for in-kernel use only.
|
||||
* Taking it in write mode is slow.
|
||||
*
|
||||
* The write mode is used only when there is a need to block all
|
||||
* user-space processes from allocating a
|
||||
* new memory area.
|
||||
* Typical use in write mode is X server VT switching, and it's allowed
|
||||
* to leave kernel space with the write lock held. If a user-space process
|
||||
* dies while having the write-lock, it will be released during the file
|
||||
* descriptor release.
|
||||
*
|
||||
* The read lock is typically placed at the start of an IOCTL- or
|
||||
* user-space callable function that may end up allocating a memory area.
|
||||
* This includes setstatus, super-ioctls and no_pfn; the latter may move
|
||||
* unmappable regions to mappable. It's a bug to leave kernel space with the
|
||||
* read lock held.
|
||||
*
|
||||
* Both read- and write lock taking is interruptible for low signal-delivery
|
||||
* latency. The locking functions will return -EAGAIN if interrupted by a
|
||||
* signal.
|
||||
*
|
||||
* Locking order: The lock should be taken BEFORE any kernel mutexes
|
||||
* or spinlocks.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
void drm_bo_init_lock(struct drm_bo_lock *lock)
|
||||
{
|
||||
DRM_INIT_WAITQUEUE(&lock->queue);
|
||||
atomic_set(&lock->write_lock_pending, 0);
|
||||
atomic_set(&lock->readers, 0);
|
||||
}
|
||||
|
||||
void drm_bo_read_unlock(struct drm_bo_lock *lock)
|
||||
{
|
||||
if (unlikely(atomic_add_negative(-1, &lock->readers)))
|
||||
BUG();
|
||||
if (atomic_read(&lock->readers) == 0)
|
||||
wake_up_interruptible(&lock->queue);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_bo_read_unlock);
|
||||
|
||||
int drm_bo_read_lock(struct drm_bo_lock *lock)
|
||||
{
|
||||
while (unlikely(atomic_read(&lock->write_lock_pending) != 0)) {
|
||||
int ret;
|
||||
ret = wait_event_interruptible
|
||||
(lock->queue, atomic_read(&lock->write_lock_pending) == 0);
|
||||
if (ret)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
while (unlikely(!atomic_add_unless(&lock->readers, 1, -1))) {
|
||||
int ret;
|
||||
ret = wait_event_interruptible
|
||||
(lock->queue, atomic_add_unless(&lock->readers, 1, -1));
|
||||
if (ret)
|
||||
return -EAGAIN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_bo_read_lock);
|
||||
|
||||
static int __drm_bo_write_unlock(struct drm_bo_lock *lock)
|
||||
{
|
||||
if (unlikely(atomic_cmpxchg(&lock->readers, -1, 0) != -1))
|
||||
return -EINVAL;
|
||||
if (unlikely(atomic_cmpxchg(&lock->write_lock_pending, 1, 0) != 1))
|
||||
return -EINVAL;
|
||||
wake_up_interruptible(&lock->queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_bo_write_lock_remove(struct drm_file *file_priv,
|
||||
struct drm_user_object *item)
|
||||
{
|
||||
struct drm_bo_lock *lock = container_of(item, struct drm_bo_lock, base);
|
||||
int ret;
|
||||
|
||||
ret = __drm_bo_write_unlock(lock);
|
||||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct drm_device *dev;
|
||||
|
||||
if (unlikely(atomic_cmpxchg(&lock->write_lock_pending, 0, 1) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (unlikely(atomic_cmpxchg(&lock->readers, 0, -1) != 0)) {
|
||||
ret = wait_event_interruptible
|
||||
(lock->queue, atomic_cmpxchg(&lock->readers, 0, -1) == 0);
|
||||
|
||||
if (ret) {
|
||||
atomic_set(&lock->write_lock_pending, 0);
|
||||
wake_up_interruptible(&lock->queue);
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a dummy user-object, the destructor of which will
|
||||
* make sure the lock is released if the client dies
|
||||
* while holding it.
|
||||
*/
|
||||
|
||||
dev = file_priv->head->dev;
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
ret = drm_add_user_object(file_priv, &lock->base, 0);
|
||||
lock->base.remove = &drm_bo_write_lock_remove;
|
||||
lock->base.type = drm_lock_type;
|
||||
if (ret) {
|
||||
(void)__drm_bo_write_unlock(lock);
|
||||
}
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_device *dev = file_priv->head->dev;
|
||||
struct drm_ref_object *ro;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
if (lock->base.owner != file_priv) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
ro = drm_lookup_ref_object(file_priv, &lock->base, _DRM_REF_USE);
|
||||
BUG_ON(!ro);
|
||||
drm_remove_ref_object(file_priv, ro);
|
||||
lock->base.owner = NULL;
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return 0;
|
||||
}
|
|
@ -35,9 +35,9 @@
|
|||
* have not been requested to free also pinned regions.
|
||||
*/
|
||||
|
||||
static void drm_bo_free_old_node(drm_buffer_object_t * bo)
|
||||
static void drm_bo_free_old_node(struct drm_buffer_object * bo)
|
||||
{
|
||||
drm_bo_mem_reg_t *old_mem = &bo->mem;
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
|
||||
if (old_mem->mm_node && (old_mem->mm_node != bo->pinned_node)) {
|
||||
mutex_lock(&bo->dev->struct_mutex);
|
||||
|
@ -48,13 +48,13 @@ static void drm_bo_free_old_node(drm_buffer_object_t * bo)
|
|||
old_mem->mm_node = NULL;
|
||||
}
|
||||
|
||||
int drm_bo_move_ttm(drm_buffer_object_t * bo,
|
||||
int evict, int no_wait, drm_bo_mem_reg_t * new_mem)
|
||||
int drm_bo_move_ttm(struct drm_buffer_object * bo,
|
||||
int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
|
||||
{
|
||||
drm_ttm_t *ttm = bo->ttm;
|
||||
drm_bo_mem_reg_t *old_mem = &bo->mem;
|
||||
uint32_t save_flags = old_mem->flags;
|
||||
uint32_t save_mask = old_mem->mask;
|
||||
struct drm_ttm *ttm = bo->ttm;
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
uint64_t save_flags = old_mem->flags;
|
||||
uint64_t save_mask = old_mem->mask;
|
||||
int ret;
|
||||
|
||||
if (old_mem->mem_type == DRM_BO_MEM_TT) {
|
||||
|
@ -71,9 +71,7 @@ int drm_bo_move_ttm(drm_buffer_object_t * bo,
|
|||
save_flags = old_mem->flags;
|
||||
}
|
||||
if (new_mem->mem_type != DRM_BO_MEM_LOCAL) {
|
||||
ret = drm_bind_ttm(ttm,
|
||||
new_mem->flags & DRM_BO_FLAG_CACHED,
|
||||
new_mem->mm_node->start);
|
||||
ret = drm_bind_ttm(ttm, new_mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -102,11 +100,11 @@ EXPORT_SYMBOL(drm_bo_move_ttm);
|
|||
* Call bo->mutex locked.
|
||||
*/
|
||||
|
||||
int drm_mem_reg_ioremap(drm_device_t * dev, drm_bo_mem_reg_t * mem,
|
||||
int drm_mem_reg_ioremap(struct drm_device * dev, struct drm_bo_mem_reg * mem,
|
||||
void **virtual)
|
||||
{
|
||||
drm_buffer_manager_t *bm = &dev->bm;
|
||||
drm_mem_type_manager_t *man = &bm->man[mem->mem_type];
|
||||
struct drm_buffer_manager *bm = &dev->bm;
|
||||
struct drm_mem_type_manager *man = &bm->man[mem->mem_type];
|
||||
unsigned long bus_offset;
|
||||
unsigned long bus_size;
|
||||
unsigned long bus_base;
|
||||
|
@ -128,6 +126,7 @@ int drm_mem_reg_ioremap(drm_device_t * dev, drm_bo_mem_reg_t * mem,
|
|||
*virtual = addr;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mem_reg_ioremap);
|
||||
|
||||
/**
|
||||
* \c Unmap mapping obtained using drm_bo_ioremap
|
||||
|
@ -137,11 +136,11 @@ int drm_mem_reg_ioremap(drm_device_t * dev, drm_bo_mem_reg_t * mem,
|
|||
* Call bo->mutex locked.
|
||||
*/
|
||||
|
||||
void drm_mem_reg_iounmap(drm_device_t * dev, drm_bo_mem_reg_t * mem,
|
||||
void drm_mem_reg_iounmap(struct drm_device * dev, struct drm_bo_mem_reg * mem,
|
||||
void *virtual)
|
||||
{
|
||||
drm_buffer_manager_t *bm;
|
||||
drm_mem_type_manager_t *man;
|
||||
struct drm_buffer_manager *bm;
|
||||
struct drm_mem_type_manager *man;
|
||||
|
||||
bm = &dev->bm;
|
||||
man = &bm->man[mem->mem_type];
|
||||
|
@ -164,7 +163,7 @@ static int drm_copy_io_page(void *dst, void *src, unsigned long page)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_copy_io_ttm_page(drm_ttm_t * ttm, void *src, unsigned long page)
|
||||
static int drm_copy_io_ttm_page(struct drm_ttm * ttm, void *src, unsigned long page)
|
||||
{
|
||||
struct page *d = drm_ttm_get_page(ttm, page);
|
||||
void *dst;
|
||||
|
@ -182,7 +181,7 @@ static int drm_copy_io_ttm_page(drm_ttm_t * ttm, void *src, unsigned long page)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_copy_ttm_io_page(drm_ttm_t * ttm, void *dst, unsigned long page)
|
||||
static int drm_copy_ttm_io_page(struct drm_ttm * ttm, void *dst, unsigned long page)
|
||||
{
|
||||
struct page *s = drm_ttm_get_page(ttm, page);
|
||||
void *src;
|
||||
|
@ -200,19 +199,19 @@ static int drm_copy_ttm_io_page(drm_ttm_t * ttm, void *dst, unsigned long page)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_bo_move_memcpy(drm_buffer_object_t * bo,
|
||||
int evict, int no_wait, drm_bo_mem_reg_t * new_mem)
|
||||
int drm_bo_move_memcpy(struct drm_buffer_object * bo,
|
||||
int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
|
||||
{
|
||||
drm_device_t *dev = bo->dev;
|
||||
drm_mem_type_manager_t *man = &dev->bm.man[new_mem->mem_type];
|
||||
drm_ttm_t *ttm = bo->ttm;
|
||||
drm_bo_mem_reg_t *old_mem = &bo->mem;
|
||||
drm_bo_mem_reg_t old_copy = *old_mem;
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type];
|
||||
struct drm_ttm *ttm = bo->ttm;
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
struct drm_bo_mem_reg old_copy = *old_mem;
|
||||
void *old_iomap;
|
||||
void *new_iomap;
|
||||
int ret;
|
||||
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;
|
||||
unsigned long i;
|
||||
unsigned long page;
|
||||
unsigned long add = 0;
|
||||
|
@ -281,12 +280,12 @@ EXPORT_SYMBOL(drm_bo_move_memcpy);
|
|||
* object. Call bo->mutex locked.
|
||||
*/
|
||||
|
||||
int drm_buffer_object_transfer(drm_buffer_object_t * bo,
|
||||
drm_buffer_object_t ** new_obj)
|
||||
int drm_buffer_object_transfer(struct drm_buffer_object * bo,
|
||||
struct drm_buffer_object ** new_obj)
|
||||
{
|
||||
drm_buffer_object_t *fbo;
|
||||
drm_device_t *dev = bo->dev;
|
||||
drm_buffer_manager_t *bm = &dev->bm;
|
||||
struct drm_buffer_object *fbo;
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_buffer_manager *bm = &dev->bm;
|
||||
|
||||
fbo = drm_ctl_calloc(1, sizeof(*fbo), DRM_MEM_BUFOBJ);
|
||||
if (!fbo)
|
||||
|
@ -306,7 +305,7 @@ int drm_buffer_object_transfer(drm_buffer_object_t * bo,
|
|||
INIT_LIST_HEAD(&fbo->p_mm_list);
|
||||
#endif
|
||||
|
||||
atomic_inc(&bo->fence->usage);
|
||||
drm_fence_reference_unlocked(&fbo->fence, bo->fence);
|
||||
fbo->pinned_node = NULL;
|
||||
fbo->mem.mm_node->private = (void *)fbo;
|
||||
atomic_set(&fbo->usage, 1);
|
||||
|
@ -323,26 +322,27 @@ int drm_buffer_object_transfer(drm_buffer_object_t * bo,
|
|||
* We cannot restart until it has finished.
|
||||
*/
|
||||
|
||||
int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo,
|
||||
int drm_bo_move_accel_cleanup(struct drm_buffer_object * bo,
|
||||
int evict,
|
||||
int no_wait,
|
||||
uint32_t fence_class,
|
||||
uint32_t fence_type,
|
||||
uint32_t fence_flags, drm_bo_mem_reg_t * new_mem)
|
||||
uint32_t fence_flags, struct drm_bo_mem_reg * new_mem)
|
||||
{
|
||||
drm_device_t *dev = bo->dev;
|
||||
drm_mem_type_manager_t *man = &dev->bm.man[new_mem->mem_type];
|
||||
drm_bo_mem_reg_t *old_mem = &bo->mem;
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type];
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
int ret;
|
||||
uint32_t save_flags = old_mem->flags;
|
||||
uint32_t save_mask = old_mem->mask;
|
||||
drm_buffer_object_t *old_obj;
|
||||
uint64_t save_flags = old_mem->flags;
|
||||
uint64_t save_mask = old_mem->mask;
|
||||
struct drm_buffer_object *old_obj;
|
||||
|
||||
if (bo->fence)
|
||||
drm_fence_usage_deref_unlocked(dev, bo->fence);
|
||||
drm_fence_usage_deref_unlocked(&bo->fence);
|
||||
ret = drm_fence_object_create(dev, fence_class, fence_type,
|
||||
fence_flags | DRM_FENCE_FLAG_EMIT,
|
||||
&bo->fence);
|
||||
bo->fence_type = fence_type;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -396,7 +396,7 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo,
|
|||
DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
|
||||
drm_bo_add_to_lru(old_obj);
|
||||
|
||||
drm_bo_usage_deref_locked(old_obj);
|
||||
drm_bo_usage_deref_locked(&old_obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
}
|
||||
|
@ -409,3 +409,194 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo,
|
|||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_bo_move_accel_cleanup);
|
||||
|
||||
int drm_bo_same_page(unsigned long offset,
|
||||
unsigned long offset2)
|
||||
{
|
||||
return (offset & PAGE_MASK) == (offset2 & PAGE_MASK);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_same_page);
|
||||
|
||||
unsigned long drm_bo_offset_end(unsigned long offset,
|
||||
unsigned long end)
|
||||
{
|
||||
|
||||
offset = (offset + PAGE_SIZE) & PAGE_MASK;
|
||||
return (end < offset) ? end : offset;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_offset_end);
|
||||
|
||||
|
||||
static pgprot_t drm_kernel_io_prot(uint32_t map_type)
|
||||
{
|
||||
pgprot_t tmp = PAGE_KERNEL;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#ifdef USE_PAT_WC
|
||||
#warning using pat
|
||||
if (drm_use_pat() && map_type == _DRM_TTM) {
|
||||
pgprot_val(tmp) |= _PAGE_PAT;
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) {
|
||||
pgprot_val(tmp) |= _PAGE_PCD;
|
||||
pgprot_val(tmp) &= ~_PAGE_PWT;
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
pgprot_val(tmp) |= _PAGE_NO_CACHE;
|
||||
if (map_type == _DRM_REGISTERS)
|
||||
pgprot_val(tmp) |= _PAGE_GUARDED;
|
||||
#endif
|
||||
#if defined(__ia64__)
|
||||
if (map_type == _DRM_TTM)
|
||||
tmp = pgprot_writecombine(tmp);
|
||||
else
|
||||
tmp = pgprot_noncached(tmp);
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int drm_bo_ioremap(struct drm_buffer_object *bo, unsigned long bus_base,
|
||||
unsigned long bus_offset, unsigned long bus_size,
|
||||
struct drm_bo_kmap_obj *map)
|
||||
{
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_bo_mem_reg *mem = &bo->mem;
|
||||
struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type];
|
||||
|
||||
if (!(man->flags & _DRM_FLAG_NEEDS_IOREMAP)) {
|
||||
map->bo_kmap_type = bo_map_premapped;
|
||||
map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset);
|
||||
} else {
|
||||
map->bo_kmap_type = bo_map_iomap;
|
||||
map->virtual = ioremap_nocache(bus_base + bus_offset, bus_size);
|
||||
}
|
||||
return (!map->virtual) ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
static int drm_bo_kmap_ttm(struct drm_buffer_object *bo, unsigned long start_page,
|
||||
unsigned long num_pages, struct drm_bo_kmap_obj *map)
|
||||
{
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_bo_mem_reg *mem = &bo->mem;
|
||||
struct drm_mem_type_manager *man = &dev->bm.man[mem->mem_type];
|
||||
pgprot_t prot;
|
||||
struct drm_ttm *ttm = bo->ttm;
|
||||
struct page *d;
|
||||
int i;
|
||||
|
||||
BUG_ON(!ttm);
|
||||
|
||||
if (num_pages == 1 && (mem->flags & DRM_BO_FLAG_CACHED)) {
|
||||
|
||||
/*
|
||||
* We're mapping a single page, and the desired
|
||||
* page protection is consistent with the bo.
|
||||
*/
|
||||
|
||||
map->bo_kmap_type = bo_map_kmap;
|
||||
map->page = drm_ttm_get_page(ttm, start_page);
|
||||
map->virtual = kmap(map->page);
|
||||
} else {
|
||||
/*
|
||||
* Populate the part we're mapping;
|
||||
*/
|
||||
|
||||
for (i = start_page; i< start_page + num_pages; ++i) {
|
||||
d = drm_ttm_get_page(ttm, i);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to use vmap to get the desired page protection
|
||||
* or to make the buffer object look contigous.
|
||||
*/
|
||||
|
||||
prot = (mem->flags & DRM_BO_FLAG_CACHED) ?
|
||||
PAGE_KERNEL :
|
||||
drm_kernel_io_prot(man->drm_bus_maptype);
|
||||
map->bo_kmap_type = bo_map_vmap;
|
||||
map->virtual = vmap(ttm->pages + start_page,
|
||||
num_pages, 0, prot);
|
||||
}
|
||||
return (!map->virtual) ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is to be used for kernel mapping of buffer objects.
|
||||
* It chooses the appropriate mapping method depending on the memory type
|
||||
* and caching policy the buffer currently has.
|
||||
* Mapping multiple pages or buffers that live in io memory is a bit slow and
|
||||
* consumes vmalloc space. Be restrictive with such mappings.
|
||||
* Mapping single pages usually returns the logical kernel address, (which is fast)
|
||||
* BUG may use slower temporary mappings for high memory pages or
|
||||
* uncached / write-combined pages.
|
||||
*
|
||||
* The function fills in a drm_bo_kmap_obj which can be used to return the
|
||||
* kernel virtual address of the buffer.
|
||||
*
|
||||
* Code servicing a non-priviliged user request is only allowed to map one
|
||||
* page at a time. We might need to implement a better scheme to stop such
|
||||
* processes from consuming all vmalloc space.
|
||||
*/
|
||||
|
||||
int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
|
||||
unsigned long num_pages, struct drm_bo_kmap_obj *map)
|
||||
{
|
||||
int ret;
|
||||
unsigned long bus_base;
|
||||
unsigned long bus_offset;
|
||||
unsigned long bus_size;
|
||||
|
||||
map->virtual = NULL;
|
||||
|
||||
if (num_pages > bo->num_pages)
|
||||
return -EINVAL;
|
||||
if (start_page > bo->num_pages)
|
||||
return -EINVAL;
|
||||
#if 0
|
||||
if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC))
|
||||
return -EPERM;
|
||||
#endif
|
||||
ret = drm_bo_pci_offset(bo->dev, &bo->mem, &bus_base,
|
||||
&bus_offset, &bus_size);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (bus_size == 0) {
|
||||
return drm_bo_kmap_ttm(bo, start_page, num_pages, map);
|
||||
} else {
|
||||
bus_offset += start_page << PAGE_SHIFT;
|
||||
bus_size = num_pages << PAGE_SHIFT;
|
||||
return drm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_kmap);
|
||||
|
||||
void drm_bo_kunmap(struct drm_bo_kmap_obj *map)
|
||||
{
|
||||
if (!map->virtual)
|
||||
return;
|
||||
|
||||
switch(map->bo_kmap_type) {
|
||||
case bo_map_iomap:
|
||||
iounmap(map->virtual);
|
||||
break;
|
||||
case bo_map_vmap:
|
||||
vunmap(map->virtual);
|
||||
break;
|
||||
case bo_map_kmap:
|
||||
kunmap(map->page);
|
||||
break;
|
||||
case bo_map_premapped:
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
map->virtual = NULL;
|
||||
map->page = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_kunmap);
|
||||
|
|
|
@ -36,22 +36,21 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include "drmP.h"
|
||||
|
||||
unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
|
||||
unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource)
|
||||
{
|
||||
return pci_resource_start(dev->pdev, resource);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_resource_start);
|
||||
|
||||
unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
|
||||
unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource)
|
||||
{
|
||||
return pci_resource_len(dev->pdev, resource);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_resource_len);
|
||||
|
||||
static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
|
||||
drm_local_map_t *map)
|
||||
struct drm_map_list *drm_find_matching_map(struct drm_device *dev, drm_local_map_t *map)
|
||||
{
|
||||
drm_map_list_t *entry;
|
||||
struct drm_map_list *entry;
|
||||
list_for_each_entry(entry, &dev->maplist, head) {
|
||||
if (entry->map && map->type == entry->map->type &&
|
||||
((entry->map->offset == map->offset) ||
|
||||
|
@ -62,8 +61,9 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_find_matching_map);
|
||||
|
||||
static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
|
||||
static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
|
||||
unsigned long user_token, int hashed_handle)
|
||||
{
|
||||
int use_hashed_handle;
|
||||
|
@ -92,7 +92,7 @@ static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
|
|||
* Ioctl to specify a range of memory that is available for mapping by a non-root process.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_map structure.
|
||||
* \return zero on success or a negative value on error.
|
||||
|
@ -101,12 +101,13 @@ static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
|
|||
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
|
||||
* applicable and if supported by the kernel.
|
||||
*/
|
||||
static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
||||
unsigned int size, drm_map_type_t type,
|
||||
drm_map_flags_t flags, drm_map_list_t ** maplist)
|
||||
static int drm_addmap_core(struct drm_device *dev, unsigned int offset,
|
||||
unsigned int size, enum drm_map_type type,
|
||||
enum drm_map_flags flags,
|
||||
struct drm_map_list **maplist)
|
||||
{
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *list;
|
||||
struct drm_map *map;
|
||||
struct drm_map_list *list;
|
||||
drm_dma_handle_t *dmah;
|
||||
unsigned long user_token;
|
||||
int ret;
|
||||
|
@ -212,7 +213,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|||
}
|
||||
break;
|
||||
case _DRM_AGP: {
|
||||
drm_agp_mem_t *entry;
|
||||
struct drm_agp_mem *entry;
|
||||
int valid = 0;
|
||||
|
||||
if (!drm_core_has_AGP(dev)) {
|
||||
|
@ -222,11 +223,17 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|||
#ifdef __alpha__
|
||||
map->offset += dev->hose->mem_space->start;
|
||||
#endif
|
||||
/* Note: dev->agp->base may actually be 0 when the DRM
|
||||
* is not in control of AGP space. But if user space is
|
||||
* it should already have added the AGP base itself.
|
||||
/* In some cases (i810 driver), user space may have already
|
||||
* added the AGP base itself, because dev->agp->base previously
|
||||
* only got set during AGP enable. So, only add the base
|
||||
* address if the map's offset isn't already within the
|
||||
* aperture.
|
||||
*/
|
||||
map->offset += dev->agp->base;
|
||||
if (map->offset < dev->agp->base ||
|
||||
map->offset > dev->agp->base +
|
||||
dev->agp->agp_info.aper_size * 1024 * 1024 - 1) {
|
||||
map->offset += dev->agp->base;
|
||||
}
|
||||
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
||||
|
||||
/* This assumes the DRM is in total control of AGP space.
|
||||
|
@ -310,11 +317,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_addmap(drm_device_t * dev, unsigned int offset,
|
||||
unsigned int size, drm_map_type_t type,
|
||||
drm_map_flags_t flags, drm_local_map_t ** map_ptr)
|
||||
int drm_addmap(struct drm_device *dev, unsigned int offset,
|
||||
unsigned int size, enum drm_map_type type,
|
||||
enum drm_map_flags flags, drm_local_map_t ** map_ptr)
|
||||
{
|
||||
drm_map_list_t *list;
|
||||
struct drm_map_list *list;
|
||||
int rc;
|
||||
|
||||
rc = drm_addmap_core(dev, offset, size, type, flags, &list);
|
||||
|
@ -325,38 +332,24 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
|
|||
|
||||
EXPORT_SYMBOL(drm_addmap);
|
||||
|
||||
int drm_addmap_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_addmap_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t map;
|
||||
drm_map_list_t *maplist;
|
||||
drm_map_t __user *argp = (void __user *)arg;
|
||||
struct drm_map *map = data;
|
||||
struct drm_map_list *maplist;
|
||||
int err;
|
||||
|
||||
if (!(filp->f_mode & 3))
|
||||
return -EACCES; /* Require read/write */
|
||||
|
||||
if (copy_from_user(&map, argp, sizeof(map))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
|
||||
if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP))
|
||||
return -EPERM;
|
||||
|
||||
err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
|
||||
&maplist);
|
||||
err = drm_addmap_core(dev, map->offset, map->size, map->type,
|
||||
map->flags, &maplist);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (copy_to_user(argp, maplist->map, sizeof(drm_map_t)))
|
||||
return -EFAULT;
|
||||
|
||||
/* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
|
||||
if (put_user((void *)(unsigned long)maplist->user_token, &argp->handle))
|
||||
return -EFAULT;
|
||||
map->handle = (void *)(unsigned long)maplist->user_token;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -365,9 +358,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
|
|||
* isn't in use.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_map_t structure.
|
||||
* \param arg pointer to a struct drm_map structure.
|
||||
* \return zero on success or a negative value on error.
|
||||
*
|
||||
* Searches the map on drm_device::maplist, removes it from the list, see if
|
||||
|
@ -376,9 +369,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* \sa drm_addmap
|
||||
*/
|
||||
int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
||||
int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
|
||||
{
|
||||
drm_map_list_t *r_list = NULL, *list_t;
|
||||
struct drm_map_list *r_list = NULL, *list_t;
|
||||
drm_dma_handle_t dmah;
|
||||
int found = 0;
|
||||
|
||||
|
@ -433,7 +426,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_rmmap_locked);
|
||||
|
||||
int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
|
||||
int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -454,24 +447,18 @@ EXPORT_SYMBOL(drm_rmmap);
|
|||
* gets used by drivers that the server doesn't need to care about. This seems
|
||||
* unlikely.
|
||||
*/
|
||||
int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_rmmap_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t request;
|
||||
struct drm_map *request = data;
|
||||
drm_local_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
struct drm_map_list *r_list;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
list_for_each_entry(r_list, &dev->maplist, head) {
|
||||
if (r_list->map &&
|
||||
r_list->user_token == (unsigned long)request.handle &&
|
||||
r_list->user_token == (unsigned long)request->handle &&
|
||||
r_list->map->flags & _DRM_REMOVABLE) {
|
||||
map = r_list->map;
|
||||
break;
|
||||
|
@ -486,11 +473,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!map) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Register and framebuffer maps are permanent */
|
||||
if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -512,7 +494,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Frees any pages and buffers associated with the given entry.
|
||||
*/
|
||||
static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
|
||||
static void drm_cleanup_buf_error(struct drm_device *dev, struct drm_buf_entry * entry)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -549,20 +531,20 @@ static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
|
|||
/**
|
||||
* Add AGP buffers for DMA transfers
|
||||
*
|
||||
* \param dev drm_device_t to which the buffers are to be added.
|
||||
* \param request pointer to a drm_buf_desc_t describing the request.
|
||||
* \param dev struct drm_device to which the buffers are to be added.
|
||||
* \param request pointer to a struct drm_buf_desc describing the request.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* After some sanity checks creates a drm_buf structure for each buffer and
|
||||
* reallocates the buffer list of the same size order to accommodate the new
|
||||
* buffers.
|
||||
*/
|
||||
int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
|
||||
int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_entry_t *entry;
|
||||
drm_agp_mem_t *agp_entry;
|
||||
drm_buf_t *buf;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf_entry *entry;
|
||||
struct drm_agp_mem *agp_entry;
|
||||
struct drm_buf *buf;
|
||||
unsigned long offset;
|
||||
unsigned long agp_offset;
|
||||
int count;
|
||||
|
@ -573,7 +555,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
int total;
|
||||
int byte_count;
|
||||
int i, valid;
|
||||
drm_buf_t **temp_buflist;
|
||||
struct drm_buf **temp_buflist;
|
||||
|
||||
if (!dma)
|
||||
return -EINVAL;
|
||||
|
@ -666,7 +648,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head(&buf->dma_wait);
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver->dev_priv_size;
|
||||
buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
|
||||
|
@ -727,24 +709,24 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
EXPORT_SYMBOL(drm_addbufs_agp);
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
||||
int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
|
||||
int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
int count;
|
||||
int order;
|
||||
int size;
|
||||
int total;
|
||||
int page_order;
|
||||
drm_buf_entry_t *entry;
|
||||
struct drm_buf_entry *entry;
|
||||
drm_dma_handle_t *dmah;
|
||||
drm_buf_t *buf;
|
||||
struct drm_buf *buf;
|
||||
int alignment;
|
||||
unsigned long offset;
|
||||
int i;
|
||||
int byte_count;
|
||||
int page_count;
|
||||
unsigned long *temp_pagelist;
|
||||
drm_buf_t **temp_buflist;
|
||||
struct drm_buf **temp_buflist;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
|
||||
return -EINVAL;
|
||||
|
@ -877,7 +859,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head(&buf->dma_wait);
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver->dev_priv_size;
|
||||
buf->dev_private = drm_alloc(buf->dev_priv_size,
|
||||
|
@ -953,11 +935,11 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_addbufs_pci);
|
||||
|
||||
static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
|
||||
static int drm_addbufs_sg(struct drm_device *dev, struct drm_buf_desc * request)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_entry_t *entry;
|
||||
drm_buf_t *buf;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf_entry *entry;
|
||||
struct drm_buf *buf;
|
||||
unsigned long offset;
|
||||
unsigned long agp_offset;
|
||||
int count;
|
||||
|
@ -968,7 +950,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
int total;
|
||||
int byte_count;
|
||||
int i;
|
||||
drm_buf_t **temp_buflist;
|
||||
struct drm_buf **temp_buflist;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_SG))
|
||||
return -EINVAL;
|
||||
|
@ -1055,7 +1037,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head(&buf->dma_wait);
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver->dev_priv_size;
|
||||
buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
|
||||
|
@ -1115,11 +1097,11 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
|
||||
int drm_addbufs_fb(struct drm_device *dev, struct drm_buf_desc *request)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_entry_t *entry;
|
||||
drm_buf_t *buf;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf_entry *entry;
|
||||
struct drm_buf *buf;
|
||||
unsigned long offset;
|
||||
unsigned long agp_offset;
|
||||
int count;
|
||||
|
@ -1130,7 +1112,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
int total;
|
||||
int byte_count;
|
||||
int i;
|
||||
drm_buf_t **temp_buflist;
|
||||
struct drm_buf **temp_buflist;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_FB_DMA))
|
||||
return -EINVAL;
|
||||
|
@ -1216,7 +1198,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
|
|||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head(&buf->dma_wait);
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
|
||||
buf->dev_priv_size = dev->driver->dev_priv_size;
|
||||
buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
|
||||
|
@ -1281,9 +1263,9 @@ EXPORT_SYMBOL(drm_addbufs_fb);
|
|||
* Add buffers for DMA transfers (ioctl).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_buf_desc_t request.
|
||||
* \param arg pointer to a struct drm_buf_desc request.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* According with the memory type specified in drm_buf_desc::flags and the
|
||||
|
@ -1291,39 +1273,27 @@ EXPORT_SYMBOL(drm_addbufs_fb);
|
|||
* addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
|
||||
* PCI memory respectively.
|
||||
*/
|
||||
int drm_addbufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_addbufs(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_buf_desc_t request;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
struct drm_buf_desc *request = data;
|
||||
int ret;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&request, (drm_buf_desc_t __user *) arg,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
if (request.flags & _DRM_AGP_BUFFER)
|
||||
ret = drm_addbufs_agp(dev, &request);
|
||||
if (request->flags & _DRM_AGP_BUFFER)
|
||||
ret = drm_addbufs_agp(dev, request);
|
||||
else
|
||||
#endif
|
||||
if (request.flags & _DRM_SG_BUFFER)
|
||||
ret = drm_addbufs_sg(dev, &request);
|
||||
else if (request.flags & _DRM_FB_BUFFER)
|
||||
ret = drm_addbufs_fb(dev, &request);
|
||||
if (request->flags & _DRM_SG_BUFFER)
|
||||
ret = drm_addbufs_sg(dev, request);
|
||||
else if (request->flags & _DRM_FB_BUFFER)
|
||||
ret = drm_addbufs_fb(dev, request);
|
||||
else
|
||||
ret = drm_addbufs_pci(dev, &request);
|
||||
ret = drm_addbufs_pci(dev, request);
|
||||
|
||||
if (ret == 0) {
|
||||
if (copy_to_user((void __user *) arg, &request,
|
||||
sizeof(request))) {
|
||||
ret = -EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1335,7 +1305,7 @@ int drm_addbufs(struct inode *inode, struct file *filp,
|
|||
* large buffers can be used for image transfer).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_buf_info structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -1344,14 +1314,11 @@ int drm_addbufs(struct inode *inode, struct file *filp,
|
|||
* lock, preventing of allocating more buffers after this call. Information
|
||||
* about each requested buffer is then copied into user space.
|
||||
*/
|
||||
int drm_infobufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_infobufs(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_info_t request;
|
||||
drm_buf_info_t __user *argp = (void __user *)arg;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf_info *request = data;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
|
@ -1369,9 +1336,6 @@ int drm_infobufs(struct inode *inode, struct file *filp,
|
|||
++dev->buf_use; /* Can't allocate more after this call */
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
if (copy_from_user(&request, argp, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
|
||||
if (dma->bufs[i].buf_count)
|
||||
++count;
|
||||
|
@ -1379,13 +1343,13 @@ int drm_infobufs(struct inode *inode, struct file *filp,
|
|||
|
||||
DRM_DEBUG("count = %d\n", count);
|
||||
|
||||
if (request.count >= count) {
|
||||
if (request->count >= count) {
|
||||
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
|
||||
if (dma->bufs[i].buf_count) {
|
||||
drm_buf_desc_t __user *to =
|
||||
&request.list[count];
|
||||
drm_buf_entry_t *from = &dma->bufs[i];
|
||||
drm_freelist_t *list = &dma->bufs[i].freelist;
|
||||
struct drm_buf_desc __user *to =
|
||||
&request->list[count];
|
||||
struct drm_buf_entry *from = &dma->bufs[i];
|
||||
struct drm_freelist *list = &dma->bufs[i].freelist;
|
||||
if (copy_to_user(&to->count,
|
||||
&from->buf_count,
|
||||
sizeof(from->buf_count)) ||
|
||||
|
@ -1410,10 +1374,7 @@ int drm_infobufs(struct inode *inode, struct file *filp,
|
|||
}
|
||||
}
|
||||
}
|
||||
request.count = count;
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
request->count = count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1422,7 +1383,7 @@ int drm_infobufs(struct inode *inode, struct file *filp,
|
|||
* Specifies a low and high water mark for buffer allocation
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg a pointer to a drm_buf_desc structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -1432,15 +1393,13 @@ int drm_infobufs(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* \note This ioctl is deprecated and mostly never used.
|
||||
*/
|
||||
int drm_markbufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_markbufs(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf_desc *request = data;
|
||||
int order;
|
||||
drm_buf_entry_t *entry;
|
||||
struct drm_buf_entry *entry;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
|
||||
return -EINVAL;
|
||||
|
@ -1448,24 +1407,20 @@ int drm_markbufs(struct inode *inode, struct file *filp,
|
|||
if (!dma)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&request,
|
||||
(drm_buf_desc_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG("%d, %d, %d\n",
|
||||
request.size, request.low_mark, request.high_mark);
|
||||
order = drm_order(request.size);
|
||||
request->size, request->low_mark, request->high_mark);
|
||||
order = drm_order(request->size);
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
|
||||
return -EINVAL;
|
||||
entry = &dma->bufs[order];
|
||||
|
||||
if (request.low_mark < 0 || request.low_mark > entry->buf_count)
|
||||
if (request->low_mark < 0 || request->low_mark > entry->buf_count)
|
||||
return -EINVAL;
|
||||
if (request.high_mark < 0 || request.high_mark > entry->buf_count)
|
||||
if (request->high_mark < 0 || request->high_mark > entry->buf_count)
|
||||
return -EINVAL;
|
||||
|
||||
entry->freelist.low_mark = request.low_mark;
|
||||
entry->freelist.high_mark = request.high_mark;
|
||||
entry->freelist.low_mark = request->low_mark;
|
||||
entry->freelist.high_mark = request->high_mark;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1474,7 +1429,7 @@ int drm_markbufs(struct inode *inode, struct file *filp,
|
|||
* Unreserve the buffers in list, previously reserved using drmDMA.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_buf_free structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -1482,16 +1437,14 @@ int drm_markbufs(struct inode *inode, struct file *filp,
|
|||
* Calls free_buffer() for each used buffer.
|
||||
* This function is primarily used for debugging.
|
||||
*/
|
||||
int drm_freebufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_freebufs(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_free_t request;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf_free *request = data;
|
||||
int i;
|
||||
int idx;
|
||||
drm_buf_t *buf;
|
||||
struct drm_buf *buf;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
|
||||
return -EINVAL;
|
||||
|
@ -1499,13 +1452,9 @@ int drm_freebufs(struct inode *inode, struct file *filp,
|
|||
if (!dma)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&request,
|
||||
(drm_buf_free_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG("%d\n", request.count);
|
||||
for (i = 0; i < request.count; i++) {
|
||||
if (copy_from_user(&idx, &request.list[i], sizeof(idx)))
|
||||
DRM_DEBUG("%d\n", request->count);
|
||||
for (i = 0; i < request->count; i++) {
|
||||
if (copy_from_user(&idx, &request->list[i], sizeof(idx)))
|
||||
return -EFAULT;
|
||||
if (idx < 0 || idx >= dma->buf_count) {
|
||||
DRM_ERROR("Index %d (of %d max)\n",
|
||||
|
@ -1513,7 +1462,7 @@ int drm_freebufs(struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
buf = dma->buflist[idx];
|
||||
if (buf->filp != filp) {
|
||||
if (buf->file_priv != file_priv) {
|
||||
DRM_ERROR("Process %d freeing buffer not owned\n",
|
||||
current->pid);
|
||||
return -EINVAL;
|
||||
|
@ -1528,7 +1477,7 @@ int drm_freebufs(struct inode *inode, struct file *filp,
|
|||
* Maps all of the DMA buffers into client-virtual space (ioctl).
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg pointer to a drm_buf_map structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -1538,18 +1487,15 @@ int drm_freebufs(struct inode *inode, struct file *filp,
|
|||
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
|
||||
* drm_mmap_dma().
|
||||
*/
|
||||
int drm_mapbufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_mapbufs(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_map_t __user *argp = (void __user *)arg;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
int retcode = 0;
|
||||
const int zero = 0;
|
||||
unsigned long virtual;
|
||||
unsigned long address;
|
||||
drm_buf_map_t request;
|
||||
struct drm_buf_map *request = data;
|
||||
int i;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
|
||||
|
@ -1566,16 +1512,13 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
|
|||
dev->buf_use++; /* Can't allocate more after this call */
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
if (copy_from_user(&request, argp, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
if (request.count >= dma->buf_count) {
|
||||
if (request->count >= dma->buf_count) {
|
||||
if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
|
||||
|| (drm_core_check_feature(dev, DRIVER_SG)
|
||||
&& (dma->flags & _DRM_DMA_USE_SG))
|
||||
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
|
||||
&& (dma->flags & _DRM_DMA_USE_FB))) {
|
||||
drm_map_t *map = dev->agp_buffer_map;
|
||||
struct drm_map *map = dev->agp_buffer_map;
|
||||
unsigned long token = dev->agp_buffer_token;
|
||||
|
||||
if (!map) {
|
||||
|
@ -1583,14 +1526,14 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
|
|||
goto done;
|
||||
}
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
virtual = do_mmap(filp, 0, map->size,
|
||||
virtual = do_mmap(file_priv->filp, 0, map->size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
token);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
} else {
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
virtual = do_mmap(filp, 0, dma->byte_count,
|
||||
virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, 0);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
@ -1600,28 +1543,28 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
|
|||
retcode = (signed long)virtual;
|
||||
goto done;
|
||||
}
|
||||
request.virtual = (void __user *)virtual;
|
||||
request->virtual = (void __user *)virtual;
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (copy_to_user(&request.list[i].idx,
|
||||
if (copy_to_user(&request->list[i].idx,
|
||||
&dma->buflist[i]->idx,
|
||||
sizeof(request.list[0].idx))) {
|
||||
sizeof(request->list[0].idx))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].total,
|
||||
if (copy_to_user(&request->list[i].total,
|
||||
&dma->buflist[i]->total,
|
||||
sizeof(request.list[0].total))) {
|
||||
sizeof(request->list[0].total))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].used,
|
||||
if (copy_to_user(&request->list[i].used,
|
||||
&zero, sizeof(zero))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
address = virtual + dma->buflist[i]->offset; /* *** */
|
||||
if (copy_to_user(&request.list[i].address,
|
||||
if (copy_to_user(&request->list[i].address,
|
||||
&address, sizeof(address))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
|
@ -1629,11 +1572,8 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
|
|||
}
|
||||
}
|
||||
done:
|
||||
request.count = dma->buf_count;
|
||||
DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
request->count = dma->buf_count;
|
||||
DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
@ -196,21 +196,24 @@ static int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
|
||||
struct fault_data *data)
|
||||
{
|
||||
unsigned long address = data->address;
|
||||
drm_buffer_object_t *bo = (drm_buffer_object_t *) vma->vm_private_data;
|
||||
struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
|
||||
unsigned long page_offset;
|
||||
struct page *page = NULL;
|
||||
drm_ttm_t *ttm;
|
||||
drm_device_t *dev;
|
||||
struct drm_ttm *ttm;
|
||||
struct drm_device *dev;
|
||||
unsigned long pfn;
|
||||
int err;
|
||||
unsigned long bus_base;
|
||||
unsigned long bus_offset;
|
||||
unsigned long bus_size;
|
||||
|
||||
dev = bo->dev;
|
||||
while(drm_bo_read_lock(&dev->bm.bm_lock));
|
||||
|
||||
mutex_lock(&bo->mutex);
|
||||
|
||||
|
@ -261,7 +264,7 @@ static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
|
|||
page_offset = (address - vma->vm_start) >> PAGE_SHIFT;
|
||||
|
||||
if (bus_size) {
|
||||
drm_mem_type_manager_t *man = &dev->bm.man[bo->mem.mem_type];
|
||||
struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type];
|
||||
|
||||
pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) + page_offset;
|
||||
vma->vm_page_prot = drm_io_prot(man->drm_bus_maptype, vma);
|
||||
|
@ -288,6 +291,7 @@ static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
|
|||
data->type = VM_FAULT_OOM;
|
||||
out_unlock:
|
||||
mutex_unlock(&bo->mutex);
|
||||
drm_bo_read_unlock(&dev->bm.bm_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -350,11 +354,11 @@ struct page *drm_bo_vm_nopage(struct vm_area_struct *vma,
|
|||
unsigned long address,
|
||||
int *type)
|
||||
{
|
||||
drm_buffer_object_t *bo = (drm_buffer_object_t *) vma->vm_private_data;
|
||||
struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
|
||||
unsigned long page_offset;
|
||||
struct page *page;
|
||||
drm_ttm_t *ttm;
|
||||
drm_device_t *dev;
|
||||
struct drm_ttm *ttm;
|
||||
struct drm_device *dev;
|
||||
|
||||
mutex_lock(&bo->mutex);
|
||||
|
||||
|
@ -394,7 +398,7 @@ out_unlock:
|
|||
|
||||
int drm_bo_map_bound(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_buffer_object_t *bo = (drm_buffer_object_t *)vma->vm_private_data;
|
||||
struct drm_buffer_object *bo = (struct drm_buffer_object *)vma->vm_private_data;
|
||||
int ret = 0;
|
||||
unsigned long bus_base;
|
||||
unsigned long bus_offset;
|
||||
|
@ -405,7 +409,7 @@ int drm_bo_map_bound(struct vm_area_struct *vma)
|
|||
BUG_ON(ret);
|
||||
|
||||
if (bus_size) {
|
||||
drm_mem_type_manager_t *man = &bo->dev->bm.man[bo->mem.mem_type];
|
||||
struct drm_mem_type_manager *man = &bo->dev->bm.man[bo->mem.mem_type];
|
||||
unsigned long pfn = (bus_base + bus_offset) >> PAGE_SHIFT;
|
||||
pgprot_t pgprot = drm_io_prot(man->drm_bus_maptype, vma);
|
||||
ret = io_remap_pfn_range(vma, vma->vm_start, pfn,
|
||||
|
@ -417,7 +421,7 @@ int drm_bo_map_bound(struct vm_area_struct *vma)
|
|||
}
|
||||
|
||||
|
||||
int drm_bo_add_vma(drm_buffer_object_t * bo, struct vm_area_struct *vma)
|
||||
int drm_bo_add_vma(struct drm_buffer_object * bo, struct vm_area_struct *vma)
|
||||
{
|
||||
p_mm_entry_t *entry, *n_entry;
|
||||
vma_entry_t *v_entry;
|
||||
|
@ -453,7 +457,7 @@ int drm_bo_add_vma(drm_buffer_object_t * bo, struct vm_area_struct *vma)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void drm_bo_delete_vma(drm_buffer_object_t * bo, struct vm_area_struct *vma)
|
||||
void drm_bo_delete_vma(struct drm_buffer_object * bo, struct vm_area_struct *vma)
|
||||
{
|
||||
p_mm_entry_t *entry, *n;
|
||||
vma_entry_t *v_entry, *v_n;
|
||||
|
@ -485,7 +489,7 @@ void drm_bo_delete_vma(drm_buffer_object_t * bo, struct vm_area_struct *vma)
|
|||
|
||||
|
||||
|
||||
int drm_bo_lock_kmm(drm_buffer_object_t * bo)
|
||||
int drm_bo_lock_kmm(struct drm_buffer_object * bo)
|
||||
{
|
||||
p_mm_entry_t *entry;
|
||||
int lock_ok = 1;
|
||||
|
@ -517,7 +521,7 @@ int drm_bo_lock_kmm(drm_buffer_object_t * bo)
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
void drm_bo_unlock_kmm(drm_buffer_object_t * bo)
|
||||
void drm_bo_unlock_kmm(struct drm_buffer_object * bo)
|
||||
{
|
||||
p_mm_entry_t *entry;
|
||||
|
||||
|
@ -528,7 +532,7 @@ void drm_bo_unlock_kmm(drm_buffer_object_t * bo)
|
|||
}
|
||||
}
|
||||
|
||||
int drm_bo_remap_bound(drm_buffer_object_t *bo)
|
||||
int drm_bo_remap_bound(struct drm_buffer_object *bo)
|
||||
{
|
||||
vma_entry_t *v_entry;
|
||||
int ret = 0;
|
||||
|
@ -544,7 +548,7 @@ int drm_bo_remap_bound(drm_buffer_object_t *bo)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void drm_bo_finish_unmap(drm_buffer_object_t *bo)
|
||||
void drm_bo_finish_unmap(struct drm_buffer_object *bo)
|
||||
{
|
||||
vma_entry_t *v_entry;
|
||||
|
||||
|
@ -677,4 +681,51 @@ void idr_remove_all(struct idr *idp)
|
|||
idp->layers = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(idr_remove_all);
|
||||
|
||||
#endif /* DRM_IDR_COMPAT_FN */
|
||||
|
||||
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
|
||||
/**
|
||||
* idr_replace - replace pointer for given id
|
||||
* @idp: idr handle
|
||||
* @ptr: pointer you want associated with the id
|
||||
* @id: lookup key
|
||||
*
|
||||
* Replace the pointer registered with an id and return the old value.
|
||||
* A -ENOENT return indicates that @id was not found.
|
||||
* A -EINVAL return indicates that @id was not within valid constraints.
|
||||
*
|
||||
* The caller must serialize vs idr_find(), idr_get_new(), and idr_remove().
|
||||
*/
|
||||
void *idr_replace(struct idr *idp, void *ptr, int id)
|
||||
{
|
||||
int n;
|
||||
struct idr_layer *p, *old_p;
|
||||
|
||||
n = idp->layers * IDR_BITS;
|
||||
p = idp->top;
|
||||
|
||||
id &= MAX_ID_MASK;
|
||||
|
||||
if (id >= (1 << n))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
n -= IDR_BITS;
|
||||
while ((n > 0) && p) {
|
||||
p = p->ary[(id >> n) & IDR_MASK];
|
||||
n -= IDR_BITS;
|
||||
}
|
||||
|
||||
n = id & IDR_MASK;
|
||||
if (unlikely(p == NULL || !test_bit(n, &p->bitmap)))
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
old_p = p->ary[n];
|
||||
p->ary[n] = ptr;
|
||||
|
||||
return (void *)old_p;
|
||||
}
|
||||
EXPORT_SYMBOL(idr_replace);
|
||||
#endif
|
||||
|
|
|
@ -193,7 +193,10 @@ extern void drm_clear_vma(struct vm_area_struct *vma,
|
|||
extern pgprot_t vm_get_page_prot(unsigned long vm_flags);
|
||||
|
||||
#ifndef GFP_DMA32
|
||||
#define GFP_DMA32 0
|
||||
#define GFP_DMA32 GFP_KERNEL
|
||||
#endif
|
||||
#ifndef __GFP_DMA32
|
||||
#define __GFP_DMA32 GFP_KERNEL
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
|
||||
|
@ -306,12 +309,23 @@ extern int drm_bo_map_bound(struct vm_area_struct *vma);
|
|||
|
||||
#endif
|
||||
|
||||
/* fixme when functions are upstreamed */
|
||||
/* fixme when functions are upstreamed - upstreamed for 2.6.23 */
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
|
||||
#define DRM_IDR_COMPAT_FN
|
||||
#endif
|
||||
#ifdef DRM_IDR_COMPAT_FN
|
||||
int idr_for_each(struct idr *idp,
|
||||
int (*fn)(int id, void *p, void *data), void *data);
|
||||
void idr_remove_all(struct idr *idp);
|
||||
#endif
|
||||
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
|
||||
void *idr_replace(struct idr *idp, void *ptr, int id);
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
|
||||
typedef _Bool bool;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -56,19 +56,11 @@
|
|||
* in drm_device::ctx_idr, while holding the drm_device::struct_mutex
|
||||
* lock.
|
||||
*/
|
||||
void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
|
||||
void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle)
|
||||
{
|
||||
struct drm_ctx_sarea_list *ctx;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
ctx = idr_find(&dev->ctx_idr, ctx_handle);
|
||||
if (ctx) {
|
||||
idr_remove(&dev->ctx_idr, ctx_handle);
|
||||
drm_free(ctx, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
|
||||
} else
|
||||
DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle);
|
||||
idr_remove(&dev->ctx_idr, ctx_handle);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,24 +72,19 @@ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
|
|||
* Allocate a new idr from drm_device::ctx_idr while holding the
|
||||
* drm_device::struct_mutex lock.
|
||||
*/
|
||||
static int drm_ctxbitmap_next(drm_device_t * dev)
|
||||
static int drm_ctxbitmap_next(struct drm_device *dev)
|
||||
{
|
||||
int new_id;
|
||||
int ret;
|
||||
struct drm_ctx_sarea_list *new_ctx;
|
||||
|
||||
new_ctx = drm_calloc(1, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
|
||||
if (!new_ctx)
|
||||
return -1;
|
||||
|
||||
again:
|
||||
if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) {
|
||||
DRM_ERROR("Out of memory expanding drawable idr\n");
|
||||
drm_free(new_ctx, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
ret = idr_get_new_above(&dev->ctx_idr, new_ctx, DRM_RESERVED_CONTEXTS, &new_id);
|
||||
ret = idr_get_new_above(&dev->ctx_idr, NULL,
|
||||
DRM_RESERVED_CONTEXTS, &new_id);
|
||||
if (ret == -EAGAIN) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
goto again;
|
||||
|
@ -114,21 +101,12 @@ again:
|
|||
*
|
||||
* Initialise the drm_device::ctx_idr
|
||||
*/
|
||||
int drm_ctxbitmap_init(drm_device_t * dev)
|
||||
int drm_ctxbitmap_init(struct drm_device *dev)
|
||||
{
|
||||
idr_init(&dev->ctx_idr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int drm_ctx_sarea_free(int id, void *p, void *data)
|
||||
{
|
||||
struct drm_ctx_sarea_list *ctx_entry = p;
|
||||
drm_free(ctx_entry, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context bitmap cleanup.
|
||||
*
|
||||
|
@ -137,10 +115,9 @@ static int drm_ctx_sarea_free(int id, void *p, void *data)
|
|||
* Free all idr members using drm_ctx_sarea_free helper function
|
||||
* while holding the drm_device::struct_mutex lock.
|
||||
*/
|
||||
void drm_ctxbitmap_cleanup(drm_device_t * dev)
|
||||
void drm_ctxbitmap_cleanup(struct drm_device *dev)
|
||||
{
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
idr_for_each(&dev->ctx_idr, drm_ctx_sarea_free, NULL);
|
||||
idr_remove_all(&dev->ctx_idr);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
|
@ -155,7 +132,7 @@ void drm_ctxbitmap_cleanup(drm_device_t * dev)
|
|||
* Get per-context SAREA.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx_priv_map structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -163,44 +140,34 @@ void drm_ctxbitmap_cleanup(drm_device_t * dev)
|
|||
* Gets the map from drm_device::ctx_idr with the handle specified and
|
||||
* returns its handle.
|
||||
*/
|
||||
int drm_getsareactx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_getsareactx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_priv_map_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *_entry;
|
||||
struct drm_ctx_sarea_list *ctx_sarea;
|
||||
|
||||
if (copy_from_user(&request, argp, sizeof(request)))
|
||||
return -EFAULT;
|
||||
struct drm_ctx_priv_map *request = data;
|
||||
struct drm_map *map;
|
||||
struct drm_map_list *_entry;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id);
|
||||
if (!ctx_sarea) {
|
||||
map = idr_find(&dev->ctx_idr, request->ctx_id);
|
||||
if (!map) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
map = ctx_sarea->map;
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
request.handle = NULL;
|
||||
request->handle = NULL;
|
||||
list_for_each_entry(_entry, &dev->maplist, head) {
|
||||
if (_entry->map == map) {
|
||||
request.handle =
|
||||
request->handle =
|
||||
(void *)(unsigned long)_entry->user_token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (request.handle == NULL)
|
||||
if (request->handle == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -208,7 +175,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
* Set per-context SAREA.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx_priv_map structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -216,24 +183,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
* Searches the mapping specified in \p arg and update the entry in
|
||||
* drm_device::ctx_idr with it.
|
||||
*/
|
||||
int drm_setsareactx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_setsareactx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list = NULL;
|
||||
struct drm_ctx_sarea_list *ctx_sarea;
|
||||
|
||||
if (copy_from_user(&request,
|
||||
(drm_ctx_priv_map_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
struct drm_ctx_priv_map *request = data;
|
||||
struct drm_map *map = NULL;
|
||||
struct drm_map_list *r_list = NULL;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
list_for_each_entry(r_list, &dev->maplist, head) {
|
||||
if (r_list->map
|
||||
&& r_list->user_token == (unsigned long) request.handle)
|
||||
&& r_list->user_token == (unsigned long) request->handle)
|
||||
goto found;
|
||||
}
|
||||
bad:
|
||||
|
@ -245,14 +205,11 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
|
|||
if (!map)
|
||||
goto bad;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id);
|
||||
if (!ctx_sarea)
|
||||
if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
|
||||
goto bad;
|
||||
|
||||
ctx_sarea->map = map;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -272,7 +229,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Attempt to set drm_device::context_flag.
|
||||
*/
|
||||
static int drm_context_switch(drm_device_t * dev, int old, int new)
|
||||
static int drm_context_switch(struct drm_device *dev, int old, int new)
|
||||
{
|
||||
if (test_and_set_bit(0, &dev->context_flag)) {
|
||||
DRM_ERROR("Reentering -- FIXME\n");
|
||||
|
@ -300,7 +257,7 @@ static int drm_context_switch(drm_device_t * dev, int old, int new)
|
|||
* hardware lock is held, clears the drm_device::context_flag and wakes up
|
||||
* drm_device::context_wait.
|
||||
*/
|
||||
static int drm_context_switch_complete(drm_device_t * dev, int new)
|
||||
static int drm_context_switch_complete(struct drm_device *dev, int new)
|
||||
{
|
||||
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
|
||||
dev->last_switch = jiffies;
|
||||
|
@ -322,34 +279,28 @@ static int drm_context_switch_complete(drm_device_t * dev, int new)
|
|||
* Reserve contexts.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx_res structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*/
|
||||
int drm_resctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_resctx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_ctx_res_t res;
|
||||
drm_ctx_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_t ctx;
|
||||
struct drm_ctx_res *res = data;
|
||||
struct drm_ctx ctx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&res, argp, sizeof(res)))
|
||||
return -EFAULT;
|
||||
|
||||
if (res.count >= DRM_RESERVED_CONTEXTS) {
|
||||
if (res->count >= DRM_RESERVED_CONTEXTS) {
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
ctx.handle = i;
|
||||
if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx)))
|
||||
if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
res.count = DRM_RESERVED_CONTEXTS;
|
||||
res->count = DRM_RESERVED_CONTEXTS;
|
||||
|
||||
if (copy_to_user(argp, &res, sizeof(res)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -357,40 +308,34 @@ int drm_resctx(struct inode *inode, struct file *filp,
|
|||
* Add context.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Get a new handle for the context and copy to userspace.
|
||||
*/
|
||||
int drm_addctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_addctx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_list_t *ctx_entry;
|
||||
drm_ctx_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_t ctx;
|
||||
struct drm_ctx_list *ctx_entry;
|
||||
struct drm_ctx *ctx = data;
|
||||
|
||||
if (copy_from_user(&ctx, argp, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
ctx.handle = drm_ctxbitmap_next(dev);
|
||||
if (ctx.handle == DRM_KERNEL_CONTEXT) {
|
||||
ctx->handle = drm_ctxbitmap_next(dev);
|
||||
if (ctx->handle == DRM_KERNEL_CONTEXT) {
|
||||
/* Skip kernel's context and get a new one. */
|
||||
ctx.handle = drm_ctxbitmap_next(dev);
|
||||
ctx->handle = drm_ctxbitmap_next(dev);
|
||||
}
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if (ctx.handle == -1) {
|
||||
DRM_DEBUG("%d\n", ctx->handle);
|
||||
if (ctx->handle == -1) {
|
||||
DRM_DEBUG("Not enough free contexts.\n");
|
||||
/* Should this return -EBUSY instead? */
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
if (ctx->handle != DRM_KERNEL_CONTEXT) {
|
||||
if (dev->driver->context_ctor)
|
||||
if (!dev->driver->context_ctor(dev, ctx.handle)) {
|
||||
if (!dev->driver->context_ctor(dev, ctx->handle)) {
|
||||
DRM_DEBUG("Running out of ctxs or memory.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -403,21 +348,18 @@ int drm_addctx(struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
INIT_LIST_HEAD(&ctx_entry->head);
|
||||
ctx_entry->handle = ctx.handle;
|
||||
ctx_entry->tag = priv;
|
||||
ctx_entry->handle = ctx->handle;
|
||||
ctx_entry->tag = file_priv;
|
||||
|
||||
mutex_lock(&dev->ctxlist_mutex);
|
||||
list_add(&ctx_entry->head, &dev->ctxlist);
|
||||
++dev->ctx_count;
|
||||
mutex_unlock(&dev->ctxlist_mutex);
|
||||
|
||||
if (copy_to_user(argp, &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_modctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_modctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
/* This does nothing */
|
||||
return 0;
|
||||
|
@ -427,25 +369,18 @@ int drm_modctx(struct inode *inode, struct file *filp,
|
|||
* Get context.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*/
|
||||
int drm_getctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_ctx_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if (copy_from_user(&ctx, argp, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
struct drm_ctx *ctx = data;
|
||||
|
||||
/* This is 0, because we don't handle any context flags */
|
||||
ctx.flags = 0;
|
||||
ctx->flags = 0;
|
||||
|
||||
if (copy_to_user(argp, &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -453,50 +388,40 @@ int drm_getctx(struct inode *inode, struct file *filp,
|
|||
* Switch context.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Calls context_switch().
|
||||
*/
|
||||
int drm_switchctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_switchctx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_t ctx;
|
||||
struct drm_ctx *ctx = data;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
return drm_context_switch(dev, dev->last_context, ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx->handle);
|
||||
return drm_context_switch(dev, dev->last_context, ctx->handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* New context.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Calls context_switch_complete().
|
||||
*/
|
||||
int drm_newctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_newctx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_t ctx;
|
||||
struct drm_ctx *ctx = data;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
drm_context_switch_complete(dev, ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx->handle);
|
||||
drm_context_switch_complete(dev, ctx->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -505,39 +430,34 @@ int drm_newctx(struct inode *inode, struct file *filp,
|
|||
* Remove context.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument pointing to a drm_ctx structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
|
||||
*/
|
||||
int drm_rmctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
int drm_rmctx(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_t ctx;
|
||||
struct drm_ctx *ctx = data;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if (ctx.handle == DRM_KERNEL_CONTEXT + 1) {
|
||||
priv->remove_auth_on_close = 1;
|
||||
DRM_DEBUG("%d\n", ctx->handle);
|
||||
if (ctx->handle == DRM_KERNEL_CONTEXT + 1) {
|
||||
file_priv->remove_auth_on_close = 1;
|
||||
}
|
||||
if (ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
if (ctx->handle != DRM_KERNEL_CONTEXT) {
|
||||
if (dev->driver->context_dtor)
|
||||
dev->driver->context_dtor(dev, ctx.handle);
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
dev->driver->context_dtor(dev, ctx->handle);
|
||||
drm_ctxbitmap_free(dev, ctx->handle);
|
||||
}
|
||||
|
||||
mutex_lock(&dev->ctxlist_mutex);
|
||||
if (!list_empty(&dev->ctxlist)) {
|
||||
drm_ctx_list_t *pos, *n;
|
||||
struct drm_ctx_list *pos, *n;
|
||||
|
||||
list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
|
||||
if (pos->handle == ctx.handle) {
|
||||
if (pos->handle == ctx->handle) {
|
||||
list_del(&pos->head);
|
||||
drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
|
||||
--dev->ctx_count;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
*
|
||||
* Allocate and initialize a drm_device_dma structure.
|
||||
*/
|
||||
int drm_dma_setup(drm_device_t * dev)
|
||||
int drm_dma_setup(struct drm_device * dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -67,9 +67,9 @@ int drm_dma_setup(drm_device_t * dev)
|
|||
* Free all pages associated with DMA buffers, the buffers and pages lists, and
|
||||
* finally the the drm_device::dma structure itself.
|
||||
*/
|
||||
void drm_dma_takedown(drm_device_t * dev)
|
||||
void drm_dma_takedown(struct drm_device * dev)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
int i, j;
|
||||
|
||||
if (!dma)
|
||||
|
@ -129,14 +129,14 @@ void drm_dma_takedown(drm_device_t * dev)
|
|||
*
|
||||
* Resets the fields of \p buf.
|
||||
*/
|
||||
void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf)
|
||||
void drm_free_buffer(struct drm_device * dev, struct drm_buf * buf)
|
||||
{
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->file_priv = NULL;
|
||||
buf->used = 0;
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)
|
||||
|
@ -148,19 +148,20 @@ void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf)
|
|||
/**
|
||||
* Reclaim the buffers.
|
||||
*
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
*
|
||||
* Frees each buffer associated with \p filp not already on the hardware.
|
||||
* Frees each buffer associated with \p file_priv not already on the hardware.
|
||||
*/
|
||||
void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
|
||||
void drm_core_reclaim_buffers(struct drm_device *dev,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
int i;
|
||||
|
||||
if (!dma)
|
||||
return;
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (dma->buflist[i]->filp == filp) {
|
||||
if (dma->buflist[i]->file_priv == file_priv) {
|
||||
switch (dma->buflist[i]->list) {
|
||||
case DRM_LIST_NONE:
|
||||
drm_free_buffer(dev, dma->buflist[i]);
|
||||
|
|
|
@ -40,28 +40,21 @@
|
|||
/**
|
||||
* Allocate drawable ID and memory to store information about it.
|
||||
*/
|
||||
int drm_adddraw(DRM_IOCTL_ARGS)
|
||||
int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
unsigned long irqflags;
|
||||
struct drm_drawable_list *draw_info;
|
||||
drm_draw_t draw;
|
||||
struct drm_draw *draw = data;
|
||||
int new_id = 0;
|
||||
int ret;
|
||||
|
||||
draw_info = drm_calloc(1, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
|
||||
if (!draw_info)
|
||||
return -ENOMEM;
|
||||
|
||||
again:
|
||||
if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) {
|
||||
DRM_ERROR("Out of memory expanding drawable idr\n");
|
||||
drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||
ret = idr_get_new_above(&dev->drw_idr, draw_info, 1, &new_id);
|
||||
ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id);
|
||||
if (ret == -EAGAIN) {
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
goto again;
|
||||
|
@ -69,11 +62,9 @@ again:
|
|||
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
|
||||
draw.handle = new_id;
|
||||
draw->handle = new_id;
|
||||
|
||||
DRM_DEBUG("%d\n", draw.handle);
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_draw_t __user *)data, draw, sizeof(draw));
|
||||
DRM_DEBUG("%d\n", draw->handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -81,73 +72,64 @@ again:
|
|||
/**
|
||||
* Free drawable ID and memory to store information about it.
|
||||
*/
|
||||
int drm_rmdraw(DRM_IOCTL_ARGS)
|
||||
int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_draw_t draw;
|
||||
struct drm_draw *draw = data;
|
||||
unsigned long irqflags;
|
||||
struct drm_drawable_list *draw_info;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data,
|
||||
sizeof(draw));
|
||||
|
||||
draw_info = idr_find(&dev->drw_idr, draw.handle);
|
||||
if (!draw_info) {
|
||||
DRM_DEBUG("No such drawable %d\n", draw.handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||
|
||||
idr_remove(&dev->drw_idr, draw.handle);
|
||||
drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
|
||||
drm_free(drm_get_drawable_info(dev, draw->handle),
|
||||
sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
|
||||
|
||||
idr_remove(&dev->drw_idr, draw->handle);
|
||||
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
DRM_DEBUG("%d\n", draw.handle);
|
||||
DRM_DEBUG("%d\n", draw->handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_update_drawable_info(DRM_IOCTL_ARGS) {
|
||||
DRM_DEVICE;
|
||||
drm_update_draw_t update;
|
||||
int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_update_draw *update = data;
|
||||
unsigned long irqflags;
|
||||
drm_drawable_info_t *info;
|
||||
drm_clip_rect_t *rects;
|
||||
struct drm_drawable_list *draw_info;
|
||||
struct drm_clip_rect *rects;
|
||||
struct drm_drawable_info *info;
|
||||
int err;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data,
|
||||
sizeof(update));
|
||||
|
||||
draw_info = idr_find(&dev->drw_idr, update.handle);
|
||||
if (!draw_info) {
|
||||
DRM_ERROR("No such drawable %d\n", update.handle);
|
||||
return DRM_ERR(EINVAL);
|
||||
info = idr_find(&dev->drw_idr, update->handle);
|
||||
if (!info) {
|
||||
info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) {
|
||||
DRM_ERROR("No such drawable %d\n", update->handle);
|
||||
drm_free(info, sizeof(*info), DRM_MEM_BUFS);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
info = &draw_info->info;
|
||||
|
||||
switch (update.type) {
|
||||
switch (update->type) {
|
||||
case DRM_DRAWABLE_CLIPRECTS:
|
||||
if (update.num != info->num_rects) {
|
||||
rects = drm_alloc(update.num * sizeof(drm_clip_rect_t),
|
||||
if (update->num != info->num_rects) {
|
||||
rects = drm_alloc(update->num * sizeof(struct drm_clip_rect),
|
||||
DRM_MEM_BUFS);
|
||||
} else
|
||||
rects = info->rects;
|
||||
|
||||
if (update.num && !rects) {
|
||||
if (update->num && !rects) {
|
||||
DRM_ERROR("Failed to allocate cliprect memory\n");
|
||||
err = DRM_ERR(ENOMEM);
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (update.num && DRM_COPY_FROM_USER(rects,
|
||||
(drm_clip_rect_t __user *)
|
||||
(unsigned long)update.data,
|
||||
update.num *
|
||||
if (update->num && DRM_COPY_FROM_USER(rects,
|
||||
(struct drm_clip_rect __user *)
|
||||
(unsigned long)update->data,
|
||||
update->num *
|
||||
sizeof(*rects))) {
|
||||
DRM_ERROR("Failed to copy cliprects from userspace\n");
|
||||
err = DRM_ERR(EFAULT);
|
||||
err = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -155,27 +137,27 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) {
|
|||
|
||||
if (rects != info->rects) {
|
||||
drm_free(info->rects, info->num_rects *
|
||||
sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
|
||||
sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
|
||||
}
|
||||
|
||||
info->rects = rects;
|
||||
info->num_rects = update.num;
|
||||
info->num_rects = update->num;
|
||||
|
||||
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||
|
||||
DRM_DEBUG("Updated %d cliprects for drawable %d\n",
|
||||
info->num_rects, update.handle);
|
||||
info->num_rects, update->handle);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid update type %d\n", update.type);
|
||||
return DRM_ERR(EINVAL);
|
||||
DRM_ERROR("Invalid update type %d\n", update->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (rects != info->rects)
|
||||
drm_free(rects, update.num * sizeof(drm_clip_rect_t),
|
||||
drm_free(rects, update->num * sizeof(struct drm_clip_rect),
|
||||
DRM_MEM_BUFS);
|
||||
|
||||
return err;
|
||||
|
@ -184,28 +166,26 @@ error:
|
|||
/**
|
||||
* Caller must hold the drawable spinlock!
|
||||
*/
|
||||
drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) {
|
||||
struct drm_drawable_list *draw_info;
|
||||
draw_info = idr_find(&dev->drw_idr, id);
|
||||
if (!draw_info) {
|
||||
DRM_DEBUG("No such drawable %d\n", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &draw_info->info;
|
||||
struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id)
|
||||
{
|
||||
return idr_find(&dev->drw_idr, id);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_drawable_info);
|
||||
|
||||
static int drm_drawable_free(int idr, void *p, void *data)
|
||||
{
|
||||
struct drm_drawable_list *drw_entry = p;
|
||||
drm_free(drw_entry->info.rects, drw_entry->info.num_rects *
|
||||
sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
|
||||
drm_free(drw_entry, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
|
||||
struct drm_drawable_info *info = p;
|
||||
|
||||
if (info) {
|
||||
drm_free(info->rects, info->num_rects *
|
||||
sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
|
||||
drm_free(info, sizeof(*info), DRM_MEM_BUFS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drm_drawable_free_all(drm_device_t *dev)
|
||||
void drm_drawable_free_all(struct drm_device *dev)
|
||||
{
|
||||
idr_for_each(&dev->drw_idr, drm_drawable_free, NULL);
|
||||
idr_remove_all(&dev->drw_idr);
|
||||
|
|
|
@ -48,82 +48,106 @@
|
|||
#include "drmP.h"
|
||||
#include "drm_core.h"
|
||||
|
||||
static void drm_cleanup(drm_device_t * dev);
|
||||
static void drm_cleanup(struct drm_device * dev);
|
||||
int drm_fb_loaded = 0;
|
||||
|
||||
static int drm_version(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
static int drm_version(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
/** Ioctl table */
|
||||
static drm_ioctl_desc_t drm_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY},
|
||||
static struct drm_ioctl_desc drm_ioctls[] = {
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
|
||||
/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(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_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
|
||||
|
||||
[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_MM_INIT)] = {drm_mm_init_ioctl,
|
||||
DRM_AUTH },
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MODESET_CTL)] = {drm_modeset_ctl, 0},
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
|
||||
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
|
||||
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_LOCK, drm_mm_lock_ioctl,
|
||||
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_UNLOCK, drm_mm_unlock_ioctl,
|
||||
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_CREATE, drm_fence_create_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_REFERENCE, drm_fence_reference_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_UNREFERENCE, drm_fence_unreference_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_SIGNALED, drm_fence_signaled_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_FLUSH, drm_fence_flush_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_WAIT, drm_fence_wait_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_EMIT, drm_fence_emit_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_FENCE_BUFFERS, drm_fence_buffers_ioctl, DRM_AUTH),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_CREATE, drm_bo_create_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_MAP, drm_bo_map_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0),
|
||||
};
|
||||
|
||||
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
|
||||
|
@ -138,11 +162,11 @@ static drm_ioctl_desc_t drm_ioctls[] = {
|
|||
*
|
||||
* \sa drm_device
|
||||
*/
|
||||
int drm_lastclose(drm_device_t * dev)
|
||||
int drm_lastclose(struct drm_device * dev)
|
||||
{
|
||||
drm_magic_entry_t *pt, *next;
|
||||
drm_map_list_t *r_list, *list_t;
|
||||
drm_vma_entry_t *vma, *vma_temp;
|
||||
struct drm_magic_entry *pt, *next;
|
||||
struct drm_map_list *r_list, *list_t;
|
||||
struct drm_vma_entry *vma, *vma_temp;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
@ -190,7 +214,7 @@ int drm_lastclose(drm_device_t * dev)
|
|||
|
||||
/* Clear AGP information */
|
||||
if (drm_core_has_AGP(dev) && dev->agp) {
|
||||
drm_agp_mem_t *entry, *tempe;
|
||||
struct drm_agp_mem *entry, *tempe;
|
||||
|
||||
/* Remove AGP resources, but leave dev->agp
|
||||
intact until drv_cleanup is called. */
|
||||
|
@ -246,7 +270,7 @@ int drm_lastclose(drm_device_t * dev)
|
|||
|
||||
if (dev->lock.hw_lock) {
|
||||
dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
|
||||
dev->lock.filp = NULL;
|
||||
dev->lock.file_priv = NULL;
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
}
|
||||
dev->dev_mapping = NULL;
|
||||
|
@ -258,7 +282,7 @@ int drm_lastclose(drm_device_t * dev)
|
|||
|
||||
void drm_cleanup_pci(struct pci_dev *pdev)
|
||||
{
|
||||
drm_device_t *dev = pci_get_drvdata(pdev);
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
pci_release_regions(pdev);
|
||||
|
@ -297,6 +321,11 @@ int drm_init(struct drm_driver *driver,
|
|||
while ((pdev =
|
||||
pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
|
||||
pid->subdevice, pdev))) {
|
||||
/* Are there device class requirements? */
|
||||
if ((pid->class != 0)
|
||||
&& ((pdev->class & pid->class_mask) != pid->class)) {
|
||||
continue;
|
||||
}
|
||||
/* is there already a driver loaded, or (short circuit saves work) */
|
||||
/* does something like VesaFB have control of the memory region? */
|
||||
if (pci_dev_driver(pdev)
|
||||
|
@ -312,7 +341,7 @@ int drm_init(struct drm_driver *driver,
|
|||
}
|
||||
|
||||
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];
|
||||
|
@ -323,6 +352,11 @@ int drm_init(struct drm_driver *driver,
|
|||
pci_get_subsys(pid->vendor, pid->device,
|
||||
pid->subvendor, pid->subdevice,
|
||||
pdev))) {
|
||||
/* Are there device class requirements? */
|
||||
if ((pid->class != 0)
|
||||
&& ((pdev->class & pid->class_mask) != pid->class)) {
|
||||
continue;
|
||||
}
|
||||
/* stealth mode requires a manual probe */
|
||||
pci_dev_get(pdev);
|
||||
if ((rc = drm_get_dev(pdev, &pciidlist[i], driver))) {
|
||||
|
@ -344,7 +378,7 @@ EXPORT_SYMBOL(drm_init);
|
|||
*
|
||||
* \sa drm_init
|
||||
*/
|
||||
static void drm_cleanup(drm_device_t * dev)
|
||||
static void drm_cleanup(struct drm_device * dev)
|
||||
{
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
@ -389,8 +423,8 @@ static void drm_cleanup(drm_device_t * dev)
|
|||
void drm_exit(struct drm_driver *driver)
|
||||
{
|
||||
int i;
|
||||
drm_device_t *dev = NULL;
|
||||
drm_head_t *head;
|
||||
struct drm_device *dev = NULL;
|
||||
struct drm_head *head;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
if (drm_fb_loaded) {
|
||||
|
@ -483,7 +517,7 @@ static int __init drm_core_init(void)
|
|||
CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
|
||||
return 0;
|
||||
err_p3:
|
||||
drm_sysfs_destroy(drm_class);
|
||||
drm_sysfs_destroy();
|
||||
err_p2:
|
||||
unregister_chrdev(DRM_MAJOR, "drm");
|
||||
drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
|
||||
|
@ -494,7 +528,7 @@ err_p1:
|
|||
static void __exit drm_core_exit(void)
|
||||
{
|
||||
remove_proc_entry("dri", NULL);
|
||||
drm_sysfs_destroy(drm_class);
|
||||
drm_sysfs_destroy();
|
||||
|
||||
unregister_chrdev(DRM_MAJOR, "drm");
|
||||
|
||||
|
@ -508,34 +542,26 @@ module_exit(drm_core_exit);
|
|||
* Get version information
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_version structure.
|
||||
* \return zero on success or negative number on failure.
|
||||
*
|
||||
* Fills in the version information in \p arg.
|
||||
*/
|
||||
static int drm_version(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
static int drm_version(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_version_t __user *argp = (void __user *)arg;
|
||||
drm_version_t version;
|
||||
struct drm_version *version = data;
|
||||
int len;
|
||||
|
||||
if (copy_from_user(&version, argp, sizeof(version)))
|
||||
return -EFAULT;
|
||||
version->version_major = dev->driver->major;
|
||||
version->version_minor = dev->driver->minor;
|
||||
version->version_patchlevel = dev->driver->patchlevel;
|
||||
DRM_COPY(version->name, dev->driver->name);
|
||||
DRM_COPY(version->date, dev->driver->date);
|
||||
DRM_COPY(version->desc, dev->driver->desc);
|
||||
|
||||
version.version_major = dev->driver->major;
|
||||
version.version_minor = dev->driver->minor;
|
||||
version.version_patchlevel = dev->driver->patchlevel;
|
||||
DRM_COPY(version.name, dev->driver->name);
|
||||
DRM_COPY(version.date, dev->driver->date);
|
||||
DRM_COPY(version.desc, dev->driver->desc);
|
||||
|
||||
if (copy_to_user(argp, &version, sizeof(version)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -543,31 +569,43 @@ static int drm_version(struct inode *inode, struct file *filp,
|
|||
* Called whenever a process performs an ioctl on /dev/drm.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param file_priv DRM file private.
|
||||
* \param cmd command.
|
||||
* \param arg user argument.
|
||||
* \return zero on success or negative number on failure.
|
||||
*
|
||||
* Looks up the ioctl function in the ::ioctls table, checking for root
|
||||
* previleges if so required, and dispatches to the respective function.
|
||||
*
|
||||
* Copies data in and out according to the size and direction given in cmd,
|
||||
* which must match the ioctl cmd known by the kernel. The kernel uses a 512
|
||||
* byte stack buffer to store the ioctl arguments in kernel space. Should we
|
||||
* ever need much larger ioctl arguments, we may need to allocate memory.
|
||||
*/
|
||||
int drm_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ioctl_desc_t *ioctl;
|
||||
return drm_unlocked_ioctl(filp, cmd, arg);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ioctl);
|
||||
|
||||
long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct drm_file *file_priv = filp->private_data;
|
||||
struct drm_device *dev = file_priv->head->dev;
|
||||
struct drm_ioctl_desc *ioctl;
|
||||
drm_ioctl_t *func;
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
int retcode = -EINVAL;
|
||||
char kdata[512];
|
||||
|
||||
atomic_inc(&dev->ioctl_count);
|
||||
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
|
||||
++priv->ioctl_count;
|
||||
++file_priv->ioctl_count;
|
||||
|
||||
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
current->pid, cmd, nr, (long)old_encode_dev(priv->head->device),
|
||||
priv->authenticated);
|
||||
current->pid, cmd, nr, (long)old_encode_dev(file_priv->head->device),
|
||||
file_priv->authenticated);
|
||||
|
||||
if ((nr >= DRM_CORE_IOCTL_COUNT) &&
|
||||
((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
|
||||
|
@ -577,35 +615,63 @@ int drm_ioctl(struct inode *inode, struct file *filp,
|
|||
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
|
||||
else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
|
||||
ioctl = &drm_ioctls[nr];
|
||||
else
|
||||
else {
|
||||
retcode = -EINVAL;
|
||||
goto err_i1;
|
||||
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* This check is disabled, because driver private ioctl->cmd
|
||||
* are not the ioctl commands with size and direction bits but
|
||||
* just the indices. The DRM core ioctl->cmd are the proper ioctl
|
||||
* commands. The drivers' ioctl tables need to be fixed.
|
||||
*/
|
||||
if (ioctl->cmd != cmd) {
|
||||
retcode = -EINVAL;
|
||||
goto err_i1;
|
||||
}
|
||||
#endif
|
||||
func = ioctl->func;
|
||||
/* is there a local override? */
|
||||
if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
|
||||
func = dev->driver->dma_ioctl;
|
||||
|
||||
if (cmd & IOC_IN) {
|
||||
if (copy_from_user(kdata, (void __user *)arg,
|
||||
_IOC_SIZE(cmd)) != 0) {
|
||||
retcode = -EACCES;
|
||||
goto err_i1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!func) {
|
||||
DRM_DEBUG("no function\n");
|
||||
retcode = -EINVAL;
|
||||
} else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
|
||||
((ioctl->flags & DRM_AUTH) && !priv->authenticated) ||
|
||||
((ioctl->flags & DRM_MASTER) && !priv->master)) {
|
||||
((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
|
||||
((ioctl->flags & DRM_MASTER) && !file_priv->master)) {
|
||||
retcode = -EACCES;
|
||||
} else {
|
||||
retcode = func(inode, filp, cmd, arg);
|
||||
retcode = func(dev, kdata, file_priv);
|
||||
}
|
||||
|
||||
if ((retcode == 0) && (cmd & IOC_OUT)) {
|
||||
if (copy_to_user((void __user *)arg, kdata,
|
||||
_IOC_SIZE(cmd)) != 0)
|
||||
retcode = -EACCES;
|
||||
}
|
||||
|
||||
err_i1:
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
if (retcode)
|
||||
DRM_DEBUG("ret = %x\n", retcode);
|
||||
DRM_DEBUG("ret = %d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ioctl);
|
||||
EXPORT_SYMBOL(drm_unlocked_ioctl);
|
||||
|
||||
drm_local_map_t *drm_getsarea(struct drm_device *dev)
|
||||
{
|
||||
drm_map_list_t *entry;
|
||||
struct drm_map_list *entry;
|
||||
|
||||
list_for_each_entry(entry, &dev->maplist, head) {
|
||||
if (entry->map && entry->map->type == _DRM_SHM &&
|
||||
|
|
|
@ -34,21 +34,22 @@
|
|||
* Typically called by the IRQ handler.
|
||||
*/
|
||||
|
||||
void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
||||
uint32_t sequence, uint32_t type)
|
||||
void drm_fence_handler(struct drm_device * dev, uint32_t fence_class,
|
||||
uint32_t sequence, uint32_t type, uint32_t error)
|
||||
{
|
||||
int wake = 0;
|
||||
uint32_t diff;
|
||||
uint32_t relevant;
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_class_manager_t *fc = &fm->class[class];
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_class_manager *fc = &fm->fence_class[fence_class];
|
||||
struct drm_fence_driver *driver = dev->driver->fence_driver;
|
||||
struct list_head *head;
|
||||
drm_fence_object_t *fence, *next;
|
||||
struct drm_fence_object *fence, *next;
|
||||
int found = 0;
|
||||
int is_exe = (type & DRM_FENCE_TYPE_EXE);
|
||||
int ge_last_exe;
|
||||
|
||||
|
||||
diff = (sequence - fc->exe_flush_sequence) & driver->sequence_mask;
|
||||
|
||||
if (fc->pending_exe_flush && is_exe && diff < driver->wrap_diff)
|
||||
|
@ -57,9 +58,6 @@ void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
|||
diff = (sequence - fc->last_exe_flush) & driver->sequence_mask;
|
||||
ge_last_exe = diff < driver->wrap_diff;
|
||||
|
||||
if (ge_last_exe)
|
||||
fc->pending_flush &= ~type;
|
||||
|
||||
if (is_exe && ge_last_exe) {
|
||||
fc->last_exe_flush = sequence;
|
||||
}
|
||||
|
@ -75,36 +73,68 @@ void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
|||
}
|
||||
}
|
||||
|
||||
fc->pending_flush &= ~type;
|
||||
head = (found) ? &fence->ring : &fc->ring;
|
||||
|
||||
list_for_each_entry_safe_reverse(fence, next, head, ring) {
|
||||
if (&fence->ring == &fc->ring)
|
||||
break;
|
||||
|
||||
type |= fence->native_type;
|
||||
if (error) {
|
||||
fence->error = error;
|
||||
fence->signaled = fence->type;
|
||||
fence->submitted_flush = fence->type;
|
||||
fence->flush_mask = fence->type;
|
||||
list_del_init(&fence->ring);
|
||||
wake = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_exe)
|
||||
type |= fence->native_type;
|
||||
|
||||
relevant = type & fence->type;
|
||||
|
||||
if ((fence->signaled | relevant) != fence->signaled) {
|
||||
fence->signaled |= relevant;
|
||||
fence->flush_mask |= relevant;
|
||||
fence->submitted_flush |= relevant;
|
||||
DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
|
||||
fence->base.hash.key, fence->signaled);
|
||||
fence->submitted_flush |= relevant;
|
||||
wake = 1;
|
||||
}
|
||||
|
||||
relevant = fence->flush_mask &
|
||||
~(fence->signaled | fence->submitted_flush);
|
||||
~(fence->submitted_flush | fence->signaled);
|
||||
|
||||
if (relevant) {
|
||||
fc->pending_flush |= relevant;
|
||||
fence->submitted_flush = fence->flush_mask;
|
||||
}
|
||||
fc->pending_flush |= relevant;
|
||||
fence->submitted_flush |= relevant;
|
||||
|
||||
if (!(fence->type & ~fence->signaled)) {
|
||||
DRM_DEBUG("Fence completely signaled 0x%08lx\n",
|
||||
fence->base.hash.key);
|
||||
list_del_init(&fence->ring);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Reinstate lost flush flags.
|
||||
*/
|
||||
|
||||
if ((fc->pending_flush & type) != type) {
|
||||
head = head->prev;
|
||||
list_for_each_entry(fence, head, ring) {
|
||||
if (&fence->ring == &fc->ring)
|
||||
break;
|
||||
diff = (fc->last_exe_flush - fence->sequence) &
|
||||
driver->sequence_mask;
|
||||
if (diff > driver->wrap_diff)
|
||||
break;
|
||||
|
||||
relevant = fence->submitted_flush & ~fence->signaled;
|
||||
fc->pending_flush |= relevant;
|
||||
}
|
||||
}
|
||||
|
||||
if (wake) {
|
||||
|
@ -114,9 +144,9 @@ void drm_fence_handler(drm_device_t * dev, uint32_t class,
|
|||
|
||||
EXPORT_SYMBOL(drm_fence_handler);
|
||||
|
||||
static void drm_fence_unring(drm_device_t * dev, struct list_head *ring)
|
||||
static void drm_fence_unring(struct drm_device * dev, struct list_head *ring)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
unsigned long flags;
|
||||
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
|
@ -124,57 +154,83 @@ static void drm_fence_unring(drm_device_t * dev, struct list_head *ring)
|
|||
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(struct drm_fence_object ** fence)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
struct drm_fence_object *tmp_fence = *fence;
|
||||
struct drm_device *dev = tmp_fence->dev;
|
||||
struct drm_fence_manager *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);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_usage_deref_locked);
|
||||
|
||||
void drm_fence_usage_deref_unlocked(drm_device_t * dev,
|
||||
drm_fence_object_t * fence)
|
||||
void drm_fence_usage_deref_unlocked(struct drm_fence_object ** fence)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
struct drm_fence_object *tmp_fence = *fence;
|
||||
struct drm_device *dev = tmp_fence->dev;
|
||||
struct drm_fence_manager *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);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_usage_deref_unlocked);
|
||||
|
||||
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_device_t *dev = priv->head->dev;
|
||||
drm_fence_object_t *fence =
|
||||
drm_user_object_entry(base, drm_fence_object_t, base);
|
||||
DRM_ASSERT_LOCKED(&src->dev->struct_mutex);
|
||||
|
||||
drm_fence_usage_deref_locked(dev, fence);
|
||||
atomic_inc(&src->usage);
|
||||
return src;
|
||||
}
|
||||
|
||||
static int fence_signaled(drm_device_t * dev,
|
||||
drm_fence_object_t * fence,
|
||||
uint32_t mask, int poke_flush)
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_reference_unlocked);
|
||||
|
||||
static void drm_fence_object_destroy(struct drm_file *priv, struct drm_user_object * base)
|
||||
{
|
||||
struct drm_fence_object *fence =
|
||||
drm_user_object_entry(base, struct drm_fence_object, base);
|
||||
|
||||
drm_fence_usage_deref_locked(&fence);
|
||||
}
|
||||
|
||||
int drm_fence_object_signaled(struct drm_fence_object * fence,
|
||||
uint32_t mask, int poke_flush)
|
||||
{
|
||||
unsigned long flags;
|
||||
int signaled;
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
struct drm_device *dev = fence->dev;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_driver *driver = dev->driver->fence_driver;
|
||||
|
||||
if (poke_flush)
|
||||
driver->poke_flush(dev, fence->class);
|
||||
driver->poke_flush(dev, fence->fence_class);
|
||||
read_lock_irqsave(&fm->lock, flags);
|
||||
signaled =
|
||||
(fence->type & mask & fence->signaled) == (fence->type & mask);
|
||||
|
@ -182,9 +238,10 @@ static int fence_signaled(drm_device_t * dev,
|
|||
|
||||
return signaled;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_object_signaled);
|
||||
|
||||
static void drm_fence_flush_exe(drm_fence_class_manager_t * fc,
|
||||
drm_fence_driver_t * driver, uint32_t sequence)
|
||||
static void drm_fence_flush_exe(struct drm_fence_class_manager * fc,
|
||||
struct drm_fence_driver * driver, uint32_t sequence)
|
||||
{
|
||||
uint32_t diff;
|
||||
|
||||
|
@ -200,19 +257,13 @@ static void drm_fence_flush_exe(drm_fence_class_manager_t * fc,
|
|||
}
|
||||
}
|
||||
|
||||
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(struct drm_fence_object * fence,
|
||||
uint32_t type)
|
||||
{
|
||||
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;
|
||||
struct drm_device *dev = fence->dev;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
|
||||
struct drm_fence_driver *driver = dev->driver->fence_driver;
|
||||
unsigned long flags;
|
||||
|
||||
if (type & ~fence->type) {
|
||||
|
@ -223,7 +274,8 @@ int drm_fence_object_flush(drm_device_t * dev,
|
|||
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
fence->flush_mask |= type;
|
||||
if (fence->submitted_flush == fence->signaled) {
|
||||
if ((fence->submitted_flush & fence->signaled)
|
||||
== fence->submitted_flush) {
|
||||
if ((fence->type & DRM_FENCE_TYPE_EXE) &&
|
||||
!(fence->submitted_flush & DRM_FENCE_TYPE_EXE)) {
|
||||
drm_fence_flush_exe(fc, driver, fence->sequence);
|
||||
|
@ -235,7 +287,7 @@ int drm_fence_object_flush(drm_device_t * dev,
|
|||
}
|
||||
}
|
||||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
driver->poke_flush(dev, fence->class);
|
||||
driver->poke_flush(dev, fence->fence_class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -244,14 +296,14 @@ int drm_fence_object_flush(drm_device_t * dev,
|
|||
* wrapped around and reused.
|
||||
*/
|
||||
|
||||
void drm_fence_flush_old(drm_device_t * dev, uint32_t class, uint32_t sequence)
|
||||
void drm_fence_flush_old(struct drm_device * dev, uint32_t fence_class, uint32_t sequence)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_class_manager_t *fc = &fm->class[class];
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_class_manager *fc = &fm->fence_class[fence_class];
|
||||
struct drm_fence_driver *driver = dev->driver->fence_driver;
|
||||
uint32_t old_sequence;
|
||||
unsigned long flags;
|
||||
drm_fence_object_t *fence;
|
||||
struct drm_fence_object *fence;
|
||||
uint32_t diff;
|
||||
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
|
@ -272,39 +324,38 @@ void drm_fence_flush_old(drm_device_t * dev, uint32_t class, uint32_t sequence)
|
|||
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, struct drm_fence_object, 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(struct drm_fence_object *fence,
|
||||
int ignore_signals,
|
||||
uint32_t mask)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_class_manager_t *fc = &fm->class[fence->class];
|
||||
struct drm_device *dev = fence->dev;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
|
||||
int signaled;
|
||||
unsigned long _end = jiffies + 3*DRM_HZ;
|
||||
int ret = 0;
|
||||
|
||||
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;
|
||||
|
@ -312,18 +363,26 @@ static int drm_fence_lazy_wait(drm_device_t *dev,
|
|||
if (ret == -EBUSY) {
|
||||
DRM_ERROR("Fence timeout. "
|
||||
"GPU lockup or fence driver was "
|
||||
"taken down.\n");
|
||||
"taken down. %d 0x%08x 0x%02x 0x%02x 0x%02x\n",
|
||||
fence->fence_class,
|
||||
fence->sequence,
|
||||
fence->type,
|
||||
mask,
|
||||
fence->signaled);
|
||||
DRM_ERROR("Pending exe flush %d 0x%08x\n",
|
||||
fc->pending_exe_flush,
|
||||
fc->exe_flush_sequence);
|
||||
}
|
||||
return ((ret == -EINTR) ? -EAGAIN : ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_fence_object_wait(drm_device_t * dev,
|
||||
drm_fence_object_t * fence,
|
||||
int drm_fence_object_wait(struct drm_fence_object * fence,
|
||||
int lazy, int ignore_signals, uint32_t mask)
|
||||
{
|
||||
drm_fence_driver_t *driver = dev->driver->fence_driver;
|
||||
struct drm_device *dev = fence->dev;
|
||||
struct drm_fence_driver *driver = dev->driver->fence_driver;
|
||||
int ret = 0;
|
||||
unsigned long _end;
|
||||
int signaled;
|
||||
|
@ -331,41 +390,42 @@ int drm_fence_object_wait(drm_device_t * dev,
|
|||
if (mask & ~fence->type) {
|
||||
DRM_ERROR("Wait trying to extend fence type"
|
||||
" 0x%08x 0x%08x\n", mask, fence->type);
|
||||
BUG();
|
||||
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;
|
||||
|
||||
} else {
|
||||
|
||||
if (driver->has_irq(dev, fence->class,
|
||||
if (driver->has_irq(dev, fence->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,
|
||||
if (driver->has_irq(dev, fence->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;
|
||||
|
||||
/*
|
||||
|
@ -377,7 +437,7 @@ int drm_fence_object_wait(drm_device_t * dev,
|
|||
#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)
|
||||
|
@ -385,25 +445,28 @@ int drm_fence_object_wait(drm_device_t * dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_object_wait);
|
||||
|
||||
int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
|
||||
uint32_t fence_flags, uint32_t class, uint32_t type)
|
||||
|
||||
int drm_fence_object_emit(struct drm_fence_object * fence,
|
||||
uint32_t fence_flags, uint32_t fence_class, uint32_t type)
|
||||
{
|
||||
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];
|
||||
struct drm_device *dev = fence->dev;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_driver *driver = dev->driver->fence_driver;
|
||||
struct drm_fence_class_manager *fc = &fm->fence_class[fence->fence_class];
|
||||
unsigned long flags;
|
||||
uint32_t sequence;
|
||||
uint32_t native_type;
|
||||
int ret;
|
||||
|
||||
drm_fence_unring(dev, &fence->ring);
|
||||
ret = driver->emit(dev, class, fence_flags, &sequence, &native_type);
|
||||
ret = driver->emit(dev, fence_class, fence_flags, &sequence, &native_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
fence->class = class;
|
||||
fence->fence_class = fence_class;
|
||||
fence->type = type;
|
||||
fence->flush_mask = 0x00;
|
||||
fence->submitted_flush = 0x00;
|
||||
|
@ -416,15 +479,16 @@ int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
|
|||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_object_emit);
|
||||
|
||||
static int drm_fence_object_init(drm_device_t * dev, uint32_t class,
|
||||
static int drm_fence_object_init(struct drm_device * dev, uint32_t fence_class,
|
||||
uint32_t type,
|
||||
uint32_t fence_flags,
|
||||
drm_fence_object_t * fence)
|
||||
struct drm_fence_object * fence)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
atomic_set(&fence->usage, 1);
|
||||
|
@ -432,52 +496,60 @@ static int drm_fence_object_init(drm_device_t * dev, uint32_t class,
|
|||
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
INIT_LIST_HEAD(&fence->ring);
|
||||
fence->class = class;
|
||||
|
||||
/*
|
||||
* Avoid hitting BUG() for kernel-only fence objects.
|
||||
*/
|
||||
|
||||
INIT_LIST_HEAD(&fence->base.list);
|
||||
fence->fence_class = fence_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,
|
||||
fence->class, type);
|
||||
ret = drm_fence_object_emit(fence, fence_flags,
|
||||
fence->fence_class, type);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_fence_add_user_object(drm_file_t * priv, drm_fence_object_t * fence,
|
||||
int drm_fence_add_user_object(struct drm_file * priv, struct drm_fence_object * fence,
|
||||
int shareable)
|
||||
{
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
struct drm_device *dev = priv->head->dev;
|
||||
int 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,
|
||||
unsigned flags, drm_fence_object_t ** c_fence)
|
||||
int drm_fence_object_create(struct drm_device * dev, uint32_t fence_class, uint32_t type,
|
||||
unsigned flags, struct drm_fence_object ** c_fence)
|
||||
{
|
||||
drm_fence_object_t *fence;
|
||||
struct drm_fence_object *fence;
|
||||
int ret;
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
struct drm_fence_manager *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);
|
||||
ret = drm_fence_object_init(dev, fence_class, type, flags, fence);
|
||||
if (ret) {
|
||||
drm_fence_usage_deref_unlocked(dev, fence);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
return ret;
|
||||
}
|
||||
*c_fence = fence;
|
||||
|
@ -488,15 +560,16 @@ int drm_fence_object_create(drm_device_t * dev, uint32_t class, uint32_t type,
|
|||
|
||||
EXPORT_SYMBOL(drm_fence_object_create);
|
||||
|
||||
void drm_fence_manager_init(drm_device_t * dev)
|
||||
void drm_fence_manager_init(struct drm_device * dev)
|
||||
{
|
||||
drm_fence_manager_t *fm = &dev->fm;
|
||||
drm_fence_class_manager_t *class;
|
||||
drm_fence_driver_t *fed = dev->driver->fence_driver;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_class_manager *fence_class;
|
||||
struct drm_fence_driver *fed = dev->driver->fence_driver;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
rwlock_init(&fm->lock);
|
||||
write_lock(&fm->lock);
|
||||
write_lock_irqsave(&fm->lock, flags);
|
||||
fm->initialized = 0;
|
||||
if (!fed)
|
||||
goto out_unlock;
|
||||
|
@ -506,27 +579,45 @@ void drm_fence_manager_init(drm_device_t * dev)
|
|||
BUG_ON(fm->num_classes > _DRM_FENCE_CLASSES);
|
||||
|
||||
for (i=0; i<fm->num_classes; ++i) {
|
||||
class = &fm->class[i];
|
||||
fence_class = &fm->fence_class[i];
|
||||
|
||||
INIT_LIST_HEAD(&class->ring);
|
||||
class->pending_flush = 0;
|
||||
DRM_INIT_WAITQUEUE(&class->fence_queue);
|
||||
INIT_LIST_HEAD(&fence_class->ring);
|
||||
fence_class->pending_flush = 0;
|
||||
DRM_INIT_WAITQUEUE(&fence_class->fence_queue);
|
||||
}
|
||||
|
||||
atomic_set(&fm->count, 0);
|
||||
out_unlock:
|
||||
write_unlock(&fm->lock);
|
||||
write_unlock_irqrestore(&fm->lock, flags);
|
||||
}
|
||||
|
||||
void drm_fence_manager_takedown(drm_device_t * dev)
|
||||
void drm_fence_fill_arg(struct drm_fence_object *fence, struct drm_fence_arg *arg)
|
||||
{
|
||||
struct drm_device *dev = fence->dev;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
unsigned long irq_flags;
|
||||
|
||||
read_lock_irqsave(&fm->lock, irq_flags);
|
||||
arg->handle = fence->base.hash.key;
|
||||
arg->fence_class = fence->fence_class;
|
||||
arg->type = fence->type;
|
||||
arg->signaled = fence->signaled;
|
||||
arg->error = fence->error;
|
||||
arg->sequence = fence->sequence;
|
||||
read_unlock_irqrestore(&fm->lock, irq_flags);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fence_fill_arg);
|
||||
|
||||
|
||||
void drm_fence_manager_takedown(struct drm_device * dev)
|
||||
{
|
||||
}
|
||||
|
||||
drm_fence_object_t *drm_lookup_fence_object(drm_file_t * priv, uint32_t handle)
|
||||
struct drm_fence_object *drm_lookup_fence_object(struct drm_file * priv, uint32_t handle)
|
||||
{
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_user_object_t *uo;
|
||||
drm_fence_object_t *fence;
|
||||
struct drm_device *dev = priv->head->dev;
|
||||
struct drm_user_object *uo;
|
||||
struct drm_fence_object *fence;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
uo = drm_lookup_user_object(priv, handle);
|
||||
|
@ -534,21 +625,17 @@ drm_fence_object_t *drm_lookup_fence_object(drm_file_t * priv, uint32_t handle)
|
|||
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, struct drm_fence_object, base));
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return fence;
|
||||
}
|
||||
|
||||
int drm_fence_ioctl(DRM_IOCTL_ARGS)
|
||||
int drm_fence_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
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;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
|
@ -556,106 +643,209 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
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(dev, 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);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
if (arg->flags & DRM_FENCE_FLAG_EMIT)
|
||||
LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||
ret = drm_fence_object_create(dev, arg->fence_class,
|
||||
arg->type, arg->flags, &fence);
|
||||
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);
|
||||
ret = drm_fence_add_user_object(file_priv, fence,
|
||||
arg->flags &
|
||||
DRM_FENCE_FLAG_SHAREABLE);
|
||||
if (ret) {
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
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(dev, 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(dev, 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(dev, 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;
|
||||
atomic_inc(&fence->usage);
|
||||
arg.handle = fence->base.hash.key;
|
||||
break;
|
||||
default:
|
||||
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_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
|
||||
/*
|
||||
* usage > 0. No need to lock dev->struct_mutex;
|
||||
*/
|
||||
|
||||
arg->handle = fence->base.hash.key;
|
||||
|
||||
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_fence_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
struct drm_user_object *uo;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_user_object_ref(file_priv, arg->handle, drm_fence_type, &uo);
|
||||
if (ret)
|
||||
return ret;
|
||||
fence = drm_lookup_fence_object(file_priv, arg->handle);
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int drm_fence_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return drm_user_object_unref(file_priv, arg->handle, drm_fence_type);
|
||||
}
|
||||
|
||||
int drm_fence_signaled_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fence = drm_lookup_fence_object(file_priv, arg->handle);
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_fence_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fence = drm_lookup_fence_object(file_priv, arg->handle);
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
ret = drm_fence_object_flush(fence, arg->type);
|
||||
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int drm_fence_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fence = drm_lookup_fence_object(file_priv, arg->handle);
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
ret = drm_fence_object_wait(fence,
|
||||
arg->flags & DRM_FENCE_FLAG_WAIT_LAZY,
|
||||
0, arg->type);
|
||||
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int drm_fence_emit_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||
fence = drm_lookup_fence_object(file_priv, arg->handle);
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
ret = drm_fence_object_emit(fence, arg->flags, arg->fence_class,
|
||||
arg->type);
|
||||
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_fence_buffers_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_arg *arg = data;
|
||||
struct drm_fence_object *fence;
|
||||
ret = 0;
|
||||
|
||||
if (!fm->initialized) {
|
||||
DRM_ERROR("The DRM driver does not support fencing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!dev->bm.initialized) {
|
||||
DRM_ERROR("Buffer object manager is not initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||
ret = drm_fence_buffer_objects(dev, NULL, arg->flags,
|
||||
NULL, &fence);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(arg->flags & DRM_FENCE_FLAG_NO_USER)) {
|
||||
ret = drm_fence_add_user_object(file_priv, fence,
|
||||
arg->flags &
|
||||
DRM_FENCE_FLAG_SHAREABLE);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
arg->handle = fence->base.hash.key;
|
||||
|
||||
drm_fence_fill_arg(fence, arg);
|
||||
drm_fence_usage_deref_unlocked(&fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue