summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorJesse Barnes <jesse.barnes@intel.com>2007-10-30 12:52:46 -0700
committerJesse Barnes <jesse.barnes@intel.com>2007-10-30 12:52:46 -0700
commit91aae7e683786a48547872b0a5fa92b2232e02c0 (patch)
treea30c8022886d61add4a4c2e073fa07f29d7745a7 /linux-core
parent7e9ea55a2f052cc939ba9bbf9edac39798344b7a (diff)
parent79744d730c90019edd367eee4a8ec1fa22d53402 (diff)
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.
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/Makefile10
-rw-r--r--linux-core/Makefile.kernel17
-rw-r--r--linux-core/ati_pcigart.c8
-rw-r--r--linux-core/drmP.h626
-rw-r--r--linux-core/drm_agpsupport.c213
-rw-r--r--linux-core/drm_auth.c78
-rw-r--r--linux-core/drm_bo.c1356
-rw-r--r--linux-core/drm_bo_lock.c178
-rw-r--r--linux-core/drm_bo_move.c279
-rw-r--r--linux-core/drm_bufs.c334
-rw-r--r--linux-core/drm_compat.c83
-rw-r--r--linux-core/drm_compat.h18
-rw-r--r--linux-core/drm_context.c240
-rw-r--r--linux-core/drm_dma.c21
-rw-r--r--linux-core/drm_drawable.c130
-rw-r--r--linux-core/drm_drv.c290
-rw-r--r--linux-core/drm_fence.c650
-rw-r--r--linux-core/drm_fops.c73
-rw-r--r--linux-core/drm_hashtab.c34
-rw-r--r--linux-core/drm_hashtab.h24
-rw-r--r--linux-core/drm_ioc32.c91
-rw-r--r--linux-core/drm_ioctl.c213
-rw-r--r--linux-core/drm_irq.c140
-rw-r--r--linux-core/drm_lock.c86
-rw-r--r--linux-core/drm_memory.c20
-rw-r--r--linux-core/drm_memory_debug.c2
-rw-r--r--linux-core/drm_memory_debug.h2
-rw-r--r--linux-core/drm_mm.c66
-rw-r--r--linux-core/drm_object.c118
-rw-r--r--linux-core/drm_objects.h445
-rw-r--r--linux-core/drm_os_linux.h18
-rw-r--r--linux-core/drm_pci.c6
-rw-r--r--linux-core/drm_proc.c50
-rw-r--r--linux-core/drm_scatter.c55
-rw-r--r--linux-core/drm_sman.c92
-rw-r--r--linux-core/drm_sman.h50
-rw-r--r--linux-core/drm_stub.c56
-rw-r--r--linux-core/drm_sysfs.c225
-rw-r--r--linux-core/drm_ttm.c55
-rw-r--r--linux-core/drm_vm.c114
-rw-r--r--linux-core/ffb_context.c22
-rw-r--r--linux-core/ffb_drv.c8
-rw-r--r--linux-core/ffb_drv.h2
-rw-r--r--linux-core/i810_dma.c409
-rw-r--r--linux-core/i810_drm.h30
-rw-r--r--linux-core/i810_drv.h27
-rw-r--r--linux-core/i915_buffer.c93
-rw-r--r--linux-core/i915_drv.c466
-rw-r--r--linux-core/i915_fence.c29
-rw-r--r--linux-core/mga_drv.c4
l---------linux-core/nouveau_dma.c1
l---------linux-core/nouveau_dma.h1
-rw-r--r--linux-core/nouveau_drv.c13
l---------linux-core/nouveau_notifier.c1
-rw-r--r--linux-core/nouveau_sgdma.c339
l---------linux-core/nouveau_swmthd.c1
l---------linux-core/nouveau_swmthd.h1
l---------linux-core/nv04_fifo.c1
l---------linux-core/nv04_instmem.c1
l---------linux-core/nv10_fifo.c1
l---------linux-core/nv30_graph.c1
l---------linux-core/nv40_fifo.c1
l---------linux-core/nv50_fifo.c1
l---------linux-core/nv50_graph.c1
l---------linux-core/nv50_instmem.c1
l---------linux-core/nv50_mc.c1
-rw-r--r--linux-core/r128_drv.c7
-rw-r--r--linux-core/radeon_ioc32.c6
-rw-r--r--linux-core/sis_drv.c6
-rw-r--r--linux-core/sis_mm.c123
-rw-r--r--linux-core/via_buffer.c18
-rw-r--r--linux-core/via_dmablit.c76
-rw-r--r--linux-core/via_dmablit.h2
-rw-r--r--linux-core/via_fence.c21
-rw-r--r--linux-core/via_mm.c85
-rw-r--r--linux-core/xgi_cmdlist.c326
-rw-r--r--linux-core/xgi_cmdlist.h66
l---------linux-core/xgi_drm.h1
-rw-r--r--linux-core/xgi_drv.c431
-rw-r--r--linux-core/xgi_drv.h117
-rw-r--r--linux-core/xgi_fb.c130
-rw-r--r--linux-core/xgi_fence.c127
-rw-r--r--linux-core/xgi_ioc32.c140
-rw-r--r--linux-core/xgi_misc.c477
-rw-r--r--linux-core/xgi_misc.h37
-rw-r--r--linux-core/xgi_pcie.c126
-rw-r--r--linux-core/xgi_regs.h169
87 files changed, 7063 insertions, 3450 deletions
diff --git a/linux-core/Makefile b/linux-core/Makefile
index 1758777c..7f6b123e 100644
--- a/linux-core/Makefile
+++ b/linux-core/Makefile
@@ -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
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel
index 6f5b021b..79136431 100644
--- a/linux-core/Makefile.kernel
+++ b/linux-core/Makefile.kernel
@@ -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
diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c
index 524618a8..7241c2a8 100644
--- a/linux-core/ati_pcigart.c
+++ b/linux-core/ati_pcigart.c
@@ -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;
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 0ab69feb..332ee1cd 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -84,6 +84,8 @@
#include "drm_os_linux.h"
#include "drm_hashtab.h"
+struct drm_file;
+
/* If you want the memory alloc debug functionality, change define below */
/* #define DEBUG_MEMORY */
@@ -246,15 +248,15 @@
* Test that the hardware lock is held by the caller, returning otherwise.
*
* \param dev DRM device.
- * \param filp file pointer of the caller.
+ * \param file_priv DRM file private pointer of the caller.
*/
-#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, held %d owner %p %p\n",\
__FUNCTION__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\
- dev->lock.filp, filp ); \
+ dev->lock.file_priv, file_priv ); \
return -EINVAL; \
} \
} while (0)
@@ -271,16 +273,19 @@ do { \
return -EFAULT; \
}
+struct drm_device;
+struct drm_file;
+
/**
* Ioctl function type.
*
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg argument.
+ * \param dev DRM device structure
+ * \param data pointer to kernel-space stored data, copied in and out according
+ * to ioctl description.
+ * \param file_priv DRM file private pointer.
*/
-typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+typedef int drm_ioctl_t(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
@@ -289,31 +294,34 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
#define DRM_MASTER 0x2
#define DRM_ROOT_ONLY 0x4
-typedef struct drm_ioctl_desc {
+struct drm_ioctl_desc {
+ unsigned int cmd;
drm_ioctl_t *func;
int flags;
-} drm_ioctl_desc_t;
-
-typedef struct drm_devstate {
- pid_t owner; /**< X server pid holding x_lock */
-} drm_devstate_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 {
+struct drm_magic_entry {
struct list_head head;
- drm_hash_item_t hash_item;
+ struct drm_hash_item hash_item;
struct drm_file *priv;
-} drm_magic_entry_t;
+};
-typedef struct drm_vma_entry {
+struct drm_vma_entry {
struct list_head head;
struct vm_area_struct *vma;
pid_t pid;
-} drm_vma_entry_t;
+};
/**
* DMA buffer.
*/
-typedef struct drm_buf {
+struct drm_buf {
int idx; /**< Index into master buflist */
int total; /**< Buffer size */
int order; /**< log-base-2(total) */
@@ -325,7 +333,7 @@ typedef struct drm_buf {
__volatile__ int waiting; /**< On kernel DMA queue */
__volatile__ int pending; /**< On hardware DMA queue */
wait_queue_head_t dma_wait; /**< Processes waiting */
- struct file *filp; /**< Pointer to holding file descr */
+ struct drm_file *file_priv; /**< Private of holding file descr */
int context; /**< Kernel queue for this buffer */
int while_locked; /**< Dispatch this buffer while locked */
enum {
@@ -339,30 +347,30 @@ typedef struct drm_buf {
int dev_priv_size; /**< Size of buffer private storage */
void *dev_private; /**< Per-buffer private storage */
-} drm_buf_t;
+};
/** bufs is one longer than it has to be */
-typedef struct drm_waitlist {
+struct drm_waitlist {
int count; /**< Number of possible buffers */
- drm_buf_t **bufs; /**< List of pointers to buffers */
- drm_buf_t **rp; /**< Read pointer */
- drm_buf_t **wp; /**< Write pointer */
- drm_buf_t **end; /**< End pointer */
+ struct drm_buf **bufs; /**< List of pointers to buffers */
+ struct drm_buf **rp; /**< Read pointer */
+ struct drm_buf **wp; /**< Write pointer */
+ struct drm_buf **end; /**< End pointer */
spinlock_t read_lock;
spinlock_t write_lock;
-} drm_waitlist_t;
+};
-typedef struct drm_freelist {
+struct drm_freelist {
int initialized; /**< Freelist in use */
atomic_t count; /**< Number of free buffers */
- drm_buf_t *next; /**< End pointer */
+ struct drm_buf *next; /**< End pointer */
wait_queue_head_t waiting; /**< Processes waiting on free bufs */
int low_mark; /**< Low water mark */
int high_mark; /**< High water mark */
atomic_t wfh; /**< If waiting for high mark */
spinlock_t lock;
-} drm_freelist_t;
+};
typedef struct drm_dma_handle {
dma_addr_t busaddr;
@@ -373,15 +381,15 @@ typedef struct drm_dma_handle {
/**
* Buffer entry. There is one of this for each buffer size order.
*/
-typedef struct drm_buf_entry {
+struct drm_buf_entry {
int buf_size; /**< size */
int buf_count; /**< number of buffers */
- drm_buf_t *buflist; /**< buffer list */
+ struct drm_buf *buflist; /**< buffer list */
int seg_count;
int page_order;
- drm_dma_handle_t **seglist;
- drm_freelist_t freelist;
-} drm_buf_entry_t;
+ struct drm_dma_handle **seglist;
+ struct drm_freelist freelist;
+};
/*
* This should be small enough to allow the use of kmalloc for hash tables
@@ -389,15 +397,15 @@ typedef struct drm_buf_entry {
*/
#define DRM_FILE_HASH_ORDER 8
-typedef enum{
+enum drm_ref_type {
_DRM_REF_USE=0,
_DRM_REF_TYPE1,
_DRM_NO_REF_TYPES
-} drm_ref_t;
+};
/** File private data */
-typedef struct drm_file {
+struct drm_file {
int authenticated;
int master;
int minor;
@@ -418,14 +426,14 @@ typedef struct drm_file {
*/
struct list_head refd_objects;
- struct list_head user_objects;
- drm_open_hash_t refd_object_hash[_DRM_NO_REF_TYPES];
+ struct drm_open_hash refd_object_hash[_DRM_NO_REF_TYPES];
+ struct file *filp;
void *driver_priv;
-} drm_file_t;
+};
/** Wait queue */
-typedef struct drm_queue {
+struct drm_queue {
atomic_t use_count; /**< Outstanding uses (+1) */
atomic_t finalization; /**< Finalization in progress */
atomic_t block_count; /**< Count of processes waiting */
@@ -438,33 +446,34 @@ typedef struct drm_queue {
atomic_t total_flushed; /**< Total flushes statistic */
atomic_t total_locks; /**< Total locks statistics */
#endif
- drm_ctx_flags_t flags; /**< Context preserving and 2D-only */
- drm_waitlist_t waitlist; /**< Pending buffers */
+ enum drm_ctx_flags flags; /**< Context preserving and 2D-only */
+ struct drm_waitlist waitlist; /**< Pending buffers */
wait_queue_head_t flush_queue; /**< Processes waiting until flush */
-} drm_queue_t;
+};
/**
* Lock data.
*/
-typedef struct drm_lock_data {
- drm_hw_lock_t *hw_lock; /**< Hardware lock */
- struct file *filp; /**< File descr of lock holder (0=kernel) */
+struct drm_lock_data {
+ struct drm_hw_lock *hw_lock; /**< Hardware lock */
+ /** Private of lock holder's file (NULL=kernel) */
+ struct drm_file *file_priv;
wait_queue_head_t lock_queue; /**< Queue of blocked processes */
unsigned long lock_time; /**< Time of last lock in jiffies */
spinlock_t spinlock;
uint32_t kernel_waiters;
uint32_t user_waiters;
int idle_has_lock;
-} drm_lock_data_t;
+};
/**
* DMA data.
*/
-typedef struct drm_device_dma {
+struct drm_device_dma {
- drm_buf_entry_t bufs[DRM_MAX_ORDER + 1]; /**< buffers, grouped by their size order */
+ struct drm_buf_entry bufs[DRM_MAX_ORDER + 1]; /**< buffers, grouped by their size order */
int buf_count; /**< total number of buffers */
- drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */
+ struct drm_buf **buflist; /**< Vector of pointers into drm_device_dma::bufs */
int seg_count;
int page_count; /**< number of pages */
unsigned long *pagelist; /**< page list */
@@ -476,25 +485,25 @@ typedef struct drm_device_dma {
_DRM_DMA_USE_PCI_RO = 0x08
} flags;
-} drm_device_dma_t;
+};
/**
* AGP memory entry. Stored as a doubly linked list.
*/
-typedef struct drm_agp_mem {
+struct drm_agp_mem {
unsigned long handle; /**< handle */
DRM_AGP_MEM *memory;
unsigned long bound; /**< address */
int pages;
struct list_head head;
-} drm_agp_mem_t;
+};
/**
* AGP data.
*
* \sa drm_agp_init)() and drm_device::agp.
*/
-typedef struct drm_agp_head {
+struct drm_agp_head {
DRM_AGP_KERN agp_info; /**< AGP device information */
struct list_head memory;
unsigned long mode; /**< AGP mode */
@@ -507,30 +516,30 @@ typedef struct drm_agp_head {
int agp_mtrr;
int cant_use_aperture;
unsigned long page_mask;
-} drm_agp_head_t;
+};
/**
* Scatter-gather memory.
*/
-typedef struct drm_sg_mem {
+struct drm_sg_mem {
unsigned long handle;
void *virtual;
int pages;
struct page **pagelist;
dma_addr_t *busaddr;
-} drm_sg_mem_t;
+};
-typedef struct drm_sigdata {
+struct drm_sigdata {
int context;
- drm_hw_lock_t *lock;
-} drm_sigdata_t;
+ struct drm_hw_lock *lock;
+};
/*
* Generic memory manager structs
*/
-typedef struct drm_mm_node {
+struct drm_mm_node {
struct list_head fl_entry;
struct list_head ml_entry;
int free;
@@ -538,46 +547,51 @@ typedef struct drm_mm_node {
unsigned long size;
struct drm_mm *mm;
void *private;
-} drm_mm_node_t;
+};
-typedef struct drm_mm {
+struct drm_mm {
struct list_head fl_entry;
struct list_head ml_entry;
-} drm_mm_t;
+};
/**
* Mappings list
*/
-typedef struct drm_map_list {
+struct drm_map_list {
struct list_head head; /**< list head */
- drm_hash_item_t hash;
- drm_map_t *map; /**< mapping */
- drm_u64_t user_token;
- drm_mm_node_t *file_offset_node;
-} drm_map_list_t;
+ struct drm_hash_item hash;
+ struct drm_map *map; /**< mapping */
+ uint64_t user_token;
+ struct drm_mm_node *file_offset_node;
+};
-typedef drm_map_t drm_local_map_t;
+typedef struct drm_map drm_local_map_t;
/**
* Context handle list
*/
-typedef struct drm_ctx_list {
+struct drm_ctx_list {
struct list_head head; /**< list head */
drm_context_t handle; /**< context handle */
- drm_file_t *tag; /**< associated fd private data */
-} drm_ctx_list_t;
-
-struct drm_ctx_sarea_list {
- drm_map_t *map;
+ struct drm_file *tag; /**< associated fd private data */
};
-typedef struct drm_vbl_sig {
+struct drm_vbl_sig {
struct list_head head;
unsigned int sequence;
struct siginfo info;
struct task_struct *task;
-} drm_vbl_sig_t;
+};
+
+/**
+ * Drawable information.
+ */
+struct drm_drawable_info {
+ unsigned int num_rects;
+ struct drm_clip_rect *rects;
+};
+
/* location of GART table */
#define DRM_ATI_GART_MAIN 1
@@ -587,17 +601,13 @@ typedef struct drm_vbl_sig {
#define DRM_ATI_GART_PCIE 2
#define DRM_ATI_GART_IGP 3
-typedef struct ati_pcigart_info {
+struct ati_pcigart_info {
int gart_table_location;
int gart_reg_if;
void *addr;
dma_addr_t bus_addr;
drm_local_map_t mapping;
int table_size;
-} drm_ati_pcigart_info;
-
-struct drm_drawable_list {
- drm_drawable_info_t info;
};
#include "drm_objects.h"
@@ -608,16 +618,17 @@ struct drm_drawable_list {
* in this family
*/
-struct drm_device;
struct drm_driver {
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 *, struct file * filp);
- void (*postclose) (struct drm_device *, drm_file_t *);
+ int (*open) (struct drm_device *, struct drm_file *);
+ void (*preclose) (struct drm_device *, struct drm_file *file_priv);
+ void (*postclose) (struct drm_device *, struct drm_file *);
void (*lastclose) (struct drm_device *);
int (*unload) (struct drm_device *);
- int (*dma_ioctl) (DRM_IOCTL_ARGS);
+ int (*suspend) (struct drm_device *);
+ int (*resume) (struct drm_device *);
+ int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
void (*dma_ready) (struct drm_device *);
int (*dma_quiescent) (struct drm_device *);
int (*context_ctor) (struct drm_device * dev, int context);
@@ -689,14 +700,15 @@ struct drm_driver {
void (*irq_preinstall) (struct drm_device * dev);
int (*irq_postinstall) (struct drm_device * dev);
void (*irq_uninstall) (struct drm_device * dev);
- void (*reclaim_buffers) (struct drm_device *dev, struct file * filp);
+ void (*reclaim_buffers) (struct drm_device *dev,
+ struct drm_file *file_priv);
void (*reclaim_buffers_locked) (struct drm_device *dev,
- struct file * filp);
+ struct drm_file *file_priv);
void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
- struct file * filp);
- unsigned long (*get_map_ofs) (drm_map_t * map);
+ struct drm_file *file_priv);
+ unsigned long (*get_map_ofs) (struct drm_map * map);
unsigned long (*get_reg_ofs) (struct drm_device * dev);
- void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
+ void (*set_version) (struct drm_device * dev, struct drm_set_version * sv);
struct drm_fence_driver *fence_driver;
struct drm_bo_driver *bo_driver;
@@ -711,7 +723,7 @@ struct drm_driver {
/* variables */
u32 driver_features;
int dev_priv_size;
- drm_ioctl_desc_t *ioctls;
+ struct drm_ioctl_desc *ioctls;
int num_ioctls;
struct file_operations fops;
struct pci_driver pci_driver;
@@ -722,20 +734,21 @@ struct drm_driver {
* that may contain multiple heads. Embed one per head of these in the
* private drm_device structure.
*/
-typedef struct drm_head {
+struct drm_head {
int minor; /**< Minor device number */
struct drm_device *dev;
struct proc_dir_entry *dev_root; /**< proc directory entry */
dev_t device; /**< Device number for mknod */
struct class_device *dev_class;
-} drm_head_t;
+};
/**
* DRM device structure. This structure represent a complete card that
* may contain multiple heads.
*/
-typedef struct drm_device {
+struct drm_device {
+ struct device dev; /**< Linux device */
char *unique; /**< Unique identifier: e.g., busid */
int unique_len; /**< Length of unique field */
char *devname; /**< For /proc/interrupts */
@@ -761,14 +774,14 @@ typedef struct drm_device {
/** \name Performance counters */
/*@{ */
unsigned long counters;
- drm_stat_type_t types[15];
+ enum drm_stat_type types[15];
atomic_t counts[15];
/*@} */
/** \name Authentication */
/*@{ */
struct list_head filelist;
- drm_open_hash_t magiclist;
+ struct drm_open_hash magiclist;
struct list_head magicfree;
/*@} */
@@ -776,9 +789,9 @@ typedef struct drm_device {
/*@{ */
struct list_head maplist; /**< Linked list of regions */
int map_count; /**< Number of mappable regions */
- drm_open_hash_t map_hash; /**< User token hash table for maps */
- drm_mm_t offset_manager; /**< User token manager */
- drm_open_hash_t object_hash; /**< User token hash table for objects */
+ struct drm_open_hash map_hash; /**< User token hash table for maps */
+ struct drm_mm offset_manager; /**< User token manager */
+ struct drm_open_hash object_hash; /**< User token hash table for objects */
struct address_space *dev_mapping; /**< For unmap_mapping_range() */
struct page *ttm_dummy_page;
@@ -791,7 +804,7 @@ typedef struct drm_device {
struct idr ctx_idr;
struct list_head vmalist; /**< List of vmas (for debugging) */
- drm_lock_data_t lock; /**< Information on hardware lock */
+ struct drm_lock_data lock; /**< Information on hardware lock */
/*@} */
/** \name DMA queues (contexts) */
@@ -799,8 +812,8 @@ typedef struct drm_device {
int queue_count; /**< Number of active DMA queues */
int queue_reserved; /**< Number of reserved DMA queues */
int queue_slots; /**< Actual length of queuelist */
- drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */
- drm_device_dma_t *dma; /**< Optional pointer for DMA support */
+ struct drm_queue **queuelist; /**< Vector of pointers to DMA queues */
+ struct drm_device_dma *dma; /**< Optional pointer for DMA support */
/*@} */
/** \name Context support */
@@ -846,7 +859,7 @@ typedef struct drm_device {
wait_queue_head_t buf_readers; /**< Processes waiting to read */
wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
- drm_agp_head_t *agp; /**< AGP data */
+ struct drm_agp_head *agp; /**< AGP data */
struct pci_dev *pdev; /**< PCI device structure */
int pci_vendor; /**< PCI vendor id */
@@ -855,33 +868,33 @@ typedef struct drm_device {
struct pci_controller *hose;
#endif
int num_crtcs; /**< Number of CRTCs on this device */
- drm_sg_mem_t *sg; /**< Scatter gather memory */
+ struct drm_sg_mem *sg; /**< Scatter gather memory */
void *dev_private; /**< device private data */
- drm_sigdata_t sigdata; /**< For block_all_signals */
+ struct drm_sigdata sigdata; /**< For block_all_signals */
sigset_t sigmask;
struct drm_driver *driver;
drm_local_map_t *agp_buffer_map;
unsigned int agp_buffer_token;
- drm_head_t primary; /**< primary screen head */
+ struct drm_head primary; /**< primary screen head */
- drm_fence_manager_t fm;
- drm_buffer_manager_t bm;
+ struct drm_fence_manager fm;
+ struct drm_buffer_manager bm;
/** \name Drawable information */
/*@{ */
spinlock_t drw_lock;
struct idr drw_idr;
/*@} */
-} drm_device_t;
+};
#if __OS_HAS_AGP
-typedef struct drm_agp_ttm_backend {
- drm_ttm_backend_t backend;
+struct drm_agp_ttm_backend {
+ struct drm_ttm_backend backend;
DRM_AGP_MEM *mem;
struct agp_bridge_data *bridge;
int populated;
-} drm_agp_ttm_backend_t;
+};
#endif
@@ -956,10 +969,12 @@ extern void drm_exit(struct drm_driver *driver);
extern void drm_cleanup_pci(struct pci_dev *pdev);
extern int drm_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern long drm_unlocked_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg);
extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_lastclose(drm_device_t * dev);
+extern int drm_lastclose(struct drm_device *dev);
/* Device support (drm_fops.h) */
extern int drm_open(struct inode *inode, struct file *filp);
@@ -970,7 +985,7 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
/* Mapping support (drm_vm.h) */
extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
-extern unsigned long drm_core_get_map_ofs(drm_map_t * map);
+extern unsigned long drm_core_get_map_ofs(struct drm_map * map);
extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
extern pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma);
@@ -983,183 +998,187 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
extern unsigned long drm_alloc_pages(int order, int area);
extern void drm_free_pages(unsigned long address, int order, int area);
-extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type);
+extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
extern int drm_unbind_agp(DRM_AGP_MEM * handle);
extern void drm_free_memctl(size_t size);
extern int drm_alloc_memctl(size_t size);
-extern void drm_query_memctl(drm_u64_t *cur_used,
- drm_u64_t *low_threshold,
- drm_u64_t *high_threshold);
+extern void drm_query_memctl(uint64_t *cur_used,
+ uint64_t *low_threshold,
+ uint64_t *high_threshold);
extern void drm_init_memctl(size_t low_threshold,
size_t high_threshold,
size_t unit_size);
/* Misc. IOCTL support (drm_ioctl.h) */
-extern int drm_irq_by_busid(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_setunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getmap(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getclient(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getstats(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_setversion(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_noop(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_irq_by_busid(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_getunique(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_setunique(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_getmap(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_getclient(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_getstats(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_setversion(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_noop(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* Context IOCTL support (drm_context.h) */
-extern int drm_resctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_addctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_modctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_switchctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_newctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_rmctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
-extern int drm_ctxbitmap_init(drm_device_t * dev);
-extern void drm_ctxbitmap_cleanup(drm_device_t * dev);
-extern void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle);
-
-extern int drm_setsareactx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_getsareactx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_resctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_addctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_modctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_getctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_switchctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_newctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_rmctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+extern int drm_ctxbitmap_init(struct drm_device *dev);
+extern void drm_ctxbitmap_cleanup(struct drm_device *dev);
+extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
+
+extern int drm_setsareactx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_getsareactx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* Drawable IOCTL support (drm_drawable.h) */
-extern int drm_adddraw(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_rmdraw(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_update_drawable_info(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev,
- drm_drawable_t id);
-extern void drm_drawable_free_all(drm_device_t *dev);
+extern int drm_adddraw(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_rmdraw(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_update_drawable_info(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev,
+ drm_drawable_t id);
+extern void drm_drawable_free_all(struct drm_device *dev);
/* Authentication IOCTL support (drm_auth.h) */
-extern int drm_getmagic(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_authmagic(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_getmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_authmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* Locking IOCTL support (drm_lock.h) */
-extern int drm_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_unlock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context);
-extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context);
-extern void drm_idlelock_take(drm_lock_data_t *lock_data);
-extern void drm_idlelock_release(drm_lock_data_t *lock_data);
+extern int drm_lock(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_unlock(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context);
+extern int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context);
+extern void drm_idlelock_take(struct drm_lock_data *lock_data);
+extern void drm_idlelock_release(struct drm_lock_data *lock_data);
/*
* These are exported to drivers so that they can implement fencing using
* DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
*/
-extern int drm_i_have_hw_lock(struct file *filp);
-extern int drm_kernel_take_hw_lock(struct file *filp);
+extern int drm_i_have_hw_lock(struct drm_device *dev,
+ struct drm_file *file_priv);
/* Buffer management support (drm_bufs.h) */
-extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
-extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
-extern int drm_addbufs_fb (drm_device_t * dev, drm_buf_desc_t * request);
-extern 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);
-extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
-extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
-extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_addbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_infobufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_markbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_freebufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_mapbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request);
+extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request);
+extern int drm_addbufs_fb (struct drm_device *dev, struct drm_buf_desc * request);
+extern 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);
+extern int drm_addmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_rmmap(struct drm_device *dev, drm_local_map_t *map);
+extern int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map);
+extern int drm_rmmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_addbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_infobufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_markbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_freebufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_mapbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
extern int drm_order(unsigned long size);
-extern unsigned long drm_get_resource_start(drm_device_t *dev,
+extern unsigned long drm_get_resource_start(struct drm_device *dev,
unsigned int resource);
-extern unsigned long drm_get_resource_len(drm_device_t *dev,
+extern unsigned long drm_get_resource_len(struct drm_device *dev,
unsigned int resource);
+extern struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
+ drm_local_map_t *map);
+
/* DMA support (drm_dma.h) */
-extern int drm_dma_setup(drm_device_t * dev);
-extern void drm_dma_takedown(drm_device_t * dev);
-extern void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf);
-extern void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
+extern int drm_dma_setup(struct drm_device *dev);
+extern void drm_dma_takedown(struct drm_device *dev);
+extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf);
+extern void drm_core_reclaim_buffers(struct drm_device *dev,
+ struct drm_file *filp);
/* IRQ support (drm_irq.h) */
-extern int drm_control(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_control(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
-extern int drm_irq_uninstall(drm_device_t *dev);
-extern void drm_driver_irq_preinstall(drm_device_t * dev);
-extern void drm_driver_irq_postinstall(drm_device_t * dev);
-extern void drm_driver_irq_uninstall(drm_device_t * dev);
-
-extern int drm_vblank_init(drm_device_t *dev, int num_crtcs);
-extern int drm_wait_vblank(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
-extern void drm_locked_tasklet(drm_device_t *dev, void(*func)(drm_device_t*));
-extern u32 drm_vblank_count(drm_device_t *dev, int crtc);
-extern void drm_update_vblank_count(drm_device_t *dev, int crtc);
-extern void drm_handle_vblank(drm_device_t *dev, int crtc);
-extern int drm_vblank_get(drm_device_t *dev, int crtc);
-extern void drm_vblank_put(drm_device_t *dev, int crtc);
+extern int drm_irq_install(struct drm_device *dev);
+extern int drm_irq_uninstall(struct drm_device *dev);
+extern void drm_driver_irq_preinstall(struct drm_device *dev);
+extern void drm_driver_irq_postinstall(struct drm_device *dev);
+extern void drm_driver_irq_uninstall(struct drm_device *dev);
+
+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
+extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp);
+extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq);
+extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
+extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
+extern void drm_update_vblank_count(struct drm_device *dev, int crtc);
+extern void drm_handle_vblank(struct drm_device *dev, int crtc);
+extern int drm_vblank_get(struct drm_device *dev, int crtc);
+extern void drm_vblank_put(struct drm_device *dev, int crtc);
/* Modesetting support */
-extern int drm_modeset_ctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int drm_modeset_ctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
-extern int drm_agp_acquire(drm_device_t * dev);
-extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_release(drm_device_t *dev);
-extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
-extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
-extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
-extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
-extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
-extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
-extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
+extern int drm_agp_acquire(struct drm_device *dev);
+extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_release(struct drm_device *dev);
+extern int drm_agp_release_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode);
+extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info);
+extern int drm_agp_info_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request);
+extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request);
+extern int drm_agp_free_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request);
+extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request);
+extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)
extern DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type);
#else
@@ -1168,22 +1187,22 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
-extern drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev);
+extern struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev);
/* Stub support (drm_stub.h) */
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
struct drm_driver *driver);
-extern int drm_put_dev(drm_device_t * dev);
-extern int drm_put_head(drm_head_t * head);
+extern int drm_put_dev(struct drm_device *dev);
+extern int drm_put_head(struct drm_head * head);
extern unsigned int drm_debug; /* 1 to enable debug output */
extern unsigned int drm_cards_limit;
-extern drm_head_t **drm_heads;
-extern struct drm_sysfs_class *drm_class;
+extern struct drm_head **drm_heads;
+extern struct class *drm_class;
extern struct proc_dir_entry *drm_proc_root;
extern drm_local_map_t *drm_getsarea(struct drm_device *dev);
/* Proc support (drm_proc.h) */
-extern int drm_proc_init(drm_device_t * dev,
+extern int drm_proc_init(struct drm_device *dev,
int minor,
struct proc_dir_entry *root,
struct proc_dir_entry **dev_root);
@@ -1192,47 +1211,46 @@ extern int drm_proc_cleanup(int minor,
struct proc_dir_entry *dev_root);
/* Scatter Gather Support (drm_scatter.h) */
-extern void drm_sg_cleanup(drm_sg_mem_t * entry);
-extern int drm_sg_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_sg_free(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern void drm_sg_cleanup(struct drm_sg_mem * entry);
+extern int drm_sg_alloc_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request);
+extern int drm_sg_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* ATI PCIGART support (ati_pcigart.h) */
-extern int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info *gart_info);
-extern int drm_ati_pcigart_cleanup(drm_device_t * dev, drm_ati_pcigart_info *gart_info);
+extern int drm_ati_pcigart_init(struct drm_device *dev, struct ati_pcigart_info *gart_info);
+extern int drm_ati_pcigart_cleanup(struct drm_device *dev, struct ati_pcigart_info *gart_info);
-extern drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size,
+extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size,
size_t align, dma_addr_t maxaddr);
-extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah);
-extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah);
+extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah);
+extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah);
/* sysfs support (drm_sysfs.c) */
struct drm_sysfs_class;
-extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
- char *name);
-extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
-extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
- drm_head_t * head);
-extern void drm_sysfs_device_remove(struct class_device *class_dev);
+extern struct class *drm_sysfs_create(struct module *owner, char *name);
+extern void drm_sysfs_destroy(void);
+extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head * head);
+extern void drm_sysfs_device_remove(struct drm_device *dev);
/*
* Basic memory manager support (drm_mm.c)
*/
-extern drm_mm_node_t * drm_mm_get_block(drm_mm_node_t * parent, unsigned long size,
+extern struct drm_mm_node * drm_mm_get_block(struct drm_mm_node * parent, unsigned long size,
unsigned alignment);
-extern void drm_mm_put_block(drm_mm_node_t *cur);
-extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size,
+extern void drm_mm_put_block(struct drm_mm_node *cur);
+extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size,
unsigned alignment, int best_match);
-extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size);
-extern void drm_mm_takedown(drm_mm_t *mm);
-extern int drm_mm_clean(drm_mm_t *mm);
-extern unsigned long drm_mm_tail_space(drm_mm_t *mm);
-extern int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size);
-extern int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size);
-
-static inline drm_mm_t *drm_get_mm(drm_mm_node_t *block)
+extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size);
+extern void drm_mm_takedown(struct drm_mm *mm);
+extern int drm_mm_clean(struct drm_mm *mm);
+extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
+extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
+extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
+
+static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
{
return block->mm;
}
@@ -1243,14 +1261,14 @@ extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
unsigned int token)
{
- drm_map_list_t *_entry;
+ struct drm_map_list *_entry;
list_for_each_entry(_entry, &dev->maplist, head)
if (_entry->user_token == token)
return _entry->map;
return NULL;
}
-static __inline__ int drm_device_is_agp(drm_device_t *dev)
+static __inline__ int drm_device_is_agp(struct drm_device *dev)
{
if ( dev->driver->device_is_agp != NULL ) {
int err = (*dev->driver->device_is_agp)( dev );
@@ -1263,7 +1281,7 @@ static __inline__ int drm_device_is_agp(drm_device_t *dev)
return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
}
-static __inline__ int drm_device_is_pcie(drm_device_t *dev)
+static __inline__ int drm_device_is_pcie(struct drm_device *dev)
{
return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
}
@@ -1324,5 +1342,19 @@ static inline void drm_ctl_free(void *pt, size_t size, int area)
/*@}*/
+/** Type for the OS's non-sleepable mutex lock */
+#define DRM_SPINTYPE spinlock_t
+/**
+ * Initialize the lock for use. name is an optional string describing the
+ * lock
+ */
+#define DRM_SPININIT(l,name) spin_lock_init(l)
+#define DRM_SPINUNINIT(l)
+#define DRM_SPINLOCK(l) spin_lock(l)
+#define DRM_SPINUNLOCK(l) spin_unlock(l)
+#define DRM_SPINLOCK_IRQSAVE(l, _flags) spin_lock_irqsave(l, _flags);
+#define DRM_SPINUNLOCK_IRQRESTORE(l, _flags) spin_unlock_irqrestore(l, _flags);
+#define DRM_SPINLOCK_ASSERT(l) do {} while (0)
+
#endif /* __KERNEL__ */
#endif
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c
index f134563a..b68efc64 100644
--- a/linux-core/drm_agpsupport.c
+++ b/linux-core/drm_agpsupport.c
@@ -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;
-
- if (copy_from_user(&request, argp, sizeof(request)))
- return -EFAULT;
+ struct drm_agp_buffer *request = data;
- 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;
-
- if (copy_from_user
- (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
- return -EFAULT;
+ struct drm_agp_binding *request = data;
- 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;
-
- if (copy_from_user
- (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
- return -EFAULT;
+ struct drm_agp_buffer *request = data;
- 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;
}
diff --git a/linux-core/drm_auth.c b/linux-core/drm_auth.c
index 6948d858..e35e8b6d 100644
--- a/linux-core/drm_auth.c
+++ b/linux-core/drm_auth.c
@@ -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);
+ mutex_lock(&dev->struct_mutex);
+ 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;
-
- 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))) {
+ struct drm_auth *auth = data;
+ struct drm_file *file;
+
+ 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;
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 1c7013b3..16203c77 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -49,31 +49,36 @@
*
*/
-static void drm_bo_destroy_locked(drm_buffer_object_t * bo);
-static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo);
-static void drm_bo_takedown_vm_locked(drm_buffer_object_t * bo);
-static void drm_bo_unmap_virtual(drm_buffer_object_t * bo);
+static void drm_bo_destroy_locked(struct drm_buffer_object * bo);
+static int drm_bo_setup_vm_locked(struct drm_buffer_object * bo);
+static void drm_bo_takedown_vm_locked(struct drm_buffer_object * bo);
+static void drm_bo_unmap_virtual(struct drm_buffer_object * bo);
-static inline uint32_t drm_bo_type_flags(unsigned type)
+static inline uint64_t drm_bo_type_flags(unsigned type)
{
- return (1 << (24 + type));
+ return (1ULL << (24 + type));
}
/*
* bo locked. dev->struct_mutex locked.
*/
-void drm_bo_add_to_pinned_lru(drm_buffer_object_t * bo)
+void drm_bo_add_to_pinned_lru(struct drm_buffer_object * bo)
{
- drm_mem_type_manager_t *man;
+ struct drm_mem_type_manager *man;
+
+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
+ DRM_ASSERT_LOCKED(&bo->mutex);
man = &bo->dev->bm.man[bo->pinned_mem_type];
list_add_tail(&bo->pinned_lru, &man->pinned);
}
-void drm_bo_add_to_lru(drm_buffer_object_t * bo)
+void drm_bo_add_to_lru(struct drm_buffer_object * bo)
{
- drm_mem_type_manager_t *man;
+ struct drm_mem_type_manager *man;
+
+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))
|| bo->mem.mem_type != bo->pinned_mem_type) {
@@ -84,7 +89,7 @@ void drm_bo_add_to_lru(drm_buffer_object_t * bo)
}
}
-static int drm_bo_vm_pre_move(drm_buffer_object_t * bo, int old_is_pci)
+static int drm_bo_vm_pre_move(struct drm_buffer_object * bo, int old_is_pci)
{
#ifdef DRM_ODD_MM_COMPAT
int ret;
@@ -107,7 +112,7 @@ static int drm_bo_vm_pre_move(drm_buffer_object_t * bo, int old_is_pci)
return 0;
}
-static void drm_bo_vm_post_move(drm_buffer_object_t * bo)
+static void drm_bo_vm_post_move(struct drm_buffer_object * bo)
{
#ifdef DRM_ODD_MM_COMPAT
int ret;
@@ -128,25 +133,22 @@ static void drm_bo_vm_post_move(drm_buffer_object_t * bo)
* Call bo->mutex locked.
*/
-static int drm_bo_add_ttm(drm_buffer_object_t * bo)
+static int drm_bo_add_ttm(struct drm_buffer_object * bo)
{
- drm_device_t *dev = bo->dev;
+ struct drm_device *dev = bo->dev;
int ret = 0;
bo->ttm = NULL;
+ DRM_ASSERT_LOCKED(&bo->mutex);
+
switch (bo->type) {
case drm_bo_type_dc:
- bo->ttm = drm_ttm_init(dev, bo->mem.num_pages << PAGE_SHIFT);
- if (!bo->ttm)
- ret = -ENOMEM;
- break;
case drm_bo_type_kernel:
- bo->ttm = drm_ttm_init(dev, bo->mem.num_pages << PAGE_SHIFT);
+ bo->ttm = drm_ttm_init(dev, bo->num_pages << PAGE_SHIFT);
if (!bo->ttm)
ret = -ENOMEM;
break;
case drm_bo_type_user:
- case drm_bo_type_fake:
break;
default:
DRM_ERROR("Illegal buffer object type\n");
@@ -157,19 +159,20 @@ static int drm_bo_add_ttm(drm_buffer_object_t * bo)
return ret;
}
-static int drm_bo_handle_move_mem(drm_buffer_object_t * bo,
- drm_bo_mem_reg_t * mem,
+static int drm_bo_handle_move_mem(struct drm_buffer_object * bo,
+ struct drm_bo_mem_reg * mem,
int evict, int no_wait)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
int old_is_pci = drm_mem_reg_is_pci(dev, &bo->mem);
int new_is_pci = drm_mem_reg_is_pci(dev, mem);
- drm_mem_type_manager_t *old_man = &bm->man[bo->mem.mem_type];
- drm_mem_type_manager_t *new_man = &bm->man[mem->mem_type];
+ struct drm_mem_type_manager *old_man = &bm->man[bo->mem.mem_type];
+ struct drm_mem_type_manager *new_man = &bm->man[mem->mem_type];
int ret = 0;
- if (old_is_pci || new_is_pci)
+ if (old_is_pci || new_is_pci ||
+ ((mem->flags ^ bo->mem.flags) & DRM_BO_FLAG_CACHED))
ret = drm_bo_vm_pre_move(bo, old_is_pci);
if (ret)
return ret;
@@ -184,9 +187,7 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t * bo,
goto out_err;
if (mem->mem_type != DRM_BO_MEM_LOCAL) {
- ret = drm_bind_ttm(bo->ttm, new_man->flags &
- DRM_BO_FLAG_CACHED,
- mem->mm_node->start);
+ ret = drm_bind_ttm(bo->ttm, mem);
if (ret)
goto out_err;
}
@@ -194,9 +195,9 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t * bo,
if ((bo->mem.mem_type == DRM_BO_MEM_LOCAL) && bo->ttm == NULL) {
- drm_bo_mem_reg_t *old_mem = &bo->mem;
- uint32_t save_flags = old_mem->flags;
- uint32_t save_mask = old_mem->mask;
+ struct drm_bo_mem_reg *old_mem = &bo->mem;
+ uint64_t save_flags = old_mem->flags;
+ uint64_t save_mask = old_mem->mask;
*old_mem = *mem;
mem->mm_node = NULL;
@@ -236,7 +237,9 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t * bo,
_DRM_BO_FLAG_EVICTED);
if (bo->mem.mm_node)
- bo->offset = bo->mem.mm_node->start << PAGE_SHIFT;
+ bo->offset = (bo->mem.mm_node->start << PAGE_SHIFT) +
+ bm->man[bo->mem.mem_type].gpu_offset;
+
return 0;
@@ -259,40 +262,37 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t * bo,
* Wait until the buffer is idle.
*/
-int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
+int drm_bo_wait(struct drm_buffer_object * bo, int lazy, int ignore_signals,
int no_wait)
{
-
- drm_fence_object_t *fence = bo->fence;
int ret;
- if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ DRM_ASSERT_LOCKED(&bo->mutex);
+
+ if (bo->fence) {
+ if (drm_fence_object_signaled(bo->fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
if (no_wait) {
return -EBUSY;
}
ret =
- drm_fence_object_wait(dev, fence, lazy, ignore_signals,
+ drm_fence_object_wait(bo->fence, lazy, ignore_signals,
bo->fence_type);
if (ret)
return ret;
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
-
+ drm_fence_usage_deref_unlocked(&bo->fence);
}
return 0;
}
+EXPORT_SYMBOL(drm_bo_wait);
-static int drm_bo_expire_fence(drm_buffer_object_t * bo, int allow_errors)
+static int drm_bo_expire_fence(struct drm_buffer_object * bo, int allow_errors)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
if (bo->fence) {
if (bm->nice_mode) {
@@ -312,10 +312,8 @@ static int drm_bo_expire_fence(drm_buffer_object_t * bo, int allow_errors)
"Evicting buffer.\n");
}
}
- if (bo->fence) {
- drm_fence_usage_deref_unlocked(dev, bo->fence);
- bo->fence = NULL;
- }
+ if (bo->fence)
+ drm_fence_usage_deref_unlocked(&bo->fence);
}
return 0;
}
@@ -326,10 +324,12 @@ static int drm_bo_expire_fence(drm_buffer_object_t * bo, int allow_errors)
* fence object and removing from lru lists and memory managers.
*/
-static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all)
+static void drm_bo_cleanup_refs(struct drm_buffer_object * bo, int remove_all)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
+
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
atomic_inc(&bo->usage);
mutex_unlock(&dev->struct_mutex);
@@ -337,10 +337,9 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all)
DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
- if (bo->fence && drm_fence_object_signaled(bo->fence, bo->fence_type)) {
- drm_fence_usage_deref_locked(dev, bo->fence);
- bo->fence = NULL;
- }
+ if (bo->fence && drm_fence_object_signaled(bo->fence,
+ bo->fence_type, 0))
+ drm_fence_usage_deref_unlocked(&bo->fence);
if (bo->fence && remove_all)
(void)drm_bo_expire_fence(bo, 0);
@@ -371,7 +370,7 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all)
}
if (list_empty(&bo->ddestroy)) {
- drm_fence_object_flush(dev, bo->fence, bo->fence_type);
+ drm_fence_object_flush(bo->fence, bo->fence_type);
list_add_tail(&bo->ddestroy, &bm->ddestroy);
schedule_delayed_work(&bm->wq,
((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
@@ -387,10 +386,12 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all)
* to the buffer object. Then destroy it.
*/
-static void drm_bo_destroy_locked(drm_buffer_object_t * bo)
+static void drm_bo_destroy_locked(struct drm_buffer_object * bo)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
+
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
if (list_empty(&bo->lru) && bo->mem.mm_node == NULL &&
list_empty(&bo->pinned_lru) && bo->pinned_node == NULL &&
@@ -414,6 +415,7 @@ static void drm_bo_destroy_locked(drm_buffer_object_t * bo)
atomic_dec(&bm->count);
+ // BUG_ON(!list_empty(&bo->base.list));
drm_ctl_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);
return;
@@ -433,19 +435,19 @@ static void drm_bo_destroy_locked(drm_buffer_object_t * bo)
* Call dev->struct_mutex locked.
*/
-static void drm_bo_delayed_delete(drm_device_t * dev, int remove_all)
+static void drm_bo_delayed_delete(struct drm_device * dev, int remove_all)
{
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_buffer_manager *bm = &dev->bm;
- drm_buffer_object_t *entry, *nentry;
+ struct drm_buffer_object *entry, *nentry;
struct list_head *list, *next;
list_for_each_safe(list, next, &bm->ddestroy) {
- entry = list_entry(list, drm_buffer_object_t, ddestroy);
+ entry = list_entry(list, struct drm_buffer_object, ddestroy);
nentry = NULL;
if (next != &bm->ddestroy) {
- nentry = list_entry(next, drm_buffer_object_t,
+ nentry = list_entry(next, struct drm_buffer_object,
ddestroy);
atomic_inc(&nentry->usage);
}
@@ -465,12 +467,12 @@ static void drm_bo_delayed_workqueue(struct work_struct *work)
#endif
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- drm_device_t *dev = (drm_device_t *) data;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_device *dev = (struct drm_device *) data;
+ struct drm_buffer_manager *bm = &dev->bm;
#else
- drm_buffer_manager_t *bm =
- container_of(work, drm_buffer_manager_t, wq.work);
- drm_device_t *dev = container_of(bm, drm_device_t, bm);
+ struct drm_buffer_manager *bm =
+ container_of(work, struct drm_buffer_manager, wq.work);
+ struct drm_device *dev = container_of(bm, struct drm_device, bm);
#endif
DRM_DEBUG("Delayed delete Worker\n");
@@ -488,66 +490,116 @@ static void drm_bo_delayed_workqueue(struct work_struct *work)
mutex_unlock(&dev->struct_mutex);
}
-void drm_bo_usage_deref_locked(drm_buffer_object_t * bo)
+void drm_bo_usage_deref_locked(struct drm_buffer_object ** bo)
{
- if (atomic_dec_and_test(&bo->usage)) {
- drm_bo_destroy_locked(bo);
+ struct drm_buffer_object *tmp_bo = *bo;
+ bo = NULL;
+
+ DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex);
+
+ if (atomic_dec_and_test(&tmp_bo->usage)) {
+ drm_bo_destroy_locked(tmp_bo);
}
}
+EXPORT_SYMBOL(drm_bo_usage_deref_locked);
-static void drm_bo_base_deref_locked(drm_file_t * priv, drm_user_object_t * uo)
+static void drm_bo_base_deref_locked(struct drm_file * file_priv,
+ struct drm_user_object * uo)
{
- drm_buffer_object_t *bo =
- drm_user_object_entry(uo, drm_buffer_object_t, base);
+ struct drm_buffer_object *bo =
+ drm_user_object_entry(uo, struct drm_buffer_object, base);
+
+ DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
drm_bo_takedown_vm_locked(bo);
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
}
-static void drm_bo_usage_deref_unlocked(drm_buffer_object_t * bo)
+void drm_bo_usage_deref_unlocked(struct drm_buffer_object ** bo)
{
- drm_device_t *dev = bo->dev;
+ struct drm_buffer_object *tmp_bo = *bo;
+ struct drm_device *dev = tmp_bo->dev;
- if (atomic_dec_and_test(&bo->usage)) {
+ *bo = NULL;
+ if (atomic_dec_and_test(&tmp_bo->usage)) {
mutex_lock(&dev->struct_mutex);
- if (atomic_read(&bo->usage) == 0)
- drm_bo_destroy_locked(bo);
+ if (atomic_read(&tmp_bo->usage) == 0)
+ drm_bo_destroy_locked(tmp_bo);
+ mutex_unlock(&dev->struct_mutex);
+ }
+}
+EXPORT_SYMBOL(drm_bo_usage_deref_unlocked);
+
+void drm_putback_buffer_objects(struct drm_device *dev)
+{
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct list_head *list = &bm->unfenced;
+ struct drm_buffer_object *entry, *next;
+
+ mutex_lock(&dev->struct_mutex);
+ list_for_each_entry_safe(entry, next, list, lru) {
+ atomic_inc(&entry->usage);
mutex_unlock(&dev->struct_mutex);
+
+ mutex_lock(&entry->mutex);
+ BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
+ mutex_lock(&dev->struct_mutex);
+
+ list_del_init(&entry->lru);
+ DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
+ DRM_WAKEUP(&entry->event_queue);
+
+ /*
+ * FIXME: Might want to put back on head of list
+ * instead of tail here.
+ */
+
+ drm_bo_add_to_lru(entry);
+ mutex_unlock(&entry->mutex);
+ drm_bo_usage_deref_locked(&entry);
}
+ mutex_unlock(&dev->struct_mutex);
}
+EXPORT_SYMBOL(drm_putback_buffer_objects);
+
/*
* Note. The caller has to register (if applicable)
* and deregister fence object usage.
*/
-int drm_fence_buffer_objects(drm_file_t * priv,
+int drm_fence_buffer_objects(struct drm_device *dev,
struct list_head *list,
uint32_t fence_flags,
- drm_fence_object_t * fence,
- drm_fence_object_t ** used_fence)
+ struct drm_fence_object * fence,
+ struct drm_fence_object ** used_fence)
{
- drm_device_t *dev = priv->head->dev;
- drm_buffer_manager_t *bm = &dev->bm;
-
- drm_buffer_object_t *entry;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_buffer_object *entry;
uint32_t fence_type = 0;
+ uint32_t fence_class = ~0;
int count = 0;
int ret = 0;
struct list_head *l;
- LIST_HEAD(f_list);
mutex_lock(&dev->struct_mutex);
if (!list)
list = &bm->unfenced;
+ if (fence)
+ fence_class = fence->fence_class;
+
list_for_each_entry(entry, list, lru) {
BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
- fence_type |= entry->fence_type;
- if (entry->fence_class != 0) {
- DRM_ERROR("Fence class %d is not implemented yet.\n",
- entry->fence_class);
+ fence_type |= entry->new_fence_type;
+ if (fence_class == ~0)
+ fence_class = entry->new_fence_class;
+ else if (entry->new_fence_class != fence_class) {
+ DRM_ERROR("Unmatching fence classes on unfenced list: "
+ "%d and %d.\n",
+ fence_class,
+ entry->new_fence_class);
ret = -EINVAL;
goto out;
}
@@ -559,16 +611,9 @@ int drm_fence_buffer_objects(drm_file_t * priv,
goto out;
}
- /*
- * Transfer to a local list before we release the dev->struct_mutex;
- * This is so we don't get any new unfenced objects while fencing
- * the ones we already have..
- */
-
- list_splice_init(list, &f_list);
-
if (fence) {
- if ((fence_type & fence->type) != fence_type) {
+ if ((fence_type & fence->type) != fence_type ||
+ (fence->fence_class != fence_class)) {
DRM_ERROR("Given fence doesn't match buffers "
"on unfenced list.\n");
ret = -EINVAL;
@@ -576,7 +621,7 @@ int drm_fence_buffer_objects(drm_file_t * priv,
}
} else {
mutex_unlock(&dev->struct_mutex);
- ret = drm_fence_object_create(dev, 0, fence_type,
+ ret = drm_fence_object_create(dev, fence_class, fence_type,
fence_flags | DRM_FENCE_FLAG_EMIT,
&fence);
mutex_lock(&dev->struct_mutex);
@@ -585,10 +630,10 @@ int drm_fence_buffer_objects(drm_file_t * priv,
}
count = 0;
- l = f_list.next;
- while (l != &f_list) {
+ l = list->next;
+ while (l != list) {
prefetch(l->next);
- entry = list_entry(l, drm_buffer_object_t, lru);
+ entry = list_entry(l, struct drm_buffer_object, lru);
atomic_inc(&entry->usage);
mutex_unlock(&dev->struct_mutex);
mutex_lock(&entry->mutex);
@@ -597,37 +642,37 @@ int drm_fence_buffer_objects(drm_file_t * priv,
if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
count++;
if (entry->fence)
- drm_fence_usage_deref_locked(dev, entry->fence);
- entry->fence = fence;
+ drm_fence_usage_deref_locked(&entry->fence);
+ entry->fence = drm_fence_reference_locked(fence);
+ entry->fence_class = entry->new_fence_class;
+ entry->fence_type = entry->new_fence_type;
DRM_FLAG_MASKED(entry->priv_flags, 0,
_DRM_BO_FLAG_UNFENCED);
DRM_WAKEUP(&entry->event_queue);
drm_bo_add_to_lru(entry);
}
mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_locked(entry);
- l = f_list.next;
+ drm_bo_usage_deref_locked(&entry);
+ l = list->next;
}
- atomic_add(count, &fence->usage);
DRM_DEBUG("Fenced %d buffers\n", count);
out:
mutex_unlock(&dev->struct_mutex);
*used_fence = fence;
return ret;
}
-
EXPORT_SYMBOL(drm_fence_buffer_objects);
/*
* bo->mutex locked
*/
-static int drm_bo_evict(drm_buffer_object_t * bo, unsigned mem_type,
+static int drm_bo_evict(struct drm_buffer_object * bo, unsigned mem_type,
int no_wait)
{
int ret = 0;
- drm_device_t *dev = bo->dev;
- drm_bo_mem_reg_t evict_mem;
+ struct drm_device *dev = bo->dev;
+ struct drm_bo_mem_reg evict_mem;
/*
* Someone might have modified the buffer before we took the buffer mutex.
@@ -649,12 +694,6 @@ static int drm_bo_evict(drm_buffer_object_t * bo, unsigned mem_type,
evict_mem = bo->mem;
evict_mem.mm_node = NULL;
- if (bo->type == drm_bo_type_fake) {
- bo->mem.mem_type = DRM_BO_MEM_LOCAL;
- bo->mem.mm_node = NULL;
- goto out1;
- }
-
evict_mem = bo->mem;
evict_mem.mask = dev->driver->bo_driver->evict_mask(bo);
ret = drm_bo_mem_space(bo, &evict_mem, no_wait);
@@ -674,7 +713,6 @@ static int drm_bo_evict(drm_buffer_object_t * bo, unsigned mem_type,
goto out;
}
- out1:
mutex_lock(&dev->struct_mutex);
if (evict_mem.mm_node) {
if (evict_mem.mm_node != bo->pinned_node)
@@ -692,14 +730,18 @@ static int drm_bo_evict(drm_buffer_object_t * bo, unsigned mem_type,
return ret;
}
-static int drm_bo_mem_force_space(drm_device_t * dev,
- drm_bo_mem_reg_t * mem,
+/**
+ * Repeatedly evict memory from the LRU for @mem_type until we create enough
+ * space, or we've evicted everything and there isn't enough space.
+ */
+static int drm_bo_mem_force_space(struct drm_device * dev,
+ struct drm_bo_mem_reg * mem,
uint32_t mem_type, int no_wait)
{
- drm_mm_node_t *node;
- drm_buffer_manager_t *bm = &dev->bm;
- drm_buffer_object_t *entry;
- drm_mem_type_manager_t *man = &bm->man[mem_type];
+ struct drm_mm_node *node;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_buffer_object *entry;
+ struct drm_mem_type_manager *man = &bm->man[mem_type];
struct list_head *lru;
unsigned long num_pages = mem->num_pages;
int ret;
@@ -715,7 +757,7 @@ static int drm_bo_mem_force_space(drm_device_t * dev,
if (lru->next == lru)
break;
- entry = list_entry(lru->next, drm_buffer_object_t, lru);
+ entry = list_entry(lru->next, struct drm_buffer_object, lru);
atomic_inc(&entry->usage);
mutex_unlock(&dev->struct_mutex);
mutex_lock(&entry->mutex);
@@ -723,7 +765,7 @@ static int drm_bo_mem_force_space(drm_device_t * dev,
ret = drm_bo_evict(entry, mem_type, no_wait);
mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_unlocked(entry);
+ drm_bo_usage_deref_unlocked(&entry);
if (ret)
return ret;
mutex_lock(&dev->struct_mutex);
@@ -741,12 +783,12 @@ static int drm_bo_mem_force_space(drm_device_t * dev,
return 0;
}
-static int drm_bo_mt_compatible(drm_mem_type_manager_t * man,
+static int drm_bo_mt_compatible(struct drm_mem_type_manager * man,
uint32_t mem_type,
- uint32_t mask, uint32_t * res_mask)
+ uint64_t mask, uint32_t * res_mask)
{
- uint32_t cur_flags = drm_bo_type_flags(mem_type);
- uint32_t flag_diff;
+ uint64_t cur_flags = drm_bo_type_flags(mem_type);
+ uint64_t flag_diff;
if (man->flags & _DRM_FLAG_MEMTYPE_CACHED)
cur_flags |= DRM_BO_FLAG_CACHED;
@@ -778,12 +820,20 @@ static int drm_bo_mt_compatible(drm_mem_type_manager_t * man,
return 1;
}
-int drm_bo_mem_space(drm_buffer_object_t * bo,
- drm_bo_mem_reg_t * mem, int no_wait)
+/**
+ * Creates space for memory region @mem according to its type.
+ *
+ * This function first searches for free space in compatible memory types in
+ * the priority order defined by the driver. If free space isn't found, then
+ * drm_bo_mem_force_space is attempted in priority order to evict and find
+ * space.
+ */
+int drm_bo_mem_space(struct drm_buffer_object * bo,
+ struct drm_bo_mem_reg * mem, int no_wait)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
- drm_mem_type_manager_t *man;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_mem_type_manager *man;
uint32_t num_prios = dev->driver->bo_driver->num_mem_type_prio;
const uint32_t *prios = dev->driver->bo_driver->mem_type_prio;
@@ -793,7 +843,7 @@ int drm_bo_mem_space(drm_buffer_object_t * bo,
int type_found = 0;
int type_ok = 0;
int has_eagain = 0;
- drm_mm_node_t *node = NULL;
+ struct drm_mm_node *node = NULL;
int ret;
mem->mm_node = NULL;
@@ -870,37 +920,38 @@ int drm_bo_mem_space(drm_buffer_object_t * bo,
EXPORT_SYMBOL(drm_bo_mem_space);
-static int drm_bo_new_mask(drm_buffer_object_t * bo,
- uint32_t new_mask, uint32_t hint)
+static int drm_bo_new_mask(struct drm_buffer_object * bo,
+ uint64_t new_flags, uint64_t used_mask)
{
uint32_t new_props;
if (bo->type == drm_bo_type_user) {
- DRM_ERROR("User buffers are not supported yet\n");
- return -EINVAL;
- }
- if (bo->type == drm_bo_type_fake &&
- !(new_mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))) {
- DRM_ERROR("Fake buffers must be pinned.\n");
+ DRM_ERROR("User buffers are not supported yet.\n");
return -EINVAL;
}
- if ((new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
+ if ((used_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
DRM_ERROR
("DRM_BO_FLAG_NO_EVICT is only available to priviliged "
- "processes\n");
+ "processes.\n");
+ return -EPERM;
+ }
+
+ if ((new_flags & DRM_BO_FLAG_NO_MOVE)) {
+ DRM_ERROR
+ ("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n");
return -EPERM;
}
- new_props = new_mask & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_READ);
+ new_props = new_flags & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_READ);
if (!new_props) {
DRM_ERROR("Invalid buffer object rwx properties\n");
return -EINVAL;
}
- bo->mem.mask = new_mask;
+ bo->mem.mask = new_flags;
return 0;
}
@@ -908,28 +959,29 @@ static int drm_bo_new_mask(drm_buffer_object_t * bo,
* Call dev->struct_mutex locked.
*/
-drm_buffer_object_t *drm_lookup_buffer_object(drm_file_t * priv,
+struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv,
uint32_t handle, int check_owner)
{
- drm_user_object_t *uo;
- drm_buffer_object_t *bo;
+ struct drm_user_object *uo;
+ struct drm_buffer_object *bo;
- uo = drm_lookup_user_object(priv, handle);
+ uo = drm_lookup_user_object(file_priv, handle);
if (!uo || (uo->type != drm_buffer_type)) {
DRM_ERROR("Could not find buffer object 0x%08x\n", handle);
return NULL;
}
- if (check_owner && priv != uo->owner) {
- if (!drm_lookup_ref_object(priv, uo, _DRM_REF_USE))
+ if (check_owner && file_priv != uo->owner) {
+ if (!drm_lookup_ref_object(file_priv, uo, _DRM_REF_USE))
return NULL;
}
- bo = drm_user_object_entry(uo, drm_buffer_object_t, base);
+ bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
atomic_inc(&bo->usage);
return bo;
}
+EXPORT_SYMBOL(drm_lookup_buffer_object);
/*
* Call bo->mutex locked.
@@ -937,16 +989,14 @@ drm_buffer_object_t *drm_lookup_buffer_object(drm_file_t * priv,
* Doesn't do any fence flushing as opposed to the drm_bo_busy function.
*/
-static int drm_bo_quick_busy(drm_buffer_object_t * bo)
+static int drm_bo_quick_busy(struct drm_buffer_object * bo)
{
- drm_fence_object_t *fence = bo->fence;
+ struct drm_fence_object *fence = bo->fence;
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
return 1;
@@ -959,22 +1009,19 @@ static int drm_bo_quick_busy(drm_buffer_object_t * bo)
* Returns 1 if the buffer is currently rendered to or from. 0 otherwise.
*/
-static int drm_bo_busy(drm_buffer_object_t * bo)
+static int drm_bo_busy(struct drm_buffer_object * bo)
{
- drm_fence_object_t *fence = bo->fence;
+ struct drm_fence_object *fence = bo->fence;
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
- drm_fence_object_flush(dev, fence, DRM_FENCE_TYPE_EXE);
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE);
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
return 1;
@@ -982,7 +1029,7 @@ static int drm_bo_busy(drm_buffer_object_t * bo)
return 0;
}
-static int drm_bo_read_cached(drm_buffer_object_t * bo)
+static int drm_bo_read_cached(struct drm_buffer_object * bo)
{
int ret = 0;
@@ -996,7 +1043,7 @@ static int drm_bo_read_cached(drm_buffer_object_t * bo)
* Wait until a buffer is unmapped.
*/
-static int drm_bo_wait_unmapped(drm_buffer_object_t * bo, int no_wait)
+static int drm_bo_wait_unmapped(struct drm_buffer_object * bo, int no_wait)
{
int ret = 0;
@@ -1012,7 +1059,7 @@ static int drm_bo_wait_unmapped(drm_buffer_object_t * bo, int no_wait)
return ret;
}
-static int drm_bo_check_unfenced(drm_buffer_object_t * bo)
+static int drm_bo_check_unfenced(struct drm_buffer_object * bo)
{
int ret;
@@ -1025,16 +1072,9 @@ static int drm_bo_check_unfenced(drm_buffer_object_t * bo)
/*
* Wait until a buffer, scheduled to be fenced moves off the unfenced list.
* Until then, we cannot really do anything with it except delete it.
- * The unfenced list is a PITA, and the operations
- * 1) validating
- * 2) submitting commands
- * 3) fencing
- * Should really be an atomic operation.
- * We now "solve" this problem by keeping
- * the buffer "unfenced" after validating, but before fencing.
*/
-static int drm_bo_wait_unfenced(drm_buffer_object_t * bo, int no_wait,
+static int drm_bo_wait_unfenced(struct drm_buffer_object * bo, int no_wait,
int eagain_if_wait)
{
int ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
@@ -1067,12 +1107,15 @@ static int drm_bo_wait_unfenced(drm_buffer_object_t * bo, int no_wait,
* Bo locked.
*/
-static void drm_bo_fill_rep_arg(drm_buffer_object_t * bo,
- drm_bo_arg_reply_t * rep)
+static void drm_bo_fill_rep_arg(struct drm_buffer_object * bo,
+ struct drm_bo_info_rep *rep)
{
+ if (!rep)
+ return;
+
rep->handle = bo->base.hash.key;
rep->flags = bo->mem.flags;
- rep->size = bo->mem.num_pages * PAGE_SIZE;
+ rep->size = bo->num_pages * PAGE_SIZE;
rep->offset = bo->offset;
rep->arg_handle = bo->map_list.user_token;
rep->mask = bo->mem.mask;
@@ -1094,28 +1137,26 @@ static void drm_bo_fill_rep_arg(drm_buffer_object_t * bo,
* unregistered.
*/
-static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
+static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
uint32_t map_flags, unsigned hint,
- drm_bo_arg_reply_t * rep)
+ struct drm_bo_info_rep *rep)
{
- drm_buffer_object_t *bo;
- drm_device_t *dev = priv->head->dev;
+ struct drm_buffer_object *bo;
+ struct drm_device *dev = file_priv->head->dev;
int ret = 0;
int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(priv, handle, 1);
+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
mutex_unlock(&dev->struct_mutex);
if (!bo)
return -EINVAL;
mutex_lock(&bo->mutex);
- if (!(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) {
- ret = drm_bo_wait_unfenced(bo, no_wait, 0);
- if (ret)
- goto out;
- }
+ ret = drm_bo_wait_unfenced(bo, no_wait, 0);
+ if (ret)
+ goto out;
/*
* If this returns true, we are currently unmapped.
@@ -1161,7 +1202,7 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
}
mutex_lock(&dev->struct_mutex);
- ret = drm_add_ref_object(priv, &bo->base, _DRM_REF_TYPE1);
+ ret = drm_add_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
mutex_unlock(&dev->struct_mutex);
if (ret) {
if (atomic_add_negative(-1, &bo->mapped))
@@ -1171,33 +1212,33 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
drm_bo_fill_rep_arg(bo, rep);
out:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
-static int drm_buffer_object_unmap(drm_file_t * priv, uint32_t handle)
+static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle)
{
- drm_device_t *dev = priv->head->dev;
- drm_buffer_object_t *bo;
- drm_ref_object_t *ro;
+ struct drm_device *dev = file_priv->head->dev;
+ struct drm_buffer_object *bo;
+ struct drm_ref_object *ro;
int ret = 0;
mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(priv, handle, 1);
+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
if (!bo) {
ret = -EINVAL;
goto out;
}
- ro = drm_lookup_ref_object(priv, &bo->base, _DRM_REF_TYPE1);
+ ro = drm_lookup_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
if (!ro) {
ret = -EINVAL;
goto out;
}
- drm_remove_ref_object(priv, ro);
- drm_bo_usage_deref_locked(bo);
+ drm_remove_ref_object(file_priv, ro);
+ drm_bo_usage_deref_locked(&bo);
out:
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -1207,12 +1248,12 @@ static int drm_buffer_object_unmap(drm_file_t * priv, uint32_t handle)
* Call struct-sem locked.
*/
-static void drm_buffer_user_object_unmap(drm_file_t * priv,
- drm_user_object_t * uo,
- drm_ref_t action)
+static void drm_buffer_user_object_unmap(struct drm_file *file_priv,
+ struct drm_user_object * uo,
+ enum drm_ref_type action)
{
- drm_buffer_object_t *bo =
- drm_user_object_entry(uo, drm_buffer_object_t, base);
+ struct drm_buffer_object *bo =
+ drm_user_object_entry(uo, struct drm_buffer_object, base);
/*
* We DON'T want to take the bo->lock here, because we want to
@@ -1230,13 +1271,13 @@ static void drm_buffer_user_object_unmap(drm_file_t * priv,
* Note that new_mem_flags are NOT transferred to the bo->mem.mask.
*/
-int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags,
+int drm_bo_move_buffer(struct drm_buffer_object * bo, uint64_t new_mem_flags,
int no_wait, int move_unfenced)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
int ret = 0;
- drm_bo_mem_reg_t mem;
+ struct drm_bo_mem_reg mem;
/*
* Flush outstanding fences.
*/
@@ -1251,17 +1292,14 @@ int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags,
if (ret)
return ret;
- mem.num_pages = bo->mem.num_pages;
+ mem.num_pages = bo->num_pages;
mem.size = mem.num_pages << PAGE_SHIFT;
mem.mask = new_mem_flags;
mem.page_alignment = bo->mem.page_alignment;
mutex_lock(&bm->evict_mutex);
mutex_lock(&dev->struct_mutex);
- list_del(&bo->lru);
- list_add_tail(&bo->lru, &bm->unfenced);
- DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED,
- _DRM_BO_FLAG_UNFENCED);
+ list_del_init(&bo->lru);
mutex_unlock(&dev->struct_mutex);
/*
@@ -1281,10 +1319,6 @@ int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags,
drm_mm_put_block(mem.mm_node);
mem.mm_node = NULL;
}
- DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
- DRM_WAKEUP(&bo->event_queue);
- list_del(&bo->lru);
- drm_bo_add_to_lru(bo);
mutex_unlock(&dev->struct_mutex);
}
@@ -1292,14 +1326,14 @@ int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags,
return ret;
}
-static int drm_bo_mem_compat(drm_bo_mem_reg_t * mem)
+static int drm_bo_mem_compat(struct drm_bo_mem_reg * mem)
{
uint32_t flag_diff = (mem->mask ^ mem->flags);
if ((mem->mask & mem->flags & DRM_BO_MASK_MEM) == 0)
return 0;
if ((flag_diff & DRM_BO_FLAG_CACHED) &&
- (!(mem->mask & DRM_BO_FLAG_CACHED) ||
+ (/* !(mem->mask & DRM_BO_FLAG_CACHED) ||*/
(mem->mask & DRM_BO_FLAG_FORCE_CACHING))) {
return 0;
}
@@ -1310,72 +1344,55 @@ static int drm_bo_mem_compat(drm_bo_mem_reg_t * mem)
return 1;
}
-static int drm_bo_check_fake(drm_device_t * dev, drm_bo_mem_reg_t * mem)
-{
- drm_buffer_manager_t *bm = &dev->bm;
- drm_mem_type_manager_t *man;
- uint32_t num_prios = dev->driver->bo_driver->num_mem_type_prio;
- const uint32_t *prios = dev->driver->bo_driver->mem_type_prio;
- uint32_t i;
- int type_ok = 0;
- uint32_t mem_type = 0;
- uint32_t cur_flags;
-
- if (drm_bo_mem_compat(mem))
- return 0;
-
- BUG_ON(mem->mm_node);
-
- for (i = 0; i < num_prios; ++i) {
- mem_type = prios[i];
- man = &bm->man[mem_type];
- type_ok = drm_bo_mt_compatible(man, mem_type, mem->mask,
- &cur_flags);
- if (type_ok)
- break;
- }
-
- if (type_ok) {
- mem->mm_node = NULL;
- mem->mem_type = mem_type;
- mem->flags = cur_flags;
- DRM_FLAG_MASKED(mem->flags, mem->mask, ~DRM_BO_MASK_MEMTYPE);
- return 0;
- }
-
- DRM_ERROR("Illegal fake buffer flags 0x%08x\n", mem->mask);
- return -EINVAL;
-}
-
/*
* bo locked.
*/
-static int drm_buffer_object_validate(drm_buffer_object_t * bo,
+static int drm_buffer_object_validate(struct drm_buffer_object * bo,
+ uint32_t fence_class,
int move_unfenced, int no_wait)
{
- drm_device_t *dev = bo->dev;
- drm_buffer_manager_t *bm = &dev->bm;
- drm_bo_driver_t *driver = dev->driver->bo_driver;
+ struct drm_device *dev = bo->dev;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ uint32_t ftype;
int ret;
- DRM_DEBUG("New flags 0x%08x, Old flags 0x%08x\n", bo->mem.mask,
- bo->mem.flags);
- ret =
- driver->fence_type(bo, &bo->fence_class, &bo->fence_type);
+ DRM_DEBUG("New flags 0x%016llx, Old flags 0x%016llx\n",
+ (unsigned long long) bo->mem.mask,
+ (unsigned long long) bo->mem.flags);
+
+ ret = driver->fence_type(bo, &fence_class, &ftype);
+
if (ret) {
DRM_ERROR("Driver did not support given buffer permissions\n");
return ret;
}
- ret = drm_bo_wait_unmapped(bo, no_wait);
- if (ret)
- return ret;
+ /*
+ * We're switching command submission mechanism,
+ * or cannot simply rely on the hardware serializing for us.
+ *
+ * Wait for buffer idle.
+ */
+
+ if ((fence_class != bo->fence_class) ||
+ ((ftype ^ bo->fence_type) & bo->fence_type)) {
+
+ ret = drm_bo_wait(bo, 0, 0, no_wait);
- if (bo->type == drm_bo_type_fake) {
- ret = drm_bo_check_fake(dev, &bo->mem);
if (ret)
return ret;
+
+ }
+
+ bo->new_fence_class = fence_class;
+ bo->new_fence_type = ftype;
+
+ ret = drm_bo_wait_unmapped(bo, no_wait);
+ if (ret) {
+ DRM_ERROR("Timed out waiting for buffer unmap.\n");
+ return ret;
}
/*
@@ -1457,18 +1474,13 @@ static int drm_buffer_object_validate(drm_buffer_object_t * bo,
return 0;
}
-static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
- uint32_t flags, uint32_t mask, uint32_t hint,
- drm_bo_arg_reply_t * rep)
+int drm_bo_do_validate(struct drm_buffer_object *bo,
+ uint64_t flags, uint64_t mask, uint32_t hint,
+ uint32_t fence_class,
+ int no_wait,
+ struct drm_bo_info_rep *rep)
{
- drm_buffer_object_t *bo;
int ret;
- int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
-
- bo = drm_lookup_buffer_object(priv, handle, 1);
- if (!bo) {
- return -EINVAL;
- }
mutex_lock(&bo->mutex);
ret = drm_bo_wait_unfenced(bo, no_wait, 0);
@@ -1476,30 +1488,79 @@ static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
if (ret)
goto out;
+
DRM_FLAG_MASKED(flags, bo->mem.mask, ~mask);
- ret = drm_bo_new_mask(bo, flags, hint);
+ ret = drm_bo_new_mask(bo, flags, mask);
if (ret)
goto out;
- ret =
- drm_buffer_object_validate(bo, !(hint & DRM_BO_HINT_DONT_FENCE),
- no_wait);
- drm_bo_fill_rep_arg(bo, rep);
-
- out:
+ ret = drm_buffer_object_validate(bo,
+ fence_class,
+ !(hint & DRM_BO_HINT_DONT_FENCE),
+ no_wait);
+out:
+ if (rep)
+ drm_bo_fill_rep_arg(bo, rep);
mutex_unlock(&bo->mutex);
+ return ret;
+}
+EXPORT_SYMBOL(drm_bo_do_validate);
+
+
+int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle,
+ uint32_t fence_class,
+ uint64_t flags, uint64_t mask,
+ uint32_t hint,
+ int use_old_fence_class,
+ struct drm_bo_info_rep * rep,
+ struct drm_buffer_object **bo_rep)
+{
+ struct drm_device *dev = file_priv->head->dev;
+ struct drm_buffer_object *bo;
+ int ret;
+ int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
+
+ mutex_lock(&dev->struct_mutex);
+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (!bo)
+ return -EINVAL;
+
+ if (use_old_fence_class)
+ fence_class = bo->fence_class;
+
+ /*
+ * Only allow creator to change shared buffer mask.
+ */
+
+ if (bo->base.owner != file_priv)
+ mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
+
+
+ ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class,
+ no_wait, rep);
+
+ if (!ret && bo_rep)
+ *bo_rep = bo;
+ else
+ drm_bo_usage_deref_unlocked(&bo);
- drm_bo_usage_deref_unlocked(bo);
return ret;
}
+EXPORT_SYMBOL(drm_bo_handle_validate);
-static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
- drm_bo_arg_reply_t * rep)
+static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle,
+ struct drm_bo_info_rep *rep)
{
- drm_buffer_object_t *bo;
+ struct drm_device *dev = file_priv->head->dev;
+ struct drm_buffer_object *bo;
+
+ mutex_lock(&dev->struct_mutex);
+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
+ mutex_unlock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(priv, handle, 1);
if (!bo) {
return -EINVAL;
}
@@ -1508,18 +1569,23 @@ static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
(void)drm_bo_busy(bo);
drm_bo_fill_rep_arg(bo, rep);
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return 0;
}
-static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
- uint32_t hint, drm_bo_arg_reply_t * rep)
+static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle,
+ uint32_t hint,
+ struct drm_bo_info_rep *rep)
{
- drm_buffer_object_t *bo;
+ struct drm_device *dev = file_priv->head->dev;
+ struct drm_buffer_object *bo;
int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
int ret;
- bo = drm_lookup_buffer_object(priv, handle, 1);
+ mutex_lock(&dev->struct_mutex);
+ bo = drm_lookup_buffer_object(file_priv, handle, 1);
+ mutex_unlock(&dev->struct_mutex);
+
if (!bo) {
return -EINVAL;
}
@@ -1536,25 +1602,25 @@ static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
out:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
-int drm_buffer_object_create(drm_device_t *dev,
+int drm_buffer_object_create(struct drm_device *dev,
unsigned long size,
- drm_bo_type_t type,
- uint32_t mask,
+ enum drm_bo_type type,
+ uint64_t mask,
uint32_t hint,
uint32_t page_alignment,
unsigned long buffer_start,
- drm_buffer_object_t ** buf_obj)
+ struct drm_buffer_object ** buf_obj)
{
- drm_buffer_manager_t *bm = &dev->bm;
- drm_buffer_object_t *bo;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_buffer_object *bo;
int ret = 0;
unsigned long num_pages;
- if ((buffer_start & ~PAGE_MASK) && (type != drm_bo_type_fake)) {
+ if (buffer_start & ~PAGE_MASK) {
DRM_ERROR("Invalid buffer object start.\n");
return -EINVAL;
}
@@ -1583,20 +1649,21 @@ int drm_buffer_object_create(drm_device_t *dev,
INIT_LIST_HEAD(&bo->vma_list);
#endif
bo->dev = dev;
- bo->type = type;
+ if (buffer_start != 0)
+ bo->type = drm_bo_type_user;
+ else
+ bo->type = type;
+ bo->num_pages = num_pages;
bo->mem.mem_type = DRM_BO_MEM_LOCAL;
- bo->mem.num_pages = num_pages;
+ bo->mem.num_pages = bo->num_pages;
bo->mem.mm_node = NULL;
bo->mem.page_alignment = page_alignment;
- if (bo->type == drm_bo_type_fake) {
- bo->offset = buffer_start;
- bo->buffer_start = 0;
- } else {
- bo->buffer_start = buffer_start;
- }
+ bo->buffer_start = buffer_start;
bo->priv_flags = 0;
- bo->mem.flags = 0;
- bo->mem.mask = 0;
+ bo->mem.flags = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
+ DRM_BO_FLAG_MAPPABLE;
+ bo->mem.mask = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
+ DRM_BO_FLAG_MAPPABLE;
atomic_inc(&bm->count);
ret = drm_bo_new_mask(bo, mask, hint);
@@ -1610,7 +1677,8 @@ int drm_buffer_object_create(drm_device_t *dev,
if (ret)
goto out_err;
}
- ret = drm_buffer_object_validate(bo, 0, hint & DRM_BO_HINT_DONT_BLOCK);
+
+ ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK);
if (ret)
goto out_err;
@@ -1621,18 +1689,20 @@ int drm_buffer_object_create(drm_device_t *dev,
out_err:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
+EXPORT_SYMBOL(drm_buffer_object_create);
+
-static int drm_bo_add_user_object(drm_file_t * priv, drm_buffer_object_t * bo,
- int shareable)
+static int drm_bo_add_user_object(struct drm_file *file_priv,
+ struct drm_buffer_object *bo, int shareable)
{
- drm_device_t *dev = priv->head->dev;
+ struct drm_device *dev = file_priv->head->dev;
int ret;
mutex_lock(&dev->struct_mutex);
- ret = drm_add_user_object(priv, &bo->base, shareable);
+ ret = drm_add_user_object(file_priv, &bo->base, shareable);
if (ret)
goto out;
@@ -1646,182 +1716,191 @@ static int drm_bo_add_user_object(drm_file_t * priv, drm_buffer_object_t * bo,
return ret;
}
-static int drm_bo_lock_test(drm_device_t * dev, struct file *filp)
+int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- LOCK_TEST_WITH_RETURN(dev, filp);
- return 0;
+ struct drm_bo_create_arg *arg = data;
+ struct drm_bo_create_req *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ struct drm_buffer_object *entry;
+ int ret = 0;
+
+ DRM_DEBUG("drm_bo_create_ioctl: %dkb, %dkb align\n",
+ (int)(req->size / 1024), req->page_alignment * 4);
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ ret = drm_buffer_object_create(file_priv->head->dev,
+ req->size, drm_bo_type_dc, req->mask,
+ req->hint, req->page_alignment,
+ req->buffer_start, &entry);
+ if (ret)
+ goto out;
+
+ ret = drm_bo_add_user_object(file_priv, entry,
+ req->mask & DRM_BO_FLAG_SHAREABLE);
+ if (ret) {
+ drm_bo_usage_deref_unlocked(&entry);
+ goto out;
+ }
+
+ mutex_lock(&entry->mutex);
+ drm_bo_fill_rep_arg(entry, rep);
+ mutex_unlock(&entry->mutex);
+
+out:
+ return ret;
}
-int drm_bo_ioctl(DRM_IOCTL_ARGS)
+int drm_bo_setstatus_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_bo_arg_t arg;
- drm_bo_arg_request_t *req = &arg.d.req;
- drm_bo_arg_reply_t rep;
- unsigned long next;
- drm_user_object_t *uo;
- drm_buffer_object_t *entry;
+ struct drm_bo_map_wait_idle_arg *arg = data;
+ struct drm_bo_info_req *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ int ret;
if (!dev->bm.initialized) {
DRM_ERROR("Buffer object manager is not initialized.\n");
return -EINVAL;
}
- do {
- DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ ret = drm_bo_read_lock(&dev->bm.bm_lock);
+ if (ret)
+ return ret;
- if (arg.handled) {
- data = arg.next;
- continue;
- }
+ ret = drm_bo_handle_validate(file_priv, req->handle, req->fence_class,
+ req->flags,
+ req->mask,
+ req->hint | DRM_BO_HINT_DONT_FENCE,
+ 1,
+ rep, NULL);
- rep.ret = 0;
- switch (req->op) {
- case drm_bo_create:
- rep.ret = drm_bo_lock_test(dev, filp);
- if (rep.ret)
- break;
- rep.ret =
- drm_buffer_object_create(priv->head->dev,
- req->size,
- req->type,
- req->mask,
- req->hint,
- req->page_alignment,
- req->buffer_start, &entry);
- if (rep.ret)
- break;
-
- rep.ret =
- drm_bo_add_user_object(priv, entry,
- req->
- mask &
- DRM_BO_FLAG_SHAREABLE);
- if (rep.ret)
- drm_bo_usage_deref_unlocked(entry);
-
- if (rep.ret)
- break;
-
- mutex_lock(&entry->mutex);
- drm_bo_fill_rep_arg(entry, &rep);
- mutex_unlock(&entry->mutex);
- break;
- case drm_bo_unmap:
- rep.ret = drm_buffer_object_unmap(priv, req->handle);
- break;
- case drm_bo_map:
- rep.ret = drm_buffer_object_map(priv, req->handle,
- req->mask,
- req->hint, &rep);
- break;
- case drm_bo_destroy:
- mutex_lock(&dev->struct_mutex);
- uo = drm_lookup_user_object(priv, req->handle);
- if (!uo || (uo->type != drm_buffer_type)
- || uo->owner != priv) {
- mutex_unlock(&dev->struct_mutex);
- rep.ret = -EINVAL;
- break;
- }
- rep.ret = drm_remove_user_object(priv, uo);
- mutex_unlock(&dev->struct_mutex);
- break;
- case drm_bo_reference:
- rep.ret = drm_user_object_ref(priv, req->handle,
- drm_buffer_type, &uo);
- if (rep.ret)
- break;
+ (void) drm_bo_read_unlock(&dev->bm.bm_lock);
+ if (ret)
+ return ret;
- rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
- break;
- case drm_bo_unreference:
- rep.ret = drm_user_object_unref(priv, req->handle,
- drm_buffer_type);
- break;
- case drm_bo_validate:
- rep.ret = drm_bo_lock_test(dev, filp);
-
- if (rep.ret)
- break;
- rep.ret =
- drm_bo_handle_validate(priv, req->handle, req->mask,
- req->arg_handle, req->hint,
- &rep);
- break;
- case drm_bo_fence:
- rep.ret = drm_bo_lock_test(dev, filp);
- if (rep.ret)
- break;
- /**/ break;
- case drm_bo_info:
- rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
- break;
- case drm_bo_wait_idle:
- rep.ret = drm_bo_handle_wait(priv, req->handle,
- req->hint, &rep);
- break;
- case drm_bo_ref_fence:
- rep.ret = -EINVAL;
- DRM_ERROR("Function is not implemented yet.\n");
- default:
- rep.ret = -EINVAL;
- }
- next = arg.next;
+ return 0;
+}
- /*
- * A signal interrupted us. Make sure the ioctl is restartable.
- */
+int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_bo_map_wait_idle_arg *arg = data;
+ struct drm_bo_info_req *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
- if (rep.ret == -EAGAIN)
- return -EAGAIN;
+ ret = drm_buffer_object_map(file_priv, req->handle, req->mask,
+ req->hint, rep);
+ if (ret)
+ return ret;
- arg.handled = 1;
- arg.d.rep = rep;
- DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
- data = next;
- } while (data);
return 0;
}
-/**
- *Clean the unfenced list and put on regular LRU.
- *This is part of the memory manager cleanup and should only be
- *called with the DRI lock held.
- *Call dev->struct_sem locked.
- */
+int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_bo_handle_arg *arg = data;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ ret = drm_buffer_object_unmap(file_priv, arg->handle);
+ return ret;
+}
+
-static void drm_bo_clean_unfenced(drm_device_t *dev)
+int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_buffer_manager_t *bm = &dev->bm;
- struct list_head *head, *list;
- drm_buffer_object_t *entry;
+ struct drm_bo_reference_info_arg *arg = data;
+ struct drm_bo_handle_arg *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ struct drm_user_object *uo;
+ int ret;
- head = &bm->unfenced;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
- list = head->next;
- while(list != head) {
- prefetch(list->next);
- entry = list_entry(list, drm_buffer_object_t, lru);
+ ret = drm_user_object_ref(file_priv, req->handle,
+ drm_buffer_type, &uo);
+ if (ret)
+ return ret;
+
+ ret = drm_bo_handle_info(file_priv, req->handle, rep);
+ if (ret)
+ return ret;
- atomic_inc(&entry->usage);
- mutex_unlock(&dev->struct_mutex);
- mutex_lock(&entry->mutex);
- mutex_lock(&dev->struct_mutex);
+ return 0;
+}
- list_del(&entry->lru);
- DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
- drm_bo_add_to_lru(entry);
- mutex_unlock(&entry->mutex);
- list = head->next;
+int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_bo_handle_arg *arg = data;
+ int ret = 0;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ ret = drm_user_object_unref(file_priv, arg->handle, drm_buffer_type);
+ return ret;
+}
+
+int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_bo_reference_info_arg *arg = data;
+ struct drm_bo_handle_arg *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ int ret;
+
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
}
+
+ ret = drm_bo_handle_info(file_priv, req->handle, rep);
+ if (ret)
+ return ret;
+
+ return 0;
}
-static int drm_bo_leave_list(drm_buffer_object_t * bo,
+int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_bo_map_wait_idle_arg *arg = data;
+ struct drm_bo_info_req *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ ret = drm_bo_handle_wait(file_priv, req->handle,
+ req->hint, rep);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int drm_bo_leave_list(struct drm_buffer_object * bo,
uint32_t mem_type,
- int free_pinned, int allow_errors)
+ int free_pinned,
+ int allow_errors)
{
- drm_device_t *dev = bo->dev;
+ struct drm_device *dev = bo->dev;
int ret = 0;
mutex_lock(&bo->mutex);
@@ -1868,20 +1947,20 @@ static int drm_bo_leave_list(drm_buffer_object_t * bo,
}
-static drm_buffer_object_t *drm_bo_entry(struct list_head *list,
+static struct drm_buffer_object *drm_bo_entry(struct list_head *list,
int pinned_list)
{
if (pinned_list)
- return list_entry(list, drm_buffer_object_t, pinned_lru);
+ return list_entry(list, struct drm_buffer_object, pinned_lru);
else
- return list_entry(list, drm_buffer_object_t, lru);
+ return list_entry(list, struct drm_buffer_object, lru);
}
/*
* dev->struct_mutex locked.
*/
-static int drm_bo_force_list_clean(drm_device_t * dev,
+static int drm_bo_force_list_clean(struct drm_device * dev,
struct list_head *head,
unsigned mem_type,
int free_pinned,
@@ -1889,7 +1968,7 @@ static int drm_bo_force_list_clean(drm_device_t * dev,
int pinned_list)
{
struct list_head *list, *next, *prev;
- drm_buffer_object_t *entry, *nentry;
+ struct drm_buffer_object *entry, *nentry;
int ret;
int do_restart;
@@ -1927,7 +2006,7 @@ restart:
allow_errors);
mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(entry);
+ drm_bo_usage_deref_locked(&entry);
if (ret)
return ret;
@@ -1937,10 +2016,8 @@ restart:
do_restart = ((next->prev != list) && (next->prev != prev));
- if (nentry != NULL && do_restart) {
- drm_bo_usage_deref_locked(nentry);
- nentry = NULL;
- }
+ if (nentry != NULL && do_restart)
+ drm_bo_usage_deref_locked(&nentry);
if (do_restart)
goto restart;
@@ -1948,10 +2025,10 @@ restart:
return 0;
}
-int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
+int drm_bo_clean_mm(struct drm_device * dev, unsigned mem_type)
{
- drm_buffer_manager_t *bm = &dev->bm;
- drm_mem_type_manager_t *man = &bm->man[mem_type];
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_mem_type_manager *man = &bm->man[mem_type];
int ret = -EINVAL;
if (mem_type >= DRM_BO_MEM_TYPES) {
@@ -1961,7 +2038,7 @@ int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
if (!man->has_type) {
DRM_ERROR("Trying to take down uninitialized "
- "memory manager type\n");
+ "memory manager type %u\n", mem_type);
return ret;
}
man->use_type = 0;
@@ -1969,8 +2046,7 @@ int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
ret = 0;
if (mem_type > 0) {
-
- drm_bo_clean_unfenced(dev);
+ BUG_ON(!list_empty(&bm->unfenced));
drm_bo_force_list_clean(dev, &man->lru, mem_type, 1, 0, 0);
drm_bo_force_list_clean(dev, &man->pinned, mem_type, 1, 0, 1);
@@ -1983,6 +2059,7 @@ int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
return ret;
}
+EXPORT_SYMBOL(drm_bo_clean_mm);
/**
*Evict all buffers of a particular mem_type, but leave memory manager
@@ -1990,11 +2067,11 @@ int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
*point since we have the hardware lock.
*/
-static int drm_bo_lock_mm(drm_device_t * dev, unsigned mem_type)
+static int drm_bo_lock_mm(struct drm_device * dev, unsigned mem_type)
{
int ret;
- drm_buffer_manager_t *bm = &dev->bm;
- drm_mem_type_manager_t *man = &bm->man[mem_type];
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_mem_type_manager *man = &bm->man[mem_type];
if (mem_type == 0 || mem_type >= DRM_BO_MEM_TYPES) {
DRM_ERROR("Illegal memory manager memory type %u.\n", mem_type);
@@ -2007,7 +2084,6 @@ static int drm_bo_lock_mm(drm_device_t * dev, unsigned mem_type)
return 0;
}
- drm_bo_clean_unfenced(dev);
ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 0);
if (ret)
return ret;
@@ -2016,13 +2092,13 @@ static int drm_bo_lock_mm(drm_device_t * dev, unsigned mem_type)
return ret;
}
-int drm_bo_init_mm(drm_device_t * dev,
+int drm_bo_init_mm(struct drm_device * dev,
unsigned type,
unsigned long p_offset, unsigned long p_size)
{
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_buffer_manager *bm = &dev->bm;
int ret = -EINVAL;
- drm_mem_type_manager_t *man;
+ struct drm_mem_type_manager *man;
if (type >= DRM_BO_MEM_TYPES) {
DRM_ERROR("Illegal memory type %d\n", type);
@@ -2061,18 +2137,19 @@ int drm_bo_init_mm(drm_device_t * dev,
EXPORT_SYMBOL(drm_bo_init_mm);
/*
- * This is called from lastclose, so we don't need to bother about
- * any clients still running when we set the initialized flag to zero.
+ * This function is intended to be called on drm driver unload.
+ * If you decide to call it from lastclose, you must protect the call
+ * from a potentially racing drm_bo_driver_init in firstopen.
+ * (This may happen on X server restart).
*/
-int drm_bo_driver_finish(drm_device_t * dev)
+int drm_bo_driver_finish(struct drm_device * dev)
{
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_buffer_manager *bm = &dev->bm;
int ret = 0;
unsigned i = DRM_BO_MEM_TYPES;
- drm_mem_type_manager_t *man;
+ struct drm_mem_type_manager *man;
- mutex_lock(&dev->bm.init_mutex);
mutex_lock(&dev->struct_mutex);
if (!bm->initialized)
@@ -2112,17 +2189,23 @@ int drm_bo_driver_finish(drm_device_t * dev)
}
out:
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->bm.init_mutex);
return ret;
}
-int drm_bo_driver_init(drm_device_t * dev)
+/*
+ * This function is intended to be called on drm driver load.
+ * If you decide to call it from firstopen, you must protect the call
+ * from a potentially racing drm_bo_driver_finish in lastclose.
+ * (This may happen on X server restart).
+ */
+
+int drm_bo_driver_init(struct drm_device * dev)
{
- drm_bo_driver_t *driver = dev->driver->bo_driver;
- drm_buffer_manager_t *bm = &dev->bm;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ struct drm_buffer_manager *bm = &dev->bm;
int ret = -EINVAL;
- mutex_lock(&dev->bm.init_mutex);
+ drm_bo_init_lock(&bm->bm_lock);
mutex_lock(&dev->struct_mutex);
if (!driver)
goto out_unlock;
@@ -2131,8 +2214,7 @@ int drm_bo_driver_init(drm_device_t * dev)
* Initialize the system memory buffer type.
* Other types need to be driver / IOCTL initialized.
*/
-
- ret = drm_bo_init_mm(dev, 0, 0, 0);
+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0);
if (ret)
goto out_unlock;
@@ -2149,87 +2231,155 @@ int drm_bo_driver_init(drm_device_t * dev)
INIT_LIST_HEAD(&bm->ddestroy);
out_unlock:
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->bm.init_mutex);
return ret;
}
EXPORT_SYMBOL(drm_bo_driver_init);
-int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
+int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
-
- int ret = 0;
- drm_mm_init_arg_t arg;
- drm_buffer_manager_t *bm = &dev->bm;
- drm_bo_driver_t *driver = dev->driver->bo_driver;
+ struct drm_mm_init_arg *arg = data;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ int ret;
if (!driver) {
DRM_ERROR("Buffer objects are not supported by this driver\n");
return -EINVAL;
}
- DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
+ ret = drm_bo_write_lock(&bm->bm_lock, file_priv);
+ if (ret)
+ return ret;
- switch (arg.req.op) {
- case mm_init:
- ret = -EINVAL;
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized.\n");
- break;
- }
- if (arg.req.mem_type == 0) {
- DRM_ERROR
- ("System memory buffers already initialized.\n");
- break;
- }
- ret = drm_bo_init_mm(dev, arg.req.mem_type,
- arg.req.p_offset, arg.req.p_size);
- break;
- case mm_takedown:
- LOCK_TEST_WITH_RETURN(dev, filp);
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- ret = -EINVAL;
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized\n");
- break;
- }
- if (arg.req.mem_type == 0) {
- DRM_ERROR("No takedown for System memory buffers.\n");
- break;
- }
- ret = 0;
- if (drm_bo_clean_mm(dev, arg.req.mem_type)) {
- DRM_ERROR("Memory manager type %d not clean. "
- "Delaying takedown\n", arg.req.mem_type);
- }
- break;
- case mm_lock:
- LOCK_TEST_WITH_RETURN(dev, filp);
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- ret = drm_bo_lock_mm(dev, arg.req.mem_type);
- break;
- case mm_unlock:
- LOCK_TEST_WITH_RETURN(dev, filp);
- mutex_lock(&dev->bm.init_mutex);
- mutex_lock(&dev->struct_mutex);
- ret = 0;
- break;
- default:
- DRM_ERROR("Function not implemented yet\n");
+ ret = -EINVAL;
+ if (arg->magic != DRM_BO_INIT_MAGIC) {
+ DRM_ERROR("You are using an old libdrm that is not compatible with\n"
+ "\tthe kernel DRM module. Please upgrade your libdrm.\n");
+ return -EINVAL;
+ }
+ if (arg->major != DRM_BO_INIT_MAJOR) {
+ DRM_ERROR("libdrm and kernel DRM buffer object interface major\n"
+ "\tversion don't match. Got %d, expected %d.\n",
+ arg->major, DRM_BO_INIT_MAJOR);
return -EINVAL;
}
+ mutex_lock(&dev->struct_mutex);
+ if (!bm->initialized) {
+ DRM_ERROR("DRM memory manager was not initialized.\n");
+ goto out;
+ }
+ if (arg->mem_type == 0) {
+ DRM_ERROR("System memory buffers already initialized.\n");
+ goto out;
+ }
+ ret = drm_bo_init_mm(dev, arg->mem_type,
+ arg->p_offset, arg->p_size);
+
+out:
+ mutex_unlock(&dev->struct_mutex);
+ (void) drm_bo_write_unlock(&bm->bm_lock, file_priv);
+
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_mm_type_arg *arg = data;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ int ret;
+
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
+ return -EINVAL;
+ }
+
+ ret = drm_bo_write_lock(&bm->bm_lock, file_priv);
+ if (ret)
+ return ret;
+
+ mutex_lock(&dev->struct_mutex);
+ ret = -EINVAL;
+ if (!bm->initialized) {
+ DRM_ERROR("DRM memory manager was not initialized\n");
+ goto out;
+ }
+ if (arg->mem_type == 0) {
+ DRM_ERROR("No takedown for System memory buffers.\n");
+ goto out;
+ }
+ ret = 0;
+ if (drm_bo_clean_mm(dev, arg->mem_type)) {
+ DRM_ERROR("Memory manager type %d not clean. "
+ "Delaying takedown\n", arg->mem_type);
+ }
+out:
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->bm.init_mutex);
+ (void) drm_bo_write_unlock(&bm->bm_lock, file_priv);
+
if (ret)
return ret;
- DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
+ return 0;
+}
+
+int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_mm_type_arg *arg = data;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ int ret;
+
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
+ return -EINVAL;
+ }
+
+ if (arg->lock_flags & DRM_BO_LOCK_IGNORE_NO_EVICT) {
+ DRM_ERROR("Lock flag DRM_BO_LOCK_IGNORE_NO_EVICT not supported yet.\n");
+ return -EINVAL;
+ }
+
+ if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
+ ret = drm_bo_write_lock(&dev->bm.bm_lock, file_priv);
+ if (ret)
+ return ret;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_bo_lock_mm(dev, arg->mem_type);
+ mutex_unlock(&dev->struct_mutex);
+ if (ret) {
+ (void) drm_bo_write_unlock(&dev->bm.bm_lock, file_priv);
+ return ret;
+ }
+
+ return 0;
+}
+
+int drm_mm_unlock_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mm_type_arg *arg = data;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ int ret;
+
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
+ return -EINVAL;
+ }
+
+ if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
+ ret = drm_bo_write_unlock(&dev->bm.bm_lock, file_priv);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -2237,10 +2387,10 @@ int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
* buffer object vm functions.
*/
-int drm_mem_reg_is_pci(drm_device_t * dev, drm_bo_mem_reg_t * mem)
+int drm_mem_reg_is_pci(struct drm_device * dev, struct drm_bo_mem_reg * mem)
{
- 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];
if (!(man->flags & _DRM_FLAG_MEMTYPE_FIXED)) {
if (mem->mem_type == DRM_BO_MEM_LOCAL)
@@ -2271,13 +2421,13 @@ EXPORT_SYMBOL(drm_mem_reg_is_pci);
* Otherwise returns zero.
*/
-int drm_bo_pci_offset(drm_device_t * dev,
- drm_bo_mem_reg_t * mem,
+int drm_bo_pci_offset(struct drm_device *dev,
+ struct drm_bo_mem_reg *mem,
unsigned long *bus_base,
unsigned long *bus_offset, unsigned long *bus_size)
{
- 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];
*bus_size = 0;
if (!(man->flags & _DRM_FLAG_MEMTYPE_MAPPABLE))
@@ -2300,9 +2450,9 @@ int drm_bo_pci_offset(drm_device_t * dev,
* Call bo->mutex locked.
*/
-void drm_bo_unmap_virtual(drm_buffer_object_t * bo)
+void drm_bo_unmap_virtual(struct drm_buffer_object * bo)
{
- drm_device_t *dev = bo->dev;
+ struct drm_device *dev = bo->dev;
loff_t offset = ((loff_t) bo->map_list.hash.key) << PAGE_SHIFT;
loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT;
@@ -2312,12 +2462,13 @@ void drm_bo_unmap_virtual(drm_buffer_object_t * bo)
unmap_mapping_range(dev->dev_mapping, offset, holelen, 1);
}
-static void drm_bo_takedown_vm_locked(drm_buffer_object_t * bo)
+static void drm_bo_takedown_vm_locked(struct drm_buffer_object * bo)
{
- drm_map_list_t *list = &bo->map_list;
+ struct drm_map_list *list = &bo->map_list;
drm_local_map_t *map;
- drm_device_t *dev = bo->dev;
+ struct drm_device *dev = bo->dev;
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
if (list->user_token) {
drm_ht_remove_item(&dev->map_hash, &list->hash);
list->user_token = 0;
@@ -2334,15 +2485,16 @@ static void drm_bo_takedown_vm_locked(drm_buffer_object_t * bo)
drm_ctl_free(map, sizeof(*map), DRM_MEM_BUFOBJ);
list->map = NULL;
list->user_token = 0ULL;
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
}
-static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo)
+static int drm_bo_setup_vm_locked(struct drm_buffer_object * bo)
{
- drm_map_list_t *list = &bo->map_list;
+ struct drm_map_list *list = &bo->map_list;
drm_local_map_t *map;
- drm_device_t *dev = bo->dev;
+ struct drm_device *dev = bo->dev;
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
list->map = drm_ctl_calloc(1, sizeof(*map), DRM_MEM_BUFOBJ);
if (!list->map)
return -ENOMEM;
@@ -2372,7 +2524,19 @@ static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo)
return -ENOMEM;
}
- list->user_token = ((drm_u64_t) list->hash.key) << PAGE_SHIFT;
+ list->user_token = ((uint64_t) list->hash.key) << PAGE_SHIFT;
+
+ return 0;
+}
+
+int drm_bo_version_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_bo_version_arg *arg = (struct drm_bo_version_arg *)data;
+
+ arg->major = DRM_BO_INIT_MAJOR;
+ arg->minor = DRM_BO_INIT_MINOR;
+ arg->patchlevel = DRM_BO_INIT_PATCH;
return 0;
}
diff --git a/linux-core/drm_bo_lock.c b/linux-core/drm_bo_lock.c
new file mode 100644
index 00000000..e5a86826
--- /dev/null
+++ b/linux-core/drm_bo_lock.c
@@ -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;
+}
diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c
index 4f752065..7c86c4aa 100644
--- a/linux-core/drm_bo_move.c
+++ b/linux-core/drm_bo_move.c
@@ -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);
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index a2c8a75e..60eca60c 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -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(&current->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(&current->mm->mmap_sem);
} else {
down_write(&current->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(&current->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;
}
diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c
index 08d20d06..ae44e500 100644
--- a/linux-core/drm_compat.c
+++ b/linux-core/drm_compat.c
@@ -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,
+
+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
diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h
index 024059ac..f74f4bc2 100644
--- a/linux-core/drm_compat.h
+++ b/linux-core/drm_compat.h
@@ -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
diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c
index 101a298c..7854e89c 100644
--- a/linux-core/drm_context.c
+++ b/linux-core/drm_context.c
@@ -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;
-
- if (copy_from_user(&ctx, argp, sizeof(ctx)))
- return -EFAULT;
+ struct drm_ctx_list *ctx_entry;
+ struct drm_ctx *ctx = data;
- 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;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
+ struct drm_ctx *ctx = data;
- 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;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
+ struct drm_ctx *ctx = data;
- 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;
diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c
index a7eee1a4..7cc44193 100644
--- a/linux-core/drm_dma.c
+++ b/linux-core/drm_dma.c
@@ -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]);
diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c
index eb44a189..1839c576 100644
--- a/linux-core/drm_drawable.c
+++ b/linux-core/drm_drawable.c
@@ -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;
-
- DRM_DEBUG("%d\n", draw.handle);
+ draw->handle = new_id;
- 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);
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 1b37ee4a..296a3268 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -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},
-
- [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_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_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_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_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_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_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},
+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_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_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_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_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_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_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_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_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_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_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_DEF(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 &&
diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c
index ce161dc3..e696b42d 100644
--- a/linux-core/drm_fence.c
+++ b/linux-core/drm_fence.c
@@ -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;
-
- if (atomic_dec_and_test(&fence->usage)) {
- drm_fence_unring(dev, &fence->ring);
+ struct drm_fence_object *tmp_fence = *fence;
+ struct drm_device *dev = tmp_fence->dev;
+ struct drm_fence_manager *fm = &dev->fm;
+
+ 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);
-drm_fence_object_t *drm_lookup_fence_object(drm_file_t * priv, uint32_t handle)
+
+void drm_fence_manager_takedown(struct drm_device * dev)
+{
+}
+
+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;
- }
+ 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;
+ 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;
+ }
+
+ /*
+ * usage > 0. No need to lock dev->struct_mutex;
+ */
- /*
- * usage > 0. No need to lock dev->struct_mutex;
- */
+ arg->handle = fence->base.hash.key;
- 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);
+
+ 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;
- 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);
+ 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;
- 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 &
+
+ 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;
- 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));
+ arg->handle = fence->base.hash.key;
+
+ drm_fence_fill_arg(fence, arg);
+ drm_fence_usage_deref_unlocked(&fence);
+
return ret;
}
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index e54d5079..0ccaed5b 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -39,9 +39,9 @@
#include <linux/poll.h>
static int drm_open_helper(struct inode *inode, struct file *filp,
- drm_device_t * dev);
+ struct drm_device * dev);
-static int drm_setup(drm_device_t * dev)
+static int drm_setup(struct drm_device * dev)
{
drm_local_map_t *map;
int i;
@@ -128,7 +128,7 @@ static int drm_setup(drm_device_t * dev)
*/
int drm_open(struct inode *inode, struct file *filp)
{
- drm_device_t *dev = NULL;
+ struct drm_device *dev = NULL;
int minor = iminor(inode);
int retcode = 0;
@@ -176,7 +176,7 @@ EXPORT_SYMBOL(drm_open);
*/
int drm_stub_open(struct inode *inode, struct file *filp)
{
- drm_device_t *dev = NULL;
+ struct drm_device *dev = NULL;
int minor = iminor(inode);
int err = -ENODEV;
const struct file_operations *old_fops;
@@ -232,10 +232,10 @@ static int drm_cpu_valid(void)
* filp and add it into the double linked list in \p dev.
*/
static int drm_open_helper(struct inode *inode, struct file *filp,
- drm_device_t * dev)
+ struct drm_device * dev)
{
int minor = iminor(inode);
- drm_file_t *priv;
+ struct drm_file *priv;
int ret;
int i,j;
@@ -252,6 +252,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
memset(priv, 0, sizeof(*priv));
filp->private_data = priv;
+ priv->filp = filp;
priv->uid = current->euid;
priv->pid = current->pid;
priv->minor = minor;
@@ -262,7 +263,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
priv->lock_count = 0;
INIT_LIST_HEAD(&priv->lhead);
- INIT_LIST_HEAD(&priv->user_objects);
INIT_LIST_HEAD(&priv->refd_objects);
for (i=0; i<_DRM_NO_REF_TYPES; ++i) {
@@ -320,8 +320,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
/** No-op. */
int drm_fasync(int fd, struct file *filp, int on)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev = priv->head->dev;
int retcode;
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
@@ -335,10 +335,9 @@ EXPORT_SYMBOL(drm_fasync);
static void drm_object_release(struct file *filp) {
- drm_file_t *priv = filp->private_data;
+ struct drm_file *priv = filp->private_data;
struct list_head *head;
- drm_user_object_t *user_object;
- drm_ref_object_t *ref_object;
+ struct drm_ref_object *ref_object;
int i;
/*
@@ -351,22 +350,11 @@ static void drm_object_release(struct file *filp) {
head = &priv->refd_objects;
while (head->next != head) {
- ref_object = list_entry(head->next, drm_ref_object_t, list);
+ ref_object = list_entry(head->next, struct drm_ref_object, list);
drm_remove_ref_object(priv, ref_object);
head = &priv->refd_objects;
}
- /*
- * Free leftover user objects created by me.
- */
-
- head = &priv->user_objects;
- while (head->next != head) {
- user_object = list_entry(head->next, drm_user_object_t, list);
- drm_remove_user_object(priv, user_object);
- head = &priv->user_objects;
- }
-
for(i=0; i<_DRM_NO_REF_TYPES; ++i) {
drm_ht_remove(&priv->refd_object_hash[i]);
}
@@ -376,7 +364,7 @@ static void drm_object_release(struct file *filp) {
* Release file.
*
* \param inode device inode
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \return zero on success or a negative number on failure.
*
* If the hardware lock is held then free it, and take it again for the kernel
@@ -386,29 +374,28 @@ static void drm_object_release(struct file *filp) {
*/
int drm_release(struct inode *inode, struct file *filp)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
+ struct drm_file *file_priv = filp->private_data;
+ struct drm_device *dev = file_priv->head->dev;
int retcode = 0;
lock_kernel();
- dev = priv->head->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (dev->driver->preclose)
- dev->driver->preclose(dev, filp);
+ dev->driver->preclose(dev, file_priv);
/* ========================================================
* Begin inline drm_release
*/
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
- current->pid, (long)old_encode_dev(priv->head->device),
+ current->pid, (long)old_encode_dev(file_priv->head->device),
dev->open_count);
if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
- if (drm_i_have_hw_lock(filp)) {
- dev->driver->reclaim_buffers_locked(dev, filp);
+ if (drm_i_have_hw_lock(dev, file_priv)) {
+ dev->driver->reclaim_buffers_locked(dev, file_priv);
} else {
unsigned long _end=jiffies + 3*DRM_HZ;
int locked = 0;
@@ -434,7 +421,7 @@ int drm_release(struct inode *inode, struct file *filp)
"\tI will go on reclaiming the buffers anyway.\n");
}
- dev->driver->reclaim_buffers_locked(dev, filp);
+ dev->driver->reclaim_buffers_locked(dev, file_priv);
drm_idlelock_release(&dev->lock);
}
}
@@ -442,12 +429,12 @@ int drm_release(struct inode *inode, struct file *filp)
if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) {
drm_idlelock_take(&dev->lock);
- dev->driver->reclaim_buffers_idlelocked(dev, filp);
+ dev->driver->reclaim_buffers_idlelocked(dev, file_priv);
drm_idlelock_release(&dev->lock);
}
- if (drm_i_have_hw_lock(filp)) {
+ if (drm_i_have_hw_lock(dev, file_priv)) {
DRM_DEBUG("File %p released, freeing lock for context %d\n",
filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
@@ -458,7 +445,7 @@ int drm_release(struct inode *inode, struct file *filp)
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
!dev->driver->reclaim_buffers_locked) {
- dev->driver->reclaim_buffers(dev, filp);
+ dev->driver->reclaim_buffers(dev, file_priv);
}
drm_fasync(-1, filp, 0);
@@ -466,10 +453,10 @@ int drm_release(struct inode *inode, struct file *filp)
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->tag == priv &&
+ if (pos->tag == file_priv &&
pos->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev,
@@ -487,18 +474,18 @@ int drm_release(struct inode *inode, struct file *filp)
mutex_lock(&dev->struct_mutex);
drm_object_release(filp);
- if (priv->remove_auth_on_close == 1) {
- drm_file_t *temp;
+ if (file_priv->remove_auth_on_close == 1) {
+ struct drm_file *temp;
list_for_each_entry(temp, &dev->filelist, lhead)
temp->authenticated = 0;
}
- list_del(&priv->lhead);
+ list_del(&file_priv->lhead);
mutex_unlock(&dev->struct_mutex);
if (dev->driver->postclose)
- dev->driver->postclose(dev, priv);
- drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+ dev->driver->postclose(dev, file_priv);
+ drm_free(file_priv, sizeof(*file_priv), DRM_MEM_FILES);
/* ========================================================
* End inline drm_release
diff --git a/linux-core/drm_hashtab.c b/linux-core/drm_hashtab.c
index 6f17e114..a8ec8468 100644
--- a/linux-core/drm_hashtab.c
+++ b/linux-core/drm_hashtab.c
@@ -36,7 +36,7 @@
#include "drm_hashtab.h"
#include <linux/hash.h>
-int drm_ht_create(drm_open_hash_t * ht, unsigned int order)
+int drm_ht_create(struct drm_open_hash * ht, unsigned int order)
{
unsigned int i;
@@ -63,9 +63,9 @@ int drm_ht_create(drm_open_hash_t * ht, unsigned int order)
return 0;
}
-void drm_ht_verbose_list(drm_open_hash_t * ht, unsigned long key)
+void drm_ht_verbose_list(struct drm_open_hash * ht, unsigned long key)
{
- drm_hash_item_t *entry;
+ struct drm_hash_item *entry;
struct hlist_head *h_list;
struct hlist_node *list;
unsigned int hashed_key;
@@ -75,15 +75,15 @@ void drm_ht_verbose_list(drm_open_hash_t * ht, unsigned long key)
DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key);
h_list = &ht->table[hashed_key];
hlist_for_each(list, h_list) {
- entry = hlist_entry(list, drm_hash_item_t, head);
+ entry = hlist_entry(list, struct drm_hash_item, head);
DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key);
}
}
-static struct hlist_node *drm_ht_find_key(drm_open_hash_t * ht,
+static struct hlist_node *drm_ht_find_key(struct drm_open_hash * ht,
unsigned long key)
{
- drm_hash_item_t *entry;
+ struct drm_hash_item *entry;
struct hlist_head *h_list;
struct hlist_node *list;
unsigned int hashed_key;
@@ -91,7 +91,7 @@ static struct hlist_node *drm_ht_find_key(drm_open_hash_t * ht,
hashed_key = hash_long(key, ht->order);
h_list = &ht->table[hashed_key];
hlist_for_each(list, h_list) {
- entry = hlist_entry(list, drm_hash_item_t, head);
+ entry = hlist_entry(list, struct drm_hash_item, head);
if (entry->key == key)
return list;
if (entry->key > key)
@@ -100,9 +100,9 @@ static struct hlist_node *drm_ht_find_key(drm_open_hash_t * ht,
return NULL;
}
-int drm_ht_insert_item(drm_open_hash_t * ht, drm_hash_item_t * item)
+int drm_ht_insert_item(struct drm_open_hash * ht, struct drm_hash_item * item)
{
- drm_hash_item_t *entry;
+ struct drm_hash_item *entry;
struct hlist_head *h_list;
struct hlist_node *list, *parent;
unsigned int hashed_key;
@@ -112,7 +112,7 @@ int drm_ht_insert_item(drm_open_hash_t * ht, drm_hash_item_t * item)
h_list = &ht->table[hashed_key];
parent = NULL;
hlist_for_each(list, h_list) {
- entry = hlist_entry(list, drm_hash_item_t, head);
+ entry = hlist_entry(list, struct drm_hash_item, head);
if (entry->key == key)
return -EINVAL;
if (entry->key > key)
@@ -131,7 +131,7 @@ int drm_ht_insert_item(drm_open_hash_t * ht, drm_hash_item_t * item)
* Just insert an item and return any "bits" bit key that hasn't been
* used before.
*/
-int drm_ht_just_insert_please(drm_open_hash_t * ht, drm_hash_item_t * item,
+int drm_ht_just_insert_please(struct drm_open_hash * ht, struct drm_hash_item * item,
unsigned long seed, int bits, int shift,
unsigned long add)
{
@@ -155,8 +155,8 @@ int drm_ht_just_insert_please(drm_open_hash_t * ht, drm_hash_item_t * item,
return 0;
}
-int drm_ht_find_item(drm_open_hash_t * ht, unsigned long key,
- drm_hash_item_t ** item)
+int drm_ht_find_item(struct drm_open_hash * ht, unsigned long key,
+ struct drm_hash_item ** item)
{
struct hlist_node *list;
@@ -164,11 +164,11 @@ int drm_ht_find_item(drm_open_hash_t * ht, unsigned long key,
if (!list)
return -EINVAL;
- *item = hlist_entry(list, drm_hash_item_t, head);
+ *item = hlist_entry(list, struct drm_hash_item, head);
return 0;
}
-int drm_ht_remove_key(drm_open_hash_t * ht, unsigned long key)
+int drm_ht_remove_key(struct drm_open_hash * ht, unsigned long key)
{
struct hlist_node *list;
@@ -181,14 +181,14 @@ int drm_ht_remove_key(drm_open_hash_t * ht, unsigned long key)
return -EINVAL;
}
-int drm_ht_remove_item(drm_open_hash_t * ht, drm_hash_item_t * item)
+int drm_ht_remove_item(struct drm_open_hash * ht, struct drm_hash_item * item)
{
hlist_del_init(&item->head);
ht->fill--;
return 0;
}
-void drm_ht_remove(drm_open_hash_t * ht)
+void drm_ht_remove(struct drm_open_hash * ht)
{
if (ht->table) {
if (ht->use_vmalloc)
diff --git a/linux-core/drm_hashtab.h b/linux-core/drm_hashtab.h
index 613091c9..0f137677 100644
--- a/linux-core/drm_hashtab.h
+++ b/linux-core/drm_hashtab.h
@@ -37,31 +37,31 @@
#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
-typedef struct drm_hash_item{
+struct drm_hash_item {
struct hlist_node head;
unsigned long key;
-} drm_hash_item_t;
+};
-typedef struct drm_open_hash{
+struct drm_open_hash {
unsigned int size;
unsigned int order;
unsigned int fill;
struct hlist_head *table;
int use_vmalloc;
-} drm_open_hash_t;
+};
-extern int drm_ht_create(drm_open_hash_t *ht, unsigned int order);
-extern int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item);
-extern int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item,
+extern int drm_ht_create(struct drm_open_hash *ht, unsigned int order);
+extern int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item);
+extern int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item,
unsigned long seed, int bits, int shift,
unsigned long add);
-extern int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, drm_hash_item_t **item);
+extern int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item);
-extern void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key);
-extern int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key);
-extern int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item);
-extern void drm_ht_remove(drm_open_hash_t *ht);
+extern void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key);
+extern int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key);
+extern int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item);
+extern void drm_ht_remove(struct drm_open_hash *ht);
#endif
diff --git a/linux-core/drm_ioc32.c b/linux-core/drm_ioc32.c
index bbab3ea2..0188154e 100644
--- a/linux-core/drm_ioc32.c
+++ b/linux-core/drm_ioc32.c
@@ -82,7 +82,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_version32_t v32;
- drm_version_t __user *version;
+ struct drm_version __user *version;
int err;
if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
@@ -129,7 +129,7 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_unique32_t uq32;
- drm_unique_t __user *u;
+ struct drm_unique __user *u;
int err;
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
@@ -159,7 +159,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_unique32_t uq32;
- drm_unique_t __user *u;
+ struct drm_unique __user *u;
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
return -EFAULT;
@@ -179,8 +179,8 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd,
typedef struct drm_map32 {
u32 offset; /**< Requested physical address (0 for SAREA)*/
u32 size; /**< Requested physical size (bytes) */
- drm_map_type_t type; /**< Type of memory to map */
- drm_map_flags_t flags; /**< Flags */
+ enum drm_map_type type; /**< Type of memory to map */
+ enum drm_map_flags flags; /**< Flags */
u32 handle; /**< User-space: "Handle" to pass to mmap() */
int mtrr; /**< MTRR slot used */
} drm_map32_t;
@@ -190,7 +190,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
{
drm_map32_t __user *argp = (void __user *)arg;
drm_map32_t m32;
- drm_map_t __user *map;
+ struct drm_map __user *map;
int idx, err;
void *handle;
@@ -228,7 +228,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
{
drm_map32_t __user *argp = (void __user *)arg;
drm_map32_t m32;
- drm_map_t __user *map;
+ struct drm_map __user *map;
int err;
void *handle;
@@ -270,7 +270,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_map32_t __user *argp = (void __user *)arg;
- drm_map_t __user *map;
+ struct drm_map __user *map;
u32 handle;
if (get_user(handle, &argp->handle))
@@ -300,7 +300,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
{
drm_client32_t c32;
drm_client32_t __user *argp = (void __user *)arg;
- drm_client_t __user *client;
+ struct drm_client __user *client;
int idx, err;
if (get_user(idx, &argp->idx))
@@ -333,7 +333,7 @@ typedef struct drm_stats32 {
u32 count;
struct {
u32 value;
- drm_stat_type_t type;
+ enum drm_stat_type type;
} data[15];
} drm_stats32_t;
@@ -342,7 +342,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
{
drm_stats32_t s32;
drm_stats32_t __user *argp = (void __user *)arg;
- drm_stats_t __user *stats;
+ struct drm_stats __user *stats;
int i, err;
stats = compat_alloc_user_space(sizeof(*stats));
@@ -379,7 +379,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_buf_desc32_t __user *argp = (void __user *)arg;
- drm_buf_desc_t __user *buf;
+ struct drm_buf_desc __user *buf;
int err;
unsigned long agp_start;
@@ -411,7 +411,7 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd,
{
drm_buf_desc32_t b32;
drm_buf_desc32_t __user *argp = (void __user *)arg;
- drm_buf_desc_t __user *buf;
+ struct drm_buf_desc __user *buf;
if (copy_from_user(&b32, argp, sizeof(b32)))
return -EFAULT;
@@ -440,8 +440,8 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
drm_buf_info32_t req32;
drm_buf_info32_t __user *argp = (void __user *)arg;
drm_buf_desc32_t __user *to;
- drm_buf_info_t __user *request;
- drm_buf_desc_t __user *list;
+ struct drm_buf_info __user *request;
+ struct drm_buf_desc __user *list;
size_t nbytes;
int i, err;
int count, actual;
@@ -457,11 +457,11 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
&& !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
return -EFAULT;
- nbytes = sizeof(*request) + count * sizeof(drm_buf_desc_t);
+ nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc);
request = compat_alloc_user_space(nbytes);
if (!access_ok(VERIFY_WRITE, request, nbytes))
return -EFAULT;
- list = (drm_buf_desc_t *) (request + 1);
+ list = (struct drm_buf_desc *) (request + 1);
if (__put_user(count, &request->count)
|| __put_user(list, &request->list))
@@ -477,7 +477,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
if (count >= actual)
for (i = 0; i < actual; ++i)
if (__copy_in_user(&to[i], &list[i],
- offsetof(drm_buf_desc_t, flags)))
+ offsetof(struct drm_buf_desc, flags)))
return -EFAULT;
if (__put_user(actual, &argp->count))
@@ -505,8 +505,8 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
drm_buf_map32_t __user *argp = (void __user *)arg;
drm_buf_map32_t req32;
drm_buf_pub32_t __user *list32;
- drm_buf_map_t __user *request;
- drm_buf_pub_t __user *list;
+ struct drm_buf_map __user *request;
+ struct drm_buf_pub __user *list;
int i, err;
int count, actual;
size_t nbytes;
@@ -519,11 +519,11 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
if (count < 0)
return -EINVAL;
- nbytes = sizeof(*request) + count * sizeof(drm_buf_pub_t);
+ nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub);
request = compat_alloc_user_space(nbytes);
if (!access_ok(VERIFY_WRITE, request, nbytes))
return -EFAULT;
- list = (drm_buf_pub_t *) (request + 1);
+ list = (struct drm_buf_pub *) (request + 1);
if (__put_user(count, &request->count)
|| __put_user(list, &request->list))
@@ -539,7 +539,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
if (count >= actual)
for (i = 0; i < actual; ++i)
if (__copy_in_user(&list32[i], &list[i],
- offsetof(drm_buf_pub_t, address))
+ offsetof(struct drm_buf_pub, address))
|| __get_user(addr, &list[i].address)
|| __put_user((unsigned long)addr,
&list32[i].address))
@@ -562,7 +562,7 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_buf_free32_t req32;
- drm_buf_free_t __user *request;
+ struct drm_buf_free __user *request;
drm_buf_free32_t __user *argp = (void __user *)arg;
if (copy_from_user(&req32, argp, sizeof(req32)))
@@ -589,7 +589,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_ctx_priv_map32_t req32;
- drm_ctx_priv_map_t __user *request;
+ struct drm_ctx_priv_map __user *request;
drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
if (copy_from_user(&req32, argp, sizeof(req32)))
@@ -610,7 +610,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
unsigned long arg)
{
- drm_ctx_priv_map_t __user *request;
+ struct drm_ctx_priv_map __user *request;
drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
int err;
unsigned int ctx_id;
@@ -648,7 +648,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
{
drm_ctx_res32_t __user *argp = (void __user *)arg;
drm_ctx_res32_t res32;
- drm_ctx_res_t __user *res;
+ struct drm_ctx_res __user *res;
int err;
if (copy_from_user(&res32, argp, sizeof(res32)))
@@ -658,7 +658,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
return -EFAULT;
if (__put_user(res32.count, &res->count)
- || __put_user((drm_ctx_t __user *)(unsigned long)res32.contexts,
+ || __put_user((struct drm_ctx __user *) (unsigned long)res32.contexts,
&res->contexts))
return -EFAULT;
@@ -679,7 +679,7 @@ typedef struct drm_dma32 {
int send_count; /**< Number of buffers to send */
u32 send_indices; /**< List of handles to buffers */
u32 send_sizes; /**< Lengths of data to send */
- drm_dma_flags_t flags; /**< Flags */
+ enum drm_dma_flags flags; /**< Flags */
int request_count; /**< Number of buffers requested */
int request_size; /**< Desired size for buffers */
u32 request_indices; /**< Buffer information */
@@ -692,7 +692,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd,
{
drm_dma32_t d32;
drm_dma32_t __user *argp = (void __user *)arg;
- drm_dma_t __user *d;
+ struct drm_dma __user *d;
int err;
if (copy_from_user(&d32, argp, sizeof(d32)))
@@ -740,7 +740,7 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
{
drm_agp_mode32_t __user *argp = (void __user *)arg;
drm_agp_mode32_t m32;
- drm_agp_mode_t __user *mode;
+ struct drm_agp_mode __user *mode;
if (get_user(m32.mode, &argp->mode))
return -EFAULT;
@@ -772,7 +772,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd,
{
drm_agp_info32_t __user *argp = (void __user *)arg;
drm_agp_info32_t i32;
- drm_agp_info_t __user *info;
+ struct drm_agp_info __user *info;
int err;
info = compat_alloc_user_space(sizeof(*info));
@@ -813,7 +813,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
{
drm_agp_buffer32_t __user *argp = (void __user *)arg;
drm_agp_buffer32_t req32;
- drm_agp_buffer_t __user *request;
+ struct drm_agp_buffer __user *request;
int err;
if (copy_from_user(&req32, argp, sizeof(req32)))
@@ -845,7 +845,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_agp_buffer32_t __user *argp = (void __user *)arg;
- drm_agp_buffer_t __user *request;
+ struct drm_agp_buffer __user *request;
u32 handle;
request = compat_alloc_user_space(sizeof(*request));
@@ -868,7 +868,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
{
drm_agp_binding32_t __user *argp = (void __user *)arg;
drm_agp_binding32_t req32;
- drm_agp_binding_t __user *request;
+ struct drm_agp_binding __user *request;
if (copy_from_user(&req32, argp, sizeof(req32)))
return -EFAULT;
@@ -887,7 +887,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_agp_binding32_t __user *argp = (void __user *)arg;
- drm_agp_binding_t __user *request;
+ struct drm_agp_binding __user *request;
u32 handle;
request = compat_alloc_user_space(sizeof(*request));
@@ -910,7 +910,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_scatter_gather32_t __user *argp = (void __user *)arg;
- drm_scatter_gather_t __user *request;
+ struct drm_scatter_gather __user *request;
int err;
unsigned long x;
@@ -938,7 +938,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
unsigned long arg)
{
drm_scatter_gather32_t __user *argp = (void __user *)arg;
- drm_scatter_gather_t __user *request;
+ struct drm_scatter_gather __user *request;
unsigned long x;
request = compat_alloc_user_space(sizeof(*request));
@@ -953,13 +953,13 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
}
struct drm_wait_vblank_request32 {
- drm_vblank_seq_type_t type;
+ enum drm_vblank_seq_type type;
unsigned int sequence;
u32 signal;
};
struct drm_wait_vblank_reply32 {
- drm_vblank_seq_type_t type;
+ enum drm_vblank_seq_type type;
unsigned int sequence;
s32 tval_sec;
s32 tval_usec;
@@ -975,7 +975,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
{
drm_wait_vblank32_t __user *argp = (void __user *)arg;
drm_wait_vblank32_t req32;
- drm_wait_vblank_t __user *request;
+ union drm_wait_vblank __user *request;
int err;
if (copy_from_user(&req32, argp, sizeof(req32)))
@@ -1040,7 +1040,7 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = {
* Called whenever a 32-bit process running under a 64-bit kernel
* performs an ioctl on /dev/drm.
*
- * \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.
@@ -1051,8 +1051,13 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
drm_ioctl_compat_t *fn;
int ret;
+
+ /* Assume that ioctls without an explicit compat routine will "just
+ * work". This may not always be a good assumption, but it's better
+ * than always failing.
+ */
if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls))
- return -ENOTTY;
+ return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
fn = drm_compat_ioctls[nr];
diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c
index 97df972f..9d52fd8a 100644
--- a/linux-core/drm_ioctl.c
+++ b/linux-core/drm_ioctl.c
@@ -42,30 +42,24 @@
* Get the bus id.
*
* \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_unique structure.
* \return zero on success or a negative number on failure.
*
* Copies the bus id from drm_device::unique into user space.
*/
-int drm_getunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_getunique(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_unique_t __user *argp = (void __user *)arg;
- drm_unique_t u;
+ struct drm_unique *u = data;
- if (copy_from_user(&u, argp, sizeof(u)))
- return -EFAULT;
- if (u.unique_len >= dev->unique_len) {
- if (copy_to_user(u.unique, dev->unique, dev->unique_len))
+ if (u->unique_len >= dev->unique_len) {
+ if (copy_to_user(u->unique, dev->unique, dev->unique_len))
return -EFAULT;
}
- u.unique_len = dev->unique_len;
- if (copy_to_user(argp, &u, sizeof(u)))
- return -EFAULT;
+ u->unique_len = dev->unique_len;
+
return 0;
}
@@ -73,7 +67,7 @@ int drm_getunique(struct inode *inode, struct file *filp,
* Set the bus id.
*
* \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_unique structure.
* \return zero on success or a negative number on failure.
@@ -83,28 +77,23 @@ int drm_getunique(struct inode *inode, struct file *filp,
* in interface version 1.1 and will return EBUSY when setversion has requested
* version 1.1 or greater.
*/
-int drm_setunique(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_setunique(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_unique_t u;
+ struct drm_unique *u = data;
int domain, bus, slot, func, ret;
if (dev->unique_len || dev->unique)
return -EBUSY;
- if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u)))
- return -EFAULT;
-
- if (!u.unique_len || u.unique_len > 1024)
+ if (!u->unique_len || u->unique_len > 1024)
return -EINVAL;
- dev->unique_len = u.unique_len;
- dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
+ dev->unique_len = u->unique_len;
+ dev->unique = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER);
if (!dev->unique)
return -ENOMEM;
- if (copy_from_user(dev->unique, u.unique, dev->unique_len))
+ if (copy_from_user(dev->unique, u->unique, dev->unique_len))
return -EFAULT;
dev->unique[dev->unique_len] = '\0';
@@ -121,7 +110,7 @@ int drm_setunique(struct inode *inode, struct file *filp,
*/
ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
if (ret != 3)
- return DRM_ERR(EINVAL);
+ return -EINVAL;
domain = bus >> 8;
bus &= 0xff;
@@ -134,7 +123,7 @@ int drm_setunique(struct inode *inode, struct file *filp,
return 0;
}
-static int drm_set_busid(drm_device_t * dev)
+static int drm_set_busid(struct drm_device * dev)
{
int len;
if (dev->unique != NULL)
@@ -167,7 +156,7 @@ static int drm_set_busid(drm_device_t * dev)
* Get a mapping 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_map structure.
*
@@ -176,21 +165,16 @@ static int drm_set_busid(drm_device_t * dev)
* Searches for the mapping with the specified offset and copies its information
* into userspace
*/
-int drm_getmap(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_getmap(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 __user *argp = (void __user *)arg;
- drm_map_t map;
- drm_map_list_t *r_list = NULL;
+ struct drm_map *map = data;
+ struct drm_map_list *r_list = NULL;
struct list_head *list;
int idx;
int i;
- if (copy_from_user(&map, argp, sizeof(map)))
- return -EFAULT;
- idx = map.offset;
+ idx = map->offset;
mutex_lock(&dev->struct_mutex);
if (idx < 0) {
@@ -201,7 +185,7 @@ int drm_getmap(struct inode *inode, struct file *filp,
i = 0;
list_for_each(list, &dev->maplist) {
if (i == idx) {
- r_list = list_entry(list, drm_map_list_t, head);
+ r_list = list_entry(list, struct drm_map_list, head);
break;
}
i++;
@@ -211,16 +195,14 @@ int drm_getmap(struct inode *inode, struct file *filp,
return -EINVAL;
}
- map.offset = r_list->map->offset;
- map.size = r_list->map->size;
- map.type = r_list->map->type;
- map.flags = r_list->map->flags;
- map.handle = (void *)(unsigned long) r_list->user_token;
- map.mtrr = r_list->map->mtrr;
+ map->offset = r_list->map->offset;
+ map->size = r_list->map->size;
+ map->type = r_list->map->type;
+ map->flags = r_list->map->flags;
+ map->handle = (void *)(unsigned long) r_list->user_token;
+ map->mtrr = r_list->map->mtrr;
mutex_unlock(&dev->struct_mutex);
- if (copy_to_user(argp, &map, sizeof(map)))
- return -EFAULT;
return 0;
}
@@ -228,7 +210,7 @@ int drm_getmap(struct inode *inode, struct file *filp,
* Get client 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_client structure.
*
@@ -237,82 +219,68 @@ int drm_getmap(struct inode *inode, struct file *filp,
* Searches for the client with the specified index and copies its information
* into userspace
*/
-int drm_getclient(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_getclient(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_client_t __user *argp = (drm_client_t __user *)arg;
- drm_client_t client;
- drm_file_t *pt;
+ struct drm_client *client = data;
+ struct drm_file *pt;
int idx;
int i;
- if (copy_from_user(&client, argp, sizeof(client)))
- return -EFAULT;
- idx = client.idx;
+ idx = client->idx;
mutex_lock(&dev->struct_mutex);
-
- if (list_empty(&dev->filelist)) {
- mutex_unlock(&dev->struct_mutex);
- return -EINVAL;
- }
i = 0;
list_for_each_entry(pt, &dev->filelist, lhead) {
- if (i++ >= idx)
- break;
+ if (i++ >= idx) {
+ client->auth = pt->authenticated;
+ client->pid = pt->pid;
+ client->uid = pt->uid;
+ client->magic = pt->magic;
+ client->iocs = pt->ioctl_count;
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+ }
}
-
- client.auth = pt->authenticated;
- client.pid = pt->pid;
- client.uid = pt->uid;
- client.magic = pt->magic;
- client.iocs = pt->ioctl_count;
mutex_unlock(&dev->struct_mutex);
- if (copy_to_user(argp, &client, sizeof(client)))
- return -EFAULT;
- return 0;
+ return -EINVAL;
}
/**
* Get statistics 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_stats structure.
*
* \return zero on success or a negative number on failure.
*/
-int drm_getstats(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_getstats(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_stats_t stats;
+ struct drm_stats *stats = data;
int i;
- memset(&stats, 0, sizeof(stats));
+ memset(stats, 0, sizeof(stats));
mutex_lock(&dev->struct_mutex);
for (i = 0; i < dev->counters; i++) {
if (dev->types[i] == _DRM_STAT_LOCK)
- stats.data[i].value
- = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
+ 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;
mutex_unlock(&dev->struct_mutex);
- if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
- return -EFAULT;
return 0;
}
@@ -320,39 +288,28 @@ int drm_getstats(struct inode *inode, struct file *filp,
* Setversion ioctl.
*
* \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_lock structure.
* \return zero on success or negative number on failure.
*
* Sets the requested interface version
*/
-int drm_setversion(DRM_IOCTL_ARGS)
+int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_set_version_t sv;
- drm_set_version_t retv;
- int if_version;
- drm_set_version_t __user *argp = (void __user *)data;
-
- if (copy_from_user(&sv, argp, sizeof(sv)))
- return -EFAULT;
-
- 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;
-
- if (copy_to_user(argp, &retv, sizeof(retv)))
- return -EFAULT;
-
- 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)
- return -EINVAL;
- if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor);
+ struct drm_set_version *sv = data;
+ int if_version, retcode = 0;
+
+ 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) {
+ retcode = -EINVAL;
+ goto done;
+ }
+ if_version = DRM_IF_VERSION(sv->drm_di_major,
+ sv->drm_di_minor);
dev->if_version = max(if_version, dev->if_version);
- if (sv.drm_di_minor >= 1) {
+ if (sv->drm_di_minor >= 1) {
/*
* Version 1.1 includes tying of DRM to specific device
*/
@@ -360,20 +317,30 @@ 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)
- return -EINVAL;
+ 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) {
+ retcode = -EINVAL;
+ goto done;
+ }
if (dev->driver->set_version)
- dev->driver->set_version(dev, &sv);
+ dev->driver->set_version(dev, sv);
}
- return 0;
+
+done:
+ 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;
+
+ return retcode;
}
/** No-op ioctl. */
-int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+int drm_noop(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
DRM_DEBUG("\n");
return 0;
diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c
index eea00ac8..e917e7eb 100644
--- a/linux-core/drm_irq.c
+++ b/linux-core/drm_irq.c
@@ -41,7 +41,7 @@
* Get interrupt from bus id.
*
* \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_irq_busid structure.
* \return zero on success or a negative number on failure.
@@ -50,36 +50,30 @@
* This IOCTL is deprecated, and will now return EINVAL for any busid not equal
* to that of the device that this DRM instance attached to.
*/
-int drm_irq_by_busid(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_irq_by_busid(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_irq_busid_t __user *argp = (void __user *)arg;
- drm_irq_busid_t p;
+ struct drm_irq_busid *p = data;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
- if (copy_from_user(&p, argp, sizeof(p)))
- return -EFAULT;
-
- if ((p.busnum >> 8) != drm_get_pci_domain(dev) ||
- (p.busnum & 0xff) != dev->pdev->bus->number ||
- p.devnum != PCI_SLOT(dev->pdev->devfn) || p.funcnum != PCI_FUNC(dev->pdev->devfn))
+ if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
+ (p->busnum & 0xff) != dev->pdev->bus->number ||
+ p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
return -EINVAL;
- p.irq = dev->irq;
+ p->irq = dev->irq;
+
+ DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
+ p->irq);
- DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq);
- if (copy_to_user(argp, &p, sizeof(p)))
- return -EFAULT;
return 0;
}
static void vblank_disable_fn(unsigned long arg)
{
- drm_device_t *dev = (drm_device_t *)arg;
+ struct drm_device *dev = (struct drm_device *)arg;
int i;
for (i = 0; i < dev->num_crtcs; i++)
@@ -87,7 +81,7 @@ static void vblank_disable_fn(unsigned long arg)
dev->driver->disable_vblank(dev, i);
}
-int drm_vblank_init(drm_device_t *dev, int num_crtcs)
+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
{
int i, ret = -ENOMEM;
@@ -170,7 +164,7 @@ EXPORT_SYMBOL(drm_vblank_init);
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
* before and after the installation.
*/
-static int drm_irq_install(drm_device_t * dev)
+int drm_irq_install(struct drm_device * dev)
{
int ret = 0;
unsigned long sh_flags = 0;
@@ -219,6 +213,7 @@ static int drm_irq_install(drm_device_t * dev)
return ret;
}
+EXPORT_SYMBOL(drm_irq_install);
/**
* Uninstall the IRQ handler.
@@ -227,7 +222,7 @@ static int drm_irq_install(drm_device_t * dev)
*
* Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
*/
-int drm_irq_uninstall(drm_device_t * dev)
+int drm_irq_uninstall(struct drm_device * dev)
{
int irq_enabled;
@@ -258,31 +253,27 @@ EXPORT_SYMBOL(drm_irq_uninstall);
* IRQ control ioctl.
*
* \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_control structure.
* \return zero on success or a negative number on failure.
*
* Calls irq_install() or irq_uninstall() according to \p arg.
*/
-int drm_control(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_control(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_control_t ctl;
+ struct drm_control *ctl = data;
/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
- if (copy_from_user(&ctl, (drm_control_t __user *) arg, sizeof(ctl)))
- return -EFAULT;
- switch (ctl.func) {
+ switch (ctl->func) {
case DRM_INST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
- ctl.irq != dev->irq)
+ ctl->irq != dev->irq)
return -EINVAL;
return drm_irq_install(dev);
case DRM_UNINST_HANDLER:
@@ -303,7 +294,7 @@ int drm_control(struct inode *inode, struct file *filp,
* vblank events since the system was booted, including lost events due to
* modesetting activity.
*/
-u32 drm_vblank_count(drm_device_t *dev, int crtc)
+u32 drm_vblank_count(struct drm_device *dev, int crtc)
{
return atomic_read(&dev->_vblank_count[crtc]) +
dev->vblank_offset[crtc];
@@ -320,7 +311,7 @@ EXPORT_SYMBOL(drm_vblank_count);
* update the last read value so we can deal with wraparound on the next
* call if necessary.
*/
-void drm_update_vblank_count(drm_device_t *dev, int crtc)
+void drm_update_vblank_count(struct drm_device *dev, int crtc)
{
unsigned long irqflags;
u32 cur_vblank, diff;
@@ -361,7 +352,7 @@ EXPORT_SYMBOL(drm_update_vblank_count);
* RETURNS
* Zero on success, nonzero on failure.
*/
-int drm_vblank_get(drm_device_t *dev, int crtc)
+int drm_vblank_get(struct drm_device *dev, int crtc)
{
int ret = 0;
@@ -384,7 +375,7 @@ EXPORT_SYMBOL(drm_vblank_get);
* Release ownership of a given vblank counter, turning off interrupts
* if possible.
*/
-void drm_vblank_put(drm_device_t *dev, int crtc)
+void drm_vblank_put(struct drm_device *dev, int crtc)
{
/* Last user schedules interrupt disable */
if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
@@ -400,10 +391,9 @@ EXPORT_SYMBOL(drm_vblank_put);
* Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
* ioctls around modesetting so that any lost vblank events are accounted for.
*/
-int drm_modeset_ctl(DRM_IOCTL_ARGS)
+int drm_modeset_ctl(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_modeset_ctl_t __user *argp = (void __user *)data;
drm_modeset_ctl_t modeset;
int crtc, ret = 0;
@@ -442,7 +432,7 @@ out:
* Wait for VBLANK.
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
@@ -457,12 +447,10 @@ out:
*
* If a signal is not requested, then calls vblank_wait().
*/
-int drm_wait_vblank(DRM_IOCTL_ARGS)
+int drm_wait_vblank(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_wait_vblank_t __user *argp = (void __user *)data;
- drm_wait_vblank_t vblwait;
+ union drm_wait_vblank *vblwait = data;
struct timeval now;
int ret = 0;
unsigned int flags, seq, crtc;
@@ -470,18 +458,15 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
if ((!dev->irq) || (!dev->irq_enabled))
return -EINVAL;
- if (copy_from_user(&vblwait, argp, sizeof(vblwait)))
- return -EFAULT;
-
- if (vblwait.request.type &
+ if (vblwait->request.type &
~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
- vblwait.request.type,
+ vblwait->request.type,
(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
return -EINVAL;
}
- flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+ flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
if (crtc >= dev->num_crtcs)
@@ -490,10 +475,10 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
drm_update_vblank_count(dev, crtc);
seq = drm_vblank_count(dev, crtc);
- switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
+ switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
case _DRM_VBLANK_RELATIVE:
- vblwait.request.sequence += seq;
- vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+ vblwait->request.sequence += seq;
+ vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
case _DRM_VBLANK_ABSOLUTE:
break;
default:
@@ -501,14 +486,14 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
}
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
- (seq - vblwait.request.sequence) <= (1<<23)) {
- vblwait.request.sequence = seq + 1;
+ (seq - vblwait->request.sequence) <= (1<<23)) {
+ vblwait->request.sequence = seq + 1;
}
if (flags & _DRM_VBLANK_SIGNAL) {
unsigned long irqflags;
struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
- drm_vbl_sig_t *vbl_sig;
+ struct drm_vbl_sig *vbl_sig;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -517,12 +502,13 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
* that case
*/
list_for_each_entry(vbl_sig, vbl_sigs, head) {
- if (vbl_sig->sequence == vblwait.request.sequence
- && vbl_sig->info.si_signo == vblwait.request.signal
+ if (vbl_sig->sequence == vblwait->request.sequence
+ && vbl_sig->info.si_signo ==
+ vblwait->request.signal
&& vbl_sig->task == current) {
spin_unlock_irqrestore(&dev->vbl_lock,
irqflags);
- vblwait.reply.sequence = seq;
+ vblwait->reply.sequence = seq;
goto done;
}
}
@@ -534,22 +520,22 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- vbl_sig = drm_calloc(1, sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER);
- if (!vbl_sig) {
+ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
+ DRM_MEM_DRIVER);
+ if (!vbl_sig)
return -ENOMEM;
- }
ret = drm_vblank_get(dev, crtc);
if (ret) {
- drm_free(vbl_sig, sizeof(drm_vbl_sig_t),
+ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
DRM_MEM_DRIVER);
return ret;
}
atomic_inc(&dev->vbl_signal_pending);
- vbl_sig->sequence = vblwait.request.sequence;
- vbl_sig->info.si_signo = vblwait.request.signal;
+ vbl_sig->sequence = vblwait->request.sequence;
+ vbl_sig->info.si_signo = vblwait->request.signal;
vbl_sig->task = current;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -558,7 +544,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- vblwait.reply.sequence = seq;
+ vblwait->reply.sequence = seq;
} else {
unsigned long cur_vblank;
@@ -567,18 +553,16 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
return ret;
DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
(((cur_vblank = drm_vblank_count(dev, crtc))
- - vblwait.request.sequence) <= (1 << 23)));
+ - vblwait->request.sequence) <= (1 << 23)));
drm_vblank_put(dev, crtc);
do_gettimeofday(&now);
- vblwait.reply.tval_sec = now.tv_sec;
- vblwait.reply.tval_usec = now.tv_usec;
- vblwait.reply.sequence = cur_vblank;
+
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
+ vblwait->reply.sequence = cur_vblank;
}
done:
- if (copy_to_user(argp, &vblwait, sizeof(vblwait)))
- return -EFAULT;
-
return ret;
}
@@ -592,9 +576,9 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
*
* If a signal is not requested, then calls vblank_wait().
*/
-static void drm_vbl_send_signals(drm_device_t * dev, int crtc)
+static void drm_vbl_send_signals(struct drm_device * dev, int crtc)
{
- drm_vbl_sig_t *vbl_sig, *tmp;
+ struct drm_vbl_sig *vbl_sig, *tmp;
struct list_head *vbl_sigs;
unsigned int vbl_seq;
unsigned long flags;
@@ -630,7 +614,7 @@ static void drm_vbl_send_signals(drm_device_t * dev, int crtc)
* Drivers should call this routine in their vblank interrupt handlers to
* update the vblank counter and send any signals that may be pending.
*/
-void drm_handle_vblank(drm_device_t *dev, int crtc)
+void drm_handle_vblank(struct drm_device *dev, int crtc)
{
drm_update_vblank_count(dev, crtc);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
@@ -649,7 +633,7 @@ EXPORT_SYMBOL(drm_handle_vblank);
*/
static void drm_locked_tasklet_func(unsigned long data)
{
- drm_device_t *dev = (drm_device_t*)data;
+ struct drm_device *dev = (struct drm_device*)data;
unsigned long irqflags;
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
@@ -686,7 +670,7 @@ static void drm_locked_tasklet_func(unsigned long data)
* context, it must not make any assumptions about this. Also, the HW lock will
* be held with the kernel context or any client context.
*/
-void drm_locked_tasklet(drm_device_t *dev, void (*func)(drm_device_t*))
+void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device*))
{
unsigned long irqflags;
static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0);
diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c
index f02df36b..b8e4a5d9 100644
--- a/linux-core/drm_lock.c
+++ b/linux-core/drm_lock.c
@@ -41,39 +41,33 @@ static int drm_notifier(void *priv);
* Lock ioctl.
*
* \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_lock structure.
* \return zero on success or negative number on failure.
*
* Add the current task to the lock wait queue, and attempt to take to lock.
*/
-int drm_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_lock(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;
DECLARE_WAITQUEUE(entry, current);
- drm_lock_t lock;
+ struct drm_lock *lock = data;
int ret = 0;
- ++priv->lock_count;
+ ++file_priv->lock_count;
- if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
- return -EFAULT;
-
- if (lock.context == DRM_KERNEL_CONTEXT) {
+ if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- current->pid, lock.context);
+ current->pid, lock->context);
return -EINVAL;
}
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock.context, current->pid,
- dev->lock.hw_lock->lock, lock.flags);
+ lock->context, current->pid,
+ dev->lock.hw_lock->lock, lock->flags);
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
- if (lock.context < 0)
+ if (lock->context < 0)
return -EINVAL;
add_wait_queue(&dev->lock.lock_queue, &entry);
@@ -87,8 +81,8 @@ int drm_lock(struct inode *inode, struct file *filp,
ret = -EINTR;
break;
}
- if (drm_lock_take(&dev->lock, lock.context)) {
- dev->lock.filp = filp;
+ if (drm_lock_take(&dev->lock, lock->context)) {
+ dev->lock.file_priv = file_priv;
dev->lock.lock_time = jiffies;
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
break; /* Got lock */
@@ -107,7 +101,8 @@ int drm_lock(struct inode *inode, struct file *filp,
__set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->lock.lock_queue, &entry);
- DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+ DRM_DEBUG("%d %s\n", lock->context,
+ ret ? "interrupted" : "has lock");
if (ret) return ret;
sigemptyset(&dev->sigmask);
@@ -115,24 +110,26 @@ int drm_lock(struct inode *inode, struct file *filp,
sigaddset(&dev->sigmask, SIGTSTP);
sigaddset(&dev->sigmask, SIGTTIN);
sigaddset(&dev->sigmask, SIGTTOU);
- dev->sigdata.context = lock.context;
+ dev->sigdata.context = lock->context;
dev->sigdata.lock = dev->lock.hw_lock;
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
- if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
+ if (dev->driver->dma_ready && (lock->flags & _DRM_LOCK_READY))
dev->driver->dma_ready(dev);
- if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) {
+ if (dev->driver->dma_quiescent && (lock->flags & _DRM_LOCK_QUIESCENT))
+ {
if (dev->driver->dma_quiescent(dev)) {
- DRM_DEBUG( "%d waiting for DMA quiescent\n", lock.context);
- return DRM_ERR(EBUSY);
+ DRM_DEBUG("%d waiting for DMA quiescent\n",
+ lock->context);
+ return -EBUSY;
}
}
if (dev->driver->kernel_context_switch &&
- dev->last_context != lock.context) {
+ dev->last_context != lock->context) {
dev->driver->kernel_context_switch(dev, dev->last_context,
- lock.context);
+ lock->context);
}
return 0;
@@ -142,27 +139,21 @@ int drm_lock(struct inode *inode, struct file *filp,
* Unlock ioctl.
*
* \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_lock structure.
* \return zero on success or negative number on failure.
*
* Transfer and free the lock.
*/
-int drm_unlock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_unlock(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_lock_t lock;
+ struct drm_lock *lock = data;
unsigned long irqflags;
- if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
- return -EFAULT;
-
- if (lock.context == DRM_KERNEL_CONTEXT) {
+ if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- current->pid, lock.context);
+ current->pid, lock->context);
return -EINVAL;
}
@@ -184,7 +175,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
if (dev->driver->kernel_context_switch_unlock)
dev->driver->kernel_context_switch_unlock(dev);
else {
- if (drm_lock_free(&dev->lock,lock.context)) {
+ if (drm_lock_free(&dev->lock,lock->context)) {
/* FIXME: Should really bail out here. */
}
}
@@ -202,7 +193,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
*
* Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
*/
-int drm_lock_take(drm_lock_data_t *lock_data,
+int drm_lock_take(struct drm_lock_data *lock_data,
unsigned int context)
{
unsigned int old, new, prev;
@@ -252,13 +243,13 @@ int drm_lock_take(drm_lock_data_t *lock_data,
* Resets the lock file pointer.
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
*/
-static int drm_lock_transfer(drm_lock_data_t *lock_data,
+static int drm_lock_transfer(struct drm_lock_data *lock_data,
unsigned int context)
{
unsigned int old, new, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
- lock_data->filp = NULL;
+ lock_data->file_priv = NULL;
do {
old = *lock;
new = context | _DRM_LOCK_HELD;
@@ -278,7 +269,7 @@ static int drm_lock_transfer(drm_lock_data_t *lock_data,
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
* waiting on the lock queue.
*/
-int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context)
+int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
{
unsigned int old, new, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
@@ -320,7 +311,7 @@ int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context)
*/
static int drm_notifier(void *priv)
{
- drm_sigdata_t *s = (drm_sigdata_t *) priv;
+ struct drm_sigdata *s = (struct drm_sigdata *) priv;
unsigned int old, new, prev;
/* Allow signal delivery if lock isn't held */
@@ -351,7 +342,7 @@ static int drm_notifier(void *priv)
* having to worry about starvation.
*/
-void drm_idlelock_take(drm_lock_data_t *lock_data)
+void drm_idlelock_take(struct drm_lock_data *lock_data)
{
int ret = 0;
@@ -370,7 +361,7 @@ void drm_idlelock_take(drm_lock_data_t *lock_data)
}
EXPORT_SYMBOL(drm_idlelock_take);
-void drm_idlelock_release(drm_lock_data_t *lock_data)
+void drm_idlelock_release(struct drm_lock_data *lock_data)
{
unsigned int old, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
@@ -391,13 +382,12 @@ void drm_idlelock_release(drm_lock_data_t *lock_data)
EXPORT_SYMBOL(drm_idlelock_release);
-int drm_i_have_hw_lock(struct file *filp)
+int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv)
{
- DRM_DEVICE;
- return (priv->lock_count && dev->lock.hw_lock &&
+ return (file_priv->lock_count && dev->lock.hw_lock &&
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
- dev->lock.filp == filp);
+ dev->lock.file_priv == file_priv);
}
EXPORT_SYMBOL(drm_i_have_hw_lock);
diff --git a/linux-core/drm_memory.c b/linux-core/drm_memory.c
index b1423c12..f68a3a3e 100644
--- a/linux-core/drm_memory.c
+++ b/linux-core/drm_memory.c
@@ -38,9 +38,9 @@
static struct {
spinlock_t lock;
- drm_u64_t cur_used;
- drm_u64_t low_threshold;
- drm_u64_t high_threshold;
+ uint64_t cur_used;
+ uint64_t low_threshold;
+ uint64_t high_threshold;
} drm_memctl = {
.lock = SPIN_LOCK_UNLOCKED
};
@@ -82,9 +82,9 @@ void drm_free_memctl(size_t size)
}
EXPORT_SYMBOL(drm_free_memctl);
-void drm_query_memctl(drm_u64_t *cur_used,
- drm_u64_t *low_threshold,
- drm_u64_t *high_threshold)
+void drm_query_memctl(uint64_t *cur_used,
+ uint64_t *low_threshold,
+ uint64_t *high_threshold)
{
spin_lock(&drm_memctl.lock);
*cur_used = drm_memctl.cur_used;
@@ -214,7 +214,7 @@ void drm_free_pages(unsigned long address, int order, int area)
#if __OS_HAS_AGP
static void *agp_remap(unsigned long offset, unsigned long size,
- drm_device_t * dev)
+ struct drm_device * dev)
{
unsigned long *phys_addr_map, i, num_pages =
PAGE_ALIGN(size) / PAGE_SIZE;
@@ -258,12 +258,12 @@ static void *agp_remap(unsigned long offset, unsigned long size,
/** Wrapper around agp_allocate_memory() */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)
-DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
+DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type)
{
return drm_agp_allocate_memory(pages, type);
}
#else
-DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
+DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type)
{
return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
}
@@ -289,7 +289,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
#else /* __OS_HAS_AGP*/
static void *agp_remap(unsigned long offset, unsigned long size,
- drm_device_t * dev)
+ struct drm_device * dev)
{
return NULL;
}
diff --git a/linux-core/drm_memory_debug.c b/linux-core/drm_memory_debug.c
index c124f8f8..c196ee2b 100644
--- a/linux-core/drm_memory_debug.c
+++ b/linux-core/drm_memory_debug.c
@@ -291,7 +291,7 @@ void drm_free_pages(unsigned long address, int order, int area)
#if __OS_HAS_AGP
-DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
+DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type)
{
DRM_AGP_MEM *handle;
diff --git a/linux-core/drm_memory_debug.h b/linux-core/drm_memory_debug.h
index 9d0dedfb..b055ac00 100644
--- a/linux-core/drm_memory_debug.h
+++ b/linux-core/drm_memory_debug.h
@@ -277,7 +277,7 @@ void drm_free_pages (unsigned long address, int order, int area) {
#if __OS_HAS_AGP
-DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) {
+DRM_AGP_MEM *drm_alloc_agp (struct drm_device *dev, int pages, u32 type) {
DRM_AGP_MEM *handle;
if (!pages) {
diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c
index 2caf596b..cf0d92fa 100644
--- a/linux-core/drm_mm.c
+++ b/linux-core/drm_mm.c
@@ -44,26 +44,26 @@
#include "drmP.h"
#include <linux/slab.h>
-unsigned long drm_mm_tail_space(drm_mm_t *mm)
+unsigned long drm_mm_tail_space(struct drm_mm *mm)
{
struct list_head *tail_node;
- drm_mm_node_t *entry;
+ struct drm_mm_node *entry;
tail_node = mm->ml_entry.prev;
- entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
+ entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
if (!entry->free)
return 0;
return entry->size;
}
-int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size)
+int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size)
{
struct list_head *tail_node;
- drm_mm_node_t *entry;
+ struct drm_mm_node *entry;
tail_node = mm->ml_entry.prev;
- entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
+ entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
if (!entry->free)
return -ENOMEM;
@@ -75,13 +75,13 @@ int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size)
}
-static int drm_mm_create_tail_node(drm_mm_t *mm,
+static int drm_mm_create_tail_node(struct drm_mm *mm,
unsigned long start,
unsigned long size)
{
- drm_mm_node_t *child;
+ struct drm_mm_node *child;
- child = (drm_mm_node_t *)
+ child = (struct drm_mm_node *)
drm_ctl_alloc(sizeof(*child), DRM_MEM_MM);
if (!child)
return -ENOMEM;
@@ -98,13 +98,13 @@ static int drm_mm_create_tail_node(drm_mm_t *mm,
}
-int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size)
+int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size)
{
struct list_head *tail_node;
- drm_mm_node_t *entry;
+ struct drm_mm_node *entry;
tail_node = mm->ml_entry.prev;
- entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
+ entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
if (!entry->free) {
return drm_mm_create_tail_node(mm, entry->start + entry->size, size);
}
@@ -112,12 +112,12 @@ int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size)
return 0;
}
-static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent,
+static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
unsigned long size)
{
- drm_mm_node_t *child;
+ struct drm_mm_node *child;
- child = (drm_mm_node_t *)
+ child = (struct drm_mm_node *)
drm_ctl_alloc(sizeof(*child), DRM_MEM_MM);
if (!child)
return NULL;
@@ -137,12 +137,12 @@ static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent,
return child;
}
-drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
+struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
unsigned long size, unsigned alignment)
{
- drm_mm_node_t *align_splitoff = NULL;
- drm_mm_node_t *child;
+ struct drm_mm_node *align_splitoff = NULL;
+ struct drm_mm_node *child;
unsigned tmp = 0;
if (alignment)
@@ -173,26 +173,26 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
* Otherwise add to the free stack.
*/
-void drm_mm_put_block(drm_mm_node_t * cur)
+void drm_mm_put_block(struct drm_mm_node * cur)
{
- drm_mm_t *mm = cur->mm;
+ struct drm_mm *mm = cur->mm;
struct list_head *cur_head = &cur->ml_entry;
struct list_head *root_head = &mm->ml_entry;
- drm_mm_node_t *prev_node = NULL;
- drm_mm_node_t *next_node;
+ struct drm_mm_node *prev_node = NULL;
+ struct drm_mm_node *next_node;
int merged = 0;
if (cur_head->prev != root_head) {
- prev_node = list_entry(cur_head->prev, drm_mm_node_t, ml_entry);
+ prev_node = list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
if (prev_node->free) {
prev_node->size += cur->size;
merged = 1;
}
}
if (cur_head->next != root_head) {
- next_node = list_entry(cur_head->next, drm_mm_node_t, ml_entry);
+ next_node = list_entry(cur_head->next, struct drm_mm_node, ml_entry);
if (next_node->free) {
if (merged) {
prev_node->size += next_node->size;
@@ -217,14 +217,14 @@ void drm_mm_put_block(drm_mm_node_t * cur)
}
EXPORT_SYMBOL(drm_mm_put_block);
-drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
+struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
unsigned long size,
unsigned alignment, int best_match)
{
struct list_head *list;
const struct list_head *free_stack = &mm->fl_entry;
- drm_mm_node_t *entry;
- drm_mm_node_t *best;
+ struct drm_mm_node *entry;
+ struct drm_mm_node *best;
unsigned long best_size;
unsigned wasted;
@@ -232,7 +232,7 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
best_size = ~0UL;
list_for_each(list, free_stack) {
- entry = list_entry(list, drm_mm_node_t, fl_entry);
+ entry = list_entry(list, struct drm_mm_node, fl_entry);
wasted = 0;
if (entry->size < size)
@@ -258,14 +258,14 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
return best;
}
-int drm_mm_clean(drm_mm_t * mm)
+int drm_mm_clean(struct drm_mm * mm)
{
struct list_head *head = &mm->ml_entry;
return (head->next->next == head);
}
-int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size)
+int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
{
INIT_LIST_HEAD(&mm->ml_entry);
INIT_LIST_HEAD(&mm->fl_entry);
@@ -275,12 +275,12 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size)
EXPORT_SYMBOL(drm_mm_init);
-void drm_mm_takedown(drm_mm_t * mm)
+void drm_mm_takedown(struct drm_mm * mm)
{
struct list_head *bnode = mm->fl_entry.next;
- drm_mm_node_t *entry;
+ struct drm_mm_node *entry;
- entry = list_entry(bnode, drm_mm_node_t, fl_entry);
+ entry = list_entry(bnode, struct drm_mm_node, fl_entry);
if (entry->ml_entry.next != &mm->ml_entry ||
entry->fl_entry.next != &mm->fl_entry) {
diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c
index 03906034..a6d6c0d7 100644
--- a/linux-core/drm_object.c
+++ b/linux-core/drm_object.c
@@ -30,13 +30,16 @@
#include "drmP.h"
-int drm_add_user_object(drm_file_t * priv, drm_user_object_t * item,
+int drm_add_user_object(struct drm_file * priv, struct drm_user_object * item,
int shareable)
{
- drm_device_t *dev = priv->head->dev;
+ struct drm_device *dev = priv->head->dev;
int ret;
- atomic_set(&item->refcount, 1);
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
+
+ /* The refcount will be bumped to 1 when we add the ref object below. */
+ atomic_set(&item->refcount, 0);
item->shareable = shareable;
item->owner = priv;
@@ -45,25 +48,31 @@ int drm_add_user_object(drm_file_t * priv, drm_user_object_t * item,
if (ret)
return ret;
- list_add_tail(&item->list, &priv->user_objects);
- return 0;
+ ret = drm_add_ref_object(priv, item, _DRM_REF_USE);
+ if (ret)
+ ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
+
+ return ret;
}
+EXPORT_SYMBOL(drm_add_user_object);
-drm_user_object_t *drm_lookup_user_object(drm_file_t * priv, uint32_t key)
+struct drm_user_object *drm_lookup_user_object(struct drm_file * priv, uint32_t key)
{
- drm_device_t *dev = priv->head->dev;
- drm_hash_item_t *hash;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_hash_item *hash;
int ret;
- drm_user_object_t *item;
+ struct drm_user_object *item;
+
+ DRM_ASSERT_LOCKED(&dev->struct_mutex);
ret = drm_ht_find_item(&dev->object_hash, key, &hash);
if (ret) {
return NULL;
}
- item = drm_hash_entry(hash, drm_user_object_t, hash);
+ item = drm_hash_entry(hash, struct drm_user_object, hash);
if (priv != item->owner) {
- drm_open_hash_t *ht = &priv->refd_object_hash[_DRM_REF_USE];
+ struct drm_open_hash *ht = &priv->refd_object_hash[_DRM_REF_USE];
ret = drm_ht_find_item(ht, (unsigned long)item, &hash);
if (ret) {
DRM_ERROR("Object not registered for usage\n");
@@ -72,35 +81,22 @@ drm_user_object_t *drm_lookup_user_object(drm_file_t * priv, uint32_t key)
}
return item;
}
+EXPORT_SYMBOL(drm_lookup_user_object);
-static void drm_deref_user_object(drm_file_t * priv, drm_user_object_t * item)
+static void drm_deref_user_object(struct drm_file * priv, struct drm_user_object * item)
{
- drm_device_t *dev = priv->head->dev;
+ struct drm_device *dev = priv->head->dev;
int ret;
if (atomic_dec_and_test(&item->refcount)) {
ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
BUG_ON(ret);
- list_del_init(&item->list);
item->remove(priv, item);
}
}
-int drm_remove_user_object(drm_file_t * priv, drm_user_object_t * item)
-{
- if (item->owner != priv) {
- DRM_ERROR("Cannot destroy object not owned by you.\n");
- return -EINVAL;
- }
- item->owner = 0;
- item->shareable = 0;
- list_del_init(&item->list);
- drm_deref_user_object(priv, item);
- return 0;
-}
-
-static int drm_object_ref_action(drm_file_t * priv, drm_user_object_t * ro,
- drm_ref_t action)
+static int drm_object_ref_action(struct drm_file * priv, struct drm_user_object * ro,
+ enum drm_ref_type action)
{
int ret = 0;
@@ -118,13 +114,14 @@ static int drm_object_ref_action(drm_file_t * priv, drm_user_object_t * ro,
return ret;
}
-int drm_add_ref_object(drm_file_t * priv, drm_user_object_t * referenced_object,
- drm_ref_t ref_action)
+int drm_add_ref_object(struct drm_file * priv, struct drm_user_object * referenced_object,
+ enum drm_ref_type ref_action)
{
int ret = 0;
- drm_ref_object_t *item;
- drm_open_hash_t *ht = &priv->refd_object_hash[ref_action];
+ struct drm_ref_object *item;
+ struct drm_open_hash *ht = &priv->refd_object_hash[ref_action];
+ DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex);
if (!referenced_object->shareable && priv != referenced_object->owner) {
DRM_ERROR("Not allowed to reference this object\n");
return -EINVAL;
@@ -174,45 +171,48 @@ int drm_add_ref_object(drm_file_t * priv, drm_user_object_t * referenced_object,
return ret;
}
-drm_ref_object_t *drm_lookup_ref_object(drm_file_t * priv,
- drm_user_object_t * referenced_object,
- drm_ref_t ref_action)
+struct drm_ref_object *drm_lookup_ref_object(struct drm_file * priv,
+ struct drm_user_object * referenced_object,
+ enum drm_ref_type ref_action)
{
- drm_hash_item_t *hash;
+ struct drm_hash_item *hash;
int ret;
+ DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex);
ret = drm_ht_find_item(&priv->refd_object_hash[ref_action],
(unsigned long)referenced_object, &hash);
if (ret)
return NULL;
- return drm_hash_entry(hash, drm_ref_object_t, hash);
+ return drm_hash_entry(hash, struct drm_ref_object, hash);
}
+EXPORT_SYMBOL(drm_lookup_ref_object);
-static void drm_remove_other_references(drm_file_t * priv,
- drm_user_object_t * ro)
+static void drm_remove_other_references(struct drm_file * priv,
+ struct drm_user_object * ro)
{
int i;
- drm_open_hash_t *ht;
- drm_hash_item_t *hash;
- drm_ref_object_t *item;
+ struct drm_open_hash *ht;
+ struct drm_hash_item *hash;
+ struct drm_ref_object *item;
for (i = _DRM_REF_USE + 1; i < _DRM_NO_REF_TYPES; ++i) {
ht = &priv->refd_object_hash[i];
while (!drm_ht_find_item(ht, (unsigned long)ro, &hash)) {
- item = drm_hash_entry(hash, drm_ref_object_t, hash);
+ item = drm_hash_entry(hash, struct drm_ref_object, hash);
drm_remove_ref_object(priv, item);
}
}
}
-void drm_remove_ref_object(drm_file_t * priv, drm_ref_object_t * item)
+void drm_remove_ref_object(struct drm_file * priv, struct drm_ref_object * item)
{
int ret;
- drm_user_object_t *user_object = (drm_user_object_t *) item->hash.key;
- drm_open_hash_t *ht = &priv->refd_object_hash[item->unref_action];
- drm_ref_t unref_action;
+ struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key;
+ struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];
+ enum drm_ref_type unref_action;
+ DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex);
unref_action = item->unref_action;
if (atomic_dec_and_test(&item->refcount)) {
ret = drm_ht_remove_item(ht, &item->hash);
@@ -235,12 +235,12 @@ void drm_remove_ref_object(drm_file_t * priv, drm_ref_object_t * item)
}
-int drm_user_object_ref(drm_file_t * priv, uint32_t user_token,
- drm_object_type_t type, drm_user_object_t ** object)
+int drm_user_object_ref(struct drm_file * priv, uint32_t user_token,
+ enum drm_object_type type, struct drm_user_object ** object)
{
- drm_device_t *dev = priv->head->dev;
- drm_user_object_t *uo;
- drm_hash_item_t *hash;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_user_object *uo;
+ struct drm_hash_item *hash;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -249,7 +249,7 @@ int drm_user_object_ref(drm_file_t * priv, uint32_t user_token,
DRM_ERROR("Could not find user object to reference.\n");
goto out_err;
}
- uo = drm_hash_entry(hash, drm_user_object_t, hash);
+ uo = drm_hash_entry(hash, struct drm_user_object, hash);
if (uo->type != type) {
ret = -EINVAL;
goto out_err;
@@ -265,12 +265,12 @@ int drm_user_object_ref(drm_file_t * priv, uint32_t user_token,
return ret;
}
-int drm_user_object_unref(drm_file_t * priv, uint32_t user_token,
- drm_object_type_t type)
+int drm_user_object_unref(struct drm_file * priv, uint32_t user_token,
+ enum drm_object_type type)
{
- drm_device_t *dev = priv->head->dev;
- drm_user_object_t *uo;
- drm_ref_object_t *ro;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_user_object *uo;
+ struct drm_ref_object *ro;
int ret;
mutex_lock(&dev->struct_mutex);
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h
index 03ea927e..cea811eb 100644
--- a/linux-core/drm_objects.h
+++ b/linux-core/drm_objects.h
@@ -32,6 +32,7 @@
#define _DRM_OBJECTS_H
struct drm_device;
+struct drm_bo_mem_reg;
/***************************************************
* User space objects. (drm_object.c)
@@ -39,14 +40,19 @@ struct drm_device;
#define drm_user_object_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
-typedef enum {
+enum drm_object_type {
drm_fence_type,
drm_buffer_type,
- drm_ttm_type
+ drm_lock_type,
/*
* Add other user space object types here.
*/
-} drm_object_type_t;
+ drm_driver_type0 = 256,
+ drm_driver_type1,
+ drm_driver_type2,
+ drm_driver_type3,
+ drm_driver_type4
+};
/*
* A user object is a structure that helps the drm give out user handles
@@ -55,20 +61,20 @@ typedef enum {
* Designed to be accessible using a user space 32-bit handle.
*/
-typedef struct drm_user_object {
- drm_hash_item_t hash;
+struct drm_user_object {
+ struct drm_hash_item hash;
struct list_head list;
- drm_object_type_t type;
+ enum drm_object_type type;
atomic_t refcount;
int shareable;
- drm_file_t *owner;
- void (*ref_struct_locked) (drm_file_t * priv,
+ struct drm_file *owner;
+ void (*ref_struct_locked) (struct drm_file * priv,
struct drm_user_object * obj,
- drm_ref_t ref_action);
- void (*unref) (drm_file_t * priv, struct drm_user_object * obj,
- drm_ref_t unref_action);
- void (*remove) (drm_file_t * priv, struct drm_user_object * obj);
-} drm_user_object_t;
+ enum drm_ref_type ref_action);
+ void (*unref) (struct drm_file * priv, struct drm_user_object * obj,
+ enum drm_ref_type unref_action);
+ void (*remove) (struct drm_file * priv, struct drm_user_object * obj);
+};
/*
* A ref object is a structure which is used to
@@ -77,50 +83,41 @@ typedef struct drm_user_object {
* process exits. Designed to be accessible using a pointer to the _user_ object.
*/
-typedef struct drm_ref_object {
- drm_hash_item_t hash;
+struct drm_ref_object {
+ struct drm_hash_item hash;
struct list_head list;
atomic_t refcount;
- drm_ref_t unref_action;
-} drm_ref_object_t;
+ enum drm_ref_type unref_action;
+};
/**
* Must be called with the struct_mutex held.
*/
-extern int drm_add_user_object(drm_file_t * priv, drm_user_object_t * item,
+extern int drm_add_user_object(struct drm_file * priv, struct drm_user_object * item,
int shareable);
/**
* Must be called with the struct_mutex held.
*/
-extern drm_user_object_t *drm_lookup_user_object(drm_file_t * priv,
+extern struct drm_user_object *drm_lookup_user_object(struct drm_file * priv,
uint32_t key);
/*
- * Must be called with the struct_mutex held.
- * If "item" has been obtained by a call to drm_lookup_user_object. You may not
- * release the struct_mutex before calling drm_remove_ref_object.
- * This function may temporarily release the struct_mutex.
- */
-
-extern int drm_remove_user_object(drm_file_t * priv, drm_user_object_t * item);
-
-/*
* Must be called with the struct_mutex held. May temporarily release it.
*/
-extern int drm_add_ref_object(drm_file_t * priv,
- drm_user_object_t * referenced_object,
- drm_ref_t ref_action);
+extern int drm_add_ref_object(struct drm_file * priv,
+ struct drm_user_object * referenced_object,
+ enum drm_ref_type ref_action);
/*
* Must be called with the struct_mutex held.
*/
-drm_ref_object_t *drm_lookup_ref_object(drm_file_t * priv,
- drm_user_object_t * referenced_object,
- drm_ref_t ref_action);
+struct drm_ref_object *drm_lookup_ref_object(struct drm_file * priv,
+ struct drm_user_object * referenced_object,
+ enum drm_ref_type ref_action);
/*
* Must be called with the struct_mutex held.
* If "item" has been obtained by a call to drm_lookup_ref_object. You may not
@@ -128,19 +125,20 @@ drm_ref_object_t *drm_lookup_ref_object(drm_file_t * priv,
* This function may temporarily release the struct_mutex.
*/
-extern void drm_remove_ref_object(drm_file_t * priv, drm_ref_object_t * item);
-extern int drm_user_object_ref(drm_file_t * priv, uint32_t user_token,
- drm_object_type_t type,
- drm_user_object_t ** object);
-extern int drm_user_object_unref(drm_file_t * priv, uint32_t user_token,
- drm_object_type_t type);
+extern void drm_remove_ref_object(struct drm_file * priv, struct drm_ref_object * item);
+extern int drm_user_object_ref(struct drm_file * priv, uint32_t user_token,
+ enum drm_object_type type,
+ struct drm_user_object ** object);
+extern int drm_user_object_unref(struct drm_file * priv, uint32_t user_token,
+ enum drm_object_type type);
/***************************************************
* Fence objects. (drm_fence.c)
*/
-typedef struct drm_fence_object {
- drm_user_object_t base;
+struct drm_fence_object {
+ struct drm_user_object base;
+ struct drm_device *dev;
atomic_t usage;
/*
@@ -148,71 +146,95 @@ typedef struct drm_fence_object {
*/
struct list_head ring;
- int class;
+ int fence_class;
uint32_t native_type;
uint32_t type;
uint32_t signaled;
uint32_t sequence;
uint32_t flush_mask;
uint32_t submitted_flush;
-} drm_fence_object_t;
+ uint32_t error;
+};
#define _DRM_FENCE_CLASSES 8
#define _DRM_FENCE_TYPE_EXE 0x00
-typedef struct drm_fence_class_manager {
+struct drm_fence_class_manager {
struct list_head ring;
uint32_t pending_flush;
wait_queue_head_t fence_queue;
int pending_exe_flush;
uint32_t last_exe_flush;
uint32_t exe_flush_sequence;
-} drm_fence_class_manager_t;
+};
-typedef struct drm_fence_manager {
+struct drm_fence_manager {
int initialized;
rwlock_t lock;
- drm_fence_class_manager_t class[_DRM_FENCE_CLASSES];
+ struct drm_fence_class_manager fence_class[_DRM_FENCE_CLASSES];
uint32_t num_classes;
atomic_t count;
-} drm_fence_manager_t;
+};
-typedef struct drm_fence_driver {
+struct drm_fence_driver {
uint32_t num_classes;
uint32_t wrap_diff;
uint32_t flush_diff;
uint32_t sequence_mask;
int lazy_capable;
- int (*has_irq) (struct drm_device * dev, uint32_t class,
+ int (*has_irq) (struct drm_device * dev, uint32_t fence_class,
uint32_t flags);
- int (*emit) (struct drm_device * dev, uint32_t class, uint32_t flags,
+ int (*emit) (struct drm_device * dev, uint32_t fence_class, uint32_t flags,
uint32_t * breadcrumb, uint32_t * native_type);
- void (*poke_flush) (struct drm_device * dev, uint32_t class);
-} drm_fence_driver_t;
+ void (*poke_flush) (struct drm_device * dev, uint32_t fence_class);
+};
-extern void drm_fence_handler(struct drm_device *dev, uint32_t class,
- uint32_t sequence, uint32_t type);
+extern void drm_fence_handler(struct drm_device *dev, uint32_t fence_class,
+ uint32_t sequence, uint32_t type, uint32_t error);
extern void drm_fence_manager_init(struct drm_device *dev);
extern void drm_fence_manager_takedown(struct drm_device *dev);
-extern void drm_fence_flush_old(struct drm_device *dev, uint32_t class,
+extern void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class,
uint32_t sequence);
-extern int drm_fence_object_flush(struct drm_device *dev,
- drm_fence_object_t * fence, uint32_t type);
-extern int drm_fence_object_signaled(drm_fence_object_t * fence, uint32_t type);
-extern void drm_fence_usage_deref_locked(struct drm_device *dev,
- drm_fence_object_t * fence);
-extern void drm_fence_usage_deref_unlocked(struct drm_device *dev,
- drm_fence_object_t * fence);
-extern int drm_fence_object_wait(struct drm_device *dev,
- drm_fence_object_t * fence,
+extern int drm_fence_object_flush(struct drm_fence_object * fence, uint32_t type);
+extern int drm_fence_object_signaled(struct drm_fence_object * fence,
+ uint32_t type, int flush);
+extern void drm_fence_usage_deref_locked(struct drm_fence_object ** fence);
+extern void drm_fence_usage_deref_unlocked(struct drm_fence_object ** fence);
+extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src);
+extern void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+ struct drm_fence_object *src);
+extern int drm_fence_object_wait(struct drm_fence_object * fence,
int lazy, int ignore_signals, uint32_t mask);
extern int drm_fence_object_create(struct drm_device *dev, uint32_t type,
- uint32_t fence_flags, uint32_t class,
- drm_fence_object_t ** c_fence);
-extern int drm_fence_add_user_object(drm_file_t * priv,
- drm_fence_object_t * fence, int shareable);
-extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
-
+ uint32_t fence_flags, uint32_t fence_class,
+ struct drm_fence_object ** c_fence);
+extern int drm_fence_object_emit(struct drm_fence_object * fence,
+ uint32_t fence_flags, uint32_t class,
+ uint32_t type);
+extern void drm_fence_fill_arg(struct drm_fence_object *fence,
+ struct drm_fence_arg *arg);
+
+extern int drm_fence_add_user_object(struct drm_file * priv,
+ struct drm_fence_object * fence, int shareable);
+
+extern int drm_fence_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_destroy_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_reference_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_unreference_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_signaled_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_flush_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_wait_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_emit_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int drm_fence_buffers_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/**************************************************
*TTMs
*/
@@ -234,34 +256,33 @@ extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
#define DRM_BE_FLAG_BOUND_CACHED 0x00000002
struct drm_ttm_backend;
-typedef struct drm_ttm_backend_func {
+struct drm_ttm_backend_func {
int (*needs_ub_cache_adjust) (struct drm_ttm_backend * backend);
int (*populate) (struct drm_ttm_backend * backend,
unsigned long num_pages, struct page ** pages);
void (*clear) (struct drm_ttm_backend * backend);
int (*bind) (struct drm_ttm_backend * backend,
- unsigned long offset, int cached);
+ struct drm_bo_mem_reg * bo_mem);
int (*unbind) (struct drm_ttm_backend * backend);
void (*destroy) (struct drm_ttm_backend * backend);
-} drm_ttm_backend_func_t;
+};
typedef struct drm_ttm_backend {
- uint32_t flags;
- int mem_type;
- drm_ttm_backend_func_t *func;
+ struct drm_device *dev;
+ uint32_t flags;
+ struct drm_ttm_backend_func *func;
} drm_ttm_backend_t;
-typedef struct drm_ttm {
+struct drm_ttm {
struct page **pages;
uint32_t page_flags;
unsigned long num_pages;
- unsigned long aper_offset;
atomic_t vma_count;
struct drm_device *dev;
int destroy;
uint32_t mapping_offset;
- drm_ttm_backend_t *be;
+ struct drm_ttm_backend *be;
enum {
ttm_bound,
ttm_evicted,
@@ -269,14 +290,16 @@ typedef struct drm_ttm {
ttm_unpopulated,
} state;
-} drm_ttm_t;
+};
-extern drm_ttm_t *drm_ttm_init(struct drm_device *dev, unsigned long size);
-extern int drm_bind_ttm(drm_ttm_t * ttm, int cached, unsigned long aper_offset);
-extern void drm_ttm_unbind(drm_ttm_t * ttm);
-extern void drm_ttm_evict(drm_ttm_t * ttm);
-extern void drm_ttm_fixup_caching(drm_ttm_t * ttm);
-extern struct page *drm_ttm_get_page(drm_ttm_t * ttm, int index);
+extern struct drm_ttm *drm_ttm_init(struct drm_device *dev, unsigned long size);
+extern int drm_bind_ttm(struct drm_ttm * ttm, struct drm_bo_mem_reg *bo_mem);
+extern void drm_ttm_unbind(struct drm_ttm * ttm);
+extern void drm_ttm_evict(struct drm_ttm * ttm);
+extern void drm_ttm_fixup_caching(struct drm_ttm * ttm);
+extern struct page *drm_ttm_get_page(struct drm_ttm * ttm, int index);
+extern void drm_ttm_cache_flush(void);
+extern int drm_ttm_populate(struct drm_ttm * ttm);
/*
* Destroy a ttm. The user normally calls drmRmMap or a similar IOCTL to do this,
@@ -284,7 +307,7 @@ extern struct page *drm_ttm_get_page(drm_ttm_t * ttm, int index);
* when the last vma exits.
*/
-extern int drm_destroy_ttm(drm_ttm_t * ttm);
+extern int drm_destroy_ttm(struct drm_ttm * ttm);
#define DRM_FLAG_MASKED(_old, _new, _mask) {\
(_old) ^= (((_old) ^ (_new)) & (_mask)); \
@@ -307,19 +330,27 @@ extern int drm_destroy_ttm(drm_ttm_t * ttm);
* Buffer objects. (drm_bo.c, drm_bo_move.c)
*/
-typedef struct drm_bo_mem_reg {
- drm_mm_node_t *mm_node;
+struct drm_bo_mem_reg {
+ struct drm_mm_node *mm_node;
unsigned long size;
unsigned long num_pages;
uint32_t page_alignment;
uint32_t mem_type;
- uint32_t flags;
- uint32_t mask;
-} drm_bo_mem_reg_t;
-
-typedef struct drm_buffer_object {
+ uint64_t flags;
+ uint64_t mask;
+ uint32_t desired_tile_stride;
+ uint32_t hw_tile_stride;
+};
+
+enum drm_bo_type {
+ drm_bo_type_dc,
+ drm_bo_type_user,
+ drm_bo_type_kernel, /* for initial kernel allocations */
+};
+
+struct drm_buffer_object {
struct drm_device *dev;
- drm_user_object_t base;
+ struct drm_user_object base;
/*
* If there is a possibility that the usage variable is zero,
@@ -328,30 +359,32 @@ typedef struct drm_buffer_object {
atomic_t usage;
unsigned long buffer_start;
- drm_bo_type_t type;
+ enum drm_bo_type type;
unsigned long offset;
atomic_t mapped;
- drm_bo_mem_reg_t mem;
+ struct drm_bo_mem_reg mem;
struct list_head lru;
struct list_head ddestroy;
uint32_t fence_type;
uint32_t fence_class;
- drm_fence_object_t *fence;
+ uint32_t new_fence_type;
+ uint32_t new_fence_class;
+ struct drm_fence_object *fence;
uint32_t priv_flags;
wait_queue_head_t event_queue;
struct mutex mutex;
+ unsigned long num_pages;
/* For pinned buffers */
- drm_mm_node_t *pinned_node;
+ struct drm_mm_node *pinned_node;
uint32_t pinned_mem_type;
struct list_head pinned_lru;
/* For vm */
-
- drm_ttm_t *ttm;
- drm_map_list_t map_list;
+ struct drm_ttm *ttm;
+ struct drm_map_list map_list;
uint32_t memory_type;
unsigned long bus_offset;
uint32_t vm_flags;
@@ -363,23 +396,31 @@ typedef struct drm_buffer_object {
struct list_head p_mm_list;
#endif
-} drm_buffer_object_t;
+};
#define _DRM_BO_FLAG_UNFENCED 0x00000001
#define _DRM_BO_FLAG_EVICTED 0x00000002
-typedef struct drm_mem_type_manager {
+struct drm_mem_type_manager {
int has_type;
int use_type;
- drm_mm_t manager;
+ struct drm_mm manager;
struct list_head lru;
struct list_head pinned;
uint32_t flags;
uint32_t drm_bus_maptype;
+ unsigned long gpu_offset;
unsigned long io_offset;
unsigned long io_size;
void *io_addr;
-} drm_mem_type_manager_t;
+};
+
+struct drm_bo_lock {
+ struct drm_user_object base;
+ wait_queue_head_t queue;
+ atomic_t write_lock_pending;
+ atomic_t readers;
+};
#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */
#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */
@@ -389,13 +430,13 @@ typedef struct drm_mem_type_manager {
#define _DRM_FLAG_MEMTYPE_CMA 0x00000010 /* Can't map aperture */
#define _DRM_FLAG_MEMTYPE_CSELECT 0x00000020 /* Select caching */
-typedef struct drm_buffer_manager {
- struct mutex init_mutex;
- struct mutex evict_mutex;
+struct drm_buffer_manager {
+ struct drm_bo_lock bm_lock;
+ struct mutex evict_mutex;
int nice_mode;
int initialized;
- drm_file_t *last_to_validate;
- drm_mem_type_manager_t man[DRM_BO_MEM_TYPES];
+ struct drm_file *last_to_validate;
+ struct drm_mem_type_manager man[DRM_BO_MEM_TYPES];
struct list_head unfenced;
struct list_head ddestroy;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
@@ -406,69 +447,193 @@ typedef struct drm_buffer_manager {
uint32_t fence_type;
unsigned long cur_pages;
atomic_t count;
-} drm_buffer_manager_t;
+};
-typedef struct drm_bo_driver {
+struct drm_bo_driver {
const uint32_t *mem_type_prio;
const uint32_t *mem_busy_prio;
uint32_t num_mem_type_prio;
uint32_t num_mem_busy_prio;
- drm_ttm_backend_t *(*create_ttm_backend_entry)
+ struct drm_ttm_backend *(*create_ttm_backend_entry)
(struct drm_device * dev);
- int (*fence_type) (struct drm_buffer_object *bo, uint32_t * class, uint32_t * type);
- int (*invalidate_caches) (struct drm_device * dev, uint32_t flags);
+ int (*fence_type) (struct drm_buffer_object *bo, uint32_t *fclass,
+ uint32_t * type);
+ int (*invalidate_caches) (struct drm_device * dev, uint64_t flags);
int (*init_mem_type) (struct drm_device * dev, uint32_t type,
- drm_mem_type_manager_t * man);
+ struct drm_mem_type_manager * man);
uint32_t(*evict_mask) (struct drm_buffer_object *bo);
int (*move) (struct drm_buffer_object * bo,
int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
-} drm_bo_driver_t;
+ void (*ttm_cache_flush)(struct drm_ttm *ttm);
+};
/*
* buffer objects (drm_bo.c)
*/
-extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
-extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
+extern int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_setstatus_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_bo_driver_finish(struct drm_device *dev);
extern int drm_bo_driver_init(struct drm_device *dev);
extern int drm_bo_pci_offset(struct drm_device *dev,
- drm_bo_mem_reg_t * mem,
+ struct drm_bo_mem_reg * mem,
unsigned long *bus_base,
unsigned long *bus_offset,
unsigned long *bus_size);
-extern int drm_mem_reg_is_pci(struct drm_device *dev, drm_bo_mem_reg_t * mem);
+extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg * mem);
-extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo);
-extern int drm_fence_buffer_objects(drm_file_t * priv,
+extern void drm_bo_usage_deref_locked(struct drm_buffer_object ** bo);
+extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object ** bo);
+extern void drm_putback_buffer_objects(struct drm_device *dev);
+extern int drm_fence_buffer_objects(struct drm_device * dev,
struct list_head *list,
uint32_t fence_flags,
- drm_fence_object_t * fence,
- drm_fence_object_t ** used_fence);
-extern void drm_bo_add_to_lru(drm_buffer_object_t * bo);
-extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
+ struct drm_fence_object * fence,
+ struct drm_fence_object ** used_fence);
+extern void drm_bo_add_to_lru(struct drm_buffer_object * bo);
+extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size,
+ enum drm_bo_type type, uint64_t mask,
+ uint32_t hint, uint32_t page_alignment,
+ unsigned long buffer_start,
+ struct drm_buffer_object **bo);
+extern int drm_bo_wait(struct drm_buffer_object * bo, int lazy, int ignore_signals,
int no_wait);
-extern int drm_bo_mem_space(drm_buffer_object_t * bo,
- drm_bo_mem_reg_t * mem, int no_wait);
-extern int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags,
+extern int drm_bo_mem_space(struct drm_buffer_object * bo,
+ struct drm_bo_mem_reg * mem, int no_wait);
+extern int drm_bo_move_buffer(struct drm_buffer_object * bo,
+ uint64_t new_mem_flags,
int no_wait, int move_unfenced);
+extern int drm_bo_clean_mm(struct drm_device * dev, unsigned mem_type);
+extern int drm_bo_init_mm(struct drm_device * dev, unsigned type,
+ unsigned long p_offset, unsigned long p_size);
+extern int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle,
+ uint32_t fence_class, uint64_t flags,
+ uint64_t mask, uint32_t hint,
+ int use_old_fence_class,
+ struct drm_bo_info_rep * rep,
+ struct drm_buffer_object **bo_rep);
+extern struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file * file_priv,
+ uint32_t handle,
+ int check_owner);
+extern int drm_bo_do_validate(struct drm_buffer_object *bo,
+ uint64_t flags, uint64_t mask, uint32_t hint,
+ uint32_t fence_class,
+ int no_wait,
+ struct drm_bo_info_rep *rep);
/*
- * Buffer object memory move helpers.
+ * Buffer object memory move- and map helpers.
* drm_bo_move.c
*/
-extern int drm_bo_move_ttm(drm_buffer_object_t * bo,
- int evict, int no_wait, drm_bo_mem_reg_t * new_mem);
-extern int drm_bo_move_memcpy(drm_buffer_object_t * bo,
+extern int drm_bo_move_ttm(struct drm_buffer_object * bo,
+ int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
+extern int drm_bo_move_memcpy(struct drm_buffer_object * bo,
int evict,
- int no_wait, drm_bo_mem_reg_t * new_mem);
-extern int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo,
+ int no_wait, struct drm_bo_mem_reg * new_mem);
+extern 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);
+ struct drm_bo_mem_reg * new_mem);
+extern int drm_bo_same_page(unsigned long offset, unsigned long offset2);
+extern unsigned long drm_bo_offset_end(unsigned long offset,
+ unsigned long end);
+
+struct drm_bo_kmap_obj {
+ void *virtual;
+ struct page *page;
+ enum {
+ bo_map_iomap,
+ bo_map_vmap,
+ bo_map_kmap,
+ bo_map_premapped,
+ } bo_kmap_type;
+};
+
+static inline void *drm_bmo_virtual(struct drm_bo_kmap_obj *map, int *is_iomem)
+{
+ *is_iomem = (map->bo_kmap_type == bo_map_iomap ||
+ map->bo_kmap_type == bo_map_premapped);
+ return map->virtual;
+}
+extern void drm_bo_kunmap(struct drm_bo_kmap_obj *map);
+extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
+ unsigned long num_pages, struct drm_bo_kmap_obj *map);
+
+/*
+ * drm_regman.c
+ */
+
+struct drm_reg {
+ struct list_head head;
+ struct drm_fence_object *fence;
+ uint32_t fence_type;
+ uint32_t new_fence_type;
+};
+
+struct drm_reg_manager {
+ struct list_head free;
+ struct list_head lru;
+ struct list_head unfenced;
+
+ int (*reg_reusable)(const struct drm_reg *reg, const void *data);
+ void (*reg_destroy)(struct drm_reg *reg);
+};
+
+extern int drm_regs_alloc(struct drm_reg_manager *manager,
+ const void *data,
+ uint32_t fence_class,
+ uint32_t fence_type,
+ int interruptible,
+ int no_wait,
+ struct drm_reg **reg);
+
+extern void drm_regs_fence(struct drm_reg_manager *regs,
+ struct drm_fence_object *fence);
+
+extern void drm_regs_free(struct drm_reg_manager *manager);
+extern void drm_regs_add(struct drm_reg_manager *manager, struct drm_reg *reg);
+extern void drm_regs_init(struct drm_reg_manager *manager,
+ int (*reg_reusable)(const struct drm_reg *,
+ const void *),
+ void (*reg_destroy)(struct drm_reg *));
+
+/*
+ * drm_bo_lock.c
+ * Simple replacement for the hardware lock on buffer manager init and clean.
+ */
+
+
+extern void drm_bo_init_lock(struct drm_bo_lock *lock);
+extern void drm_bo_read_unlock(struct drm_bo_lock *lock);
+extern int drm_bo_read_lock(struct drm_bo_lock *lock);
+extern int drm_bo_write_lock(struct drm_bo_lock *lock,
+ struct drm_file *file_priv);
+
+extern int drm_bo_write_unlock(struct drm_bo_lock *lock,
+ struct drm_file *file_priv);
+
+#ifdef CONFIG_DEBUG_MUTEXES
+#define DRM_ASSERT_LOCKED(_mutex) \
+ BUG_ON(!mutex_is_locked(_mutex) || \
+ ((_mutex)->owner != current_thread_info()))
+#else
+#define DRM_ASSERT_LOCKED(_mutex)
+#endif
#endif
diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h
index 2ea105c5..2688479a 100644
--- a/linux-core/drm_os_linux.h
+++ b/linux-core/drm_os_linux.h
@@ -6,11 +6,6 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
-/** File pointer type */
-#define DRMFILE struct file *
-/** Ioctl arguments */
-#define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data
-#define DRM_ERR(d) -(d)
/** Current process ID */
#define DRM_CURRENTPID current->pid
#define DRM_SUSER(p) capable(CAP_SYS_ADMIN)
@@ -51,9 +46,6 @@
#define DRM_WRITEMEMORYBARRIER() wmb()
/** Read/write memory barrier */
#define DRM_MEMORYBARRIER() mb()
-/** DRM device local declaration */
-#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
- drm_device_t *dev = priv->head->dev
/** IRQ handler arguments and return type and values */
#define DRM_IRQ_ARGS int irq, void *arg
@@ -93,14 +85,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
#define MTRR_TYPE_WRCOMB 1
#endif
-/** For data going into the kernel through the ioctl argument */
-#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \
- if ( copy_from_user(&arg1, arg2, arg3) ) \
- return -EFAULT
-/** For data going from the kernel through the ioctl argument */
-#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
- if ( copy_to_user(arg1, &arg2, arg3) ) \
- return -EFAULT
/** Other copying of data to kernel space */
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
copy_from_user(arg1, arg2, arg3)
@@ -117,8 +101,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
__get_user(val, uaddr)
-#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
-
#define DRM_HZ HZ
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
diff --git a/linux-core/drm_pci.c b/linux-core/drm_pci.c
index 76252204..a608eed3 100644
--- a/linux-core/drm_pci.c
+++ b/linux-core/drm_pci.c
@@ -47,7 +47,7 @@
/**
* \brief Allocate a PCI consistent memory block, for DMA.
*/
-drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
+drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align,
dma_addr_t maxaddr)
{
drm_dma_handle_t *dmah;
@@ -123,7 +123,7 @@ EXPORT_SYMBOL(drm_pci_alloc);
*
* This function is for internal use in the Linux-specific DRM core code.
*/
-void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
+void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t *dmah)
{
unsigned long addr;
size_t sz;
@@ -167,7 +167,7 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
/**
* \brief Free a PCI consistent memory block
*/
-void drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
+void drm_pci_free(struct drm_device * dev, drm_dma_handle_t *dmah)
{
__drm_pci_free(dev, dmah);
kfree(dmah);
diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c
index e93a0406..08bf99d6 100644
--- a/linux-core/drm_proc.c
+++ b/linux-core/drm_proc.c
@@ -90,7 +90,7 @@ static struct drm_proc_list {
* "/proc/dri/%minor%/", and each entry in proc_list as
* "/proc/dri/%minor%/%name%".
*/
-int drm_proc_init(drm_device_t * dev, int minor,
+int drm_proc_init(struct drm_device * dev, int minor,
struct proc_dir_entry *root, struct proc_dir_entry **dev_root)
{
struct proc_dir_entry *ent;
@@ -165,7 +165,7 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
static int drm_name_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
if (offset > DRM_PROC_LIMIT) {
@@ -207,10 +207,10 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
static int drm__vm_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
- drm_map_t *map;
- drm_map_list_t *r_list;
+ struct drm_map *map;
+ struct drm_map_list *r_list;
/* Hardcoded from _DRM_FRAME_BUFFER,
_DRM_REGISTERS, _DRM_SHM, _DRM_AGP,
@@ -264,7 +264,7 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
static int drm_vm_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -287,10 +287,10 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
static int drm__queues_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
int i;
- drm_queue_t *q;
+ struct drm_queue *q;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -337,7 +337,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
static int drm_queues_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -360,9 +360,9 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
int i;
if (!dma || offset > DRM_PROC_LIMIT) {
@@ -409,7 +409,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -432,13 +432,13 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
static int drm__objects_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
- drm_buffer_manager_t *bm = &dev->bm;
- drm_fence_manager_t *fm = &dev->fm;
- drm_u64_t used_mem;
- drm_u64_t low_mem;
- drm_u64_t high_mem;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_fence_manager *fm = &dev->fm;
+ uint64_t used_mem;
+ uint64_t low_mem;
+ uint64_t high_mem;
if (offset > DRM_PROC_LIMIT) {
@@ -496,7 +496,7 @@ static int drm__objects_info(char *buf, char **start, off_t offset, int request,
static int drm_objects_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -519,9 +519,9 @@ static int drm_objects_info(char *buf, char **start, off_t offset, int request,
static int drm__clients_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
- drm_file_t *priv;
+ struct drm_file *priv;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
@@ -552,7 +552,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
static int drm_clients_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -566,9 +566,9 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
static int drm__vma_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int len = 0;
- drm_vma_entry_t *pt;
+ struct drm_vma_entry *pt;
struct vm_area_struct *vma;
#if defined(__i386__)
unsigned int pgprot;
@@ -625,7 +625,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
static int drm_vma_info(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
int ret;
mutex_lock(&dev->struct_mutex);
diff --git a/linux-core/drm_scatter.c b/linux-core/drm_scatter.c
index e5c9f877..3c0f672e 100644
--- a/linux-core/drm_scatter.c
+++ b/linux-core/drm_scatter.c
@@ -36,7 +36,7 @@
#define DEBUG_SCATTER 0
-void drm_sg_cleanup(drm_sg_mem_t * entry)
+void drm_sg_cleanup(struct drm_sg_mem *entry)
{
struct page *page;
int i;
@@ -55,6 +55,7 @@ void drm_sg_cleanup(drm_sg_mem_t * entry)
entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES);
drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
}
+EXPORT_SYMBOL(drm_sg_cleanup);
#ifdef _LP64
# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
@@ -62,14 +63,9 @@ void drm_sg_cleanup(drm_sg_mem_t * entry)
# define ScatterHandle(x) (unsigned int)(x)
#endif
-int drm_sg_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_scatter_gather_t __user *argp = (void __user *)arg;
- drm_scatter_gather_t request;
- drm_sg_mem_t *entry;
+ struct drm_sg_mem *entry;
unsigned long pages, i, j;
DRM_DEBUG("%s\n", __FUNCTION__);
@@ -80,17 +76,13 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
if (dev->sg)
return -EINVAL;
- if (copy_from_user(&request, argp, sizeof(request)))
- return -EFAULT;
-
entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
if (!entry)
return -ENOMEM;
memset(entry, 0, sizeof(*entry));
-
- pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
- DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages);
+ pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
+ DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages);
entry->pages = pages;
entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
@@ -142,12 +134,7 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
SetPageReserved(entry->pagelist[j]);
}
- request.handle = entry->handle;
-
- if (copy_to_user(argp, &request, sizeof(request))) {
- drm_sg_cleanup(entry);
- return -EFAULT;
- }
+ request->handle = entry->handle;
dev->sg = entry;
@@ -196,28 +183,32 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
failed:
drm_sg_cleanup(entry);
return -ENOMEM;
+
}
+EXPORT_SYMBOL(drm_sg_alloc);
-int drm_sg_free(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_sg_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_scatter_gather_t request;
- drm_sg_mem_t *entry;
+ struct drm_scatter_gather *request = data;
+
+ return drm_sg_alloc(dev, request);
+
+}
+
+int drm_sg_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_scatter_gather *request = data;
+ struct drm_sg_mem *entry;
if (!drm_core_check_feature(dev, DRIVER_SG))
return -EINVAL;
- if (copy_from_user(&request,
- (drm_scatter_gather_t __user *) arg,
- sizeof(request)))
- return -EFAULT;
-
entry = dev->sg;
dev->sg = NULL;
- if (!entry || entry->handle != request.handle)
+ if (!entry || entry->handle != request->handle)
return -EINVAL;
DRM_DEBUG("sg free virtual = %p\n", entry->virtual);
diff --git a/linux-core/drm_sman.c b/linux-core/drm_sman.c
index e15db6d6..118e82ae 100644
--- a/linux-core/drm_sman.c
+++ b/linux-core/drm_sman.c
@@ -38,13 +38,13 @@
#include "drm_sman.h"
-typedef struct drm_owner_item {
- drm_hash_item_t owner_hash;
+struct drm_owner_item {
+ struct drm_hash_item owner_hash;
struct list_head sman_list;
struct list_head mem_blocks;
-} drm_owner_item_t;
+};
-void drm_sman_takedown(drm_sman_t * sman)
+void drm_sman_takedown(struct drm_sman * sman)
{
drm_ht_remove(&sman->user_hash_tab);
drm_ht_remove(&sman->owner_hash_tab);
@@ -56,12 +56,12 @@ void drm_sman_takedown(drm_sman_t * sman)
EXPORT_SYMBOL(drm_sman_takedown);
int
-drm_sman_init(drm_sman_t * sman, unsigned int num_managers,
+drm_sman_init(struct drm_sman * sman, unsigned int num_managers,
unsigned int user_order, unsigned int owner_order)
{
int ret = 0;
- sman->mm = (drm_sman_mm_t *) drm_calloc(num_managers, sizeof(*sman->mm),
+ sman->mm = (struct drm_sman_mm *) drm_calloc(num_managers, sizeof(*sman->mm),
DRM_MEM_MM);
if (!sman->mm) {
ret = -ENOMEM;
@@ -88,8 +88,8 @@ EXPORT_SYMBOL(drm_sman_init);
static void *drm_sman_mm_allocate(void *private, unsigned long size,
unsigned alignment)
{
- drm_mm_t *mm = (drm_mm_t *) private;
- drm_mm_node_t *tmp;
+ struct drm_mm *mm = (struct drm_mm *) private;
+ struct drm_mm_node *tmp;
tmp = drm_mm_search_free(mm, size, alignment, 1);
if (!tmp) {
@@ -101,30 +101,30 @@ static void *drm_sman_mm_allocate(void *private, unsigned long size,
static void drm_sman_mm_free(void *private, void *ref)
{
- drm_mm_node_t *node = (drm_mm_node_t *) ref;
+ struct drm_mm_node *node = (struct drm_mm_node *) ref;
drm_mm_put_block(node);
}
static void drm_sman_mm_destroy(void *private)
{
- drm_mm_t *mm = (drm_mm_t *) private;
+ struct drm_mm *mm = (struct drm_mm *) private;
drm_mm_takedown(mm);
drm_free(mm, sizeof(*mm), DRM_MEM_MM);
}
static unsigned long drm_sman_mm_offset(void *private, void *ref)
{
- drm_mm_node_t *node = (drm_mm_node_t *) ref;
+ struct drm_mm_node *node = (struct drm_mm_node *) ref;
return node->start;
}
int
-drm_sman_set_range(drm_sman_t * sman, unsigned int manager,
+drm_sman_set_range(struct drm_sman * sman, unsigned int manager,
unsigned long start, unsigned long size)
{
- drm_sman_mm_t *sman_mm;
- drm_mm_t *mm;
+ struct drm_sman_mm *sman_mm;
+ struct drm_mm *mm;
int ret;
BUG_ON(manager >= sman->num_managers);
@@ -153,8 +153,8 @@ drm_sman_set_range(drm_sman_t * sman, unsigned int manager,
EXPORT_SYMBOL(drm_sman_set_range);
int
-drm_sman_set_manager(drm_sman_t * sman, unsigned int manager,
- drm_sman_mm_t * allocator)
+drm_sman_set_manager(struct drm_sman * sman, unsigned int manager,
+ struct drm_sman_mm * allocator)
{
BUG_ON(manager >= sman->num_managers);
sman->mm[manager] = *allocator;
@@ -163,16 +163,16 @@ drm_sman_set_manager(drm_sman_t * sman, unsigned int manager,
}
EXPORT_SYMBOL(drm_sman_set_manager);
-static drm_owner_item_t *drm_sman_get_owner_item(drm_sman_t * sman,
+static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman,
unsigned long owner)
{
int ret;
- drm_hash_item_t *owner_hash_item;
- drm_owner_item_t *owner_item;
+ struct drm_hash_item *owner_hash_item;
+ struct drm_owner_item *owner_item;
ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item);
if (!ret) {
- return drm_hash_entry(owner_hash_item, drm_owner_item_t,
+ return drm_hash_entry(owner_hash_item, struct drm_owner_item,
owner_hash);
}
@@ -194,14 +194,14 @@ out:
return NULL;
}
-drm_memblock_item_t *drm_sman_alloc(drm_sman_t *sman, unsigned int manager,
+struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int manager,
unsigned long size, unsigned alignment,
unsigned long owner)
{
void *tmp;
- drm_sman_mm_t *sman_mm;
- drm_owner_item_t *owner_item;
- drm_memblock_item_t *memblock;
+ struct drm_sman_mm *sman_mm;
+ struct drm_owner_item *owner_item;
+ struct drm_memblock_item *memblock;
BUG_ON(manager >= sman->num_managers);
@@ -246,9 +246,9 @@ out:
EXPORT_SYMBOL(drm_sman_alloc);
-static void drm_sman_free(drm_memblock_item_t *item)
+static void drm_sman_free(struct drm_memblock_item *item)
{
- drm_sman_t *sman = item->sman;
+ struct drm_sman *sman = item->sman;
list_del(&item->owner_list);
drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash);
@@ -256,40 +256,40 @@ static void drm_sman_free(drm_memblock_item_t *item)
drm_free(item, sizeof(*item), DRM_MEM_MM);
}
-int drm_sman_free_key(drm_sman_t *sman, unsigned int key)
+int drm_sman_free_key(struct drm_sman *sman, unsigned int key)
{
- drm_hash_item_t *hash_item;
- drm_memblock_item_t *memblock_item;
+ struct drm_hash_item *hash_item;
+ struct drm_memblock_item *memblock_item;
if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item))
return -EINVAL;
- memblock_item = drm_hash_entry(hash_item, drm_memblock_item_t, user_hash);
+ memblock_item = drm_hash_entry(hash_item, struct drm_memblock_item, user_hash);
drm_sman_free(memblock_item);
return 0;
}
EXPORT_SYMBOL(drm_sman_free_key);
-static void drm_sman_remove_owner(drm_sman_t *sman,
- drm_owner_item_t *owner_item)
+static void drm_sman_remove_owner(struct drm_sman *sman,
+ struct drm_owner_item *owner_item)
{
list_del(&owner_item->sman_list);
drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash);
drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM);
}
-int drm_sman_owner_clean(drm_sman_t *sman, unsigned long owner)
+int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner)
{
- drm_hash_item_t *hash_item;
- drm_owner_item_t *owner_item;
+ struct drm_hash_item *hash_item;
+ struct drm_owner_item *owner_item;
if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) {
return -1;
}
- owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash);
+ owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash);
if (owner_item->mem_blocks.next == &owner_item->mem_blocks) {
drm_sman_remove_owner(sman, owner_item);
return -1;
@@ -300,10 +300,10 @@ int drm_sman_owner_clean(drm_sman_t *sman, unsigned long owner)
EXPORT_SYMBOL(drm_sman_owner_clean);
-static void drm_sman_do_owner_cleanup(drm_sman_t *sman,
- drm_owner_item_t *owner_item)
+static void drm_sman_do_owner_cleanup(struct drm_sman *sman,
+ struct drm_owner_item *owner_item)
{
- drm_memblock_item_t *entry, *next;
+ struct drm_memblock_item *entry, *next;
list_for_each_entry_safe(entry, next, &owner_item->mem_blocks,
owner_list) {
@@ -312,28 +312,28 @@ static void drm_sman_do_owner_cleanup(drm_sman_t *sman,
drm_sman_remove_owner(sman, owner_item);
}
-void drm_sman_owner_cleanup(drm_sman_t *sman, unsigned long owner)
+void drm_sman_owner_cleanup(struct drm_sman *sman, unsigned long owner)
{
- drm_hash_item_t *hash_item;
- drm_owner_item_t *owner_item;
+ struct drm_hash_item *hash_item;
+ struct drm_owner_item *owner_item;
if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) {
return;
}
- owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash);
+ owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash);
drm_sman_do_owner_cleanup(sman, owner_item);
}
EXPORT_SYMBOL(drm_sman_owner_cleanup);
-void drm_sman_cleanup(drm_sman_t *sman)
+void drm_sman_cleanup(struct drm_sman *sman)
{
- drm_owner_item_t *entry, *next;
+ struct drm_owner_item *entry, *next;
unsigned int i;
- drm_sman_mm_t *sman_mm;
+ struct drm_sman_mm *sman_mm;
list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) {
drm_sman_do_owner_cleanup(sman, entry);
diff --git a/linux-core/drm_sman.h b/linux-core/drm_sman.h
index ddc732a1..39a39fef 100644
--- a/linux-core/drm_sman.h
+++ b/linux-core/drm_sman.h
@@ -50,7 +50,7 @@
* for memory management.
*/
-typedef struct drm_sman_mm {
+struct drm_sman_mm {
/* private info. If allocated, needs to be destroyed by the destroy
function */
void *private;
@@ -74,30 +74,30 @@ typedef struct drm_sman_mm {
"alloc" function */
unsigned long (*offset) (void *private, void *ref);
-} drm_sman_mm_t;
+};
-typedef struct drm_memblock_item {
+struct drm_memblock_item {
struct list_head owner_list;
- drm_hash_item_t user_hash;
+ struct drm_hash_item user_hash;
void *mm_info;
- drm_sman_mm_t *mm;
+ struct drm_sman_mm *mm;
struct drm_sman *sman;
-} drm_memblock_item_t;
+};
-typedef struct drm_sman {
- drm_sman_mm_t *mm;
+struct drm_sman {
+ struct drm_sman_mm *mm;
int num_managers;
- drm_open_hash_t owner_hash_tab;
- drm_open_hash_t user_hash_tab;
+ struct drm_open_hash owner_hash_tab;
+ struct drm_open_hash user_hash_tab;
struct list_head owner_items;
-} drm_sman_t;
+};
/*
* Take down a memory manager. This function should only be called after a
* successful init and after a call to drm_sman_cleanup.
*/
-extern void drm_sman_takedown(drm_sman_t * sman);
+extern void drm_sman_takedown(struct drm_sman * sman);
/*
* Allocate structures for a manager.
@@ -112,7 +112,7 @@ extern void drm_sman_takedown(drm_sman_t * sman);
*
*/
-extern int drm_sman_init(drm_sman_t * sman, unsigned int num_managers,
+extern int drm_sman_init(struct drm_sman * sman, unsigned int num_managers,
unsigned int user_order, unsigned int owner_order);
/*
@@ -120,7 +120,7 @@ extern int drm_sman_init(drm_sman_t * sman, unsigned int num_managers,
* manager unless a customized allogator is used.
*/
-extern int drm_sman_set_range(drm_sman_t * sman, unsigned int manager,
+extern int drm_sman_set_range(struct drm_sman * sman, unsigned int manager,
unsigned long start, unsigned long size);
/*
@@ -129,23 +129,23 @@ extern int drm_sman_set_range(drm_sman_t * sman, unsigned int manager,
* so it can be destroyed after this call.
*/
-extern int drm_sman_set_manager(drm_sman_t * sman, unsigned int mananger,
- drm_sman_mm_t * allocator);
+extern int drm_sman_set_manager(struct drm_sman * sman, unsigned int mananger,
+ struct drm_sman_mm * allocator);
/*
* Allocate a memory block. Aligment is not implemented yet.
*/
-extern drm_memblock_item_t *drm_sman_alloc(drm_sman_t * sman,
- unsigned int manager,
- unsigned long size,
- unsigned alignment,
- unsigned long owner);
+extern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman,
+ unsigned int manager,
+ unsigned long size,
+ unsigned alignment,
+ unsigned long owner);
/*
* Free a memory block identified by its user hash key.
*/
-extern int drm_sman_free_key(drm_sman_t * sman, unsigned int key);
+extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key);
/*
* returns 1 iff there are no stale memory blocks associated with this owner.
@@ -154,7 +154,7 @@ extern int drm_sman_free_key(drm_sman_t * sman, unsigned int key);
* resources associated with owner.
*/
-extern int drm_sman_owner_clean(drm_sman_t * sman, unsigned long owner);
+extern int drm_sman_owner_clean(struct drm_sman * sman, unsigned long owner);
/*
* Frees all stale memory blocks associated with this owner. Note that this
@@ -164,13 +164,13 @@ extern int drm_sman_owner_clean(drm_sman_t * sman, unsigned long owner);
* is not going to be referenced anymore.
*/
-extern void drm_sman_owner_cleanup(drm_sman_t * sman, unsigned long owner);
+extern void drm_sman_owner_cleanup(struct drm_sman * sman, unsigned long owner);
/*
* Frees all stale memory blocks associated with the memory manager.
* See idling above.
*/
-extern void drm_sman_cleanup(drm_sman_t * sman);
+extern void drm_sman_cleanup(struct drm_sman * sman);
#endif
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index f57ed9cc..1d88d375 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -50,11 +50,11 @@ MODULE_PARM_DESC(debug, "Enable debug output");
module_param_named(cards_limit, drm_cards_limit, int, 0444);
module_param_named(debug, drm_debug, int, 0600);
-drm_head_t **drm_heads;
-struct drm_sysfs_class *drm_class;
+struct drm_head **drm_heads;
+struct class *drm_class;
struct proc_dir_entry *drm_proc_root;
-static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
+static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
const struct pci_device_id *ent,
struct drm_driver *driver)
{
@@ -72,7 +72,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
init_timer(&dev->timer);
mutex_init(&dev->struct_mutex);
mutex_init(&dev->ctxlist_mutex);
- mutex_init(&dev->bm.init_mutex);
mutex_init(&dev->bm.evict_mutex);
idr_init(&dev->drw_idr);
@@ -160,9 +159,9 @@ error_out_unreg:
* create the proc init entry via proc_init(). This routines assigns
* minor numbers to secondary heads of multi-headed cards
*/
-static int drm_get_head(drm_device_t * dev, drm_head_t * head)
+static int drm_get_head(struct drm_device * dev, struct drm_head * head)
{
- drm_head_t **heads = drm_heads;
+ struct drm_head **heads = drm_heads;
int ret;
int minor;
@@ -171,7 +170,7 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head)
for (minor = 0; minor < drm_cards_limit; minor++, heads++) {
if (!*heads) {
- *head = (drm_head_t) {
+ *head = (struct drm_head) {
.dev = dev,
.device = MKDEV(DRM_MAJOR, minor),
.minor = minor,
@@ -184,11 +183,10 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head)
goto err_g1;
}
- head->dev_class = drm_sysfs_device_add(drm_class, head);
- if (IS_ERR(head->dev_class)) {
+ ret = drm_sysfs_device_add(dev, head);
+ if (ret) {
printk(KERN_ERR
"DRM: Error sysfs_device_add.\n");
- ret = PTR_ERR(head->dev_class);
goto err_g2;
}
*heads = head;
@@ -202,7 +200,7 @@ static int drm_get_head(drm_device_t * dev, drm_head_t * head)
err_g2:
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
err_g1:
- *head = (drm_head_t) {
+ *head = (struct drm_head) {
.dev = NULL};
return ret;
}
@@ -221,7 +219,7 @@ err_g1:
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
struct drm_driver *driver)
{
- drm_device_t *dev;
+ struct drm_device *dev;
int ret;
DRM_DEBUG("\n");
@@ -232,18 +230,22 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
if (!drm_fb_loaded) {
pci_set_drvdata(pdev, dev);
- pci_request_regions(pdev, driver->pci_driver.name);
+ ret = pci_request_regions(pdev, driver->pci_driver.name);
+ if (ret)
+ goto err_g1;
}
- pci_enable_device(pdev);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ goto err_g2;
pci_set_master(pdev);
if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
printk(KERN_ERR "DRM: fill_in_dev failed\n");
- goto err_g1;
+ goto err_g3;
}
if ((ret = drm_get_head(dev, &dev->primary)))
- goto err_g1;
+ goto err_g3;
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -251,12 +253,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
return 0;
-err_g1:
- if (!drm_fb_loaded) {
- pci_set_drvdata(pdev, NULL);
- pci_release_regions(pdev);
+ err_g3:
+ if (!drm_fb_loaded)
pci_disable_device(pdev);
- }
+ err_g2:
+ if (!drm_fb_loaded)
+ pci_release_regions(pdev);
+ err_g1:
+ if (!drm_fb_loaded)
+ pci_set_drvdata(pdev, NULL);
+
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
printk(KERN_ERR "DRM: drm_get_dev failed.\n");
return ret;
@@ -274,7 +280,7 @@ EXPORT_SYMBOL(drm_get_dev);
* "drm" data, otherwise unregisters the "drm" data, frees the dev list and
* unregisters the character device.
*/
-int drm_put_dev(drm_device_t * dev)
+int drm_put_dev(struct drm_device * dev)
{
DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
@@ -302,16 +308,16 @@ int drm_put_dev(drm_device_t * dev)
* last minor released.
*
*/
-int drm_put_head(drm_head_t * head)
+int drm_put_head(struct drm_head * head)
{
int minor = head->minor;
DRM_DEBUG("release secondary minor %d\n", minor);
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
- drm_sysfs_device_remove(head->dev_class);
+ drm_sysfs_device_remove(head->dev);
- *head = (drm_head_t){.dev = NULL};
+ *head = (struct drm_head){.dev = NULL};
drm_heads[minor] = NULL;
return 0;
diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c
index ace0778b..6f8623ce 100644
--- a/linux-core/drm_sysfs.c
+++ b/linux-core/drm_sysfs.c
@@ -1,3 +1,4 @@
+
/*
* drm_sysfs.c - Modifications to drm_sysfs_class.c to support
* extra sysfs attribute from DRM. Normal drm_sysfs_class
@@ -15,37 +16,46 @@
#include <linux/kdev_t.h>
#include <linux/err.h>
-#include "drmP.h"
#include "drm_core.h"
+#include "drmP.h"
-struct drm_sysfs_class {
- struct class_device_attribute attr;
- struct class class;
-};
-#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
-
-struct simple_dev {
- dev_t dev;
- struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
+#define to_drm_device(d) container_of(d, struct drm_device, dev)
-static void release_simple_dev(struct class_device *class_dev)
+/**
+ * drm_sysfs_suspend - DRM class suspend hook
+ * @dev: Linux device to suspend
+ * @state: power state to enter
+ *
+ * Just figures out what the actual struct drm_device associated with
+ * @dev is and calls its suspend hook, if present.
+ */
+static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
{
- struct simple_dev *s_dev = to_simple_dev(class_dev);
- kfree(s_dev);
-}
+ struct drm_device *drm_dev = to_drm_device(dev);
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
- struct simple_dev *s_dev = to_simple_dev(class_dev);
- return print_dev_t(buf, s_dev->dev);
+ printk(KERN_ERR "%s\n", __FUNCTION__);
+
+ if (drm_dev->driver->suspend)
+ return drm_dev->driver->suspend(drm_dev);
+
+ return 0;
}
-static void drm_sysfs_class_release(struct class *class)
+/**
+ * drm_sysfs_resume - DRM class resume hook
+ * @dev: Linux device to resume
+ *
+ * Just figures out what the actual struct drm_device associated with
+ * @dev is and calls its resume hook, if present.
+ */
+static int drm_sysfs_resume(struct device *dev)
{
- struct drm_sysfs_class *cs = to_drm_sysfs_class(class);
- kfree(cs);
+ struct drm_device *drm_dev = to_drm_device(dev);
+
+ if (drm_dev->driver->resume)
+ return drm_dev->driver->resume(drm_dev);
+
+ return 0;
}
/* Display the version of drm_core. This doesn't work right in current design */
@@ -62,141 +72,138 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
* @owner: pointer to the module that is to "own" this struct drm_sysfs_class
* @name: pointer to a string for the name of this class.
*
- * This is used to create a struct drm_sysfs_class pointer that can then be used
+ * This is used to create DRM class pointer that can then be used
* in calls to drm_sysfs_device_add().
*
* Note, the pointer created here is to be destroyed when finished by making a
* call to drm_sysfs_destroy().
*/
-struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
+struct class *drm_sysfs_create(struct module *owner, char *name)
{
- struct drm_sysfs_class *cs;
- int retval;
+ struct class *class;
+ int err;
- cs = kmalloc(sizeof(*cs), GFP_KERNEL);
- if (!cs) {
- retval = -ENOMEM;
- goto error;
+ class = class_create(owner, name);
+ if (IS_ERR(class)) {
+ err = PTR_ERR(class);
+ goto err_out;
}
- memset(cs, 0x00, sizeof(*cs));
- cs->class.name = name;
- cs->class.class_release = drm_sysfs_class_release;
- cs->class.release = release_simple_dev;
+ class->suspend = drm_sysfs_suspend;
+ class->resume = drm_sysfs_resume;
- cs->attr.attr.name = "dev";
- cs->attr.attr.mode = S_IRUGO;
- cs->attr.attr.owner = owner;
- cs->attr.show = show_dev;
- cs->attr.store = NULL;
+ err = class_create_file(class, &class_attr_version);
+ if (err)
+ goto err_out_class;
- retval = class_register(&cs->class);
- if (retval)
- goto error;
- class_create_file(&cs->class, &class_attr_version);
+ return class;
- return cs;
-
- error:
- kfree(cs);
- return ERR_PTR(retval);
+err_out_class:
+ class_destroy(class);
+err_out:
+ return ERR_PTR(err);
}
/**
- * drm_sysfs_destroy - destroys a struct drm_sysfs_class structure
- * @cs: pointer to the struct drm_sysfs_class that is to be destroyed
+ * drm_sysfs_destroy - destroys DRM class
*
- * Note, the pointer to be destroyed must have been created with a call to
- * drm_sysfs_create().
+ * Destroy the DRM device class.
*/
-void drm_sysfs_destroy(struct drm_sysfs_class *cs)
+void drm_sysfs_destroy(void)
{
- if ((cs == NULL) || (IS_ERR(cs)))
+ if ((drm_class == NULL) || (IS_ERR(drm_class)))
return;
-
- class_unregister(&cs->class);
+ class_remove_file(drm_class, &class_attr_version);
+ class_destroy(drm_class);
}
-static ssize_t show_dri(struct class_device *class_device, char *buf)
+static ssize_t show_dri(struct device *device, struct device_attribute *attr,
+ char *buf)
{
- drm_device_t * dev = ((drm_head_t *)class_get_devdata(class_device))->dev;
+ struct drm_device *dev = to_drm_device(device);
if (dev->driver->dri_library_name)
return dev->driver->dri_library_name(dev, buf);
return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name);
}
-static struct class_device_attribute class_device_attrs[] = {
+static struct device_attribute device_attrs[] = {
__ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
};
/**
- * drm_sysfs_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
- * @dev: the dev_t for the device to be added.
- * @device: a pointer to a struct device that is assiociated with this class device.
- * @fmt: string for the class device's name
+ * drm_sysfs_device_release - do nothing
+ * @dev: Linux device
*
- * A struct class_device will be created in sysfs, registered to the specified
- * class. A "dev" file will be created, showing the dev_t for the device. The
- * pointer to the struct class_device will be returned from the call. Any further
- * sysfs files that might be required can be created using this pointer.
- * Note: the struct drm_sysfs_class passed to this function must have previously been
- * created with a call to drm_sysfs_create().
+ * Normally, this would free the DRM device associated with @dev, along
+ * with cleaning up any other stuff. But we do that in the DRM core, so
+ * this function can just return and hope that the core does its job.
*/
-struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
- drm_head_t * head)
+static void drm_sysfs_device_release(struct device *dev)
{
- struct simple_dev *s_dev = NULL;
- int i, retval;
+ return;
+}
- if ((cs == NULL) || (IS_ERR(cs))) {
- retval = -ENODEV;
- goto error;
+/**
+ * drm_sysfs_device_add - adds a class device to sysfs for a character driver
+ * @dev: DRM device to be added
+ * @head: DRM head in question
+ *
+ * Add a DRM device to the DRM's device model class. We use @dev's PCI device
+ * as the parent for the Linux device, and make sure it has a file containing
+ * the driver we're using (for userspace compatibility).
+ */
+int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head)
+{
+ int err;
+ int i, j;
+
+ dev->dev.parent = &dev->pdev->dev;
+ dev->dev.class = drm_class;
+ dev->dev.release = drm_sysfs_device_release;
+ /*
+ * This will actually add the major:minor file so that udev
+ * will create the device node. We don't want to do that just
+ * yet...
+ */
+ /* dev->dev.devt = head->device; */
+ snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor);
+
+ err = device_register(&dev->dev);
+ if (err) {
+ DRM_ERROR("device add failed: %d\n", err);
+ goto err_out;
}
- s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
- if (!s_dev) {
- retval = -ENOMEM;
- goto error;
+ for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
+ err = device_create_file(&dev->dev, &device_attrs[i]);
+ if (err)
+ goto err_out_files;
}
- memset(s_dev, 0x00, sizeof(*s_dev));
-
- s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
- s_dev->class_dev.dev = &head->dev->pdev->dev;
- s_dev->class_dev.class = &cs->class;
- snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
- retval = class_device_register(&s_dev->class_dev);
- if (retval)
- goto error;
+ return 0;
- class_device_create_file(&s_dev->class_dev, &cs->attr);
- class_set_devdata(&s_dev->class_dev, head);
+err_out_files:
+ if (i > 0)
+ for (j = 0; j < i; j++)
+ device_remove_file(&dev->dev, &device_attrs[i]);
+ device_unregister(&dev->dev);
+err_out:
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
-
- return &s_dev->class_dev;
-
-error:
- kfree(s_dev);
- return ERR_PTR(retval);
+ return err;
}
/**
- * drm_sysfs_device_remove - removes a class device that was created with drm_sysfs_device_add()
- * @dev: the dev_t of the device that was previously registered.
+ * drm_sysfs_device_remove - remove DRM device
+ * @dev: DRM device to remove
*
* This call unregisters and cleans up a class device that was created with a
* call to drm_sysfs_device_add()
*/
-void drm_sysfs_device_remove(struct class_device *class_dev)
+void drm_sysfs_device_remove(struct drm_device *dev)
{
- struct simple_dev *s_dev = to_simple_dev(class_dev);
int i;
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
-
- class_device_unregister(&s_dev->class_dev);
+ for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
+ device_remove_file(&dev->dev, &device_attrs[i]);
+ device_unregister(&dev->dev);
}
diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c
index 31503c9c..df9e7e44 100644
--- a/linux-core/drm_ttm.c
+++ b/linux-core/drm_ttm.c
@@ -35,17 +35,18 @@ static void drm_ttm_ipi_handler(void *null)
flush_agp_cache();
}
-static void drm_ttm_cache_flush(void)
+void drm_ttm_cache_flush(void)
{
if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1, 1) != 0)
DRM_ERROR("Timed out waiting for drm cache flush.\n");
}
+EXPORT_SYMBOL(drm_ttm_cache_flush);
/*
* Use kmalloc if possible. Otherwise fall back to vmalloc.
*/
-static void ttm_alloc_pages(drm_ttm_t * ttm)
+static void ttm_alloc_pages(struct drm_ttm * ttm)
{
unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
ttm->pages = NULL;
@@ -66,7 +67,7 @@ static void ttm_alloc_pages(drm_ttm_t * ttm)
}
}
-static void ttm_free_pages(drm_ttm_t * ttm)
+static void ttm_free_pages(struct drm_ttm * ttm)
{
unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
@@ -105,7 +106,7 @@ static struct page *drm_ttm_alloc_page(void)
* for range of pages in a ttm.
*/
-static int drm_set_caching(drm_ttm_t * ttm, int noncached)
+static int drm_set_caching(struct drm_ttm * ttm, int noncached)
{
int i;
struct page **cur_page;
@@ -142,12 +143,12 @@ static int drm_set_caching(drm_ttm_t * ttm, int noncached)
* Free all resources associated with a ttm.
*/
-int drm_destroy_ttm(drm_ttm_t * ttm)
+int drm_destroy_ttm(struct drm_ttm * ttm)
{
int i;
struct page **cur_page;
- drm_ttm_backend_t *be;
+ struct drm_ttm_backend *be;
if (!ttm)
return 0;
@@ -159,7 +160,7 @@ int drm_destroy_ttm(drm_ttm_t * ttm)
}
if (ttm->pages) {
- drm_buffer_manager_t *bm = &ttm->dev->bm;
+ struct drm_buffer_manager *bm = &ttm->dev->bm;
if (ttm->page_flags & DRM_TTM_PAGE_UNCACHED)
drm_set_caching(ttm, 0);
@@ -191,10 +192,10 @@ int drm_destroy_ttm(drm_ttm_t * ttm)
return 0;
}
-struct page *drm_ttm_get_page(drm_ttm_t * ttm, int index)
+struct page *drm_ttm_get_page(struct drm_ttm * ttm, int index)
{
struct page *p;
- drm_buffer_manager_t *bm = &ttm->dev->bm;
+ struct drm_buffer_manager *bm = &ttm->dev->bm;
p = ttm->pages[index];
if (!p) {
@@ -206,12 +207,13 @@ struct page *drm_ttm_get_page(drm_ttm_t * ttm, int index)
}
return p;
}
+EXPORT_SYMBOL(drm_ttm_get_page);
-static int drm_ttm_populate(drm_ttm_t * ttm)
+int drm_ttm_populate(struct drm_ttm * ttm)
{
struct page *page;
unsigned long i;
- drm_ttm_backend_t *be;
+ struct drm_ttm_backend *be;
if (ttm->state != ttm_unpopulated)
return 0;
@@ -231,10 +233,10 @@ static int drm_ttm_populate(drm_ttm_t * ttm)
* Initialize a ttm.
*/
-drm_ttm_t *drm_ttm_init(struct drm_device * dev, unsigned long size)
+struct drm_ttm *drm_ttm_init(struct drm_device * dev, unsigned long size)
{
- drm_bo_driver_t *bo_driver = dev->driver->bo_driver;
- drm_ttm_t *ttm;
+ struct drm_bo_driver *bo_driver = dev->driver->bo_driver;
+ struct drm_ttm *ttm;
if (!bo_driver)
return NULL;
@@ -275,9 +277,9 @@ drm_ttm_t *drm_ttm_init(struct drm_device * dev, unsigned long size)
* Unbind a ttm region from the aperture.
*/
-void drm_ttm_evict(drm_ttm_t * ttm)
+void drm_ttm_evict(struct drm_ttm * ttm)
{
- drm_ttm_backend_t *be = ttm->be;
+ struct drm_ttm_backend *be = ttm->be;
int ret;
if (ttm->state == ttm_bound) {
@@ -288,11 +290,11 @@ void drm_ttm_evict(drm_ttm_t * ttm)
ttm->state = ttm_evicted;
}
-void drm_ttm_fixup_caching(drm_ttm_t * ttm)
+void drm_ttm_fixup_caching(struct drm_ttm * ttm)
{
if (ttm->state == ttm_evicted) {
- drm_ttm_backend_t *be = ttm->be;
+ struct drm_ttm_backend *be = ttm->be;
if (be->func->needs_ub_cache_adjust(be)) {
drm_set_caching(ttm, 0);
}
@@ -300,7 +302,7 @@ void drm_ttm_fixup_caching(drm_ttm_t * ttm)
}
}
-void drm_ttm_unbind(drm_ttm_t * ttm)
+void drm_ttm_unbind(struct drm_ttm * ttm)
{
if (ttm->state == ttm_bound)
drm_ttm_evict(ttm);
@@ -308,11 +310,11 @@ void drm_ttm_unbind(drm_ttm_t * ttm)
drm_ttm_fixup_caching(ttm);
}
-int drm_bind_ttm(drm_ttm_t * ttm, int cached, unsigned long aper_offset)
+int drm_bind_ttm(struct drm_ttm * ttm, struct drm_bo_mem_reg *bo_mem)
{
-
+ struct drm_bo_driver *bo_driver = ttm->dev->driver->bo_driver;
int ret = 0;
- drm_ttm_backend_t *be;
+ struct drm_ttm_backend *be;
if (!ttm)
return -EINVAL;
@@ -325,17 +327,18 @@ int drm_bind_ttm(drm_ttm_t * ttm, int cached, unsigned long aper_offset)
if (ret)
return ret;
- if (ttm->state == ttm_unbound && !cached) {
+ if (ttm->state == ttm_unbound && !(bo_mem->flags & DRM_BO_FLAG_CACHED)) {
drm_set_caching(ttm, DRM_TTM_PAGE_UNCACHED);
- }
+ } else if ((bo_mem->flags & DRM_BO_FLAG_CACHED) &&
+ bo_driver->ttm_cache_flush)
+ bo_driver->ttm_cache_flush(ttm);
- if ((ret = be->func->bind(be, aper_offset, cached))) {
+ if ((ret = be->func->bind(be, bo_mem))) {
ttm->state = ttm_evicted;
DRM_ERROR("Couldn't bind backend.\n");
return ret;
}
- ttm->aper_offset = aper_offset;
ttm->state = ttm_bound;
return 0;
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index f2c43508..d2554f31 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -85,11 +85,11 @@ pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
unsigned long address)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_map_t *map = NULL;
- drm_map_list_t *r_list;
- drm_hash_item_t *hash;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_map *map = NULL;
+ struct drm_map_list *r_list;
+ struct drm_hash_item *hash;
/*
* Find the right map
@@ -103,7 +103,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
goto vm_nopage_error;
- r_list = drm_hash_entry(hash, drm_map_list_t, hash);
+ r_list = drm_hash_entry(hash, struct drm_map_list, hash);
map = r_list->map;
if (map && map->type == _DRM_AGP) {
@@ -172,7 +172,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long address)
{
- drm_map_t *map = (drm_map_t *) vma->vm_private_data;
+ struct drm_map *map = (struct drm_map *) vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;
@@ -203,11 +203,11 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
*/
static void drm_vm_shm_close(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_vma_entry_t *pt, *temp;
- drm_map_t *map;
- drm_map_list_t *r_list;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_vma_entry *pt, *temp;
+ struct drm_map *map;
+ struct drm_map_list *r_list;
int found_maps = 0;
DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -285,9 +285,9 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_device_dma_t *dma = dev->dma;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_device_dma *dma = dev->dma;
unsigned long offset;
unsigned long page_nr;
struct page *page;
@@ -321,10 +321,10 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
unsigned long address)
{
- drm_map_t *map = (drm_map_t *) vma->vm_private_data;
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_sg_mem_t *entry = dev->sg;
+ struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_sg_mem *entry = dev->sg;
unsigned long offset;
unsigned long map_offset;
unsigned long page_offset;
@@ -418,9 +418,9 @@ static struct vm_operations_struct drm_vm_sg_ops = {
*/
static void drm_vm_open_locked(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_vma_entry_t *vma_entry;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_vma_entry *vma_entry;
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
@@ -436,8 +436,8 @@ static void drm_vm_open_locked(struct vm_area_struct *vma)
static void drm_vm_open(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
mutex_lock(&dev->struct_mutex);
drm_vm_open_locked(vma);
@@ -454,9 +454,9 @@ static void drm_vm_open(struct vm_area_struct *vma)
*/
static void drm_vm_close(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_vma_entry_t *pt, *temp;
+ struct drm_file *priv = vma->vm_file->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_vma_entry *pt, *temp;
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
@@ -477,7 +477,7 @@ static void drm_vm_close(struct vm_area_struct *vma)
/**
* mmap DMA memory.
*
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
*
@@ -486,9 +486,9 @@ static void drm_vm_close(struct vm_area_struct *vma)
*/
static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
- drm_device_dma_t *dma;
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev;
+ struct drm_device_dma *dma;
unsigned long length = vma->vm_end - vma->vm_start;
dev = priv->head->dev;
@@ -524,7 +524,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-unsigned long drm_core_get_map_ofs(drm_map_t * map)
+unsigned long drm_core_get_map_ofs(struct drm_map * map)
{
return map->offset;
}
@@ -543,7 +543,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
/**
* mmap DMA memory.
*
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
*
@@ -555,11 +555,11 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
*/
static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_map_t *map = NULL;
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev = priv->head->dev;
+ struct drm_map *map = NULL;
unsigned long offset = 0;
- drm_hash_item_t *hash;
+ struct drm_hash_item *hash;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
vma->vm_start, vma->vm_end, vma->vm_pgoff);
@@ -585,7 +585,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
return -EINVAL;
}
- map = drm_hash_entry(hash, drm_map_list_t, hash)->map;
+ map = drm_hash_entry(hash, struct drm_map_list, hash)->map;
if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
@@ -676,8 +676,8 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
int drm_mmap(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev = priv->head->dev;
int ret;
mutex_lock(&dev->struct_mutex);
@@ -713,11 +713,11 @@ EXPORT_SYMBOL(drm_mmap);
static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
unsigned long 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;
@@ -728,10 +728,17 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
if (address > vma->vm_end)
return NOPFN_SIGBUS;
- err = mutex_lock_interruptible(&bo->mutex);
+ dev = bo->dev;
+ err = drm_bo_read_lock(&dev->bm.bm_lock);
if (err)
return NOPFN_REFAULT;
+ err = mutex_lock_interruptible(&bo->mutex);
+ if (err) {
+ drm_bo_read_unlock(&dev->bm.bm_lock);
+ return NOPFN_REFAULT;
+ }
+
err = drm_bo_wait(bo, 0, 0, 0);
if (err) {
ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT;
@@ -754,7 +761,6 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
}
}
- dev = bo->dev;
err = drm_bo_pci_offset(dev, &bo->mem, &bus_base, &bus_offset,
&bus_size);
@@ -766,7 +772,7 @@ static unsigned long drm_bo_vm_nopfn(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);
@@ -792,13 +798,14 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
}
out_unlock:
mutex_unlock(&bo->mutex);
+ drm_bo_read_unlock(&dev->bm.bm_lock);
return ret;
}
#endif
static void drm_bo_vm_open_locked(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;
drm_vm_open_locked(vma);
atomic_inc(&bo->usage);
@@ -815,8 +822,8 @@ static void drm_bo_vm_open_locked(struct vm_area_struct *vma)
static void drm_bo_vm_open(struct vm_area_struct *vma)
{
- drm_buffer_object_t *bo = (drm_buffer_object_t *) vma->vm_private_data;
- drm_device_t *dev = bo->dev;
+ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
+ struct drm_device *dev = bo->dev;
mutex_lock(&dev->struct_mutex);
drm_bo_vm_open_locked(vma);
@@ -831,8 +838,8 @@ static void drm_bo_vm_open(struct vm_area_struct *vma)
static void drm_bo_vm_close(struct vm_area_struct *vma)
{
- drm_buffer_object_t *bo = (drm_buffer_object_t *) vma->vm_private_data;
- drm_device_t *dev = bo->dev;
+ struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
+ struct drm_device *dev = bo->dev;
drm_vm_close(vma);
if (bo) {
@@ -840,7 +847,8 @@ static void drm_bo_vm_close(struct vm_area_struct *vma)
#ifdef DRM_ODD_MM_COMPAT
drm_bo_delete_vma(bo, vma);
#endif
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked((struct drm_buffer_object **)
+ &vma->vm_private_data);
mutex_unlock(&dev->struct_mutex);
}
return;
@@ -864,7 +872,7 @@ static struct vm_operations_struct drm_bo_vm_ops = {
* mmap buffer object memory.
*
* \param vma virtual memory area.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param map The buffer object drm map.
* \return zero on success or a negative number on failure.
*/
diff --git a/linux-core/ffb_context.c b/linux-core/ffb_context.c
index e6ae60c3..586c3503 100644
--- a/linux-core/ffb_context.c
+++ b/linux-core/ffb_context.c
@@ -13,7 +13,7 @@
#include "drmP.h"
#include "ffb_drv.h"
-static int ffb_alloc_queue(drm_device_t * dev, int is_2d_only) {
+static int ffb_alloc_queue(struct drm_device * dev, int is_2d_only) {
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int i;
@@ -351,7 +351,7 @@ static void FFBWait(ffb_fbcPtr ffb)
} while (--limit);
}
-int ffb_context_switch(drm_device_t * dev, int old, int new) {
+int ffb_context_switch(struct drm_device * dev, int old, int new) {
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
#if DRM_DMA_HISTOGRAM
@@ -401,7 +401,7 @@ int ffb_resctx(struct inode * inode, struct file * filp, unsigned int cmd,
int ffb_addctx(struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg) {
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ struct drm_device *dev = priv->dev;
drm_ctx_t ctx;
int idx;
@@ -421,7 +421,7 @@ int ffb_addctx(struct inode * inode, struct file * filp, unsigned int cmd,
int ffb_modctx(struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg) {
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ struct drm_device *dev = priv->dev;
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
struct ffb_hw_context *hwctx;
drm_ctx_t ctx;
@@ -449,7 +449,7 @@ int ffb_modctx(struct inode * inode, struct file * filp, unsigned int cmd,
int ffb_getctx(struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg) {
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ struct drm_device *dev = priv->dev;
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
struct ffb_hw_context *hwctx;
drm_ctx_t ctx;
@@ -480,7 +480,7 @@ int ffb_getctx(struct inode * inode, struct file * filp, unsigned int cmd,
int ffb_switchctx(struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg) {
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ struct drm_device *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
@@ -504,7 +504,7 @@ int ffb_rmctx(struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg) {
drm_ctx_t ctx;
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ struct drm_device *dev = priv->dev;
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int idx;
@@ -523,7 +523,7 @@ int ffb_rmctx(struct inode * inode, struct file * filp, unsigned int cmd,
return 0;
}
-static void ffb_driver_reclaim_buffers_locked(drm_device_t * dev)
+static void ffb_driver_reclaim_buffers_locked(struct drm_device * dev)
{
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
@@ -537,13 +537,13 @@ static void ffb_driver_reclaim_buffers_locked(drm_device_t * dev)
}
}
-static void ffb_driver_lastclose(drm_device_t * dev)
+static void ffb_driver_lastclose(struct drm_device * dev)
{
if (dev->dev_private)
kfree(dev->dev_private);
}
-static void ffb_driver_unload(drm_device_t * dev)
+static void ffb_driver_unload(struct drm_device * dev)
{
if (ffb_position != NULL)
kfree(ffb_position);
@@ -571,7 +571,7 @@ unsigned long ffb_driver_get_map_ofs(drm_map_t * map)
return (map->offset & 0xffffffff);
}
-unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev)
+unsigned long ffb_driver_get_reg_ofs(struct drm_device * dev)
{
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
diff --git a/linux-core/ffb_drv.c b/linux-core/ffb_drv.c
index 9c88f061..f2b4cc7f 100644
--- a/linux-core/ffb_drv.c
+++ b/linux-core/ffb_drv.c
@@ -114,7 +114,7 @@ static void ffb_apply_upa_parent_ranges(int parent,
return;
}
-static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
+static int ffb_init_one(struct drm_device *dev, int prom_node, int parent_node,
int instance)
{
struct linux_prom64_registers regs[2*PROMREG_MAX];
@@ -167,7 +167,7 @@ static int __init ffb_scan_siblings(int root, int instance)
static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
{
drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
+ struct drm_device *dev;
drm_map_list_t *r_list;
struct list_head *list;
drm_map_t *map;
@@ -237,10 +237,10 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
/* This functions must be here since it references drm_numdevs)
* which drm_drv.h declares.
*/
-static int ffb_driver_firstopen(drm_device_t *dev)
+static int ffb_driver_firstopen(struct drm_device *dev)
{
ffb_dev_priv_t *ffb_priv;
- drm_device_t *temp_dev;
+ struct drm_device *temp_dev;
int ret = 0;
int i;
diff --git a/linux-core/ffb_drv.h b/linux-core/ffb_drv.h
index f76b0d92..bad3c94d 100644
--- a/linux-core/ffb_drv.h
+++ b/linux-core/ffb_drv.h
@@ -281,4 +281,4 @@ extern unsigned long ffb_get_unmapped_area(struct file *filp,
unsigned long pgoff,
unsigned long flags);
extern unsigned long ffb_driver_get_map_ofs(drm_map_t *map)
-extern unsigned long ffb_driver_get_reg_ofs(drm_device_t *dev)
+extern unsigned long ffb_driver_get_reg_ofs(struct drm_device *dev)
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c
index 49379434..7c37b4bb 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -46,9 +46,9 @@
#define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED 1
-static inline void i810_print_status_page(drm_device_t * dev)
+static inline void i810_print_status_page(struct drm_device * dev)
{
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
drm_i810_private_t *dev_priv = dev->dev_private;
u32 *temp = dev_priv->hw_status_page;
int i;
@@ -64,16 +64,16 @@ static inline void i810_print_status_page(drm_device_t * dev)
}
}
-static drm_buf_t *i810_freelist_get(drm_device_t * dev)
+static struct drm_buf *i810_freelist_get(struct drm_device * dev)
{
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
int i;
int used;
/* Linear search might not be the best solution */
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[i];
+ struct drm_buf *buf = dma->buflist[i];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
/* In use is already a pointer */
used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
@@ -89,7 +89,7 @@ static drm_buf_t *i810_freelist_get(drm_device_t * dev)
* yet, the hardware updates in use for us once its on the ring buffer.
*/
-static int i810_freelist_put(drm_device_t * dev, drm_buf_t * buf)
+static int i810_freelist_put(struct drm_device * dev, struct drm_buf * buf)
{
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
int used;
@@ -106,10 +106,10 @@ static int i810_freelist_put(drm_device_t * dev, drm_buf_t * buf)
static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
+ struct drm_file *priv = filp->private_data;
+ struct drm_device *dev;
drm_i810_private_t *dev_priv;
- drm_buf_t *buf;
+ struct drm_buf *buf;
drm_i810_buf_priv_t *buf_priv;
lock_kernel();
@@ -139,10 +139,9 @@ static const struct file_operations i810_buffer_fops = {
.fasync = drm_fasync,
};
-static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
+static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ struct drm_device *dev = file_priv->head->dev;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
drm_i810_private_t *dev_priv = dev->dev_private;
const struct file_operations *old_fops;
@@ -152,14 +151,14 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
return -EINVAL;
down_write(&current->mm->mmap_sem);
- old_fops = filp->f_op;
- filp->f_op = &i810_buffer_fops;
+ old_fops = file_priv->filp->f_op;
+ file_priv->filp->f_op = &i810_buffer_fops;
dev_priv->mmap_buffer = buf;
- buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
+ buf_priv->virtual = (void *)do_mmap(file_priv->filp, 0, buf->total,
PROT_READ | PROT_WRITE,
MAP_SHARED, buf->bus_address);
dev_priv->mmap_buffer = NULL;
- filp->f_op = old_fops;
+ file_priv->filp->f_op = old_fops;
if (IS_ERR(buf_priv->virtual)) {
/* Real error */
DRM_ERROR("mmap error\n");
@@ -171,7 +170,7 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp)
return retcode;
}
-static int i810_unmap_buffer(drm_buf_t * buf)
+static int i810_unmap_buffer(struct drm_buf * buf)
{
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
int retcode = 0;
@@ -191,10 +190,10 @@ static int i810_unmap_buffer(drm_buf_t * buf)
return retcode;
}
-static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d,
- struct file *filp)
+static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d,
+ struct drm_file *file_priv)
{
- drm_buf_t *buf;
+ struct drm_buf *buf;
drm_i810_buf_priv_t *buf_priv;
int retcode = 0;
@@ -205,13 +204,13 @@ static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d,
return retcode;
}
- retcode = i810_map_buffer(buf, filp);
+ retcode = i810_map_buffer(buf, file_priv);
if (retcode) {
i810_freelist_put(dev, buf);
DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
return retcode;
}
- buf->filp = filp;
+ buf->file_priv = file_priv;
buf_priv = buf->dev_private;
d->granted = 1;
d->request_idx = buf->idx;
@@ -221,9 +220,9 @@ static int i810_dma_get_buffer(drm_device_t * dev, drm_i810_dma_t * d,
return retcode;
}
-static int i810_dma_cleanup(drm_device_t * dev)
+static int i810_dma_cleanup(struct drm_device * dev)
{
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
@@ -252,7 +251,7 @@ static int i810_dma_cleanup(drm_device_t * dev)
dev->dev_private = NULL;
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[i];
+ struct drm_buf *buf = dma->buflist[i];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
if (buf_priv->kernel_virtual && buf->total)
@@ -262,7 +261,7 @@ static int i810_dma_cleanup(drm_device_t * dev)
return 0;
}
-static int i810_wait_ring(drm_device_t * dev, int n)
+static int i810_wait_ring(struct drm_device * dev, int n)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
@@ -295,7 +294,7 @@ static int i810_wait_ring(drm_device_t * dev, int n)
return iters;
}
-static void i810_kernel_lost_context(drm_device_t * dev)
+static void i810_kernel_lost_context(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
@@ -307,9 +306,9 @@ static void i810_kernel_lost_context(drm_device_t * dev)
ring->space += ring->Size;
}
-static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
+static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_priv)
{
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
int my_idx = 24;
u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
int i;
@@ -320,7 +319,7 @@ static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
}
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[i];
+ struct drm_buf *buf = dma->buflist[i];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
buf_priv->in_use = hw_status++;
@@ -342,11 +341,11 @@ static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
return 0;
}
-static int i810_dma_initialize(drm_device_t * dev,
+static int i810_dma_initialize(struct drm_device * dev,
drm_i810_private_t * dev_priv,
drm_i810_init_t * init)
{
- drm_map_list_t *r_list;
+ struct drm_map_list *r_list;
memset(dev_priv, 0, sizeof(drm_i810_private_t));
list_for_each_entry(r_list, &dev->maplist, head) {
@@ -399,7 +398,7 @@ static int i810_dma_initialize(drm_device_t * dev,
i810_dma_cleanup(dev);
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
- return DRM_ERR(ENOMEM);
+ return -ENOMEM;
}
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
@@ -449,99 +448,29 @@ static int i810_dma_initialize(drm_device_t * dev,
return 0;
}
-/* i810 DRM version 1.1 used a smaller init structure with different
- * ordering of values than is currently used (drm >= 1.2). There is
- * no defined way to detect the XFree version to correct this problem,
- * however by checking using this procedure we can detect the correct
- * thing to do.
- *
- * #1 Read the Smaller init structure from user-space
- * #2 Verify the overlay_physical is a valid physical address, or NULL
- * If it isn't then we have a v1.1 client. Fix up params.
- * If it is, then we have a 1.2 client... get the rest of the data.
- */
-static int i810_dma_init_compat(drm_i810_init_t * init, unsigned long arg)
+static int i810_dma_init(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
-
- /* Get v1.1 init data */
- if (copy_from_user(init, (drm_i810_pre12_init_t __user *) arg,
- sizeof(drm_i810_pre12_init_t))) {
- return -EFAULT;
- }
-
- if ((!init->overlay_physical) || (init->overlay_physical > 4096)) {
-
- /* This is a v1.2 client, just get the v1.2 init data */
- DRM_INFO("Using POST v1.2 init.\n");
- if (copy_from_user(init, (drm_i810_init_t __user *) arg,
- sizeof(drm_i810_init_t))) {
- return -EFAULT;
- }
- } else {
-
- /* This is a v1.1 client, fix the params */
- DRM_INFO("Using PRE v1.2 init.\n");
- init->pitch_bits = init->h;
- init->pitch = init->w;
- init->h = init->overlay_physical;
- init->w = init->overlay_offset;
- init->overlay_physical = 0;
- init->overlay_offset = 0;
- }
-
- return 0;
-}
-
-static int i810_dma_init(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_i810_private_t *dev_priv;
- drm_i810_init_t init;
+ drm_i810_init_t *init = data;
int retcode = 0;
- /* Get only the init func */
- if (copy_from_user
- (&init, (void __user *)arg, sizeof(drm_i810_init_func_t)))
- return -EFAULT;
-
- switch (init.func) {
- case I810_INIT_DMA:
- /* This case is for backward compatibility. It
- * handles XFree 4.1.0 and 4.2.0, and has to
- * do some parameter checking as described below.
- * It will someday go away.
- */
- retcode = i810_dma_init_compat(&init, arg);
- if (retcode)
- return retcode;
-
- dev_priv = drm_alloc(sizeof(drm_i810_private_t),
- DRM_MEM_DRIVER);
- if (dev_priv == NULL)
- return -ENOMEM;
- retcode = i810_dma_initialize(dev, dev_priv, &init);
- break;
-
- default:
+ switch (init->func) {
case I810_INIT_DMA_1_4:
DRM_INFO("Using v1.4 init.\n");
- if (copy_from_user(&init, (drm_i810_init_t __user *) arg,
- sizeof(drm_i810_init_t))) {
- return -EFAULT;
- }
dev_priv = drm_alloc(sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
if (dev_priv == NULL)
return -ENOMEM;
- retcode = i810_dma_initialize(dev, dev_priv, &init);
+ retcode = i810_dma_initialize(dev, dev_priv, init);
break;
case I810_CLEANUP_DMA:
DRM_INFO("DMA Cleanup\n");
retcode = i810_dma_cleanup(dev);
break;
+ default:
+ return -EINVAL;
}
return retcode;
@@ -553,7 +482,7 @@ static int i810_dma_init(struct inode *inode, struct file *filp,
* Use 'volatile' & local var tmp to force the emitted values to be
* identical to the verified ones.
*/
-static void i810EmitContextVerified(drm_device_t * dev,
+static void i810EmitContextVerified(struct drm_device * dev,
volatile unsigned int *code)
{
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -586,7 +515,7 @@ static void i810EmitContextVerified(drm_device_t * dev,
ADVANCE_LP_RING();
}
-static void i810EmitTexVerified(drm_device_t * dev, volatile unsigned int *code)
+static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *code)
{
drm_i810_private_t *dev_priv = dev->dev_private;
int i, j = 0;
@@ -619,7 +548,7 @@ static void i810EmitTexVerified(drm_device_t * dev, volatile unsigned int *code)
/* Need to do some additional checking when setting the dest buffer.
*/
-static void i810EmitDestVerified(drm_device_t * dev,
+static void i810EmitDestVerified(struct drm_device * dev,
volatile unsigned int *code)
{
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -654,7 +583,7 @@ static void i810EmitDestVerified(drm_device_t * dev,
ADVANCE_LP_RING();
}
-static void i810EmitState(drm_device_t * dev)
+static void i810EmitState(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -685,14 +614,14 @@ static void i810EmitState(drm_device_t * dev)
/* need to verify
*/
-static void i810_dma_dispatch_clear(drm_device_t * dev, int flags,
+static void i810_dma_dispatch_clear(struct drm_device * dev, int flags,
unsigned int clear_color,
unsigned int clear_zval)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
int nbox = sarea_priv->nbox;
- drm_clip_rect_t *pbox = sarea_priv->boxes;
+ struct drm_clip_rect *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch;
int cpp = 2;
int i;
@@ -760,12 +689,12 @@ static void i810_dma_dispatch_clear(drm_device_t * dev, int flags,
}
}
-static void i810_dma_dispatch_swap(drm_device_t * dev)
+static void i810_dma_dispatch_swap(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
int nbox = sarea_priv->nbox;
- drm_clip_rect_t *pbox = sarea_priv->boxes;
+ struct drm_clip_rect *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch;
int cpp = 2;
int i;
@@ -806,13 +735,13 @@ static void i810_dma_dispatch_swap(drm_device_t * dev)
}
}
-static void i810_dma_dispatch_vertex(drm_device_t * dev,
- drm_buf_t * buf, int discard, int used)
+static void i810_dma_dispatch_vertex(struct drm_device * dev,
+ struct drm_buf * buf, int discard, int used)
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_clip_rect_t *box = sarea_priv->boxes;
+ struct drm_clip_rect *box = sarea_priv->boxes;
int nbox = sarea_priv->nbox;
unsigned long address = (unsigned long)buf->bus_address;
unsigned long start = address - dev->agp->base;
@@ -886,7 +815,7 @@ static void i810_dma_dispatch_vertex(drm_device_t * dev,
}
}
-static void i810_dma_dispatch_flip(drm_device_t * dev)
+static void i810_dma_dispatch_flip(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
int pitch = dev_priv->pitch;
@@ -933,7 +862,7 @@ static void i810_dma_dispatch_flip(drm_device_t * dev)
}
-static void i810_dma_quiescent(drm_device_t * dev)
+static void i810_dma_quiescent(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
@@ -952,10 +881,10 @@ static void i810_dma_quiescent(drm_device_t * dev)
i810_wait_ring(dev, dev_priv->ring.Size - 8);
}
-static int i810_flush_queue(drm_device_t * dev)
+static int i810_flush_queue(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
int i, ret = 0;
RING_LOCALS;
@@ -971,7 +900,7 @@ static int i810_flush_queue(drm_device_t * dev)
i810_wait_ring(dev, dev_priv->ring.Size - 8);
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[i];
+ struct drm_buf *buf = dma->buflist[i];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
@@ -987,9 +916,10 @@ static int i810_flush_queue(drm_device_t * dev)
}
/* Must be called with the lock held */
-static void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
+static void i810_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)
@@ -1002,10 +932,10 @@ static void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
i810_flush_queue(dev);
for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[i];
+ struct drm_buf *buf = dma->buflist[i];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- if (buf->filp == filp && buf_priv) {
+ if (buf->file_priv == file_priv && buf_priv) {
int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
I810_BUF_FREE);
@@ -1017,47 +947,38 @@ static void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
}
}
-static int i810_flush_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_flush_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;
-
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
i810_flush_queue(dev);
return 0;
}
-static int i810_dma_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_dma_vertex(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;
+ struct drm_device_dma *dma = dev->dma;
drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
u32 *hw_status = dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
- drm_i810_vertex_t vertex;
+ drm_i810_vertex_t *vertex = data;
- if (copy_from_user
- (&vertex, (drm_i810_vertex_t __user *) arg, sizeof(vertex)))
- return -EFAULT;
-
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
- vertex.idx, vertex.used, vertex.discard);
+ vertex->idx, vertex->used, vertex->discard);
- if (vertex.idx < 0 || vertex.idx > dma->buf_count)
+ if (vertex->idx < 0 || vertex->idx > dma->buf_count)
return -EINVAL;
i810_dma_dispatch_vertex(dev,
- dma->buflist[vertex.idx],
- vertex.discard, vertex.used);
+ dma->buflist[vertex->idx],
+ vertex->discard, vertex->used);
- atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
+ atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
sarea_priv->last_enqueue = dev_priv->counter - 1;
sarea_priv->last_dispatch = (int)hw_status[5];
@@ -1065,48 +986,37 @@ static int i810_dma_vertex(struct inode *inode, struct file *filp,
return 0;
}
-static int i810_clear_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_clear_bufs(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_i810_clear_t clear;
-
- if (copy_from_user
- (&clear, (drm_i810_clear_t __user *) arg, sizeof(clear)))
- return -EFAULT;
+ drm_i810_clear_t *clear = data;
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
/* GH: Someone's doing nasty things... */
if (!dev->dev_private) {
return -EINVAL;
}
- i810_dma_dispatch_clear(dev, clear.flags,
- clear.clear_color, clear.clear_depth);
+ i810_dma_dispatch_clear(dev, clear->flags,
+ clear->clear_color, clear->clear_depth);
return 0;
}
-static int i810_swap_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_swap_bufs(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_DEBUG("i810_swap_bufs\n");
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
i810_dma_dispatch_swap(dev);
return 0;
}
-static int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+static int i810_getage(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_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
u32 *hw_status = dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
@@ -1116,52 +1026,45 @@ static int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
return 0;
}
-static int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+static int i810_getbuf(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;
int retcode = 0;
- drm_i810_dma_t d;
+ drm_i810_dma_t *d = data;
drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
u32 *hw_status = dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
- if (copy_from_user(&d, (drm_i810_dma_t __user *) arg, sizeof(d)))
- return -EFAULT;
-
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
- d.granted = 0;
+ d->granted = 0;
- retcode = i810_dma_get_buffer(dev, &d, filp);
+ retcode = i810_dma_get_buffer(dev, d, file_priv);
DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
- current->pid, retcode, d.granted);
+ current->pid, retcode, d->granted);
- if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))
- return -EFAULT;
sarea_priv->last_dispatch = (int)hw_status[5];
return retcode;
}
-static int i810_copybuf(struct inode *inode,
- struct file *filp, unsigned int cmd, unsigned long arg)
+static int i810_copybuf(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
/* Never copy - 2.4.x doesn't need it */
return 0;
}
-static int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+static int i810_docopy(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
/* Never copy - 2.4.x doesn't need it */
return 0;
}
-static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used,
+static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, int used,
unsigned int last_render)
{
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1221,30 +1124,25 @@ static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used,
ADVANCE_LP_RING();
}
-static int i810_dma_mc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_dma_mc(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;
+ struct drm_device_dma *dma = dev->dma;
drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
u32 *hw_status = dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
- drm_i810_mc_t mc;
+ drm_i810_mc_t *mc = data;
- if (copy_from_user(&mc, (drm_i810_mc_t __user *) arg, sizeof(mc)))
- return -EFAULT;
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
- LOCK_TEST_WITH_RETURN(dev, filp);
-
- if (mc.idx >= dma->buf_count || mc.idx < 0)
+ if (mc->idx >= dma->buf_count || mc->idx < 0)
return -EINVAL;
- i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used,
- mc.last_render);
+ i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
+ mc->last_render);
- atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]);
+ atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
sarea_priv->last_enqueue = dev_priv->counter - 1;
sarea_priv->last_dispatch = (int)hw_status[5];
@@ -1252,51 +1150,41 @@ static int i810_dma_mc(struct inode *inode, struct file *filp,
return 0;
}
-static int i810_rstatus(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_rstatus(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_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
return (int)(((u32 *) (dev_priv->hw_status_page))[4]);
}
-static int i810_ov0_info(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_ov0_info(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_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
- drm_i810_overlay_t data;
+ drm_i810_overlay_t *ov = data;
+
+ ov->offset = dev_priv->overlay_offset;
+ ov->physical = dev_priv->overlay_physical;
- data.offset = dev_priv->overlay_offset;
- data.physical = dev_priv->overlay_physical;
- if (copy_to_user
- ((drm_i810_overlay_t __user *) arg, &data, sizeof(data)))
- return -EFAULT;
return 0;
}
-static int i810_fstatus(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_fstatus(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_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
return I810_READ(0x30008);
}
-static int i810_ov0_flip(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_ov0_flip(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_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
//Tell the overlay to update
I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000);
@@ -1305,7 +1193,7 @@ static int i810_ov0_flip(struct inode *inode, struct file *filp,
/* Not sure why this isn't set all the time:
*/
-static void i810_do_init_pageflip(drm_device_t * dev)
+static void i810_do_init_pageflip(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1315,7 +1203,7 @@ static void i810_do_init_pageflip(drm_device_t * dev)
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
-static int i810_do_cleanup_pageflip(drm_device_t * dev)
+static int i810_do_cleanup_pageflip(struct drm_device * dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1327,16 +1215,14 @@ static int i810_do_cleanup_pageflip(drm_device_t * dev)
return 0;
}
-static int i810_flip_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int i810_flip_bufs(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_i810_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv->page_flipping)
i810_do_init_pageflip(dev);
@@ -1345,7 +1231,7 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp,
return 0;
}
-int i810_driver_load(drm_device_t *dev, unsigned long flags)
+int i810_driver_load(struct drm_device *dev, unsigned long flags)
{
/* i810 has 4 more counters */
dev->counters += 4;
@@ -1357,12 +1243,12 @@ int i810_driver_load(drm_device_t *dev, unsigned long flags)
return 0;
}
-void i810_driver_lastclose(drm_device_t * dev)
+void i810_driver_lastclose(struct drm_device * dev)
{
i810_dma_cleanup(dev);
}
-void i810_driver_preclose(drm_device_t * dev, DRMFILE filp)
+void i810_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
{
if (dev->dev_private) {
drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1372,33 +1258,34 @@ void i810_driver_preclose(drm_device_t * dev, DRMFILE filp)
}
}
-void i810_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
+void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file *file_priv)
{
- i810_reclaim_buffers(dev, filp);
+ i810_reclaim_buffers(dev, file_priv);
}
-int i810_driver_dma_quiescent(drm_device_t * dev)
+int i810_driver_dma_quiescent(struct drm_device * dev)
{
i810_dma_quiescent(dev);
return 0;
}
-drm_ioctl_desc_t i810_ioctls[] = {
- [DRM_IOCTL_NR(DRM_I810_INIT)] = {i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_I810_VERTEX)] = {i810_dma_vertex, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_CLEAR)] = {i810_clear_bufs, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_FLUSH)] = {i810_flush_ioctl, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_GETAGE)] = {i810_getage, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_GETBUF)] = {i810_getbuf, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_SWAP)] = {i810_swap_bufs, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_COPY)] = {i810_copybuf, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_DOCOPY)] = {i810_docopy, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_OV0INFO)] = {i810_ov0_info, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_FSTATUS)] = {i810_fstatus, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = {i810_ov0_flip, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_MC)] = {i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_I810_RSTATUS)] = {i810_rstatus, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_I810_FLIP)] = {i810_flip_bufs, DRM_AUTH}
+struct drm_ioctl_desc i810_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH)
};
int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
@@ -1414,7 +1301,7 @@ int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
* \returns
* A value of 1 is always retured to indictate every i810 is AGP.
*/
-int i810_driver_device_is_agp(drm_device_t * dev)
+int i810_driver_device_is_agp(struct drm_device * dev)
{
return 1;
}
diff --git a/linux-core/i810_drm.h b/linux-core/i810_drm.h
index beec4a2a..d803aeca 100644
--- a/linux-core/i810_drm.h
+++ b/linux-core/i810_drm.h
@@ -102,13 +102,8 @@ typedef enum _drm_i810_init_func {
/* This is the init structure after v1.2 */
typedef struct _drm_i810_init {
drm_i810_init_func_t func;
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
- int ring_map_idx;
- int buffer_map_idx;
-#else
unsigned int mmio_offset;
unsigned int buffers_offset;
-#endif
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
@@ -124,29 +119,6 @@ typedef struct _drm_i810_init {
unsigned int pitch_bits;
} drm_i810_init_t;
-/* This is the init structure prior to v1.2 */
-typedef struct _drm_i810_pre12_init {
- drm_i810_init_func_t func;
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
- int ring_map_idx;
- int buffer_map_idx;
-#else
- unsigned int mmio_offset;
- unsigned int buffers_offset;
-#endif
- int sarea_priv_offset;
- unsigned int ring_start;
- unsigned int ring_end;
- unsigned int ring_size;
- unsigned int front_offset;
- unsigned int back_offset;
- unsigned int depth_offset;
- unsigned int w;
- unsigned int h;
- unsigned int pitch;
- unsigned int pitch_bits;
-} drm_i810_pre12_init_t;
-
/* Warning: If you change the SAREA structure you must change the Xserver
* structure as well */
@@ -163,7 +135,7 @@ typedef struct _drm_i810_sarea {
unsigned int dirty;
unsigned int nbox;
- drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
+ struct drm_clip_rect boxes[I810_NR_SAREA_CLIPRECTS];
/* Maintain an LRU of contiguous regions of texture space. If
* you think you own a region of texture memory, and it has an
diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h
index 69d79499..c525e165 100644
--- a/linux-core/i810_drv.h
+++ b/linux-core/i810_drv.h
@@ -77,8 +77,8 @@ typedef struct _drm_i810_ring_buffer {
} drm_i810_ring_buffer_t;
typedef struct drm_i810_private {
- drm_map_t *sarea_map;
- drm_map_t *mmio_map;
+ struct drm_map *sarea_map;
+ struct drm_map *mmio_map;
drm_i810_sarea_t *sarea_priv;
drm_i810_ring_buffer_t ring;
@@ -88,7 +88,7 @@ typedef struct drm_i810_private {
dma_addr_t dma_status_page;
- drm_buf_t *mmap_buffer;
+ struct drm_buf *mmap_buffer;
u32 front_di1, back_di1, zi1;
@@ -115,17 +115,18 @@ typedef struct drm_i810_private {
} drm_i810_private_t;
/* i810_dma.c */
-extern int i810_driver_dma_quiescent(drm_device_t * dev);
-extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
- struct file *filp);
+extern int i810_driver_dma_quiescent(struct drm_device * dev);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file *file_priv);
extern int i810_driver_load(struct drm_device *, unsigned long flags);
-extern void i810_driver_lastclose(drm_device_t * dev);
-extern void i810_driver_preclose(drm_device_t * dev, DRMFILE filp);
-extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
- struct file *filp);
-extern int i810_driver_device_is_agp(drm_device_t * dev);
-
-extern drm_ioctl_desc_t i810_ioctls[];
+extern void i810_driver_lastclose(struct drm_device * dev);
+extern void i810_driver_preclose(struct drm_device * dev,
+ struct drm_file *file_priv);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file *file_priv);
+extern int i810_driver_device_is_agp(struct drm_device * dev);
+
+extern struct drm_ioctl_desc i810_ioctls[];
extern int i810_max_ioctl;
#define I810_BASE(reg) ((unsigned long) \
diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c
index 8589f467..bbc7e1db 100644
--- a/linux-core/i915_buffer.c
+++ b/linux-core/i915_buffer.c
@@ -33,22 +33,23 @@
#include "i915_drm.h"
#include "i915_drv.h"
-drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t * dev)
+struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device * dev)
{
return drm_agp_init_ttm(dev);
}
-int i915_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type)
+int i915_fence_types(struct drm_buffer_object *bo,
+ uint32_t * fclass,
+ uint32_t * type)
{
- *class = 0;
- if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
+ if (bo->mem.mask & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
*type = 3;
else
*type = 1;
return 0;
}
-int i915_invalidate_caches(drm_device_t * dev, uint32_t flags)
+int i915_invalidate_caches(struct drm_device * dev, uint64_t flags)
{
/*
* FIXME: Only emit once per batchbuffer submission.
@@ -64,14 +65,15 @@ int i915_invalidate_caches(drm_device_t * dev, uint32_t flags)
return i915_emit_mi_flush(dev, flush_cmd);
}
-int i915_init_mem_type(drm_device_t * dev, uint32_t type,
- drm_mem_type_manager_t * man)
+int i915_init_mem_type(struct drm_device * dev, uint32_t type,
+ struct drm_mem_type_manager * man)
{
switch (type) {
case DRM_BO_MEM_LOCAL:
man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
_DRM_FLAG_MEMTYPE_CACHED;
man->drm_bus_maptype = 0;
+ man->gpu_offset = 0;
break;
case DRM_BO_MEM_TT:
if (!(drm_core_has_AGP(dev) && dev->agp)) {
@@ -85,6 +87,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type,
man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
_DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP;
man->drm_bus_maptype = _DRM_AGP;
+ man->gpu_offset = 0;
break;
case DRM_BO_MEM_PRIV0:
if (!(drm_core_has_AGP(dev) && dev->agp)) {
@@ -98,6 +101,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type,
man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
_DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP;
man->drm_bus_maptype = _DRM_AGP;
+ man->gpu_offset = 0;
break;
default:
DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
@@ -106,7 +110,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type,
return 0;
}
-uint32_t i915_evict_mask(drm_buffer_object_t *bo)
+uint32_t i915_evict_mask(struct drm_buffer_object *bo)
{
switch (bo->mem.mem_type) {
case DRM_BO_MEM_LOCAL:
@@ -117,7 +121,9 @@ uint32_t i915_evict_mask(drm_buffer_object_t *bo)
}
}
-static void i915_emit_copy_blit(drm_device_t * dev,
+#if 0 /* See comment below */
+
+static void i915_emit_copy_blit(struct drm_device * dev,
uint32_t src_offset,
uint32_t dst_offset,
uint32_t pages, int direction)
@@ -151,10 +157,10 @@ static void i915_emit_copy_blit(drm_device_t * dev,
return;
}
-static int i915_move_blit(drm_buffer_object_t * bo,
- int evict, int no_wait, drm_bo_mem_reg_t * new_mem)
+static int i915_move_blit(struct drm_buffer_object * bo,
+ int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
{
- drm_bo_mem_reg_t *old_mem = &bo->mem;
+ struct drm_bo_mem_reg *old_mem = &bo->mem;
int dir = 0;
if ((old_mem->mem_type == new_mem->mem_type) &&
@@ -181,11 +187,11 @@ static int i915_move_blit(drm_buffer_object_t * bo,
* then blit and subsequently move out again.
*/
-static int i915_move_flip(drm_buffer_object_t * bo,
- int evict, int no_wait, drm_bo_mem_reg_t * new_mem)
+static int i915_move_flip(struct drm_buffer_object * bo,
+ int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
{
- drm_device_t *dev = bo->dev;
- drm_bo_mem_reg_t tmp_mem;
+ struct drm_device *dev = bo->dev;
+ struct drm_bo_mem_reg tmp_mem;
int ret;
tmp_mem = *new_mem;
@@ -197,7 +203,7 @@ static int i915_move_flip(drm_buffer_object_t * bo,
if (ret)
return ret;
- ret = drm_bind_ttm(bo->ttm, 1, tmp_mem.mm_node->start);
+ ret = drm_bind_ttm(bo->ttm, &tmp_mem);
if (ret)
goto out_cleanup;
@@ -217,19 +223,62 @@ out_cleanup:
return ret;
}
-int i915_move(drm_buffer_object_t * bo,
- int evict, int no_wait, drm_bo_mem_reg_t * new_mem)
+#endif
+
+/*
+ * Disable i915_move_flip for now, since we can't guarantee that the hardware lock
+ * is held here. To re-enable we need to make sure either
+ * a) The X server is using DRM to submit commands to the ring, or
+ * b) DRM can use the HP ring for these blits. This means i915 needs to implement
+ * a new ring submission mechanism and fence class.
+ */
+
+int i915_move(struct drm_buffer_object * bo,
+ int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
{
- drm_bo_mem_reg_t *old_mem = &bo->mem;
+ struct drm_bo_mem_reg *old_mem = &bo->mem;
if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
} else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
- if (i915_move_flip(bo, evict, no_wait, new_mem))
+ if (0 /*i915_move_flip(bo, evict, no_wait, new_mem)*/)
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
} else {
- if (i915_move_blit(bo, evict, no_wait, new_mem))
+ if (0 /*i915_move_blit(bo, evict, no_wait, new_mem)*/)
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
}
return 0;
}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+static inline void clflush(volatile void *__p)
+{
+ asm volatile("clflush %0" : "+m" (*(char __force *)__p));
+}
+#endif
+
+static inline void drm_cache_flush_addr(void *virt)
+{
+ int i;
+
+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+ clflush(virt+i);
+}
+
+static inline void drm_cache_flush_page(struct page *p)
+{
+ drm_cache_flush_addr(page_address(p));
+}
+
+void i915_flush_ttm(struct drm_ttm *ttm)
+{
+ int i;
+
+ if (!ttm)
+ return;
+
+ DRM_MEMORYBARRIER();
+ for (i = ttm->num_pages-1; i >= 0; i--)
+ drm_cache_flush_page(drm_ttm_get_page(ttm, i));
+ DRM_MEMORYBARRIER();
+}
diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c
index e7f69e63..84df64a7 100644
--- a/linux-core/i915_drv.c
+++ b/linux-core/i915_drv.c
@@ -39,11 +39,11 @@ static struct pci_device_id pciidlist[] = {
};
#ifdef I915_HAVE_FENCE
-static drm_fence_driver_t i915_fence_driver = {
+static struct drm_fence_driver i915_fence_driver = {
.num_classes = 1,
- .wrap_diff = (1 << 30),
- .flush_diff = (1 << 29),
- .sequence_mask = 0xffffffffU,
+ .wrap_diff = (1U << (BREADCRUMB_BITS - 1)),
+ .flush_diff = (1U << (BREADCRUMB_BITS - 2)),
+ .sequence_mask = BREADCRUMB_MASK,
.lazy_capable = 1,
.emit = i915_fence_emit_sequence,
.poke_flush = i915_poke_flush,
@@ -55,7 +55,7 @@ static drm_fence_driver_t i915_fence_driver = {
static uint32_t i915_mem_prios[] = {DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_LOCAL};
-static drm_bo_driver_t i915_bo_driver = {
+static struct drm_bo_driver i915_bo_driver = {
.mem_type_prio = i915_mem_prios,
.mem_busy_prio = i915_busy_prios,
.num_mem_type_prio = sizeof(i915_mem_prios)/sizeof(uint32_t),
@@ -66,9 +66,462 @@ static drm_bo_driver_t i915_bo_driver = {
.init_mem_type = i915_init_mem_type,
.evict_mask = i915_evict_mask,
.move = i915_move,
+ .ttm_cache_flush = i915_flush_ttm,
};
#endif
+enum pipe {
+ PIPE_A = 0,
+ PIPE_B,
+};
+
+static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (pipe == PIPE_A)
+ return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
+ else
+ return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
+}
+
+static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for(i = 0; i < 256; i++)
+ array[i] = I915_READ(reg + (i << 2));
+}
+
+static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for(i = 0; i < 256; i++)
+ I915_WRITE(reg + (i << 2), array[i]);
+}
+
+static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg)
+{
+ outb(reg, index_port);
+ return inb(data_port);
+}
+
+static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable)
+{
+ inb(st01);
+ outb(palette_enable | reg, VGA_AR_INDEX);
+ return inb(VGA_AR_DATA_READ);
+}
+
+static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable)
+{
+ inb(st01);
+ outb(palette_enable | reg, VGA_AR_INDEX);
+ outb(val, VGA_AR_DATA_WRITE);
+}
+
+static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val)
+{
+ outb(reg, index_port);
+ outb(val, data_port);
+}
+
+static void i915_save_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* VGA color palette registers */
+ dev_priv->saveDACMASK = inb(VGA_DACMASK);
+ /* DACCRX automatically increments during read */
+ outb(0, VGA_DACRX);
+ /* Read 3 bytes of color data from each index */
+ for (i = 0; i < 256 * 3; i++)
+ dev_priv->saveDACDATA[i] = inb(VGA_DACDATA);
+
+ /* MSR bits */
+ dev_priv->saveMSR = inb(VGA_MSR_READ);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* CRT controller regs */
+ i915_write_indexed(cr_index, cr_data, 0x11,
+ i915_read_indexed(cr_index, cr_data, 0x11) &
+ (~0x80));
+ for (i = 0; i < 0x24; i++)
+ dev_priv->saveCR[i] =
+ i915_read_indexed(cr_index, cr_data, i);
+ /* Make sure we don't turn off CR group 0 writes */
+ dev_priv->saveCR[0x11] &= ~0x80;
+
+ /* Attribute controller registers */
+ inb(st01);
+ dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX);
+ for (i = 0; i < 20; i++)
+ dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
+ inb(st01);
+ outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
+
+ /* Graphics controller registers */
+ for (i = 0; i < 9; i++)
+ dev_priv->saveGR[i] =
+ i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i);
+
+ dev_priv->saveGR[0x10] =
+ i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10);
+ dev_priv->saveGR[0x11] =
+ i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11);
+ dev_priv->saveGR[0x18] =
+ i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18);
+
+ /* Sequencer registers */
+ for (i = 0; i < 8; i++)
+ dev_priv->saveSR[i] =
+ i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i);
+}
+
+static void i915_restore_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* MSR bits */
+ outb(dev_priv->saveMSR, VGA_MSR_WRITE);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* Sequencer registers, don't write SR07 */
+ for (i = 0; i < 7; i++)
+ i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i,
+ dev_priv->saveSR[i]);
+
+ /* CRT controller regs */
+ /* Enable CR group 0 writes */
+ i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
+ for (i = 0; i < 0x24; i++)
+ i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]);
+
+ /* Graphics controller regs */
+ for (i = 0; i < 9; i++)
+ i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i,
+ dev_priv->saveGR[i]);
+
+ i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10,
+ dev_priv->saveGR[0x10]);
+ i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11,
+ dev_priv->saveGR[0x11]);
+ i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18,
+ dev_priv->saveGR[0x18]);
+
+ /* Attribute controller registers */
+ for (i = 0; i < 20; i++)
+ i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
+ inb(st01); /* switch back to index mode */
+ outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
+
+ /* VGA color palette registers */
+ outb(dev_priv->saveDACMASK, VGA_DACMASK);
+ /* DACCRX automatically increments during read */
+ outb(0, VGA_DACWX);
+ /* Read 3 bytes of color data from each index */
+ for (i = 0; i < 256 * 3; i++)
+ outb(dev_priv->saveDACDATA[i], VGA_DACDATA);
+
+}
+
+static int i915_suspend(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ if (!dev || !dev_priv) {
+ printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
+ printk(KERN_ERR "DRM not initialized, aborting suspend.\n");
+ return -ENODEV;
+ }
+
+ pci_save_state(dev->pdev);
+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
+
+ /* Pipe & plane A info */
+ dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
+ dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
+ dev_priv->saveFPA0 = I915_READ(FPA0);
+ dev_priv->saveFPA1 = I915_READ(FPA1);
+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
+ if (IS_I965G(dev))
+ dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
+ dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
+ dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
+ dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
+ dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
+ dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
+ dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
+ dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
+ dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
+ dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
+ dev_priv->saveDSPABASE = I915_READ(DSPABASE);
+ if (IS_I965G(dev)) {
+ dev_priv->saveDSPASURF = I915_READ(DSPASURF);
+ dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
+ }
+ i915_save_palette(dev, PIPE_A);
+
+ /* Pipe & plane B info */
+ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
+ dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
+ dev_priv->saveFPB0 = I915_READ(FPB0);
+ dev_priv->saveFPB1 = I915_READ(FPB1);
+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
+ if (IS_I965G(dev))
+ dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
+ dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
+ dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
+ dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
+ dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
+ dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
+ dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
+ dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
+ dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
+ dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
+ dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
+ if (IS_I965GM(dev)) {
+ dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
+ dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
+ }
+ i915_save_palette(dev, PIPE_B);
+
+ /* CRT state */
+ dev_priv->saveADPA = I915_READ(ADPA);
+
+ /* LVDS state */
+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+ if (IS_I965G(dev))
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ dev_priv->saveLVDS = I915_READ(LVDS);
+ if (!IS_I830(dev) && !IS_845G(dev))
+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
+ dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
+ dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
+ dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
+
+ /* FIXME: save TV & SDVO state */
+
+ /* FBC state */
+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+
+ /* VGA state */
+ dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
+ dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
+ dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+
+ /* Scratch space */
+ for (i = 0; i < 16; i++) {
+ dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
+ }
+ for (i = 0; i < 3; i++)
+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
+
+ i915_save_vga(dev);
+
+ /* Shut down the device */
+ pci_disable_device(dev->pdev);
+ pci_set_power_state(dev->pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int i915_resume(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ pci_set_power_state(dev->pdev, PCI_D0);
+ pci_restore_state(dev->pdev);
+ if (pci_enable_device(dev->pdev))
+ return -1;
+
+ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
+
+ /* Pipe & plane A info */
+ /* Prime the clock */
+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
+ ~DPLL_VCO_ENABLE);
+ udelay(150);
+ }
+ I915_WRITE(FPA0, dev_priv->saveFPA0);
+ I915_WRITE(FPA1, dev_priv->saveFPA1);
+ /* Actually enable it */
+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
+ udelay(150);
+ if (IS_I965G(dev))
+ I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
+ udelay(150);
+
+ /* Restore mode */
+ I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
+ I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
+ I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
+ I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
+ I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
+ I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
+
+ /* Restore plane info */
+ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
+ I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
+ I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
+ I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
+ I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
+ if (IS_I965G(dev)) {
+ I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
+ I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
+ }
+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
+ i915_restore_palette(dev, PIPE_A);
+ /* Enable the plane */
+ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
+ I915_WRITE(DSPABASE, I915_READ(DSPABASE));
+
+ /* Pipe & plane B info */
+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
+ ~DPLL_VCO_ENABLE);
+ udelay(150);
+ }
+ I915_WRITE(FPB0, dev_priv->saveFPB0);
+ I915_WRITE(FPB1, dev_priv->saveFPB1);
+ /* Actually enable it */
+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
+ udelay(150);
+ if (IS_I965G(dev))
+ I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
+ udelay(150);
+
+ /* Restore mode */
+ I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
+ I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
+ I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
+ I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
+ I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
+ I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
+
+ /* Restore plane info */
+ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
+ I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
+ I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
+ I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
+ I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
+ if (IS_I965G(dev)) {
+ I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
+ I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
+ }
+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
+ i915_restore_palette(dev, PIPE_A);
+ /* Enable the plane */
+ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
+ I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
+
+ /* CRT state */
+ I915_WRITE(ADPA, dev_priv->saveADPA);
+
+ /* LVDS state */
+ if (IS_I965G(dev))
+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ I915_WRITE(LVDS, dev_priv->saveLVDS);
+ if (!IS_I830(dev) && !IS_845G(dev))
+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
+
+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
+ I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
+ I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+
+ /* FIXME: restore TV & SDVO state */
+
+ /* FBC info */
+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
+
+ /* VGA state */
+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+ I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
+ I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
+ I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
+ udelay(150);
+
+ for (i = 0; i < 16; i++) {
+ I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
+ }
+ for (i = 0; i < 3; i++)
+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+
+ i915_restore_vga(dev);
+
+ return 0;
+}
+
static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static struct drm_driver driver = {
/* don't use mtrr's here, the Xserver or user space app should
@@ -78,9 +531,12 @@ static struct drm_driver driver = {
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR | */
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.load = i915_driver_load,
+ .unload = i915_driver_unload,
.firstopen = i915_driver_firstopen,
.lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose,
+ .suspend = i915_suspend,
+ .resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
.get_vblank_counter = i915_get_vblank_counter,
.enable_vblank = i915_enable_vblank,
diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c
index 88daa57c..a0f22785 100644
--- a/linux-core/i915_fence.c
+++ b/linux-core/i915_fence.c
@@ -38,12 +38,12 @@
* Implements an intel sync flush operation.
*/
-static void i915_perform_flush(drm_device_t * dev)
+static void i915_perform_flush(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- drm_fence_manager_t *fm = &dev->fm;
- drm_fence_class_manager_t *fc = &fm->class[0];
- 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[0];
+ struct drm_fence_driver *driver = dev->driver->fence_driver;
uint32_t flush_flags = 0;
uint32_t flush_sequence = 0;
uint32_t i_status;
@@ -61,9 +61,10 @@ static void i915_perform_flush(drm_device_t * dev)
* First update fences with the current breadcrumb.
*/
- diff = sequence - fc->last_exe_flush;
+ diff = (sequence - fc->last_exe_flush) & BREADCRUMB_MASK;
if (diff < driver->wrap_diff && diff != 0) {
- drm_fence_handler(dev, 0, sequence, DRM_FENCE_TYPE_EXE);
+ drm_fence_handler(dev, 0, sequence,
+ DRM_FENCE_TYPE_EXE, 0);
}
if (dev_priv->fence_irq_on && !fc->pending_exe_flush) {
@@ -82,7 +83,7 @@ static void i915_perform_flush(drm_device_t * dev)
flush_flags = dev_priv->flush_flags;
flush_sequence = dev_priv->flush_sequence;
dev_priv->flush_pending = 0;
- drm_fence_handler(dev, 0, flush_sequence, flush_flags);
+ drm_fence_handler(dev, 0, flush_sequence, flush_flags, 0);
}
}
@@ -103,15 +104,15 @@ static void i915_perform_flush(drm_device_t * dev)
flush_flags = dev_priv->flush_flags;
flush_sequence = dev_priv->flush_sequence;
dev_priv->flush_pending = 0;
- drm_fence_handler(dev, 0, flush_sequence, flush_flags);
+ drm_fence_handler(dev, 0, flush_sequence, flush_flags, 0);
}
}
}
-void i915_poke_flush(drm_device_t * dev, uint32_t class)
+void i915_poke_flush(struct drm_device * dev, uint32_t class)
{
- drm_fence_manager_t *fm = &dev->fm;
+ struct drm_fence_manager *fm = &dev->fm;
unsigned long flags;
write_lock_irqsave(&fm->lock, flags);
@@ -119,7 +120,7 @@ void i915_poke_flush(drm_device_t * dev, uint32_t class)
write_unlock_irqrestore(&fm->lock, flags);
}
-int i915_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
+int i915_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t flags,
uint32_t * sequence, uint32_t * native_type)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -135,16 +136,16 @@ int i915_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
return 0;
}
-void i915_fence_handler(drm_device_t * dev)
+void i915_fence_handler(struct drm_device * dev)
{
- drm_fence_manager_t *fm = &dev->fm;
+ struct drm_fence_manager *fm = &dev->fm;
write_lock(&fm->lock);
i915_perform_flush(dev);
write_unlock(&fm->lock);
}
-int i915_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags)
+int i915_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags)
{
/*
* We have an irq that tells us when we have a new breadcrumb.
diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c
index 6419cbdc..11796b01 100644
--- a/linux-core/mga_drv.c
+++ b/linux-core/mga_drv.c
@@ -36,7 +36,7 @@
#include "drm_pciids.h"
-static int mga_driver_device_is_agp(drm_device_t * dev);
+static int mga_driver_device_is_agp(struct drm_device * dev);
static struct pci_device_id pciidlist[] = {
mga_PCI_IDS
@@ -128,7 +128,7 @@ MODULE_LICENSE("GPL and additional rights");
* \returns
* If the device is a PCI G450, zero is returned. Otherwise 2 is returned.
*/
-static int mga_driver_device_is_agp(drm_device_t * dev)
+static int mga_driver_device_is_agp(struct drm_device * dev)
{
const struct pci_dev * const pdev = dev->pdev;
diff --git a/linux-core/nouveau_dma.c b/linux-core/nouveau_dma.c
new file mode 120000
index 00000000..f8e0bdc3
--- /dev/null
+++ b/linux-core/nouveau_dma.c
@@ -0,0 +1 @@
+../shared-core/nouveau_dma.c \ No newline at end of file
diff --git a/linux-core/nouveau_dma.h b/linux-core/nouveau_dma.h
new file mode 120000
index 00000000..a545e387
--- /dev/null
+++ b/linux-core/nouveau_dma.h
@@ -0,0 +1 @@
+../shared-core/nouveau_dma.h \ No newline at end of file
diff --git a/linux-core/nouveau_drv.c b/linux-core/nouveau_drv.c
index ac030d89..01de67de 100644
--- a/linux-core/nouveau_drv.c
+++ b/linux-core/nouveau_drv.c
@@ -29,10 +29,19 @@
#include "drm_pciids.h"
static struct pci_device_id pciidlist[] = {
- nouveau_PCI_IDS
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff << 16,
+ },
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff << 16,
+ }
};
-extern drm_ioctl_desc_t nouveau_ioctls[];
+extern struct drm_ioctl_desc nouveau_ioctls[];
extern int nouveau_max_ioctl;
static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
diff --git a/linux-core/nouveau_notifier.c b/linux-core/nouveau_notifier.c
new file mode 120000
index 00000000..285469c5
--- /dev/null
+++ b/linux-core/nouveau_notifier.c
@@ -0,0 +1 @@
+../shared-core/nouveau_notifier.c \ No newline at end of file
diff --git a/linux-core/nouveau_sgdma.c b/linux-core/nouveau_sgdma.c
new file mode 100644
index 00000000..b86c5d7c
--- /dev/null
+++ b/linux-core/nouveau_sgdma.c
@@ -0,0 +1,339 @@
+#include "drmP.h"
+#include "nouveau_drv.h"
+
+#define NV_CTXDMA_PAGE_SHIFT 12
+#define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT)
+#define NV_CTXDMA_PAGE_MASK (NV_CTXDMA_PAGE_SIZE - 1)
+
+struct nouveau_sgdma_be {
+ struct drm_ttm_backend backend;
+ struct drm_device *dev;
+
+ int pages;
+ int pages_populated;
+ dma_addr_t *pagelist;
+ int is_bound;
+
+ unsigned int pte_start;
+};
+
+static int
+nouveau_sgdma_needs_ub_cache_adjust(struct drm_ttm_backend *be)
+{
+ return ((be->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
+}
+
+static int
+nouveau_sgdma_populate(struct drm_ttm_backend *be, unsigned long num_pages,
+ struct page **pages)
+{
+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+ int p, d, o;
+
+ DRM_DEBUG("num_pages = %ld\n", num_pages);
+
+ if (nvbe->pagelist)
+ return -EINVAL;
+ nvbe->pages = (num_pages << PAGE_SHIFT) >> NV_CTXDMA_PAGE_SHIFT;
+ nvbe->pagelist = drm_alloc(nvbe->pages*sizeof(dma_addr_t),
+ DRM_MEM_PAGES);
+
+ nvbe->pages_populated = d = 0;
+ for (p = 0; p < num_pages; p++) {
+ for (o = 0; o < PAGE_SIZE; o += NV_CTXDMA_PAGE_SIZE) {
+ nvbe->pagelist[d] = pci_map_page(nvbe->dev->pdev,
+ pages[p], o,
+ NV_CTXDMA_PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ if (pci_dma_mapping_error(nvbe->pagelist[d])) {
+ be->func->clear(be);
+ DRM_ERROR("pci_map_page failed\n");
+ return -EINVAL;
+ }
+ nvbe->pages_populated = ++d;
+ }
+ }
+
+ return 0;
+}
+
+static void
+nouveau_sgdma_clear(struct drm_ttm_backend *be)
+{
+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+ int d;
+
+ DRM_DEBUG("\n");
+
+ if (nvbe && nvbe->pagelist) {
+ if (nvbe->is_bound)
+ be->func->unbind(be);
+
+ for (d = 0; d < nvbe->pages_populated; d++) {
+ pci_unmap_page(nvbe->dev->pdev, nvbe->pagelist[d],
+ NV_CTXDMA_PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ }
+ drm_free(nvbe->pagelist, nvbe->pages*sizeof(dma_addr_t),
+ DRM_MEM_PAGES);
+ }
+}
+
+static int
+nouveau_sgdma_bind(struct drm_ttm_backend *be, struct drm_bo_mem_reg *mem)
+{
+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+ struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
+ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+ uint64_t offset = (mem->mm_node->start << PAGE_SHIFT);
+ uint32_t i;
+
+ DRM_DEBUG("pg=0x%lx (0x%llx), cached=%d\n", mem->mm_node->start,
+ offset, (mem->flags & DRM_BO_FLAG_CACHED) == 1);
+
+ if (offset & NV_CTXDMA_PAGE_MASK)
+ return -EINVAL;
+ nvbe->pte_start = (offset >> NV_CTXDMA_PAGE_SHIFT);
+ if (dev_priv->card_type < NV_50)
+ nvbe->pte_start += 2; /* skip ctxdma header */
+
+ for (i = nvbe->pte_start; i < nvbe->pte_start + nvbe->pages; i++) {
+ uint64_t pteval = nvbe->pagelist[i - nvbe->pte_start];
+
+ if (pteval & NV_CTXDMA_PAGE_MASK) {
+ DRM_ERROR("Bad pteval 0x%llx\n", pteval);
+ return -EINVAL;
+ }
+
+ if (dev_priv->card_type < NV_50) {
+ INSTANCE_WR(gpuobj, i, pteval | 3);
+ } else {
+ INSTANCE_WR(gpuobj, (i<<1)+0, pteval | 0x21);
+ INSTANCE_WR(gpuobj, (i<<1)+1, 0x00000000);
+ }
+ }
+
+ nvbe->is_bound = 1;
+ return 0;
+}
+
+static int
+nouveau_sgdma_unbind(struct drm_ttm_backend *be)
+{
+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+ struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
+
+ DRM_DEBUG("\n");
+
+ if (nvbe->is_bound) {
+ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+ unsigned int pte;
+
+ pte = nvbe->pte_start;
+ while (pte < (nvbe->pte_start + nvbe->pages)) {
+ uint64_t pteval = dev_priv->gart_info.sg_dummy_bus;
+
+ if (dev_priv->card_type < NV_50) {
+ INSTANCE_WR(gpuobj, pte, pteval | 3);
+ } else {
+ INSTANCE_WR(gpuobj, (pte<<1)+0, 0x00000010);
+ INSTANCE_WR(gpuobj, (pte<<1)+1, 0x00000004);
+ }
+
+ pte++;
+ }
+
+ nvbe->is_bound = 0;
+ }
+
+ return 0;
+}
+
+static void
+nouveau_sgdma_destroy(struct drm_ttm_backend *be)
+{
+ DRM_DEBUG("\n");
+ if (be) {
+ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+ if (nvbe) {
+ if (nvbe->pagelist)
+ be->func->clear(be);
+ drm_ctl_free(nvbe, sizeof(*nvbe), DRM_MEM_TTM);
+ }
+ }
+}
+
+static struct drm_ttm_backend_func nouveau_sgdma_backend = {
+ .needs_ub_cache_adjust = nouveau_sgdma_needs_ub_cache_adjust,
+ .populate = nouveau_sgdma_populate,
+ .clear = nouveau_sgdma_clear,
+ .bind = nouveau_sgdma_bind,
+ .unbind = nouveau_sgdma_unbind,
+ .destroy = nouveau_sgdma_destroy
+};
+
+struct drm_ttm_backend *
+nouveau_sgdma_init_ttm(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_sgdma_be *nvbe;
+
+ if (!dev_priv->gart_info.sg_ctxdma)
+ return NULL;
+
+ nvbe = drm_ctl_calloc(1, sizeof(*nvbe), DRM_MEM_TTM);
+ if (!nvbe)
+ return NULL;
+
+ nvbe->dev = dev;
+
+ nvbe->backend.func = &nouveau_sgdma_backend;
+
+ return &nvbe->backend;
+}
+
+int
+nouveau_sgdma_init(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_gpuobj *gpuobj = NULL;
+ uint32_t aper_size, obj_size;
+ int i, ret;
+
+ if (dev_priv->card_type < NV_50) {
+ aper_size = (64 * 1024 * 1024);
+ obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
+ obj_size += 8; /* ctxdma header */
+ } else {
+ /* 1 entire VM page table */
+ aper_size = (512 * 1024 * 1024);
+ obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8;
+ }
+
+ if ((ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16,
+ NVOBJ_FLAG_ALLOW_NO_REFS |
+ NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_ZERO_FREE, &gpuobj))) {
+ DRM_ERROR("Error creating sgdma object: %d\n", ret);
+ return ret;
+ }
+
+ if (dev_priv->card_type < NV_50) {
+ dev_priv->gart_info.sg_dummy_page =
+ alloc_page(GFP_KERNEL|__GFP_DMA32);
+ SetPageLocked(dev_priv->gart_info.sg_dummy_page);
+ dev_priv->gart_info.sg_dummy_bus =
+ pci_map_page(dev->pdev,
+ dev_priv->gart_info.sg_dummy_page, 0,
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+
+ /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
+ * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE
+ * on those cards? */
+ INSTANCE_WR(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY |
+ (1 << 12) /* PT present */ |
+ (0 << 13) /* PT *not* linear */ |
+ (NV_DMA_ACCESS_RW << 14) |
+ (NV_DMA_TARGET_PCI << 16));
+ INSTANCE_WR(gpuobj, 1, aper_size - 1);
+ for (i=2; i<2+(aper_size>>12); i++) {
+ INSTANCE_WR(gpuobj, i,
+ dev_priv->gart_info.sg_dummy_bus | 3);
+ }
+ } else {
+ for (i=0; i<obj_size; i+=8) {
+ INSTANCE_WR(gpuobj, (i+0)/4, 0); //x00000010);
+ INSTANCE_WR(gpuobj, (i+4)/4, 0); //0x00000004);
+ }
+ }
+
+ dev_priv->gart_info.type = NOUVEAU_GART_SGDMA;
+ dev_priv->gart_info.aper_base = 0;
+ dev_priv->gart_info.aper_size = aper_size;
+ dev_priv->gart_info.sg_ctxdma = gpuobj;
+ return 0;
+}
+
+void
+nouveau_sgdma_takedown(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->gart_info.sg_dummy_page) {
+ pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus,
+ NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ unlock_page(dev_priv->gart_info.sg_dummy_page);
+ __free_page(dev_priv->gart_info.sg_dummy_page);
+ dev_priv->gart_info.sg_dummy_page = NULL;
+ dev_priv->gart_info.sg_dummy_bus = 0;
+ }
+
+ nouveau_gpuobj_del(dev, &dev_priv->gart_info.sg_ctxdma);
+}
+
+int
+nouveau_sgdma_nottm_hack_init(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct drm_ttm_backend *be;
+ struct drm_scatter_gather sgreq;
+ struct drm_mm_node mm_node;
+ struct drm_bo_mem_reg mem;
+ int ret;
+
+ dev_priv->gart_info.sg_be = nouveau_sgdma_init_ttm(dev);
+ if (!dev_priv->gart_info.sg_be)
+ return -ENOMEM;
+ be = dev_priv->gart_info.sg_be;
+
+ /* Hack the aperture size down to the amount of system memory
+ * we're going to bind into it.
+ */
+ if (dev_priv->gart_info.aper_size > 32*1024*1024)
+ dev_priv->gart_info.aper_size = 32*1024*1024;
+
+ sgreq.size = dev_priv->gart_info.aper_size;
+ if ((ret = drm_sg_alloc(dev, &sgreq))) {
+ DRM_ERROR("drm_sg_alloc failed: %d\n", ret);
+ return ret;
+ }
+ dev_priv->gart_info.sg_handle = sgreq.handle;
+
+ if ((ret = be->func->populate(be, dev->sg->pages, dev->sg->pagelist))) {
+ DRM_ERROR("failed populate: %d\n", ret);
+ return ret;
+ }
+
+ mm_node.start = 0;
+ mem.mm_node = &mm_node;
+
+ if ((ret = be->func->bind(be, &mem))) {
+ DRM_ERROR("failed bind: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void
+nouveau_sgdma_nottm_hack_takedown(struct drm_device *dev)
+{
+}
+
+int
+nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+ int pte;
+
+ pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
+ if (dev_priv->card_type < NV_50) {
+ *page = INSTANCE_RD(gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
+ return 0;
+ }
+
+ DRM_ERROR("Unimplemented on NV50\n");
+ return -EINVAL;
+}
+
diff --git a/linux-core/nouveau_swmthd.c b/linux-core/nouveau_swmthd.c
new file mode 120000
index 00000000..c5390801
--- /dev/null
+++ b/linux-core/nouveau_swmthd.c
@@ -0,0 +1 @@
+../shared-core/nouveau_swmthd.c \ No newline at end of file
diff --git a/linux-core/nouveau_swmthd.h b/linux-core/nouveau_swmthd.h
new file mode 120000
index 00000000..33425dcd
--- /dev/null
+++ b/linux-core/nouveau_swmthd.h
@@ -0,0 +1 @@
+../shared-core/nouveau_swmthd.h \ No newline at end of file
diff --git a/linux-core/nv04_fifo.c b/linux-core/nv04_fifo.c
new file mode 120000
index 00000000..d10beb19
--- /dev/null
+++ b/linux-core/nv04_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv04_fifo.c \ No newline at end of file
diff --git a/linux-core/nv04_instmem.c b/linux-core/nv04_instmem.c
new file mode 120000
index 00000000..e720fb5b
--- /dev/null
+++ b/linux-core/nv04_instmem.c
@@ -0,0 +1 @@
+../shared-core/nv04_instmem.c \ No newline at end of file
diff --git a/linux-core/nv10_fifo.c b/linux-core/nv10_fifo.c
new file mode 120000
index 00000000..8630ad04
--- /dev/null
+++ b/linux-core/nv10_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv10_fifo.c \ No newline at end of file
diff --git a/linux-core/nv30_graph.c b/linux-core/nv30_graph.c
deleted file mode 120000
index 25568ecb..00000000
--- a/linux-core/nv30_graph.c
+++ /dev/null
@@ -1 +0,0 @@
-../shared-core/nv30_graph.c \ No newline at end of file
diff --git a/linux-core/nv40_fifo.c b/linux-core/nv40_fifo.c
new file mode 120000
index 00000000..cc71e7a4
--- /dev/null
+++ b/linux-core/nv40_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv40_fifo.c \ No newline at end of file
diff --git a/linux-core/nv50_fifo.c b/linux-core/nv50_fifo.c
new file mode 120000
index 00000000..4c9990a9
--- /dev/null
+++ b/linux-core/nv50_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv50_fifo.c \ No newline at end of file
diff --git a/linux-core/nv50_graph.c b/linux-core/nv50_graph.c
new file mode 120000
index 00000000..03f69e68
--- /dev/null
+++ b/linux-core/nv50_graph.c
@@ -0,0 +1 @@
+../shared-core/nv50_graph.c \ No newline at end of file
diff --git a/linux-core/nv50_instmem.c b/linux-core/nv50_instmem.c
new file mode 120000
index 00000000..4e45344a
--- /dev/null
+++ b/linux-core/nv50_instmem.c
@@ -0,0 +1 @@
+../shared-core/nv50_instmem.c \ No newline at end of file
diff --git a/linux-core/nv50_mc.c b/linux-core/nv50_mc.c
new file mode 120000
index 00000000..f4bb369e
--- /dev/null
+++ b/linux-core/nv50_mc.c
@@ -0,0 +1 @@
+../shared-core/nv50_mc.c \ No newline at end of file
diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c
index ef4a5cbd..7b6159b9 100644
--- a/linux-core/r128_drv.c
+++ b/linux-core/r128_drv.c
@@ -44,12 +44,13 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
- DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
- DRIVER_IRQ_VBL,
+ DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
.preclose = r128_driver_preclose,
.lastclose = r128_driver_lastclose,
- .vblank_wait = r128_driver_vblank_wait,
+ .get_vblank_counter = r128_get_vblank_counter,
+ .enable_vblank = r128_enable_vblank,
+ .disable_vblank = r128_disable_vblank,
.irq_preinstall = r128_driver_irq_preinstall,
.irq_postinstall = r128_driver_irq_postinstall,
.irq_uninstall = r128_driver_irq_uninstall,
diff --git a/linux-core/radeon_ioc32.c b/linux-core/radeon_ioc32.c
index 1be50bd9..bc8aa35a 100644
--- a/linux-core/radeon_ioc32.c
+++ b/linux-core/radeon_ioc32.c
@@ -349,6 +349,8 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
}
+/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
+#if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
typedef struct drm_radeon_setparam32 {
int param;
u64 value;
@@ -373,7 +375,9 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
return drm_ioctl(file->f_dentry->d_inode, file,
DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
}
-
+#else
+#define compat_radeon_cp_setparam NULL
+#endif /* X86_64 || IA64 */
drm_ioctl_compat_t *radeon_compat_ioctls[] = {
[DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c
index 114ec8f9..c9112c63 100644
--- a/linux-core/sis_drv.c
+++ b/linux-core/sis_drv.c
@@ -36,14 +36,14 @@ static struct pci_device_id pciidlist[] = {
};
-static int sis_driver_load(drm_device_t *dev, unsigned long chipset)
+static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
{
drm_sis_private_t *dev_priv;
int ret;
dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER);
if (dev_priv == NULL)
- return DRM_ERR(ENOMEM);
+ return -ENOMEM;
dev->dev_private = (void *)dev_priv;
dev_priv->chipset = chipset;
@@ -55,7 +55,7 @@ static int sis_driver_load(drm_device_t *dev, unsigned long chipset)
return ret;
}
-static int sis_driver_unload(drm_device_t *dev)
+static int sis_driver_unload(struct drm_device *dev)
{
drm_sis_private_t *dev_priv = dev->dev_private;
diff --git a/linux-core/sis_mm.c b/linux-core/sis_mm.c
index 21c1f2d7..9222b08d 100644
--- a/linux-core/sis_mm.c
+++ b/linux-core/sis_mm.c
@@ -81,19 +81,16 @@ unsigned long sis_sman_mm_offset(void *private, void *ref)
#endif
-static int sis_fb_init(DRM_IOCTL_ARGS)
+static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_fb_t fb;
+ drm_sis_fb_t *fb = data;
int ret;
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb));
-
mutex_lock(&dev->struct_mutex);
#if defined(__linux__) && defined(CONFIG_FB_SIS)
{
- drm_sman_mm_t sman_mm;
+ struct drm_sman_mm sman_mm;
sman_mm.private = (void *)0xFFFFFFFF;
sman_mm.allocate = sis_sman_mm_allocate;
sman_mm.free = sis_sman_mm_free;
@@ -104,7 +101,7 @@ static int sis_fb_init(DRM_IOCTL_ARGS)
}
#else
ret = drm_sman_set_range(&dev_priv->sman, VIDEO_TYPE, 0,
- fb.size >> SIS_MM_ALIGN_SHIFT);
+ fb->size >> SIS_MM_ALIGN_SHIFT);
#endif
if (ret) {
@@ -114,24 +111,21 @@ static int sis_fb_init(DRM_IOCTL_ARGS)
}
dev_priv->vram_initialized = 1;
- dev_priv->vram_offset = fb.offset;
+ dev_priv->vram_offset = fb->offset;
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+ DRM_DEBUG("offset = %u, size = %u", fb->offset, fb->size);
return 0;
}
-static int sis_drm_alloc(drm_device_t * dev, drm_file_t * priv,
- unsigned long data, int pool)
+static int sis_drm_alloc(struct drm_device * dev, struct drm_file *file_priv,
+ void *data, int pool)
{
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *) data;
- drm_sis_mem_t mem;
+ drm_sis_mem_t *mem = data;
int retval = 0;
- drm_memblock_item_t *item;
-
- DRM_COPY_FROM_USER_IOCTL(mem, argp, sizeof(mem));
+ struct drm_memblock_item *item;
mutex_lock(&dev->struct_mutex);
@@ -139,73 +133,66 @@ static int sis_drm_alloc(drm_device_t * dev, drm_file_t * priv,
dev_priv->agp_initialized)) {
DRM_ERROR
("Attempt to allocate from uninitialized memory manager.\n");
- return DRM_ERR(EINVAL);
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
}
- mem.size = (mem.size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
- item = drm_sman_alloc(&dev_priv->sman, pool, mem.size, 0,
- (unsigned long)priv);
+ mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
+ item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0,
+ (unsigned long)file_priv);
mutex_unlock(&dev->struct_mutex);
if (item) {
- mem.offset = ((pool == 0) ?
+ mem->offset = ((pool == 0) ?
dev_priv->vram_offset : dev_priv->agp_offset) +
(item->mm->
offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT);
- mem.free = item->user_hash.key;
- mem.size = mem.size << SIS_MM_ALIGN_SHIFT;
+ mem->free = item->user_hash.key;
+ mem->size = mem->size << SIS_MM_ALIGN_SHIFT;
} else {
- mem.offset = 0;
- mem.size = 0;
- mem.free = 0;
- retval = DRM_ERR(ENOMEM);
+ mem->offset = 0;
+ mem->size = 0;
+ mem->free = 0;
+ retval = -ENOMEM;
}
- DRM_COPY_TO_USER_IOCTL(argp, mem, sizeof(mem));
-
- DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem.size,
- mem.offset);
+ DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size,
+ mem->offset);
return retval;
}
-static int sis_drm_free(DRM_IOCTL_ARGS)
+static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_mem_t mem;
+ drm_sis_mem_t *mem = data;
int ret;
- DRM_COPY_FROM_USER_IOCTL(mem, (drm_sis_mem_t __user *) data,
- sizeof(mem));
-
mutex_lock(&dev->struct_mutex);
- ret = drm_sman_free_key(&dev_priv->sman, mem.free);
+ ret = drm_sman_free_key(&dev_priv->sman, mem->free);
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("free = 0x%lx\n", mem.free);
+ DRM_DEBUG("free = 0x%lx\n", mem->free);
return ret;
}
-static int sis_fb_alloc(DRM_IOCTL_ARGS)
+static int sis_fb_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- DRM_DEVICE;
- return sis_drm_alloc(dev, priv, data, VIDEO_TYPE);
+ return sis_drm_alloc(dev, file_priv, data, VIDEO_TYPE);
}
-static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
+static int sis_ioctl_agp_init(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_sis_agp_t agp;
+ drm_sis_agp_t *agp = data;
int ret;
dev_priv = dev->dev_private;
- DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data,
- sizeof(agp));
mutex_lock(&dev->struct_mutex);
ret = drm_sman_set_range(&dev_priv->sman, AGP_TYPE, 0,
- agp.size >> SIS_MM_ALIGN_SHIFT);
+ agp->size >> SIS_MM_ALIGN_SHIFT);
if (ret) {
DRM_ERROR("AGP memory manager initialisation error\n");
@@ -214,23 +201,23 @@ static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
}
dev_priv->agp_initialized = 1;
- dev_priv->agp_offset = agp.offset;
+ dev_priv->agp_offset = agp->offset;
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
+ DRM_DEBUG("offset = %u, size = %u", agp->offset, agp->size);
return 0;
}
-static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
+static int sis_ioctl_agp_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- DRM_DEVICE;
- return sis_drm_alloc(dev, priv, data, AGP_TYPE);
+ return sis_drm_alloc(dev, file_priv, data, AGP_TYPE);
}
-static drm_local_map_t *sis_reg_init(drm_device_t *dev)
+static drm_local_map_t *sis_reg_init(struct drm_device *dev)
{
- drm_map_list_t *entry;
+ struct drm_map_list *entry;
drm_local_map_t *map;
list_for_each_entry(entry, &dev->maplist, head) {
@@ -245,7 +232,7 @@ static drm_local_map_t *sis_reg_init(drm_device_t *dev)
}
int
-sis_idle(drm_device_t *dev)
+sis_idle(struct drm_device *dev)
{
drm_sis_private_t *dev_priv = dev->dev_private;
uint32_t idle_reg;
@@ -314,13 +301,13 @@ void sis_lastclose(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
}
-void sis_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
+void sis_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file *file_priv)
{
drm_sis_private_t *dev_priv = dev->dev_private;
- drm_file_t *priv = filp->private_data;
mutex_lock(&dev->struct_mutex);
- if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)priv)) {
+ if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) {
mutex_unlock(&dev->struct_mutex);
return;
}
@@ -329,20 +316,18 @@ void sis_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
dev->driver->dma_quiescent(dev);
}
- drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)priv);
+ drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
mutex_unlock(&dev->struct_mutex);
return;
}
-drm_ioctl_desc_t sis_ioctls[] = {
- [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_drm_free, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] =
- {sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_drm_free, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] =
- {sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY}
+struct drm_ioctl_desc sis_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
};
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
diff --git a/linux-core/via_buffer.c b/linux-core/via_buffer.c
index ebc8c371..a6c59832 100644
--- a/linux-core/via_buffer.c
+++ b/linux-core/via_buffer.c
@@ -32,19 +32,19 @@
#include "via_drm.h"
#include "via_drv.h"
-drm_ttm_backend_t *via_create_ttm_backend_entry(drm_device_t * dev)
+struct drm_ttm_backend *via_create_ttm_backend_entry(struct drm_device * dev)
{
return drm_agp_init_ttm(dev);
}
-int via_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type)
+int via_fence_types(struct drm_buffer_object *bo, uint32_t * fclass,
+ uint32_t * type)
{
- *class = 0;
*type = 3;
return 0;
}
-int via_invalidate_caches(drm_device_t * dev, uint32_t flags)
+int via_invalidate_caches(struct drm_device * dev, uint64_t flags)
{
/*
* FIXME: Invalidate texture caches here.
@@ -54,14 +54,14 @@ int via_invalidate_caches(drm_device_t * dev, uint32_t flags)
}
-static int via_vram_info(drm_device_t *dev,
+static int via_vram_info(struct drm_device *dev,
unsigned long *offset,
unsigned long *size)
{
struct pci_dev *pdev = dev->pdev;
unsigned long flags;
- int ret = DRM_ERR(EINVAL);
+ int ret = -EINVAL;
int i;
for (i=0; i<6; ++i) {
flags = pci_resource_flags(pdev, i);
@@ -82,8 +82,8 @@ static int via_vram_info(drm_device_t *dev,
return 0;
}
-int via_init_mem_type(drm_device_t * dev, uint32_t type,
- drm_mem_type_manager_t * man)
+int via_init_mem_type(struct drm_device * dev, uint32_t type,
+ struct drm_mem_type_manager * man)
{
switch (type) {
case DRM_BO_MEM_LOCAL:
@@ -144,7 +144,7 @@ int via_init_mem_type(drm_device_t * dev, uint32_t type,
return 0;
}
-uint32_t via_evict_mask(drm_buffer_object_t *bo)
+uint32_t via_evict_mask(struct drm_buffer_object *bo)
{
switch (bo->mem.mem_type) {
case DRM_BO_MEM_LOCAL:
diff --git a/linux-core/via_dmablit.c b/linux-core/via_dmablit.c
index 2f508374..d44c26f4 100644
--- a/linux-core/via_dmablit.c
+++ b/linux-core/via_dmablit.c
@@ -206,7 +206,7 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
*/
static void
-via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine)
+via_fire_dmablit(struct drm_device *dev, drm_via_sg_info_t *vsg, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
@@ -236,7 +236,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
first_pfn + 1;
if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages)))
- return DRM_ERR(ENOMEM);
+ return -ENOMEM;
memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages);
down_read(&current->mm->mmap_sem);
ret = get_user_pages(current, current->mm, (unsigned long) xfer->mem_addr,
@@ -248,7 +248,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
if (ret < 0)
return ret;
vsg->state = dr_via_pages_locked;
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
vsg->state = dr_via_pages_locked;
DRM_DEBUG("DMA pages locked\n");
@@ -271,14 +271,14 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg)
vsg->descriptors_per_page;
if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL)))
- return DRM_ERR(ENOMEM);
+ return -ENOMEM;
memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages);
vsg->state = dr_via_desc_pages_alloc;
for (i=0; i<vsg->num_desc_pages; ++i) {
if (NULL == (vsg->desc_pages[i] =
(drm_via_descriptor_t *) __get_free_page(GFP_KERNEL)))
- return DRM_ERR(ENOMEM);
+ return -ENOMEM;
}
DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages,
vsg->num_desc);
@@ -286,7 +286,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg)
}
static void
-via_abort_dmablit(drm_device_t *dev, int engine)
+via_abort_dmablit(struct drm_device *dev, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
@@ -294,7 +294,7 @@ via_abort_dmablit(drm_device_t *dev, int engine)
}
static void
-via_dmablit_engine_off(drm_device_t *dev, int engine)
+via_dmablit_engine_off(struct drm_device *dev, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
@@ -311,7 +311,7 @@ via_dmablit_engine_off(drm_device_t *dev, int engine)
*/
void
-via_dmablit_handler(drm_device_t *dev, int engine, int from_irq)
+via_dmablit_handler(struct drm_device *dev, int engine, int from_irq)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
@@ -432,7 +432,7 @@ via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_que
*/
static int
-via_dmablit_sync(drm_device_t *dev, uint32_t handle, int engine)
+via_dmablit_sync(struct drm_device *dev, uint32_t handle, int engine)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
@@ -465,7 +465,7 @@ static void
via_dmablit_timer(unsigned long data)
{
drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
- drm_device_t *dev = blitq->dev;
+ struct drm_device *dev = blitq->dev;
int engine = (int)
(blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues);
@@ -509,7 +509,7 @@ via_dmablit_workqueue(struct work_struct *work)
#else
drm_via_blitq_t *blitq = container_of(work, drm_via_blitq_t, wq);
#endif
- drm_device_t *dev = blitq->dev;
+ struct drm_device *dev = blitq->dev;
unsigned long irqsave;
drm_via_sg_info_t *cur_sg;
int cur_released;
@@ -552,7 +552,7 @@ via_dmablit_workqueue(struct work_struct *work)
void
-via_init_dmablit(drm_device_t *dev)
+via_init_dmablit(struct drm_device *dev)
{
int i,j;
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
@@ -568,7 +568,7 @@ via_init_dmablit(drm_device_t *dev)
blitq->head = 0;
blitq->cur = 0;
blitq->serviced = 0;
- blitq->num_free = VIA_NUM_BLIT_SLOTS;
+ blitq->num_free = VIA_NUM_BLIT_SLOTS - 1;
blitq->num_outstanding = 0;
blitq->is_active = 0;
blitq->aborting = 0;
@@ -594,7 +594,7 @@ via_init_dmablit(drm_device_t *dev)
static int
-via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
+via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
{
int draw = xfer->to_fb;
int ret = 0;
@@ -606,7 +606,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
if (xfer->num_lines <= 0 || xfer->line_length <= 0) {
DRM_ERROR("Zero size bitblt.\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
/*
@@ -619,7 +619,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
if ((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) {
DRM_ERROR("Too large system memory stride. Stride: %d, "
"Length: %d\n", xfer->mem_stride, xfer->line_length);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
if ((xfer->mem_stride == xfer->line_length) &&
@@ -637,7 +637,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
if (xfer->num_lines > 2048 || (xfer->num_lines*xfer->mem_stride > (2048*2048*4))) {
DRM_ERROR("Too large PCI DMA bitblt.\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
/*
@@ -648,7 +648,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
if (xfer->mem_stride < xfer->line_length ||
abs(xfer->fb_stride) < xfer->line_length) {
DRM_ERROR("Invalid frame-buffer / memory stride.\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
/*
@@ -661,13 +661,13 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *
if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) ||
((xfer->num_lines > 1) && ((xfer->mem_stride & 3) != (xfer->fb_stride & 3)))) {
DRM_ERROR("Invalid DRM bitblt alignment.\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
#else
if ((((unsigned long)xfer->mem_addr & 15) || ((unsigned long)xfer->fb_addr & 3)) ||
((xfer->num_lines > 1) && ((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) {
DRM_ERROR("Invalid DRM bitblt alignment.\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
#endif
@@ -707,7 +707,7 @@ via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine)
DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0);
if (ret) {
- return (DRM_ERR(EINTR) == ret) ? DRM_ERR(EAGAIN) : ret;
+ return (-EINTR == ret) ? -EAGAIN : ret;
}
spin_lock_irqsave(&blitq->blit_lock, irqsave);
@@ -740,7 +740,7 @@ via_dmablit_release_slot(drm_via_blitq_t *blitq)
static int
-via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
+via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer)
{
drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
drm_via_sg_info_t *vsg;
@@ -751,7 +751,7 @@ via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
if (dev_priv == NULL) {
DRM_ERROR("Called without initialization.\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
engine = (xfer->to_fb) ? 0 : 1;
@@ -761,7 +761,7 @@ via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
}
if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) {
via_dmablit_release_slot(blitq);
- return DRM_ERR(ENOMEM);
+ return -ENOMEM;
}
if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) {
via_dmablit_release_slot(blitq);
@@ -792,21 +792,18 @@ via_dmablit(drm_device_t *dev, drm_via_dmablit_t *xfer)
*/
int
-via_dma_blit_sync( DRM_IOCTL_ARGS )
+via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv )
{
- drm_via_blitsync_t sync;
+ drm_via_blitsync_t *sync = data;
int err;
- DRM_DEVICE;
- DRM_COPY_FROM_USER_IOCTL(sync, (drm_via_blitsync_t *)data, sizeof(sync));
-
- if (sync.engine >= VIA_NUM_BLIT_ENGINES)
- return DRM_ERR(EINVAL);
+ if (sync->engine >= VIA_NUM_BLIT_ENGINES)
+ return -EINVAL;
- err = via_dmablit_sync(dev, sync.sync_handle, sync.engine);
+ err = via_dmablit_sync(dev, sync->sync_handle, sync->engine);
- if (DRM_ERR(EINTR) == err)
- err = DRM_ERR(EAGAIN);
+ if (-EINTR == err)
+ err = -EAGAIN;
return err;
}
@@ -819,17 +816,12 @@ via_dma_blit_sync( DRM_IOCTL_ARGS )
*/
int
-via_dma_blit( DRM_IOCTL_ARGS )
+via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv )
{
- drm_via_dmablit_t xfer;
+ drm_via_dmablit_t *xfer = data;
int err;
- DRM_DEVICE;
-
- DRM_COPY_FROM_USER_IOCTL(xfer, (drm_via_dmablit_t __user *)data, sizeof(xfer));
-
- err = via_dmablit(dev, &xfer);
- DRM_COPY_TO_USER_IOCTL((void __user *)data, xfer, sizeof(xfer));
+ err = via_dmablit(dev, xfer);
return err;
}
diff --git a/linux-core/via_dmablit.h b/linux-core/via_dmablit.h
index f6ae03ec..726ad25d 100644
--- a/linux-core/via_dmablit.h
+++ b/linux-core/via_dmablit.h
@@ -59,7 +59,7 @@ typedef struct _drm_via_sg_info {
} drm_via_sg_info_t;
typedef struct _drm_via_blitq {
- drm_device_t *dev;
+ struct drm_device *dev;
uint32_t cur_blit_handle;
uint32_t done_blit_handle;
unsigned serviced;
diff --git a/linux-core/via_fence.c b/linux-core/via_fence.c
index 02249939..9af1bf3b 100644
--- a/linux-core/via_fence.c
+++ b/linux-core/via_fence.c
@@ -39,10 +39,10 @@
*/
-static uint32_t via_perform_flush(drm_device_t *dev, uint32_t class)
+static uint32_t via_perform_flush(struct drm_device *dev, uint32_t class)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- drm_fence_class_manager_t *fc = &dev->fm.class[class];
+ struct drm_fence_class_manager *fc = &dev->fm.fence_class[class];
uint32_t pending_flush_types = 0;
uint32_t signaled_flush_types = 0;
uint32_t status;
@@ -98,7 +98,8 @@ static uint32_t via_perform_flush(drm_device_t *dev, uint32_t class)
drm_idlelock_release(&dev->lock);
dev_priv->have_idlelock = 0;
}
- drm_fence_handler(dev, 0, dev_priv->emit_0_sequence, signaled_flush_types);
+ drm_fence_handler(dev, 0, dev_priv->emit_0_sequence,
+ signaled_flush_types, 0);
}
}
@@ -113,7 +114,7 @@ static uint32_t via_perform_flush(drm_device_t *dev, uint32_t class)
* Emit a fence sequence.
*/
-int via_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
+int via_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t flags,
uint32_t * sequence, uint32_t * native_type)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
@@ -142,7 +143,7 @@ int via_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
*native_type = DRM_FENCE_TYPE_EXE;
break;
default:
- ret = DRM_ERR(EINVAL);
+ ret = -EINVAL;
break;
}
return ret;
@@ -152,10 +153,10 @@ int via_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
* Manual poll (from the fence manager).
*/
-void via_poke_flush(drm_device_t * dev, uint32_t class)
+void via_poke_flush(struct drm_device * dev, uint32_t class)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- drm_fence_manager_t *fm = &dev->fm;
+ struct drm_fence_manager *fm = &dev->fm;
unsigned long flags;
uint32_t pending_flush;
@@ -200,11 +201,11 @@ int via_fence_has_irq(struct drm_device * dev, uint32_t class,
void via_fence_timer(unsigned long data)
{
- drm_device_t *dev = (drm_device_t *) data;
+ struct drm_device *dev = (struct drm_device *) data;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- drm_fence_manager_t *fm = &dev->fm;
+ struct drm_fence_manager *fm = &dev->fm;
uint32_t pending_flush;
- drm_fence_class_manager_t *fc = &dev->fm.class[0];
+ struct drm_fence_class_manager *fc = &dev->fm.fence_class[0];
if (!dev_priv)
return;
diff --git a/linux-core/via_mm.c b/linux-core/via_mm.c
index d97269f5..35ca6bfc 100644
--- a/linux-core/via_mm.c
+++ b/linux-core/via_mm.c
@@ -33,18 +33,15 @@
#define VIA_MM_ALIGN_SHIFT 4
#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1)
-int via_agp_init(DRM_IOCTL_ARGS)
+int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_via_agp_t agp;
+ drm_via_agp_t *agp = data;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
int ret;
- DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t __user *) data,
- sizeof(agp));
mutex_lock(&dev->struct_mutex);
ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_AGP, 0,
- agp.size >> VIA_MM_ALIGN_SHIFT);
+ agp->size >> VIA_MM_ALIGN_SHIFT);
if (ret) {
DRM_ERROR("AGP memory manager initialisation error\n");
@@ -53,25 +50,22 @@ int via_agp_init(DRM_IOCTL_ARGS)
}
dev_priv->agp_initialized = 1;
- dev_priv->agp_offset = agp.offset;
+ dev_priv->agp_offset = agp->offset;
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
+ DRM_DEBUG("offset = %u, size = %u", agp->offset, agp->size);
return 0;
}
-int via_fb_init(DRM_IOCTL_ARGS)
+int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_via_fb_t fb;
+ drm_via_fb_t *fb = data;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
int ret;
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t __user *) data, sizeof(fb));
-
mutex_lock(&dev->struct_mutex);
ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_VIDEO, 0,
- fb.size >> VIA_MM_ALIGN_SHIFT);
+ fb->size >> VIA_MM_ALIGN_SHIFT);
if (ret) {
DRM_ERROR("VRAM memory manager initialisation error\n");
@@ -80,10 +74,10 @@ int via_fb_init(DRM_IOCTL_ARGS)
}
dev_priv->vram_initialized = 1;
- dev_priv->vram_offset = fb.offset;
+ dev_priv->vram_offset = fb->offset;
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+ DRM_DEBUG("offset = %u, size = %u", fb->offset, fb->size);
return 0;
@@ -123,80 +117,71 @@ void via_lastclose(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
}
-int via_mem_alloc(DRM_IOCTL_ARGS)
+int via_mem_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- DRM_DEVICE;
-
- drm_via_mem_t mem;
+ drm_via_mem_t *mem = data;
int retval = 0;
- drm_memblock_item_t *item;
+ struct drm_memblock_item *item;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
unsigned long tmpSize;
- DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
- sizeof(mem));
-
- if (mem.type > VIA_MEM_AGP) {
+ if (mem->type > VIA_MEM_AGP) {
DRM_ERROR("Unknown memory type allocation\n");
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
mutex_lock(&dev->struct_mutex);
- if (0 == ((mem.type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
+ if (0 == ((mem->type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
dev_priv->agp_initialized)) {
DRM_ERROR
("Attempt to allocate from uninitialized memory manager.\n");
mutex_unlock(&dev->struct_mutex);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
- tmpSize = (mem.size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
- item = drm_sman_alloc(&dev_priv->sman, mem.type, tmpSize, 0,
- (unsigned long)priv);
+ tmpSize = (mem->size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
+ item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0,
+ (unsigned long)file_priv);
mutex_unlock(&dev->struct_mutex);
if (item) {
- mem.offset = ((mem.type == VIA_MEM_VIDEO) ?
+ mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
dev_priv->vram_offset : dev_priv->agp_offset) +
(item->mm->
offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
- mem.index = item->user_hash.key;
+ mem->index = item->user_hash.key;
} else {
- mem.offset = 0;
- mem.size = 0;
- mem.index = 0;
+ mem->offset = 0;
+ mem->size = 0;
+ mem->index = 0;
DRM_DEBUG("Video memory allocation failed\n");
- retval = DRM_ERR(ENOMEM);
+ retval = -ENOMEM;
}
- DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, sizeof(mem));
return retval;
}
-int via_mem_free(DRM_IOCTL_ARGS)
+int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_via_private_t *dev_priv = dev->dev_private;
- drm_via_mem_t mem;
+ drm_via_mem_t *mem = data;
int ret;
- DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
- sizeof(mem));
-
mutex_lock(&dev->struct_mutex);
- ret = drm_sman_free_key(&dev_priv->sman, mem.index);
+ ret = drm_sman_free_key(&dev_priv->sman, mem->index);
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("free = 0x%lx\n", mem.index);
+ DRM_DEBUG("free = 0x%lx\n", mem->index);
return ret;
}
-void via_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
+void via_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file *file_priv)
{
drm_via_private_t *dev_priv = dev->dev_private;
- drm_file_t *priv = filp->private_data;
mutex_lock(&dev->struct_mutex);
- if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)priv)) {
+ if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) {
mutex_unlock(&dev->struct_mutex);
return;
}
@@ -205,7 +190,7 @@ void via_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
dev->driver->dma_quiescent(dev);
}
- drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)priv);
+ drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
mutex_unlock(&dev->struct_mutex);
return;
}
diff --git a/linux-core/xgi_cmdlist.c b/linux-core/xgi_cmdlist.c
new file mode 100644
index 00000000..d7b23c89
--- /dev/null
+++ b/linux-core/xgi_cmdlist.c
@@ -0,0 +1,326 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#include "xgi_drv.h"
+#include "xgi_regs.h"
+#include "xgi_misc.h"
+#include "xgi_cmdlist.h"
+
+static void xgi_emit_flush(struct xgi_info * info, bool stop);
+static void xgi_emit_nop(struct xgi_info * info);
+static unsigned int get_batch_command(enum xgi_batch_type type);
+static void triggerHWCommandList(struct xgi_info * info);
+static void xgi_cmdlist_reset(struct xgi_info * info);
+
+
+/**
+ * Graphic engine register (2d/3d) acessing interface
+ */
+static inline void dwWriteReg(struct drm_map * map, u32 addr, u32 data)
+{
+#ifdef XGI_MMIO_DEBUG
+ DRM_INFO("mmio_map->handle = 0x%p, addr = 0x%x, data = 0x%x\n",
+ map->handle, addr, data);
+#endif
+ DRM_WRITE32(map, addr, data);
+}
+
+
+int xgi_cmdlist_initialize(struct xgi_info * info, size_t size,
+ struct drm_file * filp)
+{
+ struct xgi_mem_alloc mem_alloc = {
+ .location = XGI_MEMLOC_NON_LOCAL,
+ .size = size,
+ };
+ int err;
+
+ err = xgi_alloc(info, &mem_alloc, filp);
+ if (err) {
+ return err;
+ }
+
+ info->cmdring.ptr = xgi_find_pcie_virt(info, mem_alloc.hw_addr);
+ info->cmdring.size = mem_alloc.size;
+ info->cmdring.ring_hw_base = mem_alloc.hw_addr;
+ info->cmdring.last_ptr = NULL;
+ info->cmdring.ring_offset = 0;
+
+ return 0;
+}
+
+
+/**
+ * get_batch_command - Get the command ID for the current begin type.
+ * @type: Type of the current batch
+ *
+ * See section 3.2.2 "Begin" (page 15) of the 3D SPG.
+ *
+ * This function assumes that @type is on the range [0,3].
+ */
+unsigned int get_batch_command(enum xgi_batch_type type)
+{
+ static const unsigned int ports[4] = {
+ 0x30 >> 2, 0x40 >> 2, 0x50 >> 2, 0x20 >> 2
+ };
+
+ return ports[type];
+}
+
+
+int xgi_submit_cmdlist(struct drm_device * dev, void * data,
+ struct drm_file * filp)
+{
+ struct xgi_info *const info = dev->dev_private;
+ const struct xgi_cmd_info *const pCmdInfo =
+ (struct xgi_cmd_info *) data;
+ const unsigned int cmd = get_batch_command(pCmdInfo->type);
+ u32 begin[4];
+
+
+ begin[0] = (cmd << 24) | BEGIN_VALID_MASK
+ | (BEGIN_BEGIN_IDENTIFICATION_MASK & info->next_sequence);
+ begin[1] = BEGIN_LINK_ENABLE_MASK | pCmdInfo->size;
+ begin[2] = pCmdInfo->hw_addr >> 4;
+ begin[3] = 0;
+
+ if (info->cmdring.last_ptr == NULL) {
+ const unsigned int portOffset = BASE_3D_ENG + (cmd << 2);
+
+
+ /* Enable PCI Trigger Mode
+ */
+ dwWriteReg(info->mmio_map,
+ BASE_3D_ENG + M2REG_AUTO_LINK_SETTING_ADDRESS,
+ (M2REG_AUTO_LINK_SETTING_ADDRESS << 22) |
+ M2REG_CLEAR_COUNTERS_MASK | 0x08 |
+ M2REG_PCI_TRIGGER_MODE_MASK);
+
+ dwWriteReg(info->mmio_map,
+ BASE_3D_ENG + M2REG_AUTO_LINK_SETTING_ADDRESS,
+ (M2REG_AUTO_LINK_SETTING_ADDRESS << 22) | 0x08 |
+ M2REG_PCI_TRIGGER_MODE_MASK);
+
+
+ /* Send PCI begin command
+ */
+ dwWriteReg(info->mmio_map, portOffset, begin[0]);
+ dwWriteReg(info->mmio_map, portOffset + 4, begin[1]);
+ dwWriteReg(info->mmio_map, portOffset + 8, begin[2]);
+ dwWriteReg(info->mmio_map, portOffset + 12, begin[3]);
+ } else {
+ DRM_DEBUG("info->cmdring.last_ptr != NULL\n");
+
+ if (pCmdInfo->type == BTYPE_3D) {
+ xgi_emit_flush(info, FALSE);
+ }
+
+ info->cmdring.last_ptr[1] = cpu_to_le32(begin[1]);
+ info->cmdring.last_ptr[2] = cpu_to_le32(begin[2]);
+ info->cmdring.last_ptr[3] = cpu_to_le32(begin[3]);
+ DRM_WRITEMEMORYBARRIER();
+ info->cmdring.last_ptr[0] = cpu_to_le32(begin[0]);
+
+ triggerHWCommandList(info);
+ }
+
+ info->cmdring.last_ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr);
+ drm_fence_flush_old(info->dev, 0, info->next_sequence);
+ return 0;
+}
+
+
+/*
+ state: 0 - console
+ 1 - graphic
+ 2 - fb
+ 3 - logout
+*/
+int xgi_state_change(struct xgi_info * info, unsigned int to,
+ unsigned int from)
+{
+#define STATE_CONSOLE 0
+#define STATE_GRAPHIC 1
+#define STATE_FBTERM 2
+#define STATE_LOGOUT 3
+#define STATE_REBOOT 4
+#define STATE_SHUTDOWN 5
+
+ if ((from == STATE_GRAPHIC) && (to == STATE_CONSOLE)) {
+ DRM_INFO("Leaving graphical mode (probably VT switch)\n");
+ } else if ((from == STATE_CONSOLE) && (to == STATE_GRAPHIC)) {
+ DRM_INFO("Entering graphical mode (probably VT switch)\n");
+ xgi_cmdlist_reset(info);
+ } else if ((from == STATE_GRAPHIC)
+ && ((to == STATE_LOGOUT)
+ || (to == STATE_REBOOT)
+ || (to == STATE_SHUTDOWN))) {
+ DRM_INFO("Leaving graphical mode (probably X shutting down)\n");
+ } else {
+ DRM_ERROR("Invalid state change.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+int xgi_state_change_ioctl(struct drm_device * dev, void * data,
+ struct drm_file * filp)
+{
+ struct xgi_state_info *const state =
+ (struct xgi_state_info *) data;
+ struct xgi_info *info = dev->dev_private;
+
+
+ return xgi_state_change(info, state->_toState, state->_fromState);
+}
+
+
+void xgi_cmdlist_reset(struct xgi_info * info)
+{
+ info->cmdring.last_ptr = NULL;
+ info->cmdring.ring_offset = 0;
+}
+
+
+void xgi_cmdlist_cleanup(struct xgi_info * info)
+{
+ if (info->cmdring.ring_hw_base != 0) {
+ /* If command lists have been issued, terminate the command
+ * list chain with a flush command.
+ */
+ if (info->cmdring.last_ptr != NULL) {
+ xgi_emit_flush(info, FALSE);
+ xgi_emit_nop(info);
+ }
+
+ xgi_waitfor_pci_idle(info);
+
+ (void) memset(&info->cmdring, 0, sizeof(info->cmdring));
+ }
+}
+
+static void triggerHWCommandList(struct xgi_info * info)
+{
+ static unsigned int s_triggerID = 1;
+
+ dwWriteReg(info->mmio_map,
+ BASE_3D_ENG + M2REG_PCI_TRIGGER_REGISTER_ADDRESS,
+ 0x05000000 + (0x0ffff & s_triggerID++));
+}
+
+
+/**
+ * Emit a flush to the CRTL command stream.
+ * @info XGI info structure
+ *
+ * This function assumes info->cmdring.ptr is non-NULL.
+ */
+void xgi_emit_flush(struct xgi_info * info, bool stop)
+{
+ const u32 flush_command[8] = {
+ ((0x10 << 24)
+ | (BEGIN_BEGIN_IDENTIFICATION_MASK & info->next_sequence)),
+ BEGIN_LINK_ENABLE_MASK | (0x00004),
+ 0x00000000, 0x00000000,
+
+ /* Flush the 2D engine with the default 32 clock delay.
+ */
+ M2REG_FLUSH_ENGINE_COMMAND | M2REG_FLUSH_2D_ENGINE_MASK,
+ M2REG_FLUSH_ENGINE_COMMAND | M2REG_FLUSH_2D_ENGINE_MASK,
+ M2REG_FLUSH_ENGINE_COMMAND | M2REG_FLUSH_2D_ENGINE_MASK,
+ M2REG_FLUSH_ENGINE_COMMAND | M2REG_FLUSH_2D_ENGINE_MASK,
+ };
+ const unsigned int flush_size = sizeof(flush_command);
+ u32 *batch_addr;
+ u32 hw_addr;
+ unsigned int i;
+
+
+ /* check buf is large enough to contain a new flush batch */
+ if ((info->cmdring.ring_offset + flush_size) >= info->cmdring.size) {
+ info->cmdring.ring_offset = 0;
+ }
+
+ hw_addr = info->cmdring.ring_hw_base
+ + info->cmdring.ring_offset;
+ batch_addr = info->cmdring.ptr
+ + (info->cmdring.ring_offset / 4);
+
+ for (i = 0; i < (flush_size / 4); i++) {
+ batch_addr[i] = cpu_to_le32(flush_command[i]);
+ }
+
+ if (stop) {
+ *batch_addr |= cpu_to_le32(BEGIN_STOP_STORE_CURRENT_POINTER_MASK);
+ }
+
+ info->cmdring.last_ptr[1] = cpu_to_le32(BEGIN_LINK_ENABLE_MASK | (flush_size / 4));
+ info->cmdring.last_ptr[2] = cpu_to_le32(hw_addr >> 4);
+ info->cmdring.last_ptr[3] = 0;
+ DRM_WRITEMEMORYBARRIER();
+ info->cmdring.last_ptr[0] = cpu_to_le32((get_batch_command(BTYPE_CTRL) << 24)
+ | (BEGIN_VALID_MASK));
+
+ triggerHWCommandList(info);
+
+ info->cmdring.ring_offset += flush_size;
+ info->cmdring.last_ptr = batch_addr;
+}
+
+
+/**
+ * Emit an empty command to the CRTL command stream.
+ * @info XGI info structure
+ *
+ * This function assumes info->cmdring.ptr is non-NULL. In addition, since
+ * this function emits a command that does not have linkage information,
+ * it sets info->cmdring.ptr to NULL.
+ */
+void xgi_emit_nop(struct xgi_info * info)
+{
+ info->cmdring.last_ptr[1] = cpu_to_le32(BEGIN_LINK_ENABLE_MASK
+ | (BEGIN_BEGIN_IDENTIFICATION_MASK & info->next_sequence));
+ info->cmdring.last_ptr[2] = 0;
+ info->cmdring.last_ptr[3] = 0;
+ DRM_WRITEMEMORYBARRIER();
+ info->cmdring.last_ptr[0] = cpu_to_le32((get_batch_command(BTYPE_CTRL) << 24)
+ | (BEGIN_VALID_MASK));
+
+ triggerHWCommandList(info);
+
+ info->cmdring.last_ptr = NULL;
+}
+
+
+void xgi_emit_irq(struct xgi_info * info)
+{
+ if (info->cmdring.last_ptr == NULL)
+ return;
+
+ xgi_emit_flush(info, TRUE);
+}
diff --git a/linux-core/xgi_cmdlist.h b/linux-core/xgi_cmdlist.h
new file mode 100644
index 00000000..f6f1c1ef
--- /dev/null
+++ b/linux-core/xgi_cmdlist.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#ifndef _XGI_CMDLIST_H_
+#define _XGI_CMDLIST_H_
+
+struct xgi_cmdring_info {
+ /**
+ * Kernel space pointer to the base of the command ring.
+ */
+ u32 * ptr;
+
+ /**
+ * Size, in bytes, of the command ring.
+ */
+ unsigned int size;
+
+ /**
+ * Base address of the command ring from the hardware's PoV.
+ */
+ unsigned int ring_hw_base;
+
+ u32 * last_ptr;
+
+ /**
+ * Offset, in bytes, from the start of the ring to the next available
+ * location to store a command.
+ */
+ unsigned int ring_offset;
+};
+
+struct xgi_info;
+extern int xgi_cmdlist_initialize(struct xgi_info * info, size_t size,
+ struct drm_file * filp);
+
+extern int xgi_state_change(struct xgi_info * info, unsigned int to,
+ unsigned int from);
+
+extern void xgi_cmdlist_cleanup(struct xgi_info * info);
+
+extern void xgi_emit_irq(struct xgi_info * info);
+
+#endif /* _XGI_CMDLIST_H_ */
diff --git a/linux-core/xgi_drm.h b/linux-core/xgi_drm.h
new file mode 120000
index 00000000..677586d7
--- /dev/null
+++ b/linux-core/xgi_drm.h
@@ -0,0 +1 @@
+../shared-core/xgi_drm.h \ No newline at end of file
diff --git a/linux-core/xgi_drv.c b/linux-core/xgi_drv.c
new file mode 100644
index 00000000..4e66197e
--- /dev/null
+++ b/linux-core/xgi_drv.c
@@ -0,0 +1,431 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#include "drmP.h"
+#include "drm.h"
+#include "xgi_drv.h"
+#include "xgi_regs.h"
+#include "xgi_misc.h"
+#include "xgi_cmdlist.h"
+
+#include "drm_pciids.h"
+
+static struct pci_device_id pciidlist[] = {
+ xgi_PCI_IDS
+};
+
+static struct drm_fence_driver xgi_fence_driver = {
+ .num_classes = 1,
+ .wrap_diff = BEGIN_BEGIN_IDENTIFICATION_MASK,
+ .flush_diff = BEGIN_BEGIN_IDENTIFICATION_MASK - 1,
+ .sequence_mask = BEGIN_BEGIN_IDENTIFICATION_MASK,
+ .lazy_capable = 1,
+ .emit = xgi_fence_emit_sequence,
+ .poke_flush = xgi_poke_flush,
+ .has_irq = xgi_fence_has_irq
+};
+
+int xgi_bootstrap(struct drm_device *, void *, struct drm_file *);
+
+static struct drm_ioctl_desc xgi_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_XGI_BOOTSTRAP, xgi_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_XGI_ALLOC, xgi_alloc_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_XGI_FREE, xgi_free_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_XGI_SUBMIT_CMDLIST, xgi_submit_cmdlist, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_XGI_STATE_CHANGE, xgi_state_change_ioctl, DRM_AUTH|DRM_MASTER),
+};
+
+static const int xgi_max_ioctl = DRM_ARRAY_SIZE(xgi_ioctls);
+
+static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static int xgi_driver_load(struct drm_device *dev, unsigned long flags);
+static int xgi_driver_unload(struct drm_device *dev);
+static void xgi_driver_lastclose(struct drm_device * dev);
+static void xgi_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file * filp);
+static irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS);
+
+
+static struct drm_driver driver = {
+ .driver_features =
+ DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ |
+ DRIVER_IRQ_SHARED | DRIVER_SG,
+ .dev_priv_size = sizeof(struct xgi_info),
+ .load = xgi_driver_load,
+ .unload = xgi_driver_unload,
+ .lastclose = xgi_driver_lastclose,
+ .dma_quiescent = NULL,
+ .irq_preinstall = NULL,
+ .irq_postinstall = NULL,
+ .irq_uninstall = NULL,
+ .irq_handler = xgi_kern_isr,
+ .reclaim_buffers = drm_core_reclaim_buffers,
+ .reclaim_buffers_idlelocked = xgi_reclaim_buffers_locked,
+ .get_map_ofs = drm_core_get_map_ofs,
+ .get_reg_ofs = drm_core_get_reg_ofs,
+ .ioctls = xgi_ioctls,
+ .dma_ioctl = NULL,
+
+ .fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+#if defined(CONFIG_COMPAT) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
+ .compat_ioctl = xgi_compat_ioctl,
+#endif
+ },
+
+ .pci_driver = {
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ .probe = probe,
+ .remove = __devexit_p(drm_cleanup_pci),
+ },
+
+ .fence_driver = &xgi_fence_driver,
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+
+};
+
+static int probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return drm_get_dev(pdev, ent, &driver);
+}
+
+
+static int __init xgi_init(void)
+{
+ driver.num_ioctls = xgi_max_ioctl;
+ return drm_init(&driver, pciidlist);
+}
+
+static void __exit xgi_exit(void)
+{
+ drm_exit(&driver);
+}
+
+module_init(xgi_init);
+module_exit(xgi_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
+
+
+void xgi_engine_init(struct xgi_info * info)
+{
+ u8 temp;
+
+
+ OUT3C5B(info->mmio_map, 0x11, 0x92);
+
+ /* -------> copy from OT2D
+ * PCI Retry Control Register.
+ * disable PCI read retry & enable write retry in mem. (10xx xxxx)b
+ */
+ temp = IN3X5B(info->mmio_map, 0x55);
+ OUT3X5B(info->mmio_map, 0x55, (temp & 0xbf) | 0x80);
+
+ xgi_enable_ge(info);
+
+ /* Enable linear addressing of the card. */
+ temp = IN3X5B(info->mmio_map, 0x21);
+ OUT3X5B(info->mmio_map, 0x21, temp | 0x20);
+
+ /* Enable 32-bit internal data path */
+ temp = IN3X5B(info->mmio_map, 0x2A);
+ OUT3X5B(info->mmio_map, 0x2A, temp | 0x40);
+
+ /* Enable PCI burst write ,disable burst read and enable MMIO. */
+ /*
+ * 0x3D4.39 Enable PCI burst write, disable burst read and enable MMIO.
+ * 7 ---- Pixel Data Format 1: big endian 0: little endian
+ * 6 5 4 3---- Memory Data with Big Endian Format, BE[3:0]# with Big Endian Format
+ * 2 ---- PCI Burst Write Enable
+ * 1 ---- PCI Burst Read Enable
+ * 0 ---- MMIO Control
+ */
+ temp = IN3X5B(info->mmio_map, 0x39);
+ OUT3X5B(info->mmio_map, 0x39, (temp | 0x05) & 0xfd);
+
+ /* enable GEIO decode */
+ /* temp = IN3X5B(info->mmio_map, 0x29);
+ * OUT3X5B(info->mmio_map, 0x29, temp | 0x08);
+ */
+
+ /* Enable graphic engine I/O PCI retry function*/
+ /* temp = IN3X5B(info->mmio_map, 0x62);
+ * OUT3X5B(info->mmio_map, 0x62, temp | 0x50);
+ */
+
+ /* protect all register except which protected by 3c5.0e.7 */
+ /* OUT3C5B(info->mmio_map, 0x11, 0x87); */
+}
+
+
+int xgi_bootstrap(struct drm_device * dev, void * data,
+ struct drm_file * filp)
+{
+ struct xgi_info *info = dev->dev_private;
+ struct xgi_bootstrap * bs = (struct xgi_bootstrap *) data;
+ struct drm_map_list *maplist;
+ int err;
+
+
+ DRM_SPININIT(&info->fence_lock, "fence lock");
+ info->next_sequence = 0;
+ info->complete_sequence = 0;
+
+ if (info->mmio_map == NULL) {
+ err = drm_addmap(dev, info->mmio.base, info->mmio.size,
+ _DRM_REGISTERS, _DRM_KERNEL,
+ &info->mmio_map);
+ if (err) {
+ DRM_ERROR("Unable to map MMIO region: %d\n", err);
+ return err;
+ }
+
+ xgi_enable_mmio(info);
+ xgi_engine_init(info);
+ }
+
+
+ info->fb.size = IN3CFB(info->mmio_map, 0x54) * 8 * 1024 * 1024;
+
+ DRM_INFO("fb base: 0x%lx, size: 0x%x (probed)\n",
+ (unsigned long) info->fb.base, info->fb.size);
+
+
+ if ((info->fb.base == 0) || (info->fb.size == 0)) {
+ DRM_ERROR("framebuffer appears to be wrong: 0x%lx 0x%x\n",
+ (unsigned long) info->fb.base, info->fb.size);
+ return -EINVAL;
+ }
+
+
+ /* Init the resource manager */
+ if (!info->fb_heap_initialized) {
+ err = xgi_fb_heap_init(info);
+ if (err) {
+ DRM_ERROR("Unable to initialize FB heap.\n");
+ return err;
+ }
+ }
+
+
+ info->pcie.size = bs->gart.size;
+
+ /* Init the resource manager */
+ if (!info->pcie_heap_initialized) {
+ err = xgi_pcie_heap_init(info);
+ if (err) {
+ DRM_ERROR("Unable to initialize GART heap.\n");
+ return err;
+ }
+
+ /* Alloc 1M bytes for cmdbuffer which is flush2D batch array */
+ err = xgi_cmdlist_initialize(info, 0x100000, filp);
+ if (err) {
+ DRM_ERROR("xgi_cmdlist_initialize() failed\n");
+ return err;
+ }
+ }
+
+
+ if (info->pcie_map == NULL) {
+ err = drm_addmap(info->dev, 0, info->pcie.size,
+ _DRM_SCATTER_GATHER, _DRM_LOCKED,
+ & info->pcie_map);
+ if (err) {
+ DRM_ERROR("Could not add map for GART backing "
+ "store.\n");
+ return err;
+ }
+ }
+
+
+ maplist = drm_find_matching_map(dev, info->pcie_map);
+ if (maplist == NULL) {
+ DRM_ERROR("Could not find GART backing store map.\n");
+ return -EINVAL;
+ }
+
+ bs->gart = *info->pcie_map;
+ bs->gart.handle = (void *)(unsigned long) maplist->user_token;
+ return 0;
+}
+
+
+void xgi_driver_lastclose(struct drm_device * dev)
+{
+ struct xgi_info * info = dev->dev_private;
+
+ if (info != NULL) {
+ if (info->mmio_map != NULL) {
+ xgi_cmdlist_cleanup(info);
+ xgi_disable_ge(info);
+ xgi_disable_mmio(info);
+ }
+
+ /* The core DRM lastclose routine will destroy all of our
+ * mappings for us. NULL out the pointers here so that
+ * xgi_bootstrap can do the right thing.
+ */
+ info->pcie_map = NULL;
+ info->mmio_map = NULL;
+ info->fb_map = NULL;
+
+ if (info->pcie_heap_initialized) {
+ drm_ati_pcigart_cleanup(dev, &info->gart_info);
+ }
+
+ if (info->fb_heap_initialized
+ || info->pcie_heap_initialized) {
+ drm_sman_cleanup(&info->sman);
+
+ info->fb_heap_initialized = FALSE;
+ info->pcie_heap_initialized = FALSE;
+ }
+ }
+}
+
+
+void xgi_reclaim_buffers_locked(struct drm_device * dev,
+ struct drm_file * filp)
+{
+ struct xgi_info * info = dev->dev_private;
+
+ mutex_lock(&info->dev->struct_mutex);
+ if (drm_sman_owner_clean(&info->sman, (unsigned long) filp)) {
+ mutex_unlock(&info->dev->struct_mutex);
+ return;
+ }
+
+ if (dev->driver->dma_quiescent) {
+ dev->driver->dma_quiescent(dev);
+ }
+
+ drm_sman_owner_cleanup(&info->sman, (unsigned long) filp);
+ mutex_unlock(&info->dev->struct_mutex);
+ return;
+}
+
+
+/*
+ * driver receives an interrupt if someone waiting, then hand it off.
+ */
+irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS)
+{
+ struct drm_device *dev = (struct drm_device *) arg;
+ struct xgi_info *info = dev->dev_private;
+ const u32 irq_bits = le32_to_cpu(DRM_READ32(info->mmio_map,
+ (0x2800
+ + M2REG_AUTO_LINK_STATUS_ADDRESS)))
+ & (M2REG_ACTIVE_TIMER_INTERRUPT_MASK
+ | M2REG_ACTIVE_INTERRUPT_0_MASK
+ | M2REG_ACTIVE_INTERRUPT_2_MASK
+ | M2REG_ACTIVE_INTERRUPT_3_MASK);
+
+
+ if (irq_bits != 0) {
+ DRM_WRITE32(info->mmio_map,
+ 0x2800 + M2REG_AUTO_LINK_SETTING_ADDRESS,
+ cpu_to_le32(M2REG_AUTO_LINK_SETTING_COMMAND | irq_bits));
+ xgi_fence_handler(dev);
+ return IRQ_HANDLED;
+ } else {
+ return IRQ_NONE;
+ }
+}
+
+
+int xgi_driver_load(struct drm_device *dev, unsigned long flags)
+{
+ struct xgi_info *info = drm_alloc(sizeof(*info), DRM_MEM_DRIVER);
+ int err;
+
+ if (!info)
+ return -ENOMEM;
+
+ (void) memset(info, 0, sizeof(*info));
+ dev->dev_private = info;
+ info->dev = dev;
+
+ info->mmio.base = drm_get_resource_start(dev, 1);
+ info->mmio.size = drm_get_resource_len(dev, 1);
+
+ DRM_INFO("mmio base: 0x%lx, size: 0x%x\n",
+ (unsigned long) info->mmio.base, info->mmio.size);
+
+
+ if ((info->mmio.base == 0) || (info->mmio.size == 0)) {
+ DRM_ERROR("mmio appears to be wrong: 0x%lx 0x%x\n",
+ (unsigned long) info->mmio.base, info->mmio.size);
+ err = -EINVAL;
+ goto fail;
+ }
+
+
+ info->fb.base = drm_get_resource_start(dev, 0);
+ info->fb.size = drm_get_resource_len(dev, 0);
+
+ DRM_INFO("fb base: 0x%lx, size: 0x%x\n",
+ (unsigned long) info->fb.base, info->fb.size);
+
+
+ err = drm_sman_init(&info->sman, 2, 12, 8);
+ if (err) {
+ goto fail;
+ }
+
+
+ return 0;
+
+fail:
+ drm_free(info, sizeof(*info), DRM_MEM_DRIVER);
+ return err;
+}
+
+int xgi_driver_unload(struct drm_device *dev)
+{
+ struct xgi_info * info = dev->dev_private;
+
+ drm_sman_takedown(&info->sman);
+ drm_free(info, sizeof(*info), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+
+ return 0;
+}
diff --git a/linux-core/xgi_drv.h b/linux-core/xgi_drv.h
new file mode 100644
index 00000000..d9a94f5f
--- /dev/null
+++ b/linux-core/xgi_drv.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#ifndef _XGI_DRV_H_
+#define _XGI_DRV_H_
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sman.h"
+
+#define DRIVER_AUTHOR "Andrea Zhang <andrea_zhang@macrosynergy.com>"
+
+#define DRIVER_NAME "xgi"
+#define DRIVER_DESC "XGI XP5 / XP10 / XG47"
+#define DRIVER_DATE "20071003"
+
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 1
+#define DRIVER_PATCHLEVEL 3
+
+#include "xgi_cmdlist.h"
+#include "xgi_drm.h"
+
+struct xgi_aperture {
+ dma_addr_t base;
+ unsigned int size;
+};
+
+struct xgi_info {
+ struct drm_device *dev;
+
+ bool bootstrap_done;
+
+ /* physical characteristics */
+ struct xgi_aperture mmio;
+ struct xgi_aperture fb;
+ struct xgi_aperture pcie;
+
+ struct drm_map *mmio_map;
+ struct drm_map *pcie_map;
+ struct drm_map *fb_map;
+
+ /* look up table parameters */
+ struct ati_pcigart_info gart_info;
+ unsigned int lutPageSize;
+
+ struct drm_sman sman;
+ bool fb_heap_initialized;
+ bool pcie_heap_initialized;
+
+ struct xgi_cmdring_info cmdring;
+
+ DRM_SPINTYPE fence_lock;
+ unsigned complete_sequence;
+ unsigned next_sequence;
+};
+
+extern long xgi_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
+extern int xgi_fb_heap_init(struct xgi_info * info);
+
+extern int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
+ struct drm_file * filp);
+
+extern int xgi_free(struct xgi_info * info, unsigned long index,
+ struct drm_file * filp);
+
+extern int xgi_pcie_heap_init(struct xgi_info * info);
+
+extern void *xgi_find_pcie_virt(struct xgi_info * info, u32 address);
+
+extern void xgi_enable_mmio(struct xgi_info * info);
+extern void xgi_disable_mmio(struct xgi_info * info);
+extern void xgi_enable_ge(struct xgi_info * info);
+extern void xgi_disable_ge(struct xgi_info * info);
+
+extern void xgi_poke_flush(struct drm_device * dev, uint32_t class);
+extern int xgi_fence_emit_sequence(struct drm_device * dev, uint32_t class,
+ uint32_t flags, uint32_t * sequence, uint32_t * native_type);
+extern void xgi_fence_handler(struct drm_device * dev);
+extern int xgi_fence_has_irq(struct drm_device *dev, uint32_t class,
+ uint32_t flags);
+
+extern int xgi_alloc_ioctl(struct drm_device * dev, void * data,
+ struct drm_file * filp);
+extern int xgi_free_ioctl(struct drm_device * dev, void * data,
+ struct drm_file * filp);
+extern int xgi_submit_cmdlist(struct drm_device * dev, void * data,
+ struct drm_file * filp);
+extern int xgi_state_change_ioctl(struct drm_device * dev, void * data,
+ struct drm_file * filp);
+
+#endif
diff --git a/linux-core/xgi_fb.c b/linux-core/xgi_fb.c
new file mode 100644
index 00000000..2e2d0094
--- /dev/null
+++ b/linux-core/xgi_fb.c
@@ -0,0 +1,130 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#include "xgi_drv.h"
+
+#define XGI_FB_HEAP_START 0x1000000
+
+int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
+ struct drm_file * filp)
+{
+ struct drm_memblock_item *block;
+ const char *const mem_name = (alloc->location == XGI_MEMLOC_LOCAL)
+ ? "on-card" : "GART";
+
+
+ if ((alloc->location != XGI_MEMLOC_LOCAL)
+ && (alloc->location != XGI_MEMLOC_NON_LOCAL)) {
+ DRM_ERROR("Invalid memory pool (0x%08x) specified.\n",
+ alloc->location);
+ return -EINVAL;
+ }
+
+ if ((alloc->location == XGI_MEMLOC_LOCAL)
+ ? !info->fb_heap_initialized : !info->pcie_heap_initialized) {
+ DRM_ERROR("Attempt to allocate from uninitialized memory "
+ "pool (0x%08x).\n", alloc->location);
+ return -EINVAL;
+ }
+
+ mutex_lock(&info->dev->struct_mutex);
+ block = drm_sman_alloc(&info->sman, alloc->location, alloc->size,
+ 0, (unsigned long) filp);
+ mutex_unlock(&info->dev->struct_mutex);
+
+ if (block == NULL) {
+ alloc->size = 0;
+ DRM_ERROR("%s memory allocation failed\n", mem_name);
+ return -ENOMEM;
+ } else {
+ alloc->offset = (*block->mm->offset)(block->mm,
+ block->mm_info);
+ alloc->hw_addr = alloc->offset;
+ alloc->index = block->user_hash.key;
+
+ if (block->user_hash.key != (unsigned long) alloc->index) {
+ DRM_ERROR("%s truncated handle %lx for pool %d "
+ "offset %x\n",
+ __func__, block->user_hash.key,
+ alloc->location, alloc->offset);
+ }
+
+ if (alloc->location == XGI_MEMLOC_NON_LOCAL) {
+ alloc->hw_addr += info->pcie.base;
+ }
+
+ DRM_DEBUG("%s memory allocation succeeded: 0x%x\n",
+ mem_name, alloc->offset);
+ }
+
+ return 0;
+}
+
+
+int xgi_alloc_ioctl(struct drm_device * dev, void * data,
+ struct drm_file * filp)
+{
+ struct xgi_info *info = dev->dev_private;
+
+ return xgi_alloc(info, (struct xgi_mem_alloc *) data, filp);
+}
+
+
+int xgi_free(struct xgi_info * info, unsigned long index,
+ struct drm_file * filp)
+{
+ int err;
+
+ mutex_lock(&info->dev->struct_mutex);
+ err = drm_sman_free_key(&info->sman, index);
+ mutex_unlock(&info->dev->struct_mutex);
+
+ return err;
+}
+
+
+int xgi_free_ioctl(struct drm_device * dev, void * data,
+ struct drm_file * filp)
+{
+ struct xgi_info *info = dev->dev_private;
+
+ return xgi_free(info, *(unsigned long *) data, filp);
+}
+
+
+int xgi_fb_heap_init(struct xgi_info * info)
+{
+ int err;
+
+ mutex_lock(&info->dev->struct_mutex);
+ err = drm_sman_set_range(&info->sman, XGI_MEMLOC_LOCAL,
+ XGI_FB_HEAP_START,
+ info->fb.size - XGI_FB_HEAP_START);
+ mutex_unlock(&info->dev->struct_mutex);
+
+ info->fb_heap_initialized = (err == 0);
+ return err;
+}
diff --git a/linux-core/xgi_fence.c b/linux-core/xgi_fence.c
new file mode 100644
index 00000000..526bc5db
--- /dev/null
+++ b/linux-core/xgi_fence.c
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright IBM Corporation 2007
+ * 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
+ * on 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 AUTHORS AND/OR THEIR 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:
+ * Ian Romanick <idr@us.ibm.com>
+ */
+
+#include "xgi_drv.h"
+#include "xgi_regs.h"
+#include "xgi_misc.h"
+#include "xgi_cmdlist.h"
+
+static uint32_t xgi_do_flush(struct drm_device * dev, uint32_t class)
+{
+ struct xgi_info * info = dev->dev_private;
+ struct drm_fence_class_manager * fc = &dev->fm.fence_class[class];
+ uint32_t pending_flush_types = 0;
+ uint32_t signaled_flush_types = 0;
+
+
+ if ((info == NULL) || (class != 0))
+ return 0;
+
+ DRM_SPINLOCK(&info->fence_lock);
+
+ pending_flush_types = fc->pending_flush |
+ ((fc->pending_exe_flush) ? DRM_FENCE_TYPE_EXE : 0);
+
+ if (pending_flush_types) {
+ if (pending_flush_types & DRM_FENCE_TYPE_EXE) {
+ const u32 begin_id = le32_to_cpu(DRM_READ32(info->mmio_map,
+ 0x2820))
+ & BEGIN_BEGIN_IDENTIFICATION_MASK;
+
+ if (begin_id != info->complete_sequence) {
+ info->complete_sequence = begin_id;
+ signaled_flush_types |= DRM_FENCE_TYPE_EXE;
+ }
+ }
+
+ if (signaled_flush_types) {
+ drm_fence_handler(dev, 0, info->complete_sequence,
+ signaled_flush_types, 0);
+ }
+ }
+
+ DRM_SPINUNLOCK(&info->fence_lock);
+
+ return fc->pending_flush |
+ ((fc->pending_exe_flush) ? DRM_FENCE_TYPE_EXE : 0);
+}
+
+
+int xgi_fence_emit_sequence(struct drm_device * dev, uint32_t class,
+ uint32_t flags, uint32_t * sequence,
+ uint32_t * native_type)
+{
+ struct xgi_info * info = dev->dev_private;
+
+ if ((info == NULL) || (class != 0))
+ return -EINVAL;
+
+
+ DRM_SPINLOCK(&info->fence_lock);
+ info->next_sequence++;
+ if (info->next_sequence > BEGIN_BEGIN_IDENTIFICATION_MASK) {
+ info->next_sequence = 1;
+ }
+ DRM_SPINUNLOCK(&info->fence_lock);
+
+
+ xgi_emit_irq(info);
+
+ *sequence = (uint32_t) info->next_sequence;
+ *native_type = DRM_FENCE_TYPE_EXE;
+
+ return 0;
+}
+
+
+void xgi_poke_flush(struct drm_device * dev, uint32_t class)
+{
+ struct drm_fence_manager * fm = &dev->fm;
+ unsigned long flags;
+
+
+ write_lock_irqsave(&fm->lock, flags);
+ xgi_do_flush(dev, class);
+ write_unlock_irqrestore(&fm->lock, flags);
+}
+
+
+void xgi_fence_handler(struct drm_device * dev)
+{
+ struct drm_fence_manager * fm = &dev->fm;
+
+
+ write_lock(&fm->lock);
+ xgi_do_flush(dev, 0);
+ write_unlock(&fm->lock);
+}
+
+
+int xgi_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags)
+{
+ return ((class == 0) && (flags == DRM_FENCE_TYPE_EXE)) ? 1 : 0;
+}
diff --git a/linux-core/xgi_ioc32.c b/linux-core/xgi_ioc32.c
new file mode 100644
index 00000000..c54044fa
--- /dev/null
+++ b/linux-core/xgi_ioc32.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright IBM Corporation 2007
+ * Copyright (C) Paul Mackerras 2005.
+ * 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
+ * on 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 AUTHORS AND/OR THEIR 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:
+ * Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <linux/compat.h>
+
+#include "drmP.h"
+#include "drm.h"
+
+#include "xgi_drm.h"
+
+/* This is copied from drm_ioc32.c.
+ */
+struct drm_map32 {
+ u32 offset; /**< Requested physical address (0 for SAREA)*/
+ u32 size; /**< Requested physical size (bytes) */
+ enum drm_map_type type; /**< Type of memory to map */
+ enum drm_map_flags flags; /**< Flags */
+ u32 handle; /**< User-space: "Handle" to pass to mmap() */
+ int mtrr; /**< MTRR slot used */
+};
+
+struct drm32_xgi_bootstrap {
+ struct drm_map32 gart;
+};
+
+
+extern int xgi_bootstrap(struct drm_device *, void *, struct drm_file *);
+
+static int compat_xgi_bootstrap(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct drm32_xgi_bootstrap __user *const argp = (void __user *)arg;
+ struct drm32_xgi_bootstrap bs32;
+ struct xgi_bootstrap __user *bs;
+ int err;
+ void *handle;
+
+
+ if (copy_from_user(&bs32, argp, sizeof(bs32))) {
+ return -EFAULT;
+ }
+
+ bs = compat_alloc_user_space(sizeof(*bs));
+ if (!access_ok(VERIFY_WRITE, bs, sizeof(*bs))) {
+ return -EFAULT;
+ }
+
+ if (__put_user(bs32.gart.offset, &bs->gart.offset)
+ || __put_user(bs32.gart.size, &bs->gart.size)
+ || __put_user(bs32.gart.type, &bs->gart.type)
+ || __put_user(bs32.gart.flags, &bs->gart.flags)) {
+ return -EFAULT;
+ }
+
+ err = drm_ioctl(filp->f_dentry->d_inode, filp, XGI_IOCTL_BOOTSTRAP,
+ (unsigned long)bs);
+ if (err) {
+ return err;
+ }
+
+ if (__get_user(bs32.gart.offset, &bs->gart.offset)
+ || __get_user(bs32.gart.mtrr, &bs->gart.mtrr)
+ || __get_user(handle, &bs->gart.handle)) {
+ return -EFAULT;
+ }
+
+ bs32.gart.handle = (unsigned long)handle;
+ if (bs32.gart.handle != (unsigned long)handle && printk_ratelimit()) {
+ printk(KERN_ERR "%s truncated handle %p for type %d "
+ "offset %x\n",
+ __func__, handle, bs32.gart.type, bs32.gart.offset);
+ }
+
+ if (copy_to_user(argp, &bs32, sizeof(bs32))) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+
+drm_ioctl_compat_t *xgi_compat_ioctls[] = {
+ [DRM_XGI_BOOTSTRAP] = compat_xgi_bootstrap,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long xgi_compat_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ const unsigned int nr = DRM_IOCTL_NR(cmd);
+ drm_ioctl_compat_t *fn = NULL;
+ int ret;
+
+ if (nr < DRM_COMMAND_BASE)
+ return drm_compat_ioctl(filp, cmd, arg);
+
+ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(xgi_compat_ioctls))
+ fn = xgi_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+ lock_kernel();
+ ret = (fn != NULL)
+ ? (*fn)(filp, cmd, arg)
+ : drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+ unlock_kernel();
+
+ return ret;
+}
diff --git a/linux-core/xgi_misc.c b/linux-core/xgi_misc.c
new file mode 100644
index 00000000..4a4a9844
--- /dev/null
+++ b/linux-core/xgi_misc.c
@@ -0,0 +1,477 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#include "xgi_drv.h"
+#include "xgi_regs.h"
+
+#include <linux/delay.h>
+
+/*
+ * irq functions
+ */
+#define STALL_INTERRUPT_RESET_THRESHOLD 0xffff
+
+static unsigned int s_invalid_begin = 0;
+
+static bool xgi_validate_signal(struct drm_map * map)
+{
+ if (le32_to_cpu(DRM_READ32(map, 0x2800) & 0x001c0000)) {
+ u16 check;
+
+ /* Check Read back status */
+ DRM_WRITE8(map, 0x235c, 0x80);
+ check = le16_to_cpu(DRM_READ16(map, 0x2360));
+
+ if ((check & 0x3f) != ((check & 0x3f00) >> 8)) {
+ return FALSE;
+ }
+
+ /* Check RO channel */
+ DRM_WRITE8(map, 0x235c, 0x83);
+ check = le16_to_cpu(DRM_READ16(map, 0x2360));
+ if ((check & 0x0f) != ((check & 0xf0) >> 4)) {
+ return FALSE;
+ }
+
+ /* Check RW channel */
+ DRM_WRITE8(map, 0x235c, 0x88);
+ check = le16_to_cpu(DRM_READ16(map, 0x2360));
+ if ((check & 0x0f) != ((check & 0xf0) >> 4)) {
+ return FALSE;
+ }
+
+ /* Check RO channel outstanding */
+ DRM_WRITE8(map, 0x235c, 0x8f);
+ check = le16_to_cpu(DRM_READ16(map, 0x2360));
+ if (0 != (check & 0x3ff)) {
+ return FALSE;
+ }
+
+ /* Check RW channel outstanding */
+ DRM_WRITE8(map, 0x235c, 0x90);
+ check = le16_to_cpu(DRM_READ16(map, 0x2360));
+ if (0 != (check & 0x3ff)) {
+ return FALSE;
+ }
+
+ /* No pending PCIE request. GE stall. */
+ }
+
+ return TRUE;
+}
+
+
+static void xgi_ge_hang_reset(struct drm_map * map)
+{
+ int time_out = 0xffff;
+
+ DRM_WRITE8(map, 0xb057, 8);
+ while (0 != le32_to_cpu(DRM_READ32(map, 0x2800) & 0xf0000000)) {
+ while (0 != ((--time_out) & 0xfff))
+ /* empty */ ;
+
+ if (0 == time_out) {
+ u8 old_3ce;
+ u8 old_3cf;
+ u8 old_index;
+ u8 old_36;
+
+ DRM_INFO("Can not reset back 0x%x!\n",
+ le32_to_cpu(DRM_READ32(map, 0x2800)));
+
+ DRM_WRITE8(map, 0xb057, 0);
+
+ /* Have to use 3x5.36 to reset. */
+ /* Save and close dynamic gating */
+
+ old_3ce = DRM_READ8(map, 0x3ce);
+ DRM_WRITE8(map, 0x3ce, 0x2a);
+ old_3cf = DRM_READ8(map, 0x3cf);
+ DRM_WRITE8(map, 0x3cf, old_3cf & 0xfe);
+
+ /* Reset GE */
+ old_index = DRM_READ8(map, 0x3d4);
+ DRM_WRITE8(map, 0x3d4, 0x36);
+ old_36 = DRM_READ8(map, 0x3d5);
+ DRM_WRITE8(map, 0x3d5, old_36 | 0x10);
+
+ while (0 != ((--time_out) & 0xfff))
+ /* empty */ ;
+
+ DRM_WRITE8(map, 0x3d5, old_36);
+ DRM_WRITE8(map, 0x3d4, old_index);
+
+ /* Restore dynamic gating */
+ DRM_WRITE8(map, 0x3cf, old_3cf);
+ DRM_WRITE8(map, 0x3ce, old_3ce);
+ break;
+ }
+ }
+
+ DRM_WRITE8(map, 0xb057, 0);
+}
+
+
+bool xgi_ge_irq_handler(struct xgi_info * info)
+{
+ const u32 int_status = le32_to_cpu(DRM_READ32(info->mmio_map, 0x2810));
+ bool is_support_auto_reset = FALSE;
+
+ /* Check GE on/off */
+ if (0 == (0xffffc0f0 & int_status)) {
+ if (0 != (0x1000 & int_status)) {
+ /* We got GE stall interrupt.
+ */
+ DRM_WRITE32(info->mmio_map, 0x2810,
+ cpu_to_le32(int_status | 0x04000000));
+
+ if (is_support_auto_reset) {
+ static cycles_t last_tick;
+ static unsigned continue_int_count = 0;
+
+ /* OE II is busy. */
+
+ if (!xgi_validate_signal(info->mmio_map)) {
+ /* Nothing but skip. */
+ } else if (0 == continue_int_count++) {
+ last_tick = get_cycles();
+ } else {
+ const cycles_t new_tick = get_cycles();
+ if ((new_tick - last_tick) >
+ STALL_INTERRUPT_RESET_THRESHOLD) {
+ continue_int_count = 0;
+ } else if (continue_int_count >= 3) {
+ continue_int_count = 0;
+
+ /* GE Hung up, need reset. */
+ DRM_INFO("Reset GE!\n");
+
+ xgi_ge_hang_reset(info->mmio_map);
+ }
+ }
+ }
+ } else if (0 != (0x1 & int_status)) {
+ s_invalid_begin++;
+ DRM_WRITE32(info->mmio_map, 0x2810,
+ cpu_to_le32((int_status & ~0x01) | 0x04000000));
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool xgi_crt_irq_handler(struct xgi_info * info)
+{
+ bool ret = FALSE;
+ u8 save_3ce = DRM_READ8(info->mmio_map, 0x3ce);
+
+ /* CRT1 interrupt just happened
+ */
+ if (IN3CFB(info->mmio_map, 0x37) & 0x01) {
+ u8 op3cf_3d;
+ u8 op3cf_37;
+
+ /* What happened?
+ */
+ op3cf_37 = IN3CFB(info->mmio_map, 0x37);
+
+ /* Clear CRT interrupt
+ */
+ op3cf_3d = IN3CFB(info->mmio_map, 0x3d);
+ OUT3CFB(info->mmio_map, 0x3d, (op3cf_3d | 0x04));
+ OUT3CFB(info->mmio_map, 0x3d, (op3cf_3d & ~0x04));
+ ret = TRUE;
+ }
+ DRM_WRITE8(info->mmio_map, 0x3ce, save_3ce);
+
+ return (ret);
+}
+
+bool xgi_dvi_irq_handler(struct xgi_info * info)
+{
+ bool ret = FALSE;
+ const u8 save_3ce = DRM_READ8(info->mmio_map, 0x3ce);
+
+ /* DVI interrupt just happened
+ */
+ if (IN3CFB(info->mmio_map, 0x38) & 0x20) {
+ const u8 save_3x4 = DRM_READ8(info->mmio_map, 0x3d4);
+ u8 op3cf_39;
+ u8 op3cf_37;
+ u8 op3x5_5a;
+
+ /* What happened?
+ */
+ op3cf_37 = IN3CFB(info->mmio_map, 0x37);
+
+ /* Notify BIOS that DVI plug/unplug happened
+ */
+ op3x5_5a = IN3X5B(info->mmio_map, 0x5a);
+ OUT3X5B(info->mmio_map, 0x5a, op3x5_5a & 0xf7);
+
+ DRM_WRITE8(info->mmio_map, 0x3d4, save_3x4);
+
+ /* Clear DVI interrupt
+ */
+ op3cf_39 = IN3CFB(info->mmio_map, 0x39);
+ OUT3C5B(info->mmio_map, 0x39, (op3cf_39 & ~0x01));
+ OUT3C5B(info->mmio_map, 0x39, (op3cf_39 | 0x01));
+
+ ret = TRUE;
+ }
+ DRM_WRITE8(info->mmio_map, 0x3ce, save_3ce);
+
+ return (ret);
+}
+
+
+static void dump_reg_header(unsigned regbase)
+{
+ printk("\n=====xgi_dump_register========0x%x===============\n",
+ regbase);
+ printk(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
+}
+
+
+static void dump_indexed_reg(struct xgi_info * info, unsigned regbase)
+{
+ unsigned i, j;
+ u8 temp;
+
+
+ dump_reg_header(regbase);
+ for (i = 0; i < 0x10; i++) {
+ printk("%1x ", i);
+
+ for (j = 0; j < 0x10; j++) {
+ DRM_WRITE8(info->mmio_map, regbase - 1,
+ (i * 0x10) + j);
+ temp = DRM_READ8(info->mmio_map, regbase);
+ printk("%3x", temp);
+ }
+ printk("\n");
+ }
+}
+
+
+static void dump_reg(struct xgi_info * info, unsigned regbase, unsigned range)
+{
+ unsigned i, j;
+
+
+ dump_reg_header(regbase);
+ for (i = 0; i < range; i++) {
+ printk("%1x ", i);
+
+ for (j = 0; j < 0x10; j++) {
+ u8 temp = DRM_READ8(info->mmio_map,
+ regbase + (i * 0x10) + j);
+ printk("%3x", temp);
+ }
+ printk("\n");
+ }
+}
+
+
+void xgi_dump_register(struct xgi_info * info)
+{
+ dump_indexed_reg(info, 0x3c5);
+ dump_indexed_reg(info, 0x3d5);
+ dump_indexed_reg(info, 0x3cf);
+
+ dump_reg(info, 0xB000, 0x05);
+ dump_reg(info, 0x2200, 0x0B);
+ dump_reg(info, 0x2300, 0x07);
+ dump_reg(info, 0x2400, 0x10);
+ dump_reg(info, 0x2800, 0x10);
+}
+
+
+#define WHOLD_GE_STATUS 0x2800
+
+/* Test everything except the "whole GE busy" bit, the "master engine busy"
+ * bit, and the reserved bits [26:21].
+ */
+#define IDLE_MASK ~((1U<<31) | (1U<<28) | (0x3f<<21))
+
+void xgi_waitfor_pci_idle(struct xgi_info * info)
+{
+ unsigned int idleCount = 0;
+ u32 old_status = 0;
+ unsigned int same_count = 0;
+
+ while (idleCount < 5) {
+ const u32 status = DRM_READ32(info->mmio_map, WHOLD_GE_STATUS)
+ & IDLE_MASK;
+
+ if (status == old_status) {
+ same_count++;
+
+ if ((same_count % 100) == 0) {
+ DRM_ERROR("GE status stuck at 0x%08x for %u iterations!\n",
+ old_status, same_count);
+ }
+ } else {
+ old_status = status;
+ same_count = 0;
+ }
+
+ if (status != 0) {
+ msleep(1);
+ idleCount = 0;
+ } else {
+ idleCount++;
+ }
+ }
+}
+
+
+void xgi_enable_mmio(struct xgi_info * info)
+{
+ u8 protect = 0;
+ u8 temp;
+
+ /* Unprotect registers */
+ DRM_WRITE8(info->mmio_map, 0x3C4, 0x11);
+ protect = DRM_READ8(info->mmio_map, 0x3C5);
+ DRM_WRITE8(info->mmio_map, 0x3C5, 0x92);
+
+ DRM_WRITE8(info->mmio_map, 0x3D4, 0x3A);
+ temp = DRM_READ8(info->mmio_map, 0x3D5);
+ DRM_WRITE8(info->mmio_map, 0x3D5, temp | 0x20);
+
+ /* Enable MMIO */
+ DRM_WRITE8(info->mmio_map, 0x3D4, 0x39);
+ temp = DRM_READ8(info->mmio_map, 0x3D5);
+ DRM_WRITE8(info->mmio_map, 0x3D5, temp | 0x01);
+
+ /* Protect registers */
+ OUT3C5B(info->mmio_map, 0x11, protect);
+}
+
+
+void xgi_disable_mmio(struct xgi_info * info)
+{
+ u8 protect = 0;
+ u8 temp;
+
+ /* Unprotect registers */
+ DRM_WRITE8(info->mmio_map, 0x3C4, 0x11);
+ protect = DRM_READ8(info->mmio_map, 0x3C5);
+ DRM_WRITE8(info->mmio_map, 0x3C5, 0x92);
+
+ /* Disable MMIO access */
+ DRM_WRITE8(info->mmio_map, 0x3D4, 0x39);
+ temp = DRM_READ8(info->mmio_map, 0x3D5);
+ DRM_WRITE8(info->mmio_map, 0x3D5, temp & 0xFE);
+
+ /* Protect registers */
+ OUT3C5B(info->mmio_map, 0x11, protect);
+}
+
+
+void xgi_enable_ge(struct xgi_info * info)
+{
+ u8 bOld3cf2a;
+ int wait = 0;
+
+ OUT3C5B(info->mmio_map, 0x11, 0x92);
+
+ /* Save and close dynamic gating
+ */
+ bOld3cf2a = IN3CFB(info->mmio_map, XGI_MISC_CTRL);
+ OUT3CFB(info->mmio_map, XGI_MISC_CTRL, bOld3cf2a & ~EN_GEPWM);
+
+ /* Enable 2D and 3D GE
+ */
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
+ wait = 10;
+ while (wait--) {
+ DRM_READ8(info->mmio_map, 0x36);
+ }
+
+ /* Reset both 3D and 2D engine
+ */
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL,
+ (GE_ENABLE | GE_RESET | GE_ENABLE_3D));
+ wait = 10;
+ while (wait--) {
+ DRM_READ8(info->mmio_map, 0x36);
+ }
+
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
+ wait = 10;
+ while (wait--) {
+ DRM_READ8(info->mmio_map, 0x36);
+ }
+
+ /* Enable 2D engine only
+ */
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, GE_ENABLE);
+
+ /* Enable 2D+3D engine
+ */
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
+
+ /* Restore dynamic gating
+ */
+ OUT3CFB(info->mmio_map, XGI_MISC_CTRL, bOld3cf2a);
+}
+
+
+void xgi_disable_ge(struct xgi_info * info)
+{
+ int wait = 0;
+
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
+
+ wait = 10;
+ while (wait--) {
+ DRM_READ8(info->mmio_map, 0x36);
+ }
+
+ /* Reset both 3D and 2D engine
+ */
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL,
+ (GE_ENABLE | GE_RESET | GE_ENABLE_3D));
+
+ wait = 10;
+ while (wait--) {
+ DRM_READ8(info->mmio_map, 0x36);
+ }
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, (GE_ENABLE | GE_ENABLE_3D));
+
+ wait = 10;
+ while (wait--) {
+ DRM_READ8(info->mmio_map, 0x36);
+ }
+
+ /* Disable 2D engine and 3D engine.
+ */
+ OUT3X5B(info->mmio_map, XGI_GE_CNTL, 0);
+}
diff --git a/linux-core/xgi_misc.h b/linux-core/xgi_misc.h
new file mode 100644
index 00000000..af19a11a
--- /dev/null
+++ b/linux-core/xgi_misc.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#ifndef _XGI_MISC_H_
+#define _XGI_MISC_H_
+
+extern void xgi_dump_register(struct xgi_info * info);
+
+extern bool xgi_ge_irq_handler(struct xgi_info * info);
+extern bool xgi_crt_irq_handler(struct xgi_info * info);
+extern bool xgi_dvi_irq_handler(struct xgi_info * info);
+extern void xgi_waitfor_pci_idle(struct xgi_info * info);
+
+#endif
diff --git a/linux-core/xgi_pcie.c b/linux-core/xgi_pcie.c
new file mode 100644
index 00000000..a7d3ea24
--- /dev/null
+++ b/linux-core/xgi_pcie.c
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#include "xgi_drv.h"
+#include "xgi_regs.h"
+#include "xgi_misc.h"
+
+void xgi_gart_flush(struct drm_device *dev)
+{
+ struct xgi_info *const info = dev->dev_private;
+ u8 temp;
+
+ DRM_MEMORYBARRIER();
+
+ /* Set GART in SFB */
+ temp = DRM_READ8(info->mmio_map, 0xB00C);
+ DRM_WRITE8(info->mmio_map, 0xB00C, temp & ~0x02);
+
+ /* Set GART base address to HW */
+ DRM_WRITE32(info->mmio_map, 0xB034, info->gart_info.bus_addr);
+
+ /* Flush GART table. */
+ DRM_WRITE8(info->mmio_map, 0xB03F, 0x40);
+ DRM_WRITE8(info->mmio_map, 0xB03F, 0x00);
+}
+
+
+int xgi_pcie_heap_init(struct xgi_info * info)
+{
+ u8 temp = 0;
+ int err;
+ struct drm_scatter_gather request;
+
+ /* Get current FB aperture size */
+ temp = IN3X5B(info->mmio_map, 0x27);
+ DRM_INFO("In3x5(0x27): 0x%x \n", temp);
+
+ if (temp & 0x01) { /* 256MB; Jong 06/05/2006; 0x10000000 */
+ info->pcie.base = 256 * 1024 * 1024;
+ } else { /* 128MB; Jong 06/05/2006; 0x08000000 */
+ info->pcie.base = 128 * 1024 * 1024;
+ }
+
+
+ DRM_INFO("info->pcie.base: 0x%lx\n", (unsigned long) info->pcie.base);
+
+ /* Get current lookup table page size */
+ temp = DRM_READ8(info->mmio_map, 0xB00C);
+ if (temp & 0x04) { /* 8KB */
+ info->lutPageSize = 8 * 1024;
+ } else { /* 4KB */
+ info->lutPageSize = 4 * 1024;
+ }
+
+ DRM_INFO("info->lutPageSize: 0x%x \n", info->lutPageSize);
+
+
+ request.size = info->pcie.size;
+ err = drm_sg_alloc(info->dev, & request);
+ if (err) {
+ DRM_ERROR("cannot allocate PCIE GART backing store! "
+ "size = %d\n", info->pcie.size);
+ return err;
+ }
+
+ info->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
+ info->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
+ info->gart_info.table_size = info->dev->sg->pages * sizeof(u32);
+
+ if (!drm_ati_pcigart_init(info->dev, &info->gart_info)) {
+ DRM_ERROR("failed to init PCI GART!\n");
+ return -ENOMEM;
+ }
+
+
+ xgi_gart_flush(info->dev);
+
+ mutex_lock(&info->dev->struct_mutex);
+ err = drm_sman_set_range(&info->sman, XGI_MEMLOC_NON_LOCAL,
+ 0, info->pcie.size);
+ mutex_unlock(&info->dev->struct_mutex);
+ if (err) {
+ drm_ati_pcigart_cleanup(info->dev, &info->gart_info);
+ }
+
+ info->pcie_heap_initialized = (err == 0);
+ return err;
+}
+
+
+/**
+ * xgi_find_pcie_virt
+ * @address: GE HW address
+ *
+ * Returns CPU virtual address. Assumes the CPU VAddr is continuous in not
+ * the same block
+ */
+void *xgi_find_pcie_virt(struct xgi_info * info, u32 address)
+{
+ const unsigned long offset = address - info->pcie.base;
+
+ return ((u8 *) info->dev->sg->virtual) + offset;
+}
diff --git a/linux-core/xgi_regs.h b/linux-core/xgi_regs.h
new file mode 100644
index 00000000..5c0100a0
--- /dev/null
+++ b/linux-core/xgi_regs.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+ * Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * 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 on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, 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
+ * XGI 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.
+ ***************************************************************************/
+
+#ifndef _XGI_REGS_H_
+#define _XGI_REGS_H_
+
+#include "drmP.h"
+#include "drm.h"
+
+#define MAKE_MASK(bits) ((1U << (bits)) - 1)
+
+#define ONE_BIT_MASK MAKE_MASK(1)
+#define TWENTY_BIT_MASK MAKE_MASK(20)
+#define TWENTYONE_BIT_MASK MAKE_MASK(21)
+#define TWENTYTWO_BIT_MASK MAKE_MASK(22)
+
+
+/* Port 0x3d4/0x3d5, index 0x2a */
+#define XGI_INTERFACE_SEL 0x2a
+#define DUAL_64BIT (1U<<7)
+#define INTERNAL_32BIT (1U<<6)
+#define EN_SEP_WR (1U<<5)
+#define POWER_DOWN_SEL (1U<<4)
+/*#define RESERVED_3 (1U<<3) */
+#define SUBS_MCLK_PCICLK (1U<<2)
+#define MEM_SIZE_MASK (3<<0)
+#define MEM_SIZE_32MB (0<<0)
+#define MEM_SIZE_64MB (1<<0)
+#define MEM_SIZE_128MB (2<<0)
+#define MEM_SIZE_256MB (3<<0)
+
+/* Port 0x3d4/0x3d5, index 0x36 */
+#define XGI_GE_CNTL 0x36
+#define GE_ENABLE (1U<<7)
+/*#define RESERVED_6 (1U<<6) */
+/*#define RESERVED_5 (1U<<5) */
+#define GE_RESET (1U<<4)
+/*#define RESERVED_3 (1U<<3) */
+#define GE_ENABLE_3D (1U<<2)
+/*#define RESERVED_1 (1U<<1) */
+/*#define RESERVED_0 (1U<<0) */
+
+/* Port 0x3ce/0x3cf, index 0x2a */
+#define XGI_MISC_CTRL 0x2a
+#define MOTION_VID_SUSPEND (1U<<7)
+#define DVI_CRTC_TIMING_SEL (1U<<6)
+#define LCD_SEL_CTL_NEW (1U<<5)
+#define LCD_SEL_EXT_DELYCTRL (1U<<4)
+#define REG_LCDDPARST (1U<<3)
+#define LCD2DPAOFF (1U<<2)
+/*#define RESERVED_1 (1U<<1) */
+#define EN_GEPWM (1U<<0) /* Enable GE power management */
+
+
+#define BASE_3D_ENG 0x2800
+
+#define M2REG_FLUSH_ENGINE_ADDRESS 0x000
+#define M2REG_FLUSH_ENGINE_COMMAND 0x00
+#define M2REG_FLUSH_FLIP_ENGINE_MASK (ONE_BIT_MASK<<21)
+#define M2REG_FLUSH_2D_ENGINE_MASK (ONE_BIT_MASK<<20)
+#define M2REG_FLUSH_3D_ENGINE_MASK TWENTY_BIT_MASK
+
+#define M2REG_RESET_ADDRESS 0x004
+#define M2REG_RESET_COMMAND 0x01
+#define M2REG_RESET_STATUS2_MASK (ONE_BIT_MASK<<10)
+#define M2REG_RESET_STATUS1_MASK (ONE_BIT_MASK<<9)
+#define M2REG_RESET_STATUS0_MASK (ONE_BIT_MASK<<8)
+#define M2REG_RESET_3DENG_MASK (ONE_BIT_MASK<<4)
+#define M2REG_RESET_2DENG_MASK (ONE_BIT_MASK<<2)
+
+/* Write register */
+#define M2REG_AUTO_LINK_SETTING_ADDRESS 0x010
+#define M2REG_AUTO_LINK_SETTING_COMMAND 0x04
+#define M2REG_CLEAR_TIMER_INTERRUPT_MASK (ONE_BIT_MASK<<11)
+#define M2REG_CLEAR_INTERRUPT_3_MASK (ONE_BIT_MASK<<10)
+#define M2REG_CLEAR_INTERRUPT_2_MASK (ONE_BIT_MASK<<9)
+#define M2REG_CLEAR_INTERRUPT_0_MASK (ONE_BIT_MASK<<8)
+#define M2REG_CLEAR_COUNTERS_MASK (ONE_BIT_MASK<<4)
+#define M2REG_PCI_TRIGGER_MODE_MASK (ONE_BIT_MASK<<1)
+#define M2REG_INVALID_LIST_AUTO_INTERRUPT_MASK (ONE_BIT_MASK<<0)
+
+/* Read register */
+#define M2REG_AUTO_LINK_STATUS_ADDRESS 0x010
+#define M2REG_AUTO_LINK_STATUS_COMMAND 0x04
+#define M2REG_ACTIVE_TIMER_INTERRUPT_MASK (ONE_BIT_MASK<<11)
+#define M2REG_ACTIVE_INTERRUPT_3_MASK (ONE_BIT_MASK<<10)
+#define M2REG_ACTIVE_INTERRUPT_2_MASK (ONE_BIT_MASK<<9)
+#define M2REG_ACTIVE_INTERRUPT_0_MASK (ONE_BIT_MASK<<8)
+#define M2REG_INVALID_LIST_AUTO_INTERRUPTED_MODE_MASK (ONE_BIT_MASK<<0)
+
+#define M2REG_PCI_TRIGGER_REGISTER_ADDRESS 0x014
+#define M2REG_PCI_TRIGGER_REGISTER_COMMAND 0x05
+
+
+/**
+ * Begin instruction, double-word 0
+ */
+#define BEGIN_STOP_STORE_CURRENT_POINTER_MASK (ONE_BIT_MASK<<22)
+#define BEGIN_VALID_MASK (ONE_BIT_MASK<<20)
+#define BEGIN_BEGIN_IDENTIFICATION_MASK TWENTY_BIT_MASK
+
+/**
+ * Begin instruction, double-word 1
+ */
+#define BEGIN_LINK_ENABLE_MASK (ONE_BIT_MASK<<31)
+#define BEGIN_COMMAND_LIST_LENGTH_MASK TWENTYTWO_BIT_MASK
+
+
+/* Hardware access functions */
+static inline void OUT3C5B(struct drm_map * map, u8 index, u8 data)
+{
+ DRM_WRITE8(map, 0x3C4, index);
+ DRM_WRITE8(map, 0x3C5, data);
+}
+
+static inline void OUT3X5B(struct drm_map * map, u8 index, u8 data)
+{
+ DRM_WRITE8(map, 0x3D4, index);
+ DRM_WRITE8(map, 0x3D5, data);
+}
+
+static inline void OUT3CFB(struct drm_map * map, u8 index, u8 data)
+{
+ DRM_WRITE8(map, 0x3CE, index);
+ DRM_WRITE8(map, 0x3CF, data);
+}
+
+static inline u8 IN3C5B(struct drm_map * map, u8 index)
+{
+ DRM_WRITE8(map, 0x3C4, index);
+ return DRM_READ8(map, 0x3C5);
+}
+
+static inline u8 IN3X5B(struct drm_map * map, u8 index)
+{
+ DRM_WRITE8(map, 0x3D4, index);
+ return DRM_READ8(map, 0x3D5);
+}
+
+static inline u8 IN3CFB(struct drm_map * map, u8 index)
+{
+ DRM_WRITE8(map, 0x3CE, index);
+ return DRM_READ8(map, 0x3CF);
+}
+
+#endif