Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
4c6b5945
Commit
4c6b5945
authored
May 09, 2004
by
David Airlie
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux.bkbits.net/linux-2.5
into hostme.bitkeeper.com:/repos/d/drm/drm-2.6
parents
3dc567d8
27aac887
Changes
48
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
1700 additions
and
899 deletions
+1700
-899
drivers/char/drm/drm.h
drivers/char/drm/drm.h
+25
-2
drivers/char/drm/drmP.h
drivers/char/drm/drmP.h
+45
-40
drivers/char/drm/drm_agpsupport.h
drivers/char/drm/drm_agpsupport.h
+7
-1
drivers/char/drm/drm_bufs.h
drivers/char/drm/drm_bufs.h
+10
-2
drivers/char/drm/drm_context.h
drivers/char/drm/drm_context.h
+29
-0
drivers/char/drm/drm_dma.h
drivers/char/drm/drm_dma.h
+5
-298
drivers/char/drm/drm_drv.h
drivers/char/drm/drm_drv.h
+140
-124
drivers/char/drm/drm_fops.h
drivers/char/drm/drm_fops.h
+2
-0
drivers/char/drm/drm_ioctl.h
drivers/char/drm/drm_ioctl.h
+82
-110
drivers/char/drm/drm_irq.h
drivers/char/drm/drm_irq.h
+371
-0
drivers/char/drm/drm_memory_debug.h
drivers/char/drm/drm_memory_debug.h
+1
-0
drivers/char/drm/drm_os_linux.h
drivers/char/drm/drm_os_linux.h
+6
-0
drivers/char/drm/drm_pciids.h
drivers/char/drm/drm_pciids.h
+203
-0
drivers/char/drm/drm_sarea.h
drivers/char/drm/drm_sarea.h
+14
-0
drivers/char/drm/drm_stub.h
drivers/char/drm/drm_stub.h
+2
-2
drivers/char/drm/drm_vm.h
drivers/char/drm/drm_vm.h
+97
-51
drivers/char/drm/ffb.h
drivers/char/drm/ffb.h
+1
-0
drivers/char/drm/gamma.h
drivers/char/drm/gamma.h
+2
-2
drivers/char/drm/gamma_dma.c
drivers/char/drm/gamma_dma.c
+4
-4
drivers/char/drm/gamma_drv.c
drivers/char/drm/gamma_drv.c
+1
-0
drivers/char/drm/i810.h
drivers/char/drm/i810.h
+1
-2
drivers/char/drm/i810_dma.c
drivers/char/drm/i810_dma.c
+2
-2
drivers/char/drm/i830.h
drivers/char/drm/i830.h
+2
-2
drivers/char/drm/i830_dma.c
drivers/char/drm/i830_dma.c
+3
-3
drivers/char/drm/i830_drv.c
drivers/char/drm/i830_drv.c
+1
-0
drivers/char/drm/i830_irq.c
drivers/char/drm/i830_irq.c
+1
-1
drivers/char/drm/mga.h
drivers/char/drm/mga.h
+1
-1
drivers/char/drm/mga_dma.c
drivers/char/drm/mga_dma.c
+2
-10
drivers/char/drm/mga_drm.h
drivers/char/drm/mga_drm.h
+24
-11
drivers/char/drm/mga_drv.c
drivers/char/drm/mga_drv.c
+1
-0
drivers/char/drm/mga_drv.h
drivers/char/drm/mga_drv.h
+0
-1
drivers/char/drm/mga_irq.c
drivers/char/drm/mga_irq.c
+1
-1
drivers/char/drm/r128.h
drivers/char/drm/r128.h
+1
-1
drivers/char/drm/r128_cce.c
drivers/char/drm/r128_cce.c
+11
-39
drivers/char/drm/r128_drm.h
drivers/char/drm/r128_drm.h
+42
-19
drivers/char/drm/r128_drv.c
drivers/char/drm/r128_drv.c
+1
-0
drivers/char/drm/r128_drv.h
drivers/char/drm/r128_drv.h
+32
-26
drivers/char/drm/r128_irq.c
drivers/char/drm/r128_irq.c
+1
-1
drivers/char/drm/r128_state.c
drivers/char/drm/r128_state.c
+25
-9
drivers/char/drm/radeon.h
drivers/char/drm/radeon.h
+18
-4
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_cp.c
+22
-18
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drm.h
+74
-27
drivers/char/drm/radeon_drv.c
drivers/char/drm/radeon_drv.c
+1
-0
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_drv.h
+5
-1
drivers/char/drm/radeon_irq.c
drivers/char/drm/radeon_irq.c
+1
-1
drivers/char/drm/radeon_state.c
drivers/char/drm/radeon_state.c
+370
-42
drivers/char/drm/tdfx.h
drivers/char/drm/tdfx.h
+10
-0
drivers/char/drm/tdfx_drv.c
drivers/char/drm/tdfx_drv.c
+0
-41
No files found.
drivers/char/drm/drm.h
View file @
4c6b5945
...
...
@@ -46,8 +46,8 @@
#define DRM_IOC_WRITE _IOC_WRITE
#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
#if defined(__FreeBSD__) && defined(
XFree86Server
)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|| defined(__OpenBSD__)
#if defined(__FreeBSD__) && defined(
IN_MODULE
)
/* Prevent name collision when including sys/ioccom.h */
#undef ioctl
#include <sys/ioccom.h>
...
...
@@ -130,6 +130,18 @@ typedef struct drm_tex_region {
unsigned
int
age
;
}
drm_tex_region_t
;
/**
* Hardware lock.
*
* The lock structure is a simple cache-line aligned integer. To avoid
* processor bus contention on a multiprocessor system, there should not be any
* other data stored in the same cache line.
*/
typedef
struct
drm_hw_lock
{
__volatile__
unsigned
int
lock
;
/**< lock variable */
char
padding
[
60
];
/**< Pad to cache line */
}
drm_hw_lock_t
;
/**
* DRM_IOCTL_VERSION ioctl argument type.
...
...
@@ -580,6 +592,16 @@ typedef struct drm_scatter_gather {
unsigned
long
handle
;
/**< Used for mapping / unmapping */
}
drm_scatter_gather_t
;
/**
* DRM_IOCTL_SET_VERSION ioctl argument type.
*/
typedef
struct
drm_set_version
{
int
drm_di_major
;
int
drm_di_minor
;
int
drm_dd_major
;
int
drm_dd_minor
;
}
drm_set_version_t
;
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
...
...
@@ -594,6 +616,7 @@ typedef struct drm_scatter_gather {
#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t)
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, drm_set_version_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
...
...
drivers/char/drm/drmP.h
View file @
4c6b5945
...
...
@@ -92,8 +92,8 @@
#ifndef __HAVE_DMA
#define __HAVE_DMA 0
#endif
#ifndef __HAVE_
DMA_
IRQ
#define __HAVE_
DMA_
IRQ 0
#ifndef __HAVE_IRQ
#define __HAVE_IRQ 0
#endif
#ifndef __HAVE_DMA_WAITLIST
#define __HAVE_DMA_WAITLIST 0
...
...
@@ -148,6 +148,7 @@
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
#define DRM_MEM_SGLISTS 20
#define DRM_MEM_CTXLIST 21
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
...
...
@@ -324,6 +325,7 @@ do { \
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
/**
* Get the private SAREA mapping.
*
...
...
@@ -362,11 +364,6 @@ do { \
typedef
int
drm_ioctl_t
(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
);
typedef
struct
drm_pci_list
{
u16
vendor
;
u16
device
;
}
drm_pci_list_t
;
typedef
struct
drm_ioctl_desc
{
drm_ioctl_t
*
func
;
int
auth_needed
;
...
...
@@ -463,18 +460,6 @@ typedef struct drm_buf_entry {
drm_freelist_t
freelist
;
}
drm_buf_entry_t
;
/**
* Hardware lock.
*
* The lock structure is a simple cache-line aligned integer. To avoid
* processor bus contention on a multiprocessor system, there should not be any
* other data stored in the same cache line.
*/
typedef
struct
drm_hw_lock
{
__volatile__
unsigned
int
lock
;
/**< lock variable */
char
padding
[
60
];
/**< Pad to cache line */
}
drm_hw_lock_t
;
/** File private data */
typedef
struct
drm_file
{
int
authenticated
;
...
...
@@ -488,6 +473,9 @@ typedef struct drm_file {
struct
drm_device
*
dev
;
int
remove_auth_on_close
;
unsigned
long
lock_count
;
#ifdef DRIVER_FILE_FIELDS
DRIVER_FILE_FIELDS
;
#endif
}
drm_file_t
;
/** Wait queue */
...
...
@@ -602,6 +590,15 @@ typedef struct drm_map_list {
typedef
drm_map_t
drm_local_map_t
;
/**
* Context handle list
*/
typedef
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
;
#if __HAVE_VBL_IRQ
typedef
struct
drm_vbl_sig
{
...
...
@@ -622,6 +619,8 @@ typedef struct drm_device {
int
unique_len
;
/**< Length of unique field */
dev_t
device
;
/**< Device number for mknod */
char
*
devname
;
/**< For /proc/interrupts */
int
minor
;
/**< Minor device number */
int
if_version
;
/**< Highest interface version set */
int
blocked
;
/**< Blocked due to VC switch? */
struct
proc_dir_entry
*
root
;
/**< Root for this device's entries */
...
...
@@ -660,6 +659,12 @@ typedef struct drm_device {
drm_map_list_t
*
maplist
;
/**< Linked list of regions */
int
map_count
;
/**< Number of mappable regions */
/** \name Context handle management */
/*@{*/
drm_ctx_list_t
*
ctxlist
;
/**< Linked list of context handles */
int
ctx_count
;
/**< Number of context handles */
struct
semaphore
ctxlist_sem
;
/**< For ctxlist */
drm_map_t
**
context_sareas
;
/**< per-context SAREA's */
int
max_context
;
...
...
@@ -679,6 +684,7 @@ typedef struct drm_device {
/** \name Context support */
/*@{*/
int
irq
;
/**< Interrupt used by board */
int
irq_enabled
;
/**< True if irq handler is enabled */
__volatile__
long
context_flag
;
/**< Context swapping flag */
__volatile__
long
interrupt_flag
;
/**< Interruption handler flag */
__volatile__
long
dma_flag
;
/**< DMA dispatch flag */
...
...
@@ -714,7 +720,12 @@ typedef struct drm_device {
#if __REALLY_HAVE_AGP
drm_agp_head_t
*
agp
;
/**< AGP data */
#endif
struct
pci_dev
*
pdev
;
/**< PCI device structure */
struct
pci_dev
*
pdev
;
/**< PCI device structure */
int
pci_domain
;
/**< PCI bus domain number */
int
pci_bus
;
/**< PCI bus number */
int
pci_slot
;
/**< PCI slot number */
int
pci_func
;
/**< PCI function number */
#ifdef __alpha__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
struct
pci_controler
*
hose
;
...
...
@@ -758,18 +769,6 @@ extern int DRM(flush)(struct file *filp);
extern
int
DRM
(
fasync
)(
int
fd
,
struct
file
*
filp
,
int
on
);
/* Mapping support (drm_vm.h) */
extern
struct
page
*
DRM
(
vm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
);
extern
struct
page
*
DRM
(
vm_shm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
);
extern
struct
page
*
DRM
(
vm_dma_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
);
extern
struct
page
*
DRM
(
vm_sg_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
);
extern
void
DRM
(
vm_open
)(
struct
vm_area_struct
*
vma
);
extern
void
DRM
(
vm_close
)(
struct
vm_area_struct
*
vma
);
extern
void
DRM
(
vm_shm_close
)(
struct
vm_area_struct
*
vma
);
...
...
@@ -804,8 +803,8 @@ extern int DRM(unbind_agp)(DRM_AGP_MEM *handle);
#endif
/* Misc. IOCTL support (drm_ioctl.h) */
extern
int
DRM
(
irq_busid
)(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
);
extern
int
DRM
(
irq_b
y_b
usid
)(
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
,
...
...
@@ -816,6 +815,8 @@ 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
);
/* Context IOCTL support (drm_context.h) */
extern
int
DRM
(
resctx
)(
struct
inode
*
inode
,
struct
file
*
filp
,
...
...
@@ -900,12 +901,17 @@ 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
(
reclaim_buffers
)(
struct
file
*
filp
);
#if __HAVE_DMA_IRQ
#endif
/* __HAVE_DMA */
/* IRQ support (drm_irq.h) */
#if __HAVE_IRQ || __HAVE_DMA
extern
int
DRM
(
control
)(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
);
extern
int
DRM
(
irq_install
)(
drm_device_t
*
dev
,
int
irq
);
#endif
#if __HAVE_IRQ
extern
int
DRM
(
irq_install
)(
drm_device_t
*
dev
);
extern
int
DRM
(
irq_uninstall
)(
drm_device_t
*
dev
);
extern
irqreturn_t
DRM
(
dma_service
)(
DRM_IRQ_ARGS
);
extern
irqreturn_t
DRM
(
irq_handler
)(
DRM_IRQ_ARGS
);
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
);
...
...
@@ -915,12 +921,11 @@ extern int DRM(wait_vblank)(struct inode *inode, struct file *filp,
extern
int
DRM
(
vblank_wait
)(
drm_device_t
*
dev
,
unsigned
int
*
vbl_seq
);
extern
void
DRM
(
vbl_send_signals
)(
drm_device_t
*
dev
);
#endif
#if __HAVE_
DMA_
IRQ_BH
extern
void
DRM
(
dma
_immediate_bh
)(
void
*
dev
);
#if __HAVE_IRQ_BH
extern
void
DRM
(
irq
_immediate_bh
)(
void
*
dev
);
#endif
#endif
#endif
/* __HAVE_DMA */
#if __REALLY_HAVE_AGP
/* AGP/GART support (drm_agpsupport.h) */
...
...
drivers/char/drm/drm_agpsupport.h
View file @
4c6b5945
...
...
@@ -103,7 +103,13 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t
*
dev
=
priv
->
dev
;
int
retcode
;
if
(
!
dev
->
agp
||
dev
->
agp
->
acquired
||
!
drm_agp
->
acquire
)
if
(
!
dev
->
agp
)
return
-
ENODEV
;
if
(
dev
->
agp
->
acquired
)
return
-
EBUSY
;
if
(
!
drm_agp
->
acquire
)
return
-
EINVAL
;
if
(
dev
->
agp
->
cant_use_aperture
)
return
-
EINVAL
;
if
((
retcode
=
drm_agp
->
acquire
()))
return
retcode
;
...
...
drivers/char/drm/drm_bufs.h
View file @
4c6b5945
...
...
@@ -147,7 +147,9 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
MTRR_TYPE_WRCOMB
,
1
);
}
#endif
map
->
handle
=
DRM
(
ioremap
)(
map
->
offset
,
map
->
size
,
dev
);
if
(
map
->
type
==
_DRM_REGISTERS
)
map
->
handle
=
DRM
(
ioremap
)(
map
->
offset
,
map
->
size
,
dev
);
break
;
case
_DRM_SHM
:
...
...
@@ -160,6 +162,12 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
}
map
->
offset
=
(
unsigned
long
)
map
->
handle
;
if
(
map
->
flags
&
_DRM_CONTAINS_LOCK
)
{
/* Prevent a 2nd X Server from creating a 2nd lock */
if
(
dev
->
lock
.
hw_lock
!=
NULL
)
{
vfree
(
map
->
handle
);
DRM
(
free
)(
map
,
sizeof
(
*
map
),
DRM_MEM_MAPS
);
return
-
EBUSY
;
}
dev
->
sigdata
.
lock
=
dev
->
lock
.
hw_lock
=
map
->
handle
;
/* Pointer to lock */
}
...
...
@@ -767,7 +775,7 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
}
#endif
/* __HAVE_PCI_DMA */
#if
def
__HAVE_SG
#if __HAVE_SG
int
DRM
(
addbufs_sg
)(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
...
...
drivers/char/drm/drm_context.h
View file @
4c6b5945
...
...
@@ -401,6 +401,7 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
{
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_ctx_list_t
*
ctx_entry
;
drm_ctx_t
ctx
;
if
(
copy_from_user
(
&
ctx
,
(
drm_ctx_t
*
)
arg
,
sizeof
(
ctx
)
)
)
...
...
@@ -421,6 +422,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
if
(
ctx
.
handle
!=
DRM_KERNEL_CONTEXT
)
DRIVER_CTX_CTOR
(
ctx
.
handle
);
/* XXX: also pass dev ? */
#endif
ctx_entry
=
DRM
(
alloc
)(
sizeof
(
*
ctx_entry
),
DRM_MEM_CTXLIST
);
if
(
!
ctx_entry
)
{
DRM_DEBUG
(
"out of memory
\n
"
);
return
-
ENOMEM
;
}
INIT_LIST_HEAD
(
&
ctx_entry
->
head
);
ctx_entry
->
handle
=
ctx
.
handle
;
ctx_entry
->
tag
=
priv
;
down
(
&
dev
->
ctxlist_sem
);
list_add
(
&
ctx_entry
->
head
,
&
dev
->
ctxlist
->
head
);
++
dev
->
ctx_count
;
up
(
&
dev
->
ctxlist_sem
);
if
(
copy_to_user
(
(
drm_ctx_t
*
)
arg
,
&
ctx
,
sizeof
(
ctx
)
)
)
return
-
EFAULT
;
...
...
@@ -543,6 +558,20 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
DRM
(
ctxbitmap_free
)(
dev
,
ctx
.
handle
);
}
down
(
&
dev
->
ctxlist_sem
);
if
(
!
list_empty
(
&
dev
->
ctxlist
->
head
)
)
{
drm_ctx_list_t
*
pos
,
*
n
;
list_for_each_entry_safe
(
pos
,
n
,
&
dev
->
ctxlist
->
head
,
head
)
{
if
(
pos
->
handle
==
ctx
.
handle
)
{
list_del
(
&
pos
->
head
);
DRM
(
free
)(
pos
,
sizeof
(
*
pos
),
DRM_MEM_CTXLIST
);
--
dev
->
ctx_count
;
}
}
}
up
(
&
dev
->
ctxlist_sem
);
return
0
;
}
...
...
drivers/char/drm/drm_dma.h
View file @
4c6b5945
...
...
@@ -35,7 +35,6 @@
#include "drmP.h"
#include <linux/interrupt.h>
/* For task queue support */
#ifndef __HAVE_DMA_WAITQUEUE
#define __HAVE_DMA_WAITQUEUE 0
...
...
@@ -43,15 +42,6 @@
#ifndef __HAVE_DMA_RECLAIM
#define __HAVE_DMA_RECLAIM 0
#endif
#ifndef __HAVE_SHARED_IRQ
#define __HAVE_SHARED_IRQ 0
#endif
#if __HAVE_SHARED_IRQ
#define DRM_IRQ_TYPE SA_SHIRQ
#else
#define DRM_IRQ_TYPE 0
#endif
#if __HAVE_DMA
...
...
@@ -214,293 +204,11 @@ void DRM(reclaim_buffers)( struct file *filp )
}
#endif
#if __HAVE_DMA_IRQ
/**
* Install IRQ handler.
*
* \param dev DRM device.
* \param irq IRQ number.
*
* Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
* \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions
* before and after the installation.
*/
int
DRM
(
irq_install
)(
drm_device_t
*
dev
,
int
irq
)
{
int
ret
;
if
(
!
irq
)
return
-
EINVAL
;
down
(
&
dev
->
struct_sem
);
/* Driver must have been initialized */
if
(
!
dev
->
dev_private
)
{
up
(
&
dev
->
struct_sem
);
return
-
EINVAL
;
}
if
(
dev
->
irq
)
{
up
(
&
dev
->
struct_sem
);
return
-
EBUSY
;
}
dev
->
irq
=
irq
;
up
(
&
dev
->
struct_sem
);
DRM_DEBUG
(
"%s: irq=%d
\n
"
,
__FUNCTION__
,
irq
);
dev
->
context_flag
=
0
;
dev
->
interrupt_flag
=
0
;
dev
->
dma_flag
=
0
;
dev
->
dma
->
next_buffer
=
NULL
;
dev
->
dma
->
next_queue
=
NULL
;
dev
->
dma
->
this_buffer
=
NULL
;
#if __HAVE_DMA_IRQ_BH
INIT_WORK
(
&
dev
->
work
,
DRM
(
dma_immediate_bh
),
dev
);
#endif
#if __HAVE_VBL_IRQ
init_waitqueue_head
(
&
dev
->
vbl_queue
);
spin_lock_init
(
&
dev
->
vbl_lock
);
INIT_LIST_HEAD
(
&
dev
->
vbl_sigs
.
head
);
dev
->
vbl_pending
=
0
;
#endif
/* Before installing handler */
DRM
(
driver_irq_preinstall
)(
dev
);
/* Install handler */
ret
=
request_irq
(
dev
->
irq
,
DRM
(
dma_service
),
DRM_IRQ_TYPE
,
dev
->
devname
,
dev
);
if
(
ret
<
0
)
{
down
(
&
dev
->
struct_sem
);
dev
->
irq
=
0
;
up
(
&
dev
->
struct_sem
);
return
ret
;
}
/* After installing handler */
DRM
(
driver_irq_postinstall
)(
dev
);
return
0
;
}
/**
* Uninstall the IRQ handler.
*
* \param dev DRM device.
*
* Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq.
*/
int
DRM
(
irq_uninstall
)(
drm_device_t
*
dev
)
{
int
irq
;
down
(
&
dev
->
struct_sem
);
irq
=
dev
->
irq
;
dev
->
irq
=
0
;
up
(
&
dev
->
struct_sem
);
if
(
!
irq
)
return
-
EINVAL
;
DRM_DEBUG
(
"%s: irq=%d
\n
"
,
__FUNCTION__
,
irq
);
DRM
(
driver_irq_uninstall
)(
dev
);
free_irq
(
irq
,
dev
);
return
0
;
}
/**
* IRQ control ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \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
)
{
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_control_t
ctl
;
if
(
copy_from_user
(
&
ctl
,
(
drm_control_t
*
)
arg
,
sizeof
(
ctl
)
)
)
return
-
EFAULT
;
switch
(
ctl
.
func
)
{
case
DRM_INST_HANDLER
:
return
DRM
(
irq_install
)(
dev
,
ctl
.
irq
);
case
DRM_UNINST_HANDLER
:
return
DRM
(
irq_uninstall
)(
dev
);
default:
return
-
EINVAL
;
}
}
#if __HAVE_VBL_IRQ
/**
* Wait for VBLANK.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
* Verifies the IRQ is installed.
*
* If a signal is requested checks if this task has already scheduled the same signal
* for the same vblank sequence number - nothing to be done in
* that case. If the number of tasks waiting for the interrupt exceeds 100 the
* function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
* task.
*
* If a signal is not requested, then calls vblank_wait().
#if !__HAVE_IRQ
/* This stub DRM_IOCTL_CONTROL handler is for the drivers that used to require
* IRQs for DMA but no longer do. It maintains compatibility with the X Servers
* that try to use the control ioctl by simply returning success.
*/
int
DRM
(
wait_vblank
)(
DRM_IOCTL_ARGS
)
{
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_wait_vblank_t
vblwait
;
struct
timeval
now
;
int
ret
=
0
;
unsigned
int
flags
;
if
(
!
dev
->
irq
)
return
-
EINVAL
;
DRM_COPY_FROM_USER_IOCTL
(
vblwait
,
(
drm_wait_vblank_t
*
)
data
,
sizeof
(
vblwait
)
);
switch
(
vblwait
.
request
.
type
&
~
_DRM_VBLANK_FLAGS_MASK
)
{
case
_DRM_VBLANK_RELATIVE
:
vblwait
.
request
.
sequence
+=
atomic_read
(
&
dev
->
vbl_received
);
vblwait
.
request
.
type
&=
~
_DRM_VBLANK_RELATIVE
;
case
_DRM_VBLANK_ABSOLUTE
:
break
;
default:
return
-
EINVAL
;
}
flags
=
vblwait
.
request
.
type
&
_DRM_VBLANK_FLAGS_MASK
;
if
(
flags
&
_DRM_VBLANK_SIGNAL
)
{
unsigned
long
irqflags
;
drm_vbl_sig_t
*
vbl_sig
;
vblwait
.
reply
.
sequence
=
atomic_read
(
&
dev
->
vbl_received
);
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
irqflags
);
/* Check if this task has already scheduled the same signal
* for the same vblank sequence number; nothing to be done in
* that case
*/
list_for_each_entry
(
vbl_sig
,
&
dev
->
vbl_sigs
.
head
,
head
)
{
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
);
goto
done
;
}
}
if
(
dev
->
vbl_pending
>=
100
)
{
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
return
-
EBUSY
;
}
dev
->
vbl_pending
++
;
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
if
(
!
(
vbl_sig
=
DRM_MALLOC
(
sizeof
(
drm_vbl_sig_t
)
)
)
)
{
return
-
ENOMEM
;
}
memset
(
(
void
*
)
vbl_sig
,
0
,
sizeof
(
*
vbl_sig
)
);
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
);
list_add_tail
(
(
struct
list_head
*
)
vbl_sig
,
&
dev
->
vbl_sigs
.
head
);
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
}
else
{
ret
=
DRM
(
vblank_wait
)(
dev
,
&
vblwait
.
request
.
sequence
);
do_gettimeofday
(
&
now
);
vblwait
.
reply
.
tval_sec
=
now
.
tv_sec
;
vblwait
.
reply
.
tval_usec
=
now
.
tv_usec
;
}
done:
DRM_COPY_TO_USER_IOCTL
(
(
drm_wait_vblank_t
*
)
data
,
vblwait
,
sizeof
(
vblwait
)
);
return
ret
;
}
/**
* Send the VBLANK signals.
*
* \param dev DRM device.
*
* Sends a signal for each task in drm_device::vbl_sigs and empties the list.
*
* If a signal is not requested, then calls vblank_wait().
*/
void
DRM
(
vbl_send_signals
)(
drm_device_t
*
dev
)
{
struct
list_head
*
list
,
*
tmp
;
drm_vbl_sig_t
*
vbl_sig
;
unsigned
int
vbl_seq
=
atomic_read
(
&
dev
->
vbl_received
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
flags
);
list_for_each_safe
(
list
,
tmp
,
&
dev
->
vbl_sigs
.
head
)
{
vbl_sig
=
list_entry
(
list
,
drm_vbl_sig_t
,
head
);
if
(
(
vbl_seq
-
vbl_sig
->
sequence
)
<=
(
1
<<
23
)
)
{
vbl_sig
->
info
.
si_code
=
vbl_seq
;
send_sig_info
(
vbl_sig
->
info
.
si_signo
,
&
vbl_sig
->
info
,
vbl_sig
->
task
);
list_del
(
list
);
DRM_FREE
(
vbl_sig
,
sizeof
(
*
vbl_sig
)
);
dev
->
vbl_pending
--
;
}
}
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
flags
);
}
#endif
/* __HAVE_VBL_IRQ */
#else
int
DRM
(
control
)(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
...
...
@@ -517,7 +225,6 @@ int DRM(control)( struct inode *inode, struct file *filp,
return
-
EINVAL
;
}
}
#endif
/* __HAVE_DMA_IRQ */
#endif
#endif
/* __HAVE_DMA */
drivers/char/drm/drm_drv.h
View file @
4c6b5945
...
...
@@ -58,8 +58,8 @@
#ifndef __HAVE_CTX_BITMAP
#define __HAVE_CTX_BITMAP 0
#endif
#ifndef __HAVE_
DMA_
IRQ
#define __HAVE_
DMA_
IRQ 0
#ifndef __HAVE_IRQ
#define __HAVE_IRQ 0
#endif
#ifndef __HAVE_DMA_QUEUE
#define __HAVE_DMA_QUEUE 0
...
...
@@ -126,6 +126,9 @@
#ifndef DRIVER_IOCTLS
#define DRIVER_IOCTLS
#endif
#ifndef DRIVER_OPEN_HELPER
#define DRIVER_OPEN_HELPER( priv, dev )
#endif
#ifndef DRIVER_FOPS
#define DRIVER_FOPS \
static struct file_operations DRM(fops) = { \
...
...
@@ -159,15 +162,8 @@ __setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
#undef DRM_OPTIONS_FUNC
#endif
/**
* The default number of instances (minor numbers) to initialize.
*/
#ifndef DRIVER_NUM_CARDS
#define DRIVER_NUM_CARDS 1
#endif
static
drm_device_t
*
DRM
(
device
);
static
int
*
DRM
(
minor
);
#define MAX_DEVICES 4
static
drm_device_t
DRM
(
device
)[
MAX_DEVICES
];
static
int
DRM
(
numdevs
)
=
0
;
DRIVER_FOPS
;
...
...
@@ -177,10 +173,13 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[
DRM_IOCTL_NR
(
DRM_IOCTL_VERSION
)]
=
{
DRM
(
version
),
0
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_UNIQUE
)]
=
{
DRM
(
getunique
),
0
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_MAGIC
)]
=
{
DRM
(
getmagic
),
0
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_IRQ_BUSID
)]
=
{
DRM
(
irq_busid
),
0
,
1
},
#if __HAVE_IRQ
[
DRM_IOCTL_NR
(
DRM_IOCTL_IRQ_BUSID
)]
=
{
DRM
(
irq_by_busid
),
0
,
1
},
#endif
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_MAP
)]
=
{
DRM
(
getmap
),
0
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_CLIENT
)]
=
{
DRM
(
getclient
),
0
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_STATS
)]
=
{
DRM
(
getstats
),
0
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_SET_VERSION
)]
=
{
DRM
(
setversion
),
0
,
1
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_SET_UNIQUE
)]
=
{
DRM
(
setunique
),
1
,
1
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_BLOCK
)]
=
{
DRM
(
noop
),
1
,
1
},
...
...
@@ -222,9 +221,9 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[
DRM_IOCTL_NR
(
DRM_IOCTL_INFO_BUFS
)]
=
{
DRM
(
infobufs
),
1
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_MAP_BUFS
)]
=
{
DRM
(
mapbufs
),
1
,
0
},
[
DRM_IOCTL_NR
(
DRM_IOCTL_FREE_BUFS
)]
=
{
DRM
(
freebufs
),
1
,
0
},
/* The DRM_IOCTL_DMA ioctl should be defined by the driver.
*/
/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
#endif
#if __HAVE_IRQ || __HAVE_DMA
[
DRM_IOCTL_NR
(
DRM_IOCTL_CONTROL
)]
=
{
DRM
(
control
),
1
,
1
},
#endif
...
...
@@ -330,6 +329,12 @@ static int DRM(setup)( drm_device_t *dev )
memset
(
dev
->
maplist
,
0
,
sizeof
(
*
dev
->
maplist
));
INIT_LIST_HEAD
(
&
dev
->
maplist
->
head
);
dev
->
ctxlist
=
DRM
(
alloc
)(
sizeof
(
*
dev
->
ctxlist
),
DRM_MEM_CTXLIST
);
if
(
dev
->
ctxlist
==
NULL
)
return
-
ENOMEM
;
memset
(
dev
->
ctxlist
,
0
,
sizeof
(
*
dev
->
ctxlist
));
INIT_LIST_HEAD
(
&
dev
->
ctxlist
->
head
);
dev
->
vmalist
=
NULL
;
dev
->
sigdata
.
lock
=
dev
->
lock
.
hw_lock
=
NULL
;
init_waitqueue_head
(
&
dev
->
lock
.
lock_queue
);
...
...
@@ -337,7 +342,7 @@ static int DRM(setup)( drm_device_t *dev )
dev
->
queue_reserved
=
0
;
dev
->
queue_slots
=
0
;
dev
->
queuelist
=
NULL
;
dev
->
irq
=
0
;
dev
->
irq
_enabled
=
0
;
dev
->
context_flag
=
0
;
dev
->
interrupt_flag
=
0
;
dev
->
dma_flag
=
0
;
...
...
@@ -345,6 +350,7 @@ static int DRM(setup)( drm_device_t *dev )
dev
->
last_switch
=
0
;
dev
->
last_checked
=
0
;
init_waitqueue_head
(
&
dev
->
context_wait
);
dev
->
if_version
=
0
;
dev
->
ctx_start
=
0
;
dev
->
lck_start
=
0
;
...
...
@@ -391,8 +397,8 @@ static int DRM(takedown)( drm_device_t *dev )
DRM_DEBUG
(
"
\n
"
);
DRIVER_PRETAKEDOWN
();
#if __HAVE_
DMA_
IRQ
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
#if __HAVE_IRQ
if
(
dev
->
irq
_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
down
(
&
dev
->
struct_sem
);
...
...
@@ -534,43 +540,104 @@ static int DRM(takedown)( drm_device_t *dev )
return
0
;
}
/**
* Figure out how many instances to initialize.
*
* \return number of cards found.
*
* Searches for every PCI card in \c DRIVER_CARD_LIST with matching vendor and device ids.
*/
static
int
drm_count_cards
(
void
)
#include "drm_pciids.h"
static
struct
pci_device_id
DRM
(
pciidlist
)[]
=
{
DRM
(
PCI_IDS
)
};
static
int
DRM
(
probe
)(
struct
pci_dev
*
pdev
)
{
int
num
=
0
;
#if defined(DRIVER_CARD_LIST)
int
i
;
drm_pci_list_t
*
l
;
u16
device
,
vendor
;
struct
pci_dev
*
pdev
=
NULL
;
drm_device_t
*
dev
;
#if __HAVE_CTX_BITMAP
int
retcode
;
#endif
int
i
;
int
is_compat
=
0
;
DRM_DEBUG
(
"
\n
"
);
#if defined(DRIVER_COUNT_CARDS)
num
=
DRIVER_COUNT_CARDS
();
#elif defined(DRIVER_CARD_LIST)
for
(
i
=
0
,
l
=
DRIVER_CARD_LIST
;
l
[
i
].
vendor
!=
0
;
i
++
)
{
pdev
=
NULL
;
vendor
=
l
[
i
].
vendor
;
device
=
l
[
i
].
device
;
if
(
device
==
0xffff
)
device
=
PCI_ANY_ID
;
if
(
vendor
==
0xffff
)
vendor
=
PCI_ANY_ID
;
while
((
pdev
=
pci_find_device
(
vendor
,
device
,
pdev
)))
{
num
++
;
for
(
i
=
0
;
DRM
(
pciidlist
)[
i
].
vendor
!=
0
;
i
++
)
{
if
((
DRM
(
pciidlist
)[
i
].
vendor
==
pdev
->
vendor
)
&&
(
DRM
(
pciidlist
)[
i
].
device
==
pdev
->
device
))
{
is_compat
=
1
;
}
}
if
(
is_compat
==
0
)
return
-
ENODEV
;
if
(
DRM
(
numdevs
)
>=
MAX_DEVICES
)
return
-
ENODEV
;
dev
=
&
(
DRM
(
device
)[
DRM
(
numdevs
)]);
memset
(
(
void
*
)
dev
,
0
,
sizeof
(
*
dev
)
);
dev
->
count_lock
=
SPIN_LOCK_UNLOCKED
;
init_timer
(
&
dev
->
timer
);
sema_init
(
&
dev
->
struct_sem
,
1
);
sema_init
(
&
dev
->
ctxlist_sem
,
1
);
if
((
dev
->
minor
=
DRM
(
stub_register
)(
DRIVER_NAME
,
&
DRM
(
fops
),
dev
))
<
0
)
return
-
EPERM
;
dev
->
device
=
MKDEV
(
DRM_MAJOR
,
dev
->
minor
);
dev
->
name
=
DRIVER_NAME
;
dev
->
pdev
=
pdev
;
#ifdef __alpha__
dev
->
hose
=
pdev
->
sysdata
;
dev
->
pci_domain
=
dev
->
hose
->
bus
->
number
;
#else
num
=
DRIVER_NUM_CARDS
;
dev
->
pci_domain
=
0
;
#endif
dev
->
pci_bus
=
pdev
->
bus
->
number
;
dev
->
pci_slot
=
PCI_SLOT
(
pdev
->
devfn
);
dev
->
pci_func
=
PCI_FUNC
(
pdev
->
devfn
);
dev
->
irq
=
pdev
->
irq
;
DRIVER_PREINIT
();
#if __REALLY_HAVE_AGP
dev
->
agp
=
DRM
(
agp_init
)();
#if __MUST_HAVE_AGP
if
(
dev
->
agp
==
NULL
)
{
DRM_ERROR
(
"Cannot initialize the agpgart module.
\n
"
);
DRM
(
stub_unregister
)(
dev
->
minor
);
DRM
(
takedown
)(
dev
);
return
-
EINVAL
;
}
#endif
#if __REALLY_HAVE_MTRR
if
(
dev
->
agp
)
dev
->
agp
->
agp_mtrr
=
mtrr_add
(
dev
->
agp
->
agp_info
.
aper_base
,
dev
->
agp
->
agp_info
.
aper_size
*
1024
*
1024
,
MTRR_TYPE_WRCOMB
,
1
);
#endif
#endif
#if __HAVE_CTX_BITMAP
retcode
=
DRM
(
ctxbitmap_init
)(
dev
);
if
(
retcode
)
{
DRM_ERROR
(
"Cannot allocate memory for context bitmap.
\n
"
);
DRM
(
stub_unregister
)(
dev
->
minor
);
DRM
(
takedown
)(
dev
);
return
retcode
;
}
#endif
DRM_DEBUG
(
"numdevs = %d
\n
"
,
num
);
return
num
;
DRM
(
numdevs
)
++
;
/* no errors, mark it reserved */
DRM_INFO
(
"Initialized %s %d.%d.%d %s on minor %d: %s
\n
"
,
DRIVER_NAME
,
DRIVER_MAJOR
,
DRIVER_MINOR
,
DRIVER_PATCHLEVEL
,
DRIVER_DATE
,
dev
->
minor
,
pci_pretty_name
(
pdev
));
DRIVER_POSTINIT
();
return
0
;
}
/**
...
...
@@ -579,7 +646,7 @@ static int drm_count_cards(void)
*
* \return zero on success or a negative number on failure.
*
*
Allocates and initialize
an array of drm_device structures, and attempts to
*
Initializes
an array of drm_device structures, and attempts to
* initialize all available devices, using consecutive minors, registering the
* stubs and initializing the AGP device.
*
...
...
@@ -588,88 +655,19 @@ static int drm_count_cards(void)
*/
static
int
__init
drm_init
(
void
)
{
struct
pci_dev
*
pdev
=
NULL
;
drm_device_t
*
dev
;
int
i
;
#if __HAVE_CTX_BITMAP
int
retcode
;
#endif
DRM_DEBUG
(
"
\n
"
);
#ifdef MODULE
DRM
(
parse_options
)(
drm_opts
);
#endif
DRM
(
numdevs
)
=
drm_count_cards
();
/* Force at least one instance. */
if
(
DRM
(
numdevs
)
<=
0
)
DRM
(
numdevs
)
=
1
;
DRM
(
device
)
=
kmalloc
(
sizeof
(
*
DRM
(
device
))
*
DRM
(
numdevs
),
GFP_KERNEL
);
if
(
!
DRM
(
device
))
{
return
-
ENOMEM
;
}
DRM
(
minor
)
=
kmalloc
(
sizeof
(
*
DRM
(
minor
))
*
DRM
(
numdevs
),
GFP_KERNEL
);
if
(
!
DRM
(
minor
))
{
kfree
(
DRM
(
device
));
return
-
ENOMEM
;
}
DRIVER_PREINIT
();
DRM
(
mem_init
)();
for
(
i
=
0
;
i
<
DRM
(
numdevs
);
i
++
)
{
dev
=
&
(
DRM
(
device
)[
i
]);
memset
(
(
void
*
)
dev
,
0
,
sizeof
(
*
dev
)
);
dev
->
count_lock
=
SPIN_LOCK_UNLOCKED
;
init_timer
(
&
dev
->
timer
);
sema_init
(
&
dev
->
struct_sem
,
1
);
if
((
DRM
(
minor
)[
i
]
=
DRM
(
stub_register
)(
DRIVER_NAME
,
&
DRM
(
fops
),
dev
))
<
0
)
return
-
EPERM
;
dev
->
device
=
MKDEV
(
DRM_MAJOR
,
DRM
(
minor
)[
i
]
);
dev
->
name
=
DRIVER_NAME
;
#if __REALLY_HAVE_AGP
dev
->
agp
=
DRM
(
agp_init
)();
#if __MUST_HAVE_AGP
if
(
dev
->
agp
==
NULL
)
{
DRM_ERROR
(
"Cannot initialize the agpgart module.
\n
"
);
DRM
(
stub_unregister
)(
DRM
(
minor
)[
i
]);
DRM
(
takedown
)(
dev
);
return
-
EINVAL
;
}
#endif
#if __REALLY_HAVE_MTRR
if
(
dev
->
agp
)
dev
->
agp
->
agp_mtrr
=
mtrr_add
(
dev
->
agp
->
agp_info
.
aper_base
,
dev
->
agp
->
agp_info
.
aper_size
*
1024
*
1024
,
MTRR_TYPE_WRCOMB
,
1
);
#endif
#endif
#if __HAVE_CTX_BITMAP
retcode
=
DRM
(
ctxbitmap_init
)(
dev
);
if
(
retcode
)
{
DRM_ERROR
(
"Cannot allocate memory for context bitmap.
\n
"
);
DRM
(
stub_unregister
)(
DRM
(
minor
)[
i
]);
DRM
(
takedown
)(
dev
);
return
retcode
;
}
#endif
DRM_INFO
(
"Initialized %s %d.%d.%d %s on minor %d
\n
"
,
DRIVER_NAME
,
DRIVER_MAJOR
,
DRIVER_MINOR
,
DRIVER_PATCHLEVEL
,
DRIVER_DATE
,
DRM
(
minor
)[
i
]
);
while
((
pdev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
pdev
))
!=
NULL
)
{
DRM
(
probe
)(
pdev
);
}
DRIVER_POSTINIT
();
return
0
;
}
...
...
@@ -689,10 +687,10 @@ static void __exit drm_cleanup( void )
for
(
i
=
DRM
(
numdevs
)
-
1
;
i
>=
0
;
i
--
)
{
dev
=
&
(
DRM
(
device
)[
i
]);
if
(
DRM
(
stub_unregister
)(
DRM
(
minor
)[
i
]
)
)
{
if
(
DRM
(
stub_unregister
)(
dev
->
minor
)
)
{
DRM_ERROR
(
"Cannot unload module
\n
"
);
}
else
{
DRM_DEBUG
(
"minor %d unregistered
\n
"
,
DRM
(
minor
)[
i
]
);
DRM_DEBUG
(
"minor %d unregistered
\n
"
,
dev
->
minor
);
if
(
i
==
0
)
{
DRM_INFO
(
"Module unloaded
\n
"
);
}
...
...
@@ -722,8 +720,6 @@ static void __exit drm_cleanup( void )
#endif
}
DRIVER_POSTCLEANUP
();
kfree
(
DRM
(
minor
));
kfree
(
DRM
(
device
));
DRM
(
numdevs
)
=
0
;
}
...
...
@@ -795,7 +791,7 @@ int DRM(open)( struct inode *inode, struct file *filp )
int
i
;
for
(
i
=
0
;
i
<
DRM
(
numdevs
);
i
++
)
{
if
(
iminor
(
inode
)
==
DRM
(
minor
)[
i
]
)
{
if
(
iminor
(
inode
)
==
DRM
(
device
)[
i
].
minor
)
{
dev
=
&
(
DRM
(
device
)[
i
]);
break
;
}
...
...
@@ -908,6 +904,26 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM
(
fasync
)(
-
1
,
filp
,
0
);
down
(
&
dev
->
ctxlist_sem
);
if
(
!
list_empty
(
&
dev
->
ctxlist
->
head
)
)
{
drm_ctx_list_t
*
pos
,
*
n
;
list_for_each_entry_safe
(
pos
,
n
,
&
dev
->
ctxlist
->
head
,
head
)
{
if
(
pos
->
tag
==
priv
&&
pos
->
handle
!=
DRM_KERNEL_CONTEXT
)
{
#ifdef DRIVER_CTX_DTOR
DRIVER_CTX_DTOR
(
pos
->
handle
);
#endif
#if __HAVE_CTX_BITMAP
DRM
(
ctxbitmap_free
)(
dev
,
pos
->
handle
);
#endif
list_del
(
&
pos
->
head
);
DRM
(
free
)(
pos
,
sizeof
(
*
pos
),
DRM_MEM_CTXLIST
);
}
}
}
up
(
&
dev
->
ctxlist_sem
);
down
(
&
dev
->
struct_sem
);
if
(
priv
->
remove_auth_on_close
==
1
)
{
drm_file_t
*
temp
=
dev
->
file_first
;
...
...
drivers/char/drm/drm_fops.h
View file @
4c6b5945
...
...
@@ -72,6 +72,8 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
priv
->
authenticated
=
capable
(
CAP_SYS_ADMIN
);
priv
->
lock_count
=
0
;
DRIVER_OPEN_HELPER
(
priv
,
dev
);
down
(
&
dev
->
struct_sem
);
if
(
!
dev
->
file_last
)
{
priv
->
next
=
NULL
;
...
...
drivers/char/drm/drm_ioctl.h
View file @
4c6b5945
...
...
@@ -35,69 +35,7 @@
#include "drmP.h"
/**
* Get interrupt from bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_irq_busid structure.
* \return zero on success or a negative number on failure.
*
* Finds the PCI device with the specified bus id and gets its IRQ number.
*/
int
DRM
(
irq_busid
)(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_irq_busid_t
p
;
struct
pci_dev
*
dev
;
if
(
copy_from_user
(
&
p
,
(
drm_irq_busid_t
*
)
arg
,
sizeof
(
p
)))
return
-
EFAULT
;
#ifdef __alpha__
{
int
domain
=
p
.
busnum
>>
8
;
p
.
busnum
&=
0xff
;
/*
* Find the hose the device is on (the domain number is the
* hose index) and offset the bus by the root bus of that
* hose.
*/
for
(
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
NULL
);
dev
;
dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
dev
))
{
struct
pci_controller
*
hose
=
dev
->
sysdata
;
if
(
hose
->
index
==
domain
)
{
p
.
busnum
+=
hose
->
bus
->
number
;
break
;
}
}
}
#endif
dev
=
pci_find_slot
(
p
.
busnum
,
PCI_DEVFN
(
p
.
devnum
,
p
.
funcnum
));
if
(
!
dev
)
{
DRM_ERROR
(
"pci_find_slot failed for %d:%d:%d
\n
"
,
p
.
busnum
,
p
.
devnum
,
p
.
funcnum
);
p
.
irq
=
0
;
goto
out
;
}
if
(
pci_enable_device
(
dev
)
!=
0
)
{
DRM_ERROR
(
"pci_enable_device failed for %d:%d:%d
\n
"
,
p
.
busnum
,
p
.
devnum
,
p
.
funcnum
);
p
.
irq
=
0
;
goto
out
;
}
p
.
irq
=
dev
->
irq
;
out:
DRM_DEBUG
(
"%d:%d:%d => IRQ %d
\n
"
,
p
.
busnum
,
p
.
devnum
,
p
.
funcnum
,
p
.
irq
);
if
(
copy_to_user
((
drm_irq_busid_t
*
)
arg
,
&
p
,
sizeof
(
p
)))
return
-
EFAULT
;
return
0
;
}
#include "linux/pci.h"
/**
* Get the bus id.
...
...
@@ -138,8 +76,10 @@ int DRM(getunique)(struct inode *inode, struct file *filp,
* \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 userspace into drm_device::unique, and searches for
* the respective PCI device, updating drm_device::pdev.
* Copies the bus id from userspace into drm_device::unique, and verifies that
* it matches the device this DRM is attached to (EINVAL otherwise). Deprecated
* 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
)
...
...
@@ -147,6 +87,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_unique_t
u
;
int
domain
,
bus
,
slot
,
func
,
ret
;
if
(
dev
->
unique_len
||
dev
->
unique
)
return
-
EBUSY
;
...
...
@@ -164,55 +105,42 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
dev
->
devname
=
DRM
(
alloc
)(
strlen
(
dev
->
name
)
+
strlen
(
dev
->
unique
)
+
2
,
DRM_MEM_DRIVER
);
if
(
!
dev
->
devname
)
{
DRM
(
free
)(
dev
->
devname
,
sizeof
(
*
dev
->
devname
),
DRM_MEM_DRIVER
);
if
(
!
dev
->
devname
)
return
-
ENOMEM
;
}
sprintf
(
dev
->
devname
,
"%s@%s"
,
dev
->
name
,
dev
->
unique
);
do
{
struct
pci_dev
*
pci_dev
;
int
domain
,
b
,
d
,
f
;
char
*
p
;
for
(
p
=
dev
->
unique
;
p
&&
*
p
&&
*
p
!=
':'
;
p
++
);
if
(
!
p
||
!*
p
)
break
;
b
=
(
int
)
simple_strtoul
(
p
+
1
,
&
p
,
10
);
if
(
*
p
!=
':'
)
break
;
d
=
(
int
)
simple_strtoul
(
p
+
1
,
&
p
,
10
);
if
(
*
p
!=
':'
)
break
;
f
=
(
int
)
simple_strtoul
(
p
+
1
,
&
p
,
10
);
if
(
*
p
)
break
;
domain
=
b
>>
8
;
b
&=
0xff
;
#ifdef __alpha__
/*
* Find the hose the device is on (the domain number is the
* hose index) and offset the bus by the root bus of that
* hose.
*/
for
(
pci_dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
NULL
);
pci_dev
;
pci_dev
=
pci_find_device
(
PCI_ANY_ID
,
PCI_ANY_ID
,
pci_dev
))
{
struct
pci_controller
*
hose
=
pci_dev
->
sysdata
;
if
(
hose
->
index
==
domain
)
{
b
+=
hose
->
bus
->
number
;
break
;
}
}
#endif
/* Return error if the busid submitted doesn't match the device's actual
* busid.
*/
ret
=
sscanf
(
dev
->
unique
,
"PCI:%d:%d:%d"
,
&
bus
,
&
slot
,
&
func
);
if
(
ret
!=
3
)
return
DRM_ERR
(
EINVAL
);
domain
=
bus
>>
8
;
bus
&=
0xff
;
if
((
domain
!=
dev
->
pci_domain
)
||
(
bus
!=
dev
->
pci_bus
)
||
(
slot
!=
dev
->
pci_slot
)
||
(
func
!=
dev
->
pci_func
))
return
-
EINVAL
;
pci_dev
=
pci_find_slot
(
b
,
PCI_DEVFN
(
d
,
f
));
if
(
pci_dev
)
{
dev
->
pdev
=
pci_dev
;
#ifdef __alpha__
dev
->
hose
=
pci_dev
->
sysdata
;
#endif
}
}
while
(
0
);
return
0
;
}
static
int
DRM
(
set_busid
)(
drm_device_t
*
dev
)
{
if
(
dev
->
unique
!=
NULL
)
return
EBUSY
;
dev
->
unique_len
=
20
;
dev
->
unique
=
DRM
(
alloc
)(
dev
->
unique_len
+
1
,
DRM_MEM_DRIVER
);
if
(
dev
->
unique
==
NULL
)
return
ENOMEM
;
snprintf
(
dev
->
unique
,
dev
->
unique_len
,
"pci:%04x:%02x:%02x.%d"
,
dev
->
pci_domain
,
dev
->
pci_bus
,
dev
->
pci_slot
,
dev
->
pci_func
);
return
0
;
}
...
...
@@ -363,3 +291,47 @@ int DRM(getstats)( struct inode *inode, struct file *filp,
return
-
EFAULT
;
return
0
;
}
#define DRM_IF_MAJOR 1
#define DRM_IF_MINOR 2
int
DRM
(
setversion
)(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_set_version_t
sv
;
drm_set_version_t
retv
;
int
if_version
;
DRM_COPY_FROM_USER_IOCTL
(
sv
,
(
drm_set_version_t
*
)
data
,
sizeof
(
sv
));
retv
.
drm_di_major
=
DRM_IF_MAJOR
;
retv
.
drm_di_minor
=
DRM_IF_MINOR
;
retv
.
drm_dd_major
=
DRIVER_MAJOR
;
retv
.
drm_dd_minor
=
DRIVER_MINOR
;
DRM_COPY_TO_USER_IOCTL
((
drm_set_version_t
*
)
data
,
retv
,
sizeof
(
sv
));
if
(
sv
.
drm_di_major
!=
-
1
)
{
if
(
sv
.
drm_di_major
!=
DRM_IF_MAJOR
||
sv
.
drm_di_minor
<
0
||
sv
.
drm_di_minor
>
DRM_IF_MINOR
)
return
EINVAL
;
if_version
=
DRM_IF_VERSION
(
sv
.
drm_di_major
,
sv
.
drm_dd_minor
);
dev
->
if_version
=
DRM_MAX
(
if_version
,
dev
->
if_version
);
if
(
sv
.
drm_di_minor
>=
1
)
{
/*
* Version 1.1 includes tying of DRM to specific device
*/
DRM
(
set_busid
)(
dev
);
}
}
if
(
sv
.
drm_dd_major
!=
-
1
)
{
if
(
sv
.
drm_dd_major
!=
DRIVER_MAJOR
||
sv
.
drm_dd_minor
<
0
||
sv
.
drm_dd_minor
>
DRIVER_MINOR
)
return
EINVAL
;
#ifdef DRIVER_SETVERSION
DRIVER_SETVERSION
(
dev
,
&
sv
);
#endif
}
return
0
;
}
drivers/char/drm/drm_irq.h
0 → 100644
View file @
4c6b5945
/**
* \file drm_irq.h
* IRQ support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* 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, 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 NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS 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 <linux/interrupt.h>
/* For task queue support */
#ifndef __HAVE_SHARED_IRQ
#define __HAVE_SHARED_IRQ 0
#endif
#if __HAVE_SHARED_IRQ
#define DRM_IRQ_TYPE SA_SHIRQ
#else
#define DRM_IRQ_TYPE 0
#endif
/**
* Get interrupt from bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_irq_busid structure.
* \return zero on success or a negative number on failure.
*
* Finds the PCI device with the specified bus id and gets its IRQ number.
* 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
)
{
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_irq_busid_t
p
;
if
(
copy_from_user
(
&
p
,
(
drm_irq_busid_t
*
)
arg
,
sizeof
(
p
)))
return
-
EFAULT
;
if
((
p
.
busnum
>>
8
)
!=
dev
->
pci_domain
||
(
p
.
busnum
&
0xff
)
!=
dev
->
pci_bus
||
p
.
devnum
!=
dev
->
pci_slot
||
p
.
funcnum
!=
dev
->
pci_func
)
return
-
EINVAL
;
p
.
irq
=
dev
->
irq
;
DRM_DEBUG
(
"%d:%d:%d => IRQ %d
\n
"
,
p
.
busnum
,
p
.
devnum
,
p
.
funcnum
,
p
.
irq
);
if
(
copy_to_user
((
drm_irq_busid_t
*
)
arg
,
&
p
,
sizeof
(
p
)))
return
-
EFAULT
;
return
0
;
}
#if __HAVE_IRQ
/**
* Install IRQ handler.
*
* \param dev DRM device.
* \param irq IRQ number.
*
* Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
* \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions
* before and after the installation.
*/
int
DRM
(
irq_install
)(
drm_device_t
*
dev
)
{
int
ret
;
if
(
dev
->
irq
==
0
)
return
-
EINVAL
;
down
(
&
dev
->
struct_sem
);
/* Driver must have been initialized */
if
(
!
dev
->
dev_private
)
{
up
(
&
dev
->
struct_sem
);
return
-
EINVAL
;
}
if
(
dev
->
irq_enabled
)
{
up
(
&
dev
->
struct_sem
);
return
-
EBUSY
;
}
dev
->
irq_enabled
=
1
;
up
(
&
dev
->
struct_sem
);
DRM_DEBUG
(
"%s: irq=%d
\n
"
,
__FUNCTION__
,
dev
->
irq
);
#if __HAVE_DMA
dev
->
dma
->
next_buffer
=
NULL
;
dev
->
dma
->
next_queue
=
NULL
;
dev
->
dma
->
this_buffer
=
NULL
;
#endif
#if __HAVE_IRQ_BH
INIT_WORK
(
&
dev
->
work
,
DRM
(
irq_immediate_bh
),
dev
);
#endif
#if __HAVE_VBL_IRQ
init_waitqueue_head
(
&
dev
->
vbl_queue
);
spin_lock_init
(
&
dev
->
vbl_lock
);
INIT_LIST_HEAD
(
&
dev
->
vbl_sigs
.
head
);
dev
->
vbl_pending
=
0
;
#endif
/* Before installing handler */
DRM
(
driver_irq_preinstall
)(
dev
);
/* Install handler */
ret
=
request_irq
(
dev
->
irq
,
DRM
(
irq_handler
),
DRM_IRQ_TYPE
,
dev
->
devname
,
dev
);
if
(
ret
<
0
)
{
down
(
&
dev
->
struct_sem
);
dev
->
irq_enabled
=
0
;
up
(
&
dev
->
struct_sem
);
return
ret
;
}
/* After installing handler */
DRM
(
driver_irq_postinstall
)(
dev
);
return
0
;
}
/**
* Uninstall the IRQ handler.
*
* \param dev DRM device.
*
* Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq.
*/
int
DRM
(
irq_uninstall
)(
drm_device_t
*
dev
)
{
int
irq_enabled
;
down
(
&
dev
->
struct_sem
);
irq_enabled
=
dev
->
irq_enabled
;
dev
->
irq_enabled
=
0
;
up
(
&
dev
->
struct_sem
);
if
(
!
irq_enabled
)
return
-
EINVAL
;
DRM_DEBUG
(
"%s: irq=%d
\n
"
,
__FUNCTION__
,
dev
->
irq
);
DRM
(
driver_irq_uninstall
)(
dev
);
free_irq
(
dev
->
irq
,
dev
);
return
0
;
}
/**
* IRQ control ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \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
)
{
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_control_t
ctl
;
if
(
copy_from_user
(
&
ctl
,
(
drm_control_t
*
)
arg
,
sizeof
(
ctl
)
)
)
return
-
EFAULT
;
switch
(
ctl
.
func
)
{
case
DRM_INST_HANDLER
:
if
(
dev
->
if_version
<
DRM_IF_VERSION
(
1
,
2
)
&&
ctl
.
irq
!=
dev
->
irq
)
return
-
EINVAL
;
return
DRM
(
irq_install
)(
dev
);
case
DRM_UNINST_HANDLER
:
return
DRM
(
irq_uninstall
)(
dev
);
default:
return
-
EINVAL
;
}
}
#if __HAVE_VBL_IRQ
/**
* Wait for VBLANK.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
* Verifies the IRQ is installed.
*
* If a signal is requested checks if this task has already scheduled the same signal
* for the same vblank sequence number - nothing to be done in
* that case. If the number of tasks waiting for the interrupt exceeds 100 the
* function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
* task.
*
* If a signal is not requested, then calls vblank_wait().
*/
int
DRM
(
wait_vblank
)(
DRM_IOCTL_ARGS
)
{
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
dev
;
drm_wait_vblank_t
vblwait
;
struct
timeval
now
;
int
ret
=
0
;
unsigned
int
flags
;
if
(
!
dev
->
irq
)
return
-
EINVAL
;
DRM_COPY_FROM_USER_IOCTL
(
vblwait
,
(
drm_wait_vblank_t
*
)
data
,
sizeof
(
vblwait
)
);
switch
(
vblwait
.
request
.
type
&
~
_DRM_VBLANK_FLAGS_MASK
)
{
case
_DRM_VBLANK_RELATIVE
:
vblwait
.
request
.
sequence
+=
atomic_read
(
&
dev
->
vbl_received
);
vblwait
.
request
.
type
&=
~
_DRM_VBLANK_RELATIVE
;
case
_DRM_VBLANK_ABSOLUTE
:
break
;
default:
return
-
EINVAL
;
}
flags
=
vblwait
.
request
.
type
&
_DRM_VBLANK_FLAGS_MASK
;
if
(
flags
&
_DRM_VBLANK_SIGNAL
)
{
unsigned
long
irqflags
;
drm_vbl_sig_t
*
vbl_sig
;
vblwait
.
reply
.
sequence
=
atomic_read
(
&
dev
->
vbl_received
);
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
irqflags
);
/* Check if this task has already scheduled the same signal
* for the same vblank sequence number; nothing to be done in
* that case
*/
list_for_each_entry
(
vbl_sig
,
&
dev
->
vbl_sigs
.
head
,
head
)
{
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
);
goto
done
;
}
}
if
(
dev
->
vbl_pending
>=
100
)
{
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
return
-
EBUSY
;
}
dev
->
vbl_pending
++
;
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
if
(
!
(
vbl_sig
=
DRM_MALLOC
(
sizeof
(
drm_vbl_sig_t
)
)
)
)
{
return
-
ENOMEM
;
}
memset
(
(
void
*
)
vbl_sig
,
0
,
sizeof
(
*
vbl_sig
)
);
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
);
list_add_tail
(
(
struct
list_head
*
)
vbl_sig
,
&
dev
->
vbl_sigs
.
head
);
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
}
else
{
ret
=
DRM
(
vblank_wait
)(
dev
,
&
vblwait
.
request
.
sequence
);
do_gettimeofday
(
&
now
);
vblwait
.
reply
.
tval_sec
=
now
.
tv_sec
;
vblwait
.
reply
.
tval_usec
=
now
.
tv_usec
;
}
done:
DRM_COPY_TO_USER_IOCTL
(
(
drm_wait_vblank_t
*
)
data
,
vblwait
,
sizeof
(
vblwait
)
);
return
ret
;
}
/**
* Send the VBLANK signals.
*
* \param dev DRM device.
*
* Sends a signal for each task in drm_device::vbl_sigs and empties the list.
*
* If a signal is not requested, then calls vblank_wait().
*/
void
DRM
(
vbl_send_signals
)(
drm_device_t
*
dev
)
{
struct
list_head
*
list
,
*
tmp
;
drm_vbl_sig_t
*
vbl_sig
;
unsigned
int
vbl_seq
=
atomic_read
(
&
dev
->
vbl_received
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
flags
);
list_for_each_safe
(
list
,
tmp
,
&
dev
->
vbl_sigs
.
head
)
{
vbl_sig
=
list_entry
(
list
,
drm_vbl_sig_t
,
head
);
if
(
(
vbl_seq
-
vbl_sig
->
sequence
)
<=
(
1
<<
23
)
)
{
vbl_sig
->
info
.
si_code
=
vbl_seq
;
send_sig_info
(
vbl_sig
->
info
.
si_signo
,
&
vbl_sig
->
info
,
vbl_sig
->
task
);
list_del
(
list
);
DRM_FREE
(
vbl_sig
,
sizeof
(
*
vbl_sig
)
);
dev
->
vbl_pending
--
;
}
}
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
flags
);
}
#endif
/* __HAVE_VBL_IRQ */
#endif
/* __HAVE_IRQ */
drivers/char/drm/drm_memory_debug.h
View file @
4c6b5945
...
...
@@ -67,6 +67,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
[
DRM_MEM_TOTALAGP
]
=
{
"totalagp"
},
[
DRM_MEM_BOUNDAGP
]
=
{
"boundagp"
},
[
DRM_MEM_CTXBITMAP
]
=
{
"ctxbitmap"
},
[
DRM_MEM_CTXLIST
]
=
{
"ctxlist"
},
[
DRM_MEM_STUB
]
=
{
"stub"
},
{
NULL
,
0
,
}
/* Last entry must be null */
};
...
...
drivers/char/drm/drm_os_linux.h
View file @
4c6b5945
...
...
@@ -62,8 +62,12 @@
verify_area( VERIFY_READ, uaddr, size )
#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
__copy_from_user(arg1, arg2, arg3)
#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \
__copy_to_user(arg1, arg2, arg3)
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
__get_user(val, uaddr)
#define DRM_PUT_USER_UNCHECKED(uaddr, val) \
__put_user(val, uaddr)
/** 'malloc' without the overhead of DRM(alloc)() */
...
...
@@ -71,6 +75,8 @@
/** 'free' without the overhead of DRM(free)() */
#define DRM_FREE(x,size) kfree(x)
#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
/**
* Get the pointer to the SAREA.
*
...
...
drivers/char/drm/drm_pciids.h
0 → 100644
View file @
4c6b5945
/*
This file is auto-generated from the drm_pciids.txt in the DRM CVS
Please contact dri-devel@lists.sf.net to add new cards to this list
*/
#define radeon_PCI_IDS \
{0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define r128_PCI_IDS \
{0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4d46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5041, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5044, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5045, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5046, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5047, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5048, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5049, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5245, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5247, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x524b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x524c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x534d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define mga_PCI_IDS \
{0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define mach64_PCI_IDS \
{0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define sisdrv_PCI_IDS \
{0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define tdfx_PCI_IDS \
{0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define viadrv_PCI_IDS \
{0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define i810_PCI_IDS \
{0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define i830_PCI_IDS \
{0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define gamma_PCI_IDS \
{0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define savage_PCI_IDS \
{0x5333, 0x8a22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8a23, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c13, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c24, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8a25, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8d01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define ffb_PCI_IDS \
{0, 0, 0}
drivers/char/drm/drm_sarea.h
View file @
4c6b5945
...
...
@@ -32,9 +32,23 @@
#ifndef _DRM_SAREA_H_
#define _DRM_SAREA_H_
#include "drm.h"
/* SAREA area needs to be at least a page */
#if defined(__alpha__)
#define SAREA_MAX 0x2000
#elif defined(__ia64__)
#define SAREA_MAX 0x10000
/* 64kB */
#else
/* Intel 830M driver needs at least 8k SAREA */
#define SAREA_MAX 0x2000
#endif
/** Maximum number of drawables in the SAREA */
#define SAREA_MAX_DRAWABLES 256
#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000
/** SAREA drawable */
typedef
struct
drm_sarea_drawable
{
unsigned
int
stamp
;
...
...
drivers/char/drm/drm_stub.h
View file @
4c6b5945
...
...
@@ -209,8 +209,8 @@ int DRM(stub_register)(const char *name, struct file_operations *fops,
ret2
=
DRM
(
stub_info
).
info_register
(
name
,
fops
,
dev
);
if
(
ret2
)
{
if
(
!
ret1
)
{
unregister_chrdev
(
DRM_MAJOR
,
"drm"
);
class_simple_destroy
(
drm_class
);
unregister_chrdev
(
DRM_MAJOR
,
"drm"
);
class_simple_destroy
(
drm_class
);
}
if
(
!
i
)
inter_module_unregister
(
"drm"
);
...
...
drivers/char/drm/drm_vm.h
View file @
4c6b5945
...
...
@@ -35,48 +35,19 @@
#include "drmP.h"
/** AGP virtual memory operations */
struct
vm_operations_struct
DRM
(
vm_ops
)
=
{
.
nopage
=
DRM
(
vm_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_close
),
};
/** Shared virtual memory operations */
struct
vm_operations_struct
DRM
(
vm_shm_ops
)
=
{
.
nopage
=
DRM
(
vm_shm_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_shm_close
),
};
/** DMA virtual memory operations */
struct
vm_operations_struct
DRM
(
vm_dma_ops
)
=
{
.
nopage
=
DRM
(
vm_dma_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_close
),
};
/** Scatter-gather virtual memory operations */
struct
vm_operations_struct
DRM
(
vm_sg_ops
)
=
{
.
nopage
=
DRM
(
vm_sg_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_close
),
};
/**
* \c nopage method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Find the right map and if it's AGP memory find the real physical page to
* map, get the page, increment the use count and return it.
*/
struct
page
*
DRM
(
vm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
static
__inline__
struct
page
*
DRM
(
do_vm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
)
{
#if __REALLY_HAVE_AGP
drm_file_t
*
priv
=
vma
->
vm_file
->
private_data
;
...
...
@@ -133,8 +104,6 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
baddr
,
__va
(
agpmem
->
memory
->
memory
[
offset
]),
offset
,
atomic_read
(
&
page
->
count
));
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
return
page
;
}
vm_nopage_error:
...
...
@@ -148,15 +117,13 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Get the the mapping, find the real physical page to map, get the page, and
* return it.
*/
struct
page
*
DRM
(
vm_shm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
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
;
unsigned
long
offset
;
...
...
@@ -172,8 +139,6 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
if
(
!
page
)
return
NOPAGE_OOM
;
get_page
(
page
);
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
DRM_DEBUG
(
"shm_nopage 0x%lx
\n
"
,
address
);
return
page
;
...
...
@@ -265,14 +230,12 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma)
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
struct
page
*
DRM
(
vm_dma_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
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
->
dev
;
...
...
@@ -291,8 +254,6 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
(
offset
&
(
~
PAGE_MASK
))));
get_page
(
page
);
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
DRM_DEBUG
(
"dma_nopage 0x%lx (page %lu)
\n
"
,
address
,
page_nr
);
return
page
;
...
...
@@ -303,14 +264,12 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
struct
page
*
DRM
(
vm_sg_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
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
;
...
...
@@ -331,12 +290,99 @@ struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
page_offset
=
(
offset
>>
PAGE_SHIFT
)
+
(
map_offset
>>
PAGE_SHIFT
);
page
=
entry
->
pagelist
[
page_offset
];
get_page
(
page
);
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
return
page
;
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
static
struct
page
*
DRM
(
vm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
{
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
return
DRM
(
do_vm_nopage
)(
vma
,
address
);
}
static
struct
page
*
DRM
(
vm_shm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
{
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
return
DRM
(
do_vm_shm_nopage
)(
vma
,
address
);
}
static
struct
page
*
DRM
(
vm_dma_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
{
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
return
DRM
(
do_vm_dma_nopage
)(
vma
,
address
);
}
static
struct
page
*
DRM
(
vm_sg_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
*
type
)
{
if
(
type
)
*
type
=
VM_FAULT_MINOR
;
return
DRM
(
do_vm_sg_nopage
)(
vma
,
address
);
}
#else
/* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
static
struct
page
*
DRM
(
vm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
unused
)
{
return
DRM
(
do_vm_nopage
)(
vma
,
address
);
}
static
struct
page
*
DRM
(
vm_shm_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
unused
)
{
return
DRM
(
do_vm_shm_nopage
)(
vma
,
address
);
}
static
struct
page
*
DRM
(
vm_dma_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
unused
)
{
return
DRM
(
do_vm_dma_nopage
)(
vma
,
address
);
}
static
struct
page
*
DRM
(
vm_sg_nopage
)(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
int
unused
)
{
return
DRM
(
do_vm_sg_nopage
)(
vma
,
address
);
}
#endif
/** AGP virtual memory operations */
static
struct
vm_operations_struct
DRM
(
vm_ops
)
=
{
.
nopage
=
DRM
(
vm_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_close
),
};
/** Shared virtual memory operations */
static
struct
vm_operations_struct
DRM
(
vm_shm_ops
)
=
{
.
nopage
=
DRM
(
vm_shm_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_shm_close
),
};
/** DMA virtual memory operations */
static
struct
vm_operations_struct
DRM
(
vm_dma_ops
)
=
{
.
nopage
=
DRM
(
vm_dma_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_close
),
};
/** Scatter-gather virtual memory operations */
static
struct
vm_operations_struct
DRM
(
vm_sg_ops
)
=
{
.
nopage
=
DRM
(
vm_sg_nopage
),
.
open
=
DRM
(
vm_open
),
.
close
=
DRM
(
vm_close
),
};
/**
* \c open method for shared virtual memory.
*
...
...
drivers/char/drm/ffb.h
View file @
4c6b5945
...
...
@@ -13,3 +13,4 @@
#define __HAVE_KERNEL_CTX_SWITCH 1
#define __HAVE_RELEASE 1
#endif
drivers/char/drm/gamma.h
View file @
4c6b5945
...
...
@@ -104,8 +104,8 @@
return 0; \
} while (0)
#define __HAVE_
DMA_
IRQ 1
#define __HAVE_
DMA_IRQ_BH
1
#define __HAVE_IRQ 1
#define __HAVE_
IRQ_BH
1
#define DRIVER_AGP_BUFFERS_MAP( dev ) \
((drm_gamma_private_t *)((dev)->dev_private))->buffers
...
...
drivers/char/drm/gamma_dma.c
View file @
4c6b5945
...
...
@@ -116,7 +116,7 @@ static inline int gamma_dma_is_ready(drm_device_t *dev)
return
(
!
GAMMA_READ
(
GAMMA_DMACOUNT
));
}
irqreturn_t
gamma_
dma_service
(
DRM_IRQ_ARGS
)
irqreturn_t
gamma_
irq_handler
(
DRM_IRQ_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_device_dma_t
*
dma
=
dev
->
dma
;
...
...
@@ -262,7 +262,7 @@ static void gamma_dma_timer_bh(unsigned long dev)
gamma_dma_schedule
((
drm_device_t
*
)
dev
,
0
);
}
void
gamma_
dma
_immediate_bh
(
void
*
dev
)
void
gamma_
irq
_immediate_bh
(
void
*
dev
)
{
gamma_dma_schedule
(
dev
,
0
);
}
...
...
@@ -656,12 +656,12 @@ int gamma_do_cleanup_dma( drm_device_t *dev )
{
DRM_DEBUG
(
"%s
\n
"
,
__FUNCTION__
);
#if _
HAVE_DMA
_IRQ
#if _
_HAVE
_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
if
(
dev
->
irq
_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
if
(
dev
->
dev_private
)
{
...
...
drivers/char/drm/gamma_drv.c
View file @
4c6b5945
...
...
@@ -48,6 +48,7 @@
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_irq.h"
#include "gamma_lists.h"
/* NOTE */
#include "drm_lock.h"
#include "gamma_lock.h"
/* NOTE */
...
...
drivers/char/drm/i810.h
View file @
4c6b5945
...
...
@@ -77,7 +77,6 @@
[DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_FLIP)] = { i810_flip_bufs, 1, 0 }
#define __HAVE_COUNTERS 4
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
...
...
@@ -112,7 +111,7 @@
* a noop stub is generated for compatibility.
*/
/* XXX: Add vblank support? */
#define __HAVE_
DMA_
IRQ 0
#define __HAVE_IRQ 0
/* Buffer customization:
*/
...
...
drivers/char/drm/i810_dma.c
View file @
4c6b5945
...
...
@@ -232,12 +232,12 @@ int i810_dma_cleanup(drm_device_t *dev)
{
drm_device_dma_t
*
dma
=
dev
->
dma
;
#if _
HAVE_DMA
_IRQ
#if _
_HAVE
_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
if
(
dev
->
irq_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
if
(
dev
->
dev_private
)
{
...
...
drivers/char/drm/i830.h
View file @
4c6b5945
...
...
@@ -115,10 +115,10 @@
#define USE_IRQS 0
#if USE_IRQS
#define __HAVE_
DMA_
IRQ 1
#define __HAVE_IRQ 1
#define __HAVE_SHARED_IRQ 1
#else
#define __HAVE_
DMA_
IRQ 0
#define __HAVE_IRQ 0
#endif
...
...
drivers/char/drm/i830_dma.c
View file @
4c6b5945
...
...
@@ -232,12 +232,12 @@ int i830_dma_cleanup(drm_device_t *dev)
{
drm_device_dma_t
*
dma
=
dev
->
dma
;
#if _
HAVE_DMA
_IRQ
#if _
_HAVE
_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
if
(
dev
->
irq_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
if
(
dev
->
dev_private
)
{
...
...
@@ -1540,7 +1540,7 @@ int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd,
switch
(
param
.
param
)
{
case
I830_PARAM_IRQ_ACTIVE
:
value
=
dev
->
irq
?
1
:
0
;
value
=
dev
->
irq
_enabled
;
break
;
default:
return
-
EINVAL
;
...
...
drivers/char/drm/i830_drv.c
View file @
4c6b5945
...
...
@@ -50,6 +50,7 @@
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_irq.h"
#include "drm_lock.h"
#include "drm_memory.h"
#include "drm_proc.h"
...
...
drivers/char/drm/i830_irq.c
View file @
4c6b5945
...
...
@@ -35,7 +35,7 @@
#include <linux/delay.h>
irqreturn_t
DRM
(
dma_service
)(
DRM_IRQ_ARGS
)
irqreturn_t
DRM
(
irq_handler
)(
DRM_IRQ_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_i830_private_t
*
dev_priv
=
(
drm_i830_private_t
*
)
dev
->
dev_private
;
...
...
drivers/char/drm/mga.h
View file @
4c6b5945
...
...
@@ -78,7 +78,7 @@
/* DMA customization:
*/
#define __HAVE_DMA 1
#define __HAVE_
DMA_
IRQ 1
#define __HAVE_IRQ 1
#define __HAVE_VBL_IRQ 1
#define __HAVE_SHARED_IRQ 1
...
...
drivers/char/drm/mga_dma.c
View file @
4c6b5945
...
...
@@ -500,14 +500,6 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return
DRM_ERR
(
EINVAL
);
}
DRM_FIND_MAP
(
dev_priv
->
fb
,
init
->
fb_offset
);
if
(
!
dev_priv
->
fb
)
{
DRM_ERROR
(
"failed to find framebuffer!
\n
"
);
/* Assign dev_private so we can do cleanup. */
dev
->
dev_private
=
(
void
*
)
dev_priv
;
mga_do_cleanup_dma
(
dev
);
return
DRM_ERR
(
EINVAL
);
}
DRM_FIND_MAP
(
dev_priv
->
mmio
,
init
->
mmio_offset
);
if
(
!
dev_priv
->
mmio
)
{
DRM_ERROR
(
"failed to find mmio region!
\n
"
);
...
...
@@ -639,12 +631,12 @@ int mga_do_cleanup_dma( drm_device_t *dev )
{
DRM_DEBUG
(
"
\n
"
);
#if _
HAVE_DMA
_IRQ
#if _
_HAVE
_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
if
(
dev
->
irq
_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
if
(
dev
->
dev_private
)
{
...
...
drivers/char/drm/mga_drm.h
View file @
4c6b5945
...
...
@@ -117,6 +117,8 @@
#define MGA_NR_TEX_REGIONS 16
#define MGA_LOG_MIN_TEX_REGION_SIZE 16
#define DRM_MGA_IDLE_RETRY 2048
#endif
/* __MGA_SAREA_DEFINES__ */
...
...
@@ -230,16 +232,27 @@ typedef struct _drm_mga_sarea {
/* MGA specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42)
#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(0x49, drm_mga_getparam_t)
#define DRM_MGA_INIT 0x00
#define DRM_MGA_FLUSH 0x01
#define DRM_MGA_RESET 0x02
#define DRM_MGA_SWAP 0x03
#define DRM_MGA_CLEAR 0x04
#define DRM_MGA_VERTEX 0x05
#define DRM_MGA_INDICES 0x06
#define DRM_MGA_ILOAD 0x07
#define DRM_MGA_BLIT 0x08
#define DRM_MGA_GETPARAM 0x09
#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t)
#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t)
typedef
struct
_drm_mga_warp_index
{
int
installed
;
...
...
@@ -330,7 +343,7 @@ typedef struct _drm_mga_blit {
typedef
struct
drm_mga_getparam
{
int
param
;
int
*
value
;
void
*
value
;
}
drm_mga_getparam_t
;
#endif
drivers/char/drm/mga_drv.c
View file @
4c6b5945
...
...
@@ -45,6 +45,7 @@
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_irq.h"
#include "drm_lock.h"
#include "drm_memory.h"
#include "drm_proc.h"
...
...
drivers/char/drm/mga_drv.h
View file @
4c6b5945
...
...
@@ -91,7 +91,6 @@ typedef struct drm_mga_private {
unsigned
int
texture_size
;
drm_local_map_t
*
sarea
;
drm_local_map_t
*
fb
;
drm_local_map_t
*
mmio
;
drm_local_map_t
*
status
;
drm_local_map_t
*
warp
;
...
...
drivers/char/drm/mga_irq.c
View file @
4c6b5945
...
...
@@ -36,7 +36,7 @@
#include "mga_drm.h"
#include "mga_drv.h"
irqreturn_t
mga_
dma_service
(
DRM_IRQ_ARGS
)
irqreturn_t
mga_
irq_handler
(
DRM_IRQ_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_mga_private_t
*
dev_priv
=
...
...
drivers/char/drm/r128.h
View file @
4c6b5945
...
...
@@ -97,7 +97,7 @@
/* DMA customization:
*/
#define __HAVE_DMA 1
#define __HAVE_
DMA_
IRQ 1
#define __HAVE_IRQ 1
#define __HAVE_VBL_IRQ 1
#define __HAVE_SHARED_IRQ 1
...
...
drivers/char/drm/r128_cce.c
View file @
4c6b5945
...
...
@@ -212,7 +212,7 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv )
int
i
;
for
(
i
=
0
;
i
<
dev_priv
->
usec_timeout
;
i
++
)
{
if
(
GET_RING_HEAD
(
&
dev_priv
->
ring
)
==
dev_priv
->
ring
.
tail
)
{
if
(
GET_RING_HEAD
(
dev_priv
)
==
dev_priv
->
ring
.
tail
)
{
int
pm4stat
=
R128_READ
(
R128_PM4_STAT
);
if
(
(
(
pm4stat
&
R128_PM4_FIFOCNT_MASK
)
>=
dev_priv
->
cce_fifo_size
)
&&
...
...
@@ -238,7 +238,8 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv )
r128_do_wait_for_idle
(
dev_priv
);
R128_WRITE
(
R128_PM4_BUFFER_CNTL
,
dev_priv
->
cce_mode
|
dev_priv
->
ring
.
size_l2qw
);
dev_priv
->
cce_mode
|
dev_priv
->
ring
.
size_l2qw
|
R128_PM4_BUFFER_CNTL_NOUPDATE
);
R128_READ
(
R128_PM4_BUFFER_ADDR
);
/* as per the sample code */
R128_WRITE
(
R128_PM4_MICRO_CNTL
,
R128_PM4_MICRO_FREERUN
);
...
...
@@ -253,7 +254,6 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
{
R128_WRITE
(
R128_PM4_BUFFER_DL_WPTR
,
0
);
R128_WRITE
(
R128_PM4_BUFFER_DL_RPTR
,
0
);
SET_RING_HEAD
(
&
dev_priv
->
ring
,
0
);
dev_priv
->
ring
.
tail
=
0
;
}
...
...
@@ -264,7 +264,8 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
static
void
r128_do_cce_stop
(
drm_r128_private_t
*
dev_priv
)
{
R128_WRITE
(
R128_PM4_MICRO_CNTL
,
0
);
R128_WRITE
(
R128_PM4_BUFFER_CNTL
,
R128_PM4_NONPM4
);
R128_WRITE
(
R128_PM4_BUFFER_CNTL
,
R128_PM4_NONPM4
|
R128_PM4_BUFFER_CNTL_NOUPDATE
);
dev_priv
->
cce_running
=
0
;
}
...
...
@@ -333,26 +334,6 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev,
R128_WRITE
(
R128_PM4_BUFFER_DL_WPTR
,
0
);
R128_WRITE
(
R128_PM4_BUFFER_DL_RPTR
,
0
);
/* DL_RPTR_ADDR is a physical address in AGP space. */
SET_RING_HEAD
(
&
dev_priv
->
ring
,
0
);
if
(
!
dev_priv
->
is_pci
)
{
R128_WRITE
(
R128_PM4_BUFFER_DL_RPTR_ADDR
,
dev_priv
->
ring_rptr
->
offset
);
}
else
{
drm_sg_mem_t
*
entry
=
dev
->
sg
;
unsigned
long
tmp_ofs
,
page_ofs
;
tmp_ofs
=
dev_priv
->
ring_rptr
->
offset
-
dev
->
sg
->
handle
;
page_ofs
=
tmp_ofs
>>
PAGE_SHIFT
;
R128_WRITE
(
R128_PM4_BUFFER_DL_RPTR_ADDR
,
entry
->
busaddr
[
page_ofs
]);
DRM_DEBUG
(
"ring rptr: offset=0x%08lx handle=0x%08lx
\n
"
,
(
unsigned
long
)
entry
->
busaddr
[
page_ofs
],
entry
->
handle
+
tmp_ofs
);
}
/* Set watermark control */
R128_WRITE
(
R128_PM4_BUFFER_WM_CNTL
,
((
R128_WATERMARK_L
/
4
)
<<
R128_WMA_SHIFT
)
...
...
@@ -486,13 +467,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
return
DRM_ERR
(
EINVAL
);
}
DRM_FIND_MAP
(
dev_priv
->
fb
,
init
->
fb_offset
);
if
(
!
dev_priv
->
fb
)
{
DRM_ERROR
(
"could not find framebuffer!
\n
"
);
dev
->
dev_private
=
(
void
*
)
dev_priv
;
r128_do_cleanup_cce
(
dev
);
return
DRM_ERR
(
EINVAL
);
}
DRM_FIND_MAP
(
dev_priv
->
mmio
,
init
->
mmio_offset
);
if
(
!
dev_priv
->
mmio
)
{
DRM_ERROR
(
"could not find mmio region!
\n
"
);
...
...
@@ -567,9 +541,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
#endif
dev_priv
->
cce_buffers_offset
=
dev
->
sg
->
handle
;
dev_priv
->
ring
.
head
=
((
__volatile__
u32
*
)
dev_priv
->
ring_rptr
->
handle
);
dev_priv
->
ring
.
start
=
(
u32
*
)
dev_priv
->
cce_ring
->
handle
;
dev_priv
->
ring
.
end
=
((
u32
*
)
dev_priv
->
cce_ring
->
handle
+
init
->
ring_size
/
sizeof
(
u32
));
...
...
@@ -580,7 +551,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
(
dev_priv
->
ring
.
size
/
sizeof
(
u32
))
-
1
;
dev_priv
->
ring
.
high_mark
=
128
;
dev_priv
->
ring
.
ring_rptr
=
dev_priv
->
ring_rptr
;
dev_priv
->
sarea_priv
->
last_frame
=
0
;
R128_WRITE
(
R128_LAST_FRAME_REG
,
dev_priv
->
sarea_priv
->
last_frame
);
...
...
@@ -589,8 +559,9 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
R128_WRITE
(
R128_LAST_DISPATCH_REG
,
dev_priv
->
sarea_priv
->
last_dispatch
);
#if __REALLY_HAVE_
SG
#if __REALLY_HAVE_
AGP
if
(
dev_priv
->
is_pci
)
{
#endif
if
(
!
DRM
(
ati_pcigart_init
)(
dev
,
&
dev_priv
->
phys_pci_gart
,
&
dev_priv
->
bus_pci_gart
)
)
{
DRM_ERROR
(
"failed to init PCI GART!
\n
"
);
...
...
@@ -599,6 +570,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
return
DRM_ERR
(
ENOMEM
);
}
R128_WRITE
(
R128_PCI_GART_PAGE
,
dev_priv
->
bus_pci_gart
);
#if __REALLY_HAVE_AGP
}
#endif
...
...
@@ -615,12 +587,12 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
int
r128_do_cleanup_cce
(
drm_device_t
*
dev
)
{
#if _
HAVE_DMA
_IRQ
#if _
_HAVE
_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
if
(
dev
->
irq
_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
if
(
dev
->
dev_private
)
{
...
...
@@ -901,7 +873,7 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
int
i
;
for
(
i
=
0
;
i
<
dev_priv
->
usec_timeout
;
i
++
)
{
r128_update_ring_snapshot
(
ring
);
r128_update_ring_snapshot
(
dev_priv
);
if
(
ring
->
space
>=
n
)
return
0
;
DRM_UDELAY
(
1
);
...
...
drivers/char/drm/r128_drm.h
View file @
4c6b5945
...
...
@@ -176,24 +176,47 @@ typedef struct drm_r128_sarea {
/* Rage 128 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
#define DRM_IOCTL_R128_GETPARAM DRM_IOW( 0x52, drm_r128_getparam_t)
#define DRM_IOCTL_R128_FLIP DRM_IO( 0x53)
#define DRM_R128_INIT 0x00
#define DRM_R128_CCE_START 0x01
#define DRM_R128_CCE_STOP 0x02
#define DRM_R128_CCE_RESET 0x03
#define DRM_R128_CCE_IDLE 0x04
/* 0x05 not used */
#define DRM_R128_RESET 0x06
#define DRM_R128_SWAP 0x07
#define DRM_R128_CLEAR 0x08
#define DRM_R128_VERTEX 0x09
#define DRM_R128_INDICES 0x0a
#define DRM_R128_BLIT 0x0b
#define DRM_R128_DEPTH 0x0c
#define DRM_R128_STIPPLE 0x0d
/* 0x0e not used */
#define DRM_R128_INDIRECT 0x0f
#define DRM_R128_FULLSCREEN 0x10
#define DRM_R128_CLEAR2 0x11
#define DRM_R128_GETPARAM 0x12
#define DRM_R128_FLIP 0x13
#define DRM_IOCTL_R128_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INIT, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_START)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CCE_STOP, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_RESET)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_IDLE)
/* 0x05 not used */
#define DRM_IOCTL_R128_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_RESET)
#define DRM_IOCTL_R128_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_R128_SWAP)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_R128_VERTEX, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_BLIT, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( DRM_COMMAND_BASE + DRM_R128_DEPTH, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_R128_STIPPLE, drm_r128_stipple_t)
/* 0x0e not used */
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t)
#define DRM_IOCTL_R128_GETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t)
#define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP)
typedef
struct
drm_r128_init
{
enum
{
...
...
@@ -316,7 +339,7 @@ typedef struct drm_r128_fullscreen {
typedef
struct
drm_r128_getparam
{
int
param
;
int
*
value
;
void
*
value
;
}
drm_r128_getparam_t
;
#endif
drivers/char/drm/r128_drv.c
View file @
4c6b5945
...
...
@@ -47,6 +47,7 @@
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_irq.h"
#include "drm_lock.h"
#include "drm_memory.h"
#include "drm_proc.h"
...
...
drivers/char/drm/r128_drv.h
View file @
4c6b5945
...
...
@@ -34,8 +34,7 @@
#ifndef __R128_DRV_H__
#define __R128_DRV_H__
#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 )
/* (ring)->head */
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) )
/* (ring)->head */
#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR )
typedef
struct
drm_r128_freelist
{
unsigned
int
age
;
...
...
@@ -50,13 +49,11 @@ typedef struct drm_r128_ring_buffer {
int
size
;
int
size_l2qw
;
volatile
u32
*
head
;
u32
tail
;
u32
tail_mask
;
int
space
;
int
high_mark
;
drm_local_map_t
*
ring_rptr
;
}
drm_r128_ring_buffer_t
;
typedef
struct
drm_r128_private
{
...
...
@@ -100,7 +97,6 @@ typedef struct drm_r128_private {
u32
span_pitch_offset_c
;
drm_local_map_t
*
sarea
;
drm_local_map_t
*
fb
;
drm_local_map_t
*
mmio
;
drm_local_map_t
*
cce_ring
;
drm_local_map_t
*
ring_rptr
;
...
...
@@ -132,14 +128,6 @@ extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
extern
int
r128_wait_ring
(
drm_r128_private_t
*
dev_priv
,
int
n
);
static
__inline__
void
r128_update_ring_snapshot
(
drm_r128_ring_buffer_t
*
ring
)
{
ring
->
space
=
(
GET_RING_HEAD
(
ring
)
-
ring
->
tail
)
*
sizeof
(
u32
);
if
(
ring
->
space
<=
0
)
ring
->
space
+=
ring
->
size
;
}
extern
int
r128_do_cce_idle
(
drm_r128_private_t
*
dev_priv
);
extern
int
r128_do_cleanup_cce
(
drm_device_t
*
dev
);
extern
int
r128_do_cleanup_pageflip
(
drm_device_t
*
dev
);
...
...
@@ -279,6 +267,7 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
# define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27)
#define R128_PM4_BUFFER_WM_CNTL 0x0708
# define R128_WMA_SHIFT 0
...
...
@@ -403,6 +392,15 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
(pkt) | ((n) << 16))
static
__inline__
void
r128_update_ring_snapshot
(
drm_r128_private_t
*
dev_priv
)
{
drm_r128_ring_buffer_t
*
ring
=
&
dev_priv
->
ring
;
ring
->
space
=
(
GET_RING_HEAD
(
dev_priv
)
-
ring
->
tail
)
*
sizeof
(
u32
);
if
(
ring
->
space
<=
0
)
ring
->
space
+=
ring
->
size
;
}
/* ================================================================
* Misc helper macros
*/
...
...
@@ -412,7 +410,7 @@ do { \
drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \
if ( ring->space < ring->high_mark ) { \
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \
r128_update_ring_snapshot(
ring
); \
r128_update_ring_snapshot(
dev_priv
); \
if ( ring->space >= ring->high_mark ) \
goto __ring_space_done; \
DRM_UDELAY(1); \
...
...
@@ -445,17 +443,10 @@ do { \
* Ring control
*/
#if defined(__powerpc__)
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
#else
#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER()
#endif
#define R128_VERBOSE 0
#define RING_LOCALS \
int write; unsigned int tail_mask; volatile u32 *ring;
int write
, _nr
; unsigned int tail_mask; volatile u32 *ring;
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
...
...
@@ -463,9 +454,10 @@ do { \
(n), __FUNCTION__ ); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
COMMIT_RING(); \
r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \
} \
dev_priv->ring.space -= (n) * sizeof(u32);
\
_nr = n; dev_priv->ring.space -= (n) * sizeof(u32);
\
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
tail_mask = dev_priv->ring.tail_mask; \
...
...
@@ -488,9 +480,23 @@ do { \
dev_priv->ring.start, \
write * sizeof(u32) ); \
} \
r128_flush_write_combine(); \
dev_priv->ring.tail = write; \
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \
if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \
DRM_ERROR( \
"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
((dev_priv->ring.tail + _nr) & tail_mask), \
write, __LINE__); \
} else \
dev_priv->ring.tail = write; \
} while (0)
#define COMMIT_RING() do { \
if ( R128_VERBOSE ) { \
DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \
dev_priv->ring.tail ); \
} \
DRM_MEMORYBARRIER(); \
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \
R128_READ( R128_PM4_BUFFER_DL_WPTR ); \
} while (0)
#define OUT_RING( x ) do { \
...
...
drivers/char/drm/r128_irq.c
View file @
4c6b5945
...
...
@@ -36,7 +36,7 @@
#include "r128_drm.h"
#include "r128_drv.h"
irqreturn_t
r128_
dma_service
(
DRM_IRQ_ARGS
)
irqreturn_t
r128_
irq_handler
(
DRM_IRQ_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_r128_private_t
*
dev_priv
=
...
...
drivers/char/drm/r128_state.c
View file @
4c6b5945
...
...
@@ -45,7 +45,7 @@ static void r128_emit_clip_rects( drm_r128_private_t *dev_priv,
RING_LOCALS
;
DRM_DEBUG
(
" %s
\n
"
,
__FUNCTION__
);
BEGIN_RING
(
17
);
BEGIN_RING
(
(
count
<
3
?
count
:
3
)
*
5
+
2
);
if
(
count
>=
1
)
{
OUT_RING
(
CCE_PACKET0
(
R128_AUX1_SC_LEFT
,
3
)
);
...
...
@@ -1011,7 +1011,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
DRM_DEBUG
(
"
\n
"
);
count
=
depth
->
n
;
if
(
count
>
4096
||
count
<=
0
)
if
(
count
>
4096
||
count
<=
0
)
return
-
EMSGSIZE
;
xbuf_size
=
count
*
sizeof
(
*
x
);
...
...
@@ -1280,6 +1280,7 @@ int r128_cce_clear( DRM_IOCTL_ARGS )
sarea_priv
->
nbox
=
R128_NR_SAREA_CLIPRECTS
;
r128_cce_dispatch_clear
(
dev
,
&
clear
);
COMMIT_RING
();
/* Make sure we restore the 3D state next time.
*/
...
...
@@ -1315,8 +1316,10 @@ int r128_do_cleanup_pageflip( drm_device_t *dev )
R128_WRITE
(
R128_CRTC_OFFSET
,
dev_priv
->
crtc_offset
);
R128_WRITE
(
R128_CRTC_OFFSET_CNTL
,
dev_priv
->
crtc_offset_cntl
);
if
(
dev_priv
->
current_page
!=
0
)
if
(
dev_priv
->
current_page
!=
0
)
{
r128_cce_dispatch_flip
(
dev
);
COMMIT_RING
();
}
dev_priv
->
page_flipping
=
0
;
return
0
;
...
...
@@ -1341,6 +1344,7 @@ int r128_cce_flip( DRM_IOCTL_ARGS )
r128_cce_dispatch_flip
(
dev
);
COMMIT_RING
();
return
0
;
}
...
...
@@ -1362,6 +1366,7 @@ int r128_cce_swap( DRM_IOCTL_ARGS )
dev_priv
->
sarea_priv
->
dirty
|=
(
R128_UPLOAD_CONTEXT
|
R128_UPLOAD_MASKS
);
COMMIT_RING
();
return
0
;
}
...
...
@@ -1421,6 +1426,7 @@ int r128_cce_vertex( DRM_IOCTL_ARGS )
r128_cce_dispatch_vertex
(
dev
,
buf
);
COMMIT_RING
();
return
0
;
}
...
...
@@ -1492,6 +1498,7 @@ int r128_cce_indices( DRM_IOCTL_ARGS )
r128_cce_dispatch_indices
(
dev
,
buf
,
elts
.
start
,
elts
.
end
,
count
);
COMMIT_RING
();
return
0
;
}
...
...
@@ -1501,6 +1508,7 @@ int r128_cce_blit( DRM_IOCTL_ARGS )
drm_device_dma_t
*
dma
=
dev
->
dma
;
drm_r128_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_r128_blit_t
blit
;
int
ret
;
LOCK_TEST_WITH_RETURN
(
dev
,
filp
);
...
...
@@ -1518,7 +1526,10 @@ int r128_cce_blit( DRM_IOCTL_ARGS )
RING_SPACE_TEST_WITH_RETURN
(
dev_priv
);
VB_AGE_TEST_WITH_RETURN
(
dev_priv
);
return
r128_cce_dispatch_blit
(
filp
,
dev
,
&
blit
);
ret
=
r128_cce_dispatch_blit
(
filp
,
dev
,
&
blit
);
COMMIT_RING
();
return
ret
;
}
int
r128_cce_depth
(
DRM_IOCTL_ARGS
)
...
...
@@ -1526,6 +1537,7 @@ int r128_cce_depth( DRM_IOCTL_ARGS )
DRM_DEVICE
;
drm_r128_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_r128_depth_t
depth
;
int
ret
;
LOCK_TEST_WITH_RETURN
(
dev
,
filp
);
...
...
@@ -1534,18 +1546,20 @@ int r128_cce_depth( DRM_IOCTL_ARGS )
RING_SPACE_TEST_WITH_RETURN
(
dev_priv
);
ret
=
DRM_ERR
(
EINVAL
);
switch
(
depth
.
func
)
{
case
R128_WRITE_SPAN
:
ret
urn
r128_cce_dispatch_write_span
(
dev
,
&
depth
);
ret
=
r128_cce_dispatch_write_span
(
dev
,
&
depth
);
case
R128_WRITE_PIXELS
:
ret
urn
r128_cce_dispatch_write_pixels
(
dev
,
&
depth
);
ret
=
r128_cce_dispatch_write_pixels
(
dev
,
&
depth
);
case
R128_READ_SPAN
:
ret
urn
r128_cce_dispatch_read_span
(
dev
,
&
depth
);
ret
=
r128_cce_dispatch_read_span
(
dev
,
&
depth
);
case
R128_READ_PIXELS
:
ret
urn
r128_cce_dispatch_read_pixels
(
dev
,
&
depth
);
ret
=
r128_cce_dispatch_read_pixels
(
dev
,
&
depth
);
}
return
DRM_ERR
(
EINVAL
);
COMMIT_RING
();
return
ret
;
}
int
r128_cce_stipple
(
DRM_IOCTL_ARGS
)
...
...
@@ -1568,6 +1582,7 @@ int r128_cce_stipple( DRM_IOCTL_ARGS )
r128_cce_dispatch_stipple
(
dev
,
mask
);
COMMIT_RING
();
return
0
;
}
...
...
@@ -1643,6 +1658,7 @@ int r128_cce_indirect( DRM_IOCTL_ARGS )
*/
r128_cce_dispatch_indirect
(
dev
,
buf
,
indirect
.
start
,
indirect
.
end
);
COMMIT_RING
();
return
0
;
}
...
...
drivers/char/drm/radeon.h
View file @
4c6b5945
...
...
@@ -51,7 +51,7 @@
#define DRIVER_DATE "20020828"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR
9
#define DRIVER_MINOR
10
#define DRIVER_PATCHLEVEL 0
/* Interface history:
...
...
@@ -81,6 +81,9 @@
* Add 'GET' queries for starting additional clients on different VT's.
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
* Add texture rectangle support for r100.
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
* clients use to tell the DRM where they think the framebuffer is
* located in the card's address space
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
...
...
@@ -106,10 +109,21 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)] = { radeon_mem_init_heap, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 }, \
#define DRIVER_FILE_FIELDS \
int64_t radeon_fb_delta; \
#define DRIVER_OPEN_HELPER( filp_priv, dev ) \
do { \
drm_radeon_private_t *dev_priv = dev->dev_private; \
if ( dev_priv ) \
filp_priv->radeon_fb_delta = dev_priv->fb_location; \
else \
filp_priv->radeon_fb_delta = 0; \
} while( 0 )
/* When a client dies:
* - Check for and clean up flipped page state
...
...
@@ -142,7 +156,7 @@ do { \
/* DMA customization:
*/
#define __HAVE_DMA 1
#define __HAVE_
DMA_
IRQ 1
#define __HAVE_IRQ 1
#define __HAVE_VBL_IRQ 1
#define __HAVE_SHARED_IRQ 1
...
...
drivers/char/drm/radeon_cp.c
View file @
4c6b5945
...
...
@@ -855,7 +855,8 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
/* Initialize the memory controller */
RADEON_WRITE
(
RADEON_MC_FB_LOCATION
,
(
dev_priv
->
gart_vm_start
-
1
)
&
0xffff0000
);
(
(
dev_priv
->
gart_vm_start
-
1
)
&
0xffff0000
)
|
(
dev_priv
->
fb_location
>>
16
)
);
#if __REALLY_HAVE_AGP
if
(
!
dev_priv
->
is_pci
)
{
...
...
@@ -1071,13 +1072,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv
->
depth_offset
=
init
->
depth_offset
;
dev_priv
->
depth_pitch
=
init
->
depth_pitch
;
dev_priv
->
front_pitch_offset
=
(((
dev_priv
->
front_pitch
/
64
)
<<
22
)
|
(
dev_priv
->
front_offset
>>
10
));
dev_priv
->
back_pitch_offset
=
(((
dev_priv
->
back_pitch
/
64
)
<<
22
)
|
(
dev_priv
->
back_offset
>>
10
));
dev_priv
->
depth_pitch_offset
=
(((
dev_priv
->
depth_pitch
/
64
)
<<
22
)
|
(
dev_priv
->
depth_offset
>>
10
));
/* Hardware state for depth clears. Remove this if/when we no
* longer clear the depth buffer with a 3D rectangle. Hard-code
* all values to prevent unwanted 3D state from slipping through
...
...
@@ -1124,13 +1118,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
return
DRM_ERR
(
EINVAL
);
}
DRM_FIND_MAP
(
dev_priv
->
fb
,
init
->
fb_offset
);
if
(
!
dev_priv
->
fb
)
{
DRM_ERROR
(
"could not find framebuffer!
\n
"
);
dev
->
dev_private
=
(
void
*
)
dev_priv
;
radeon_do_cleanup_cp
(
dev
);
return
DRM_ERR
(
EINVAL
);
}
DRM_FIND_MAP
(
dev_priv
->
mmio
,
init
->
mmio_offset
);
if
(
!
dev_priv
->
mmio
)
{
DRM_ERROR
(
"could not find mmio region!
\n
"
);
...
...
@@ -1204,9 +1191,26 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv
->
buffers
->
handle
);
}
dev_priv
->
fb_location
=
(
RADEON_READ
(
RADEON_MC_FB_LOCATION
)
&
0xffff
)
<<
16
;
dev_priv
->
front_pitch_offset
=
(((
dev_priv
->
front_pitch
/
64
)
<<
22
)
|
(
(
dev_priv
->
front_offset
+
dev_priv
->
fb_location
)
>>
10
)
);
dev_priv
->
back_pitch_offset
=
(((
dev_priv
->
back_pitch
/
64
)
<<
22
)
|
(
(
dev_priv
->
back_offset
+
dev_priv
->
fb_location
)
>>
10
)
);
dev_priv
->
depth_pitch_offset
=
(((
dev_priv
->
depth_pitch
/
64
)
<<
22
)
|
(
(
dev_priv
->
depth_offset
+
dev_priv
->
fb_location
)
>>
10
)
);
dev_priv
->
gart_size
=
init
->
gart_size
;
dev_priv
->
gart_vm_start
=
RADEON_READ
(
RADEON_CONFIG_APER_SIZE
);
dev_priv
->
gart_vm_start
=
dev_priv
->
fb_location
+
RADEON_READ
(
RADEON_CONFIG_APER_SIZE
);
#if __REALLY_HAVE_AGP
if
(
!
dev_priv
->
is_pci
)
dev_priv
->
gart_buffers_offset
=
(
dev_priv
->
buffers
->
offset
...
...
@@ -1271,12 +1275,12 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
{
DRM_DEBUG
(
"
\n
"
);
#if _
HAVE_DMA
_IRQ
#if _
_HAVE
_IRQ
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
if
(
dev
->
irq
)
DRM
(
irq_uninstall
)(
dev
);
if
(
dev
->
irq
_enabled
)
DRM
(
irq_uninstall
)(
dev
);
#endif
if
(
dev
->
dev_private
)
{
...
...
drivers/char/drm/radeon_drm.h
View file @
4c6b5945
...
...
@@ -226,6 +226,13 @@ typedef union {
#define RADEON_MAX_TEXTURE_LEVELS 12
#define RADEON_MAX_TEXTURE_UNITS 3
/* Blits have strict offset rules. All blit offset must be aligned on
* a 1K-byte boundary.
*/
#define RADEON_OFFSET_SHIFT 10
#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT)
#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1)
#endif
/* __RADEON_SAREA_DEFINES__ */
typedef
struct
{
...
...
@@ -365,31 +372,58 @@ typedef struct {
/* Radeon specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex2_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR( 0x53, drm_radeon_mem_alloc_t)
#define DRM_IOCTL_RADEON_FREE DRM_IOW( 0x54, drm_radeon_mem_free_t)
#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( 0x55, drm_radeon_mem_init_heap_t)
#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR( 0x56, drm_radeon_irq_emit_t)
#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( 0x57, drm_radeon_irq_wait_t)
/* added by Charl P. Botha - see radeon_cp.c for details */
#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO(0x58)
#define DRM_RADEON_CP_INIT 0x00
#define DRM_RADEON_CP_START 0x01
#define DRM_RADEON_CP_STOP 0x02
#define DRM_RADEON_CP_RESET 0x03
#define DRM_RADEON_CP_IDLE 0x04
#define DRM_RADEON_RESET 0x05
#define DRM_RADEON_FULLSCREEN 0x06
#define DRM_RADEON_SWAP 0x07
#define DRM_RADEON_CLEAR 0x08
#define DRM_RADEON_VERTEX 0x09
#define DRM_RADEON_INDICES 0x0A
#define DRM_RADEON_NOT_USED
#define DRM_RADEON_STIPPLE 0x0C
#define DRM_RADEON_INDIRECT 0x0D
#define DRM_RADEON_TEXTURE 0x0E
#define DRM_RADEON_VERTEX2 0x0F
#define DRM_RADEON_CMDBUF 0x10
#define DRM_RADEON_GETPARAM 0x11
#define DRM_RADEON_FLIP 0x12
#define DRM_RADEON_ALLOC 0x13
#define DRM_RADEON_FREE 0x14
#define DRM_RADEON_INIT_HEAP 0x15
#define DRM_RADEON_IRQ_EMIT 0x16
#define DRM_RADEON_IRQ_WAIT 0x17
#define DRM_RADEON_CP_RESUME 0x18
#define DRM_RADEON_SETPARAM 0x19
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESET)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_IDLE)
#define DRM_IOCTL_RADEON_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_RESET)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FULLSCREEN, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_SWAP)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CLEAR, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INDICES, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_STIPPLE, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INDIRECT, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_TEXTURE, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX2, drm_radeon_vertex2_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CMDBUF, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GETPARAM, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_FLIP)
#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_ALLOC, drm_radeon_mem_alloc_t)
#define DRM_IOCTL_RADEON_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FREE, drm_radeon_mem_free_t)
#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INIT_HEAP, drm_radeon_mem_init_heap_t)
#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_IRQ_EMIT, drm_radeon_irq_emit_t)
#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t)
#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME)
#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
typedef
struct
drm_radeon_init
{
enum
{
...
...
@@ -502,7 +536,7 @@ typedef struct drm_radeon_tex_image {
}
drm_radeon_tex_image_t
;
typedef
struct
drm_radeon_texture
{
int
offset
;
unsigned
int
offset
;
int
pitch
;
int
format
;
int
width
;
/* Texture image coordinates */
...
...
@@ -537,10 +571,11 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_STATUS_HANDLE 8
#define RADEON_PARAM_SAREA_HANDLE 9
#define RADEON_PARAM_GART_TEX_HANDLE 10
#define RADEON_PARAM_SCRATCH_OFFSET 11
typedef
struct
drm_radeon_getparam
{
int
param
;
int
*
value
;
void
*
value
;
}
drm_radeon_getparam_t
;
/* 1.6: Set up a memory manager for regions of shared memory:
...
...
@@ -578,4 +613,16 @@ typedef struct drm_radeon_irq_wait {
}
drm_radeon_irq_wait_t
;
/* 1.10: Clients tell the DRM where they think the framebuffer is located in
* the card's address space, via a new generic ioctl to set parameters
*/
typedef
struct
drm_radeon_setparam
{
unsigned
int
param
;
int64_t
value
;
}
drm_radeon_setparam_t
;
#define RADEON_SETPARAM_FB_LOCATION 1
/* determined framebuffer location */
#endif
drivers/char/drm/radeon_drv.c
View file @
4c6b5945
...
...
@@ -48,6 +48,7 @@
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_irq.h"
#include "drm_lock.h"
#include "drm_memory.h"
#include "drm_proc.h"
...
...
drivers/char/drm/radeon_drv.h
View file @
4c6b5945
...
...
@@ -73,6 +73,8 @@ typedef struct drm_radeon_private {
drm_radeon_ring_buffer_t
ring
;
drm_radeon_sarea_t
*
sarea_priv
;
u32
fb_location
;
int
gart_size
;
u32
gart_vm_start
;
unsigned
long
gart_buffers_offset
;
...
...
@@ -133,7 +135,6 @@ typedef struct drm_radeon_private {
unsigned
long
gart_textures_offset
;
drm_local_map_t
*
sarea
;
drm_local_map_t
*
fb
;
drm_local_map_t
*
mmio
;
drm_local_map_t
*
cp_ring
;
drm_local_map_t
*
ring_rptr
;
...
...
@@ -184,6 +185,7 @@ extern int radeon_cp_indirect( DRM_IOCTL_ARGS );
extern
int
radeon_cp_vertex2
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_cmdbuf
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_getparam
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_setparam
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_flip
(
DRM_IOCTL_ARGS
);
extern
int
radeon_mem_alloc
(
DRM_IOCTL_ARGS
);
...
...
@@ -239,6 +241,7 @@ extern void radeon_do_release(drm_device_t *dev);
#define RADEON_CRTC2_OFFSET 0x0324
#define RADEON_CRTC2_OFFSET_CNTL 0x0328
#define RADEON_RB3D_COLOROFFSET 0x1c40
#define RADEON_RB3D_COLORPITCH 0x1c48
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
...
...
@@ -332,6 +335,7 @@ extern void radeon_do_release(drm_device_t *dev);
#define RADEON_PP_MISC 0x1c14
#define RADEON_PP_ROT_MATRIX_0 0x1d58
#define RADEON_PP_TXFILTER_0 0x1c54
#define RADEON_PP_TXOFFSET_0 0x1c5c
#define RADEON_PP_TXFILTER_1 0x1c6c
#define RADEON_PP_TXFILTER_2 0x1c84
...
...
drivers/char/drm/radeon_irq.c
View file @
4c6b5945
...
...
@@ -54,7 +54,7 @@
* tied to dma at all, this is just a hangover from dri prehistory.
*/
irqreturn_t
DRM
(
dma_service
)(
DRM_IRQ_ARGS
)
irqreturn_t
DRM
(
irq_handler
)(
DRM_IRQ_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_radeon_private_t
*
dev_priv
=
...
...
drivers/char/drm/radeon_state.c
View file @
4c6b5945
...
...
@@ -35,6 +35,240 @@
#include "radeon_drv.h"
/* ================================================================
* Helper functions for client state checking and fixup
*/
static
__inline__
int
radeon_check_and_fixup_offset
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
u32
*
offset
)
{
u32
off
=
*
offset
;
if
(
off
>=
dev_priv
->
fb_location
&&
off
<
(
dev_priv
->
gart_vm_start
+
dev_priv
->
gart_size
)
)
return
0
;
off
+=
filp_priv
->
radeon_fb_delta
;
DRM_DEBUG
(
"offset fixed up to 0x%x
\n
"
,
off
);
if
(
off
<
dev_priv
->
fb_location
||
off
>=
(
dev_priv
->
gart_vm_start
+
dev_priv
->
gart_size
)
)
return
DRM_ERR
(
EINVAL
);
*
offset
=
off
;
return
0
;
}
static
__inline__
int
radeon_check_and_fixup_offset_user
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
u32
*
offset
)
{
u32
off
;
DRM_GET_USER_UNCHECKED
(
off
,
offset
);
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
off
)
)
return
DRM_ERR
(
EINVAL
);
DRM_PUT_USER_UNCHECKED
(
offset
,
off
);
return
0
;
}
static
__inline__
int
radeon_check_and_fixup_packets
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
int
id
,
u32
*
data
)
{
switch
(
id
)
{
case
RADEON_EMIT_PP_MISC
:
if
(
radeon_check_and_fixup_offset_user
(
dev_priv
,
filp_priv
,
&
data
[(
RADEON_RB3D_DEPTHOFFSET
-
RADEON_PP_MISC
)
/
4
]
)
)
{
DRM_ERROR
(
"Invalid depth buffer offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
break
;
case
RADEON_EMIT_PP_CNTL
:
if
(
radeon_check_and_fixup_offset_user
(
dev_priv
,
filp_priv
,
&
data
[(
RADEON_RB3D_COLOROFFSET
-
RADEON_PP_CNTL
)
/
4
]
)
)
{
DRM_ERROR
(
"Invalid colour buffer offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
break
;
case
R200_EMIT_PP_TXOFFSET_0
:
case
R200_EMIT_PP_TXOFFSET_1
:
case
R200_EMIT_PP_TXOFFSET_2
:
case
R200_EMIT_PP_TXOFFSET_3
:
case
R200_EMIT_PP_TXOFFSET_4
:
case
R200_EMIT_PP_TXOFFSET_5
:
if
(
radeon_check_and_fixup_offset_user
(
dev_priv
,
filp_priv
,
&
data
[
0
]
)
)
{
DRM_ERROR
(
"Invalid R200 texture offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
break
;
case
RADEON_EMIT_PP_TXFILTER_0
:
case
RADEON_EMIT_PP_TXFILTER_1
:
case
RADEON_EMIT_PP_TXFILTER_2
:
if
(
radeon_check_and_fixup_offset_user
(
dev_priv
,
filp_priv
,
&
data
[(
RADEON_PP_TXOFFSET_0
-
RADEON_PP_TXFILTER_0
)
/
4
]
)
)
{
DRM_ERROR
(
"Invalid R100 texture offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
break
;
case
R200_EMIT_PP_CUBIC_OFFSETS_0
:
case
R200_EMIT_PP_CUBIC_OFFSETS_1
:
case
R200_EMIT_PP_CUBIC_OFFSETS_2
:
case
R200_EMIT_PP_CUBIC_OFFSETS_3
:
case
R200_EMIT_PP_CUBIC_OFFSETS_4
:
case
R200_EMIT_PP_CUBIC_OFFSETS_5
:
{
int
i
;
for
(
i
=
0
;
i
<
5
;
i
++
)
{
if
(
radeon_check_and_fixup_offset_user
(
dev_priv
,
filp_priv
,
&
data
[
i
]
)
)
{
DRM_ERROR
(
"Invalid R200 cubic texture offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
}
break
;
}
case
RADEON_EMIT_RB3D_COLORPITCH
:
case
RADEON_EMIT_RE_LINE_PATTERN
:
case
RADEON_EMIT_SE_LINE_WIDTH
:
case
RADEON_EMIT_PP_LUM_MATRIX
:
case
RADEON_EMIT_PP_ROT_MATRIX_0
:
case
RADEON_EMIT_RB3D_STENCILREFMASK
:
case
RADEON_EMIT_SE_VPORT_XSCALE
:
case
RADEON_EMIT_SE_CNTL
:
case
RADEON_EMIT_SE_CNTL_STATUS
:
case
RADEON_EMIT_RE_MISC
:
case
RADEON_EMIT_PP_BORDER_COLOR_0
:
case
RADEON_EMIT_PP_BORDER_COLOR_1
:
case
RADEON_EMIT_PP_BORDER_COLOR_2
:
case
RADEON_EMIT_SE_ZBIAS_FACTOR
:
case
RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT
:
case
RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED
:
case
R200_EMIT_PP_TXCBLEND_0
:
case
R200_EMIT_PP_TXCBLEND_1
:
case
R200_EMIT_PP_TXCBLEND_2
:
case
R200_EMIT_PP_TXCBLEND_3
:
case
R200_EMIT_PP_TXCBLEND_4
:
case
R200_EMIT_PP_TXCBLEND_5
:
case
R200_EMIT_PP_TXCBLEND_6
:
case
R200_EMIT_PP_TXCBLEND_7
:
case
R200_EMIT_TCL_LIGHT_MODEL_CTL_0
:
case
R200_EMIT_TFACTOR_0
:
case
R200_EMIT_VTX_FMT_0
:
case
R200_EMIT_VAP_CTL
:
case
R200_EMIT_MATRIX_SELECT_0
:
case
R200_EMIT_TEX_PROC_CTL_2
:
case
R200_EMIT_TCL_UCP_VERT_BLEND_CTL
:
case
R200_EMIT_PP_TXFILTER_0
:
case
R200_EMIT_PP_TXFILTER_1
:
case
R200_EMIT_PP_TXFILTER_2
:
case
R200_EMIT_PP_TXFILTER_3
:
case
R200_EMIT_PP_TXFILTER_4
:
case
R200_EMIT_PP_TXFILTER_5
:
case
R200_EMIT_VTE_CNTL
:
case
R200_EMIT_OUTPUT_VTX_COMP_SEL
:
case
R200_EMIT_PP_TAM_DEBUG3
:
case
R200_EMIT_PP_CNTL_X
:
case
R200_EMIT_RB3D_DEPTHXY_OFFSET
:
case
R200_EMIT_RE_AUX_SCISSOR_CNTL
:
case
R200_EMIT_RE_SCISSOR_TL_0
:
case
R200_EMIT_RE_SCISSOR_TL_1
:
case
R200_EMIT_RE_SCISSOR_TL_2
:
case
R200_EMIT_SE_VAP_CNTL_STATUS
:
case
R200_EMIT_SE_VTX_STATE_CNTL
:
case
R200_EMIT_RE_POINTSIZE
:
case
R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0
:
case
R200_EMIT_PP_CUBIC_FACES_0
:
case
R200_EMIT_PP_CUBIC_FACES_1
:
case
R200_EMIT_PP_CUBIC_FACES_2
:
case
R200_EMIT_PP_CUBIC_FACES_3
:
case
R200_EMIT_PP_CUBIC_FACES_4
:
case
R200_EMIT_PP_CUBIC_FACES_5
:
case
RADEON_EMIT_PP_TEX_SIZE_0
:
case
RADEON_EMIT_PP_TEX_SIZE_1
:
case
RADEON_EMIT_PP_TEX_SIZE_2
:
/* These packets don't contain memory offsets */
break
;
default:
DRM_ERROR
(
"Unknown state packet ID %d
\n
"
,
id
);
return
DRM_ERR
(
EINVAL
);
}
return
0
;
}
static
__inline__
int
radeon_check_and_fixup_packet3
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
drm_radeon_cmd_buffer_t
*
cmdbuf
,
unsigned
int
*
cmdsz
)
{
u32
tmp
[
4
],
*
cmd
=
(
u32
*
)
cmdbuf
->
buf
;
if
(
DRM_COPY_FROM_USER_UNCHECKED
(
tmp
,
cmd
,
sizeof
(
tmp
)
)
)
{
DRM_ERROR
(
"Failed to copy data from user space
\n
"
);
return
DRM_ERR
(
EFAULT
);
}
*
cmdsz
=
2
+
(
(
tmp
[
0
]
&
RADEON_CP_PACKET_COUNT_MASK
)
>>
16
);
if
(
(
tmp
[
0
]
&
0xc0000000
)
!=
RADEON_CP_PACKET3
)
{
DRM_ERROR
(
"Not a type 3 packet
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
if
(
4
*
*
cmdsz
>
cmdbuf
->
bufsz
)
{
DRM_ERROR
(
"Packet size larger than size of data provided
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
/* Check client state and fix it up if necessary */
if
(
tmp
[
0
]
&
0x8000
)
{
/* MSB of opcode: next DWORD GUI_CNTL */
u32
offset
;
if
(
tmp
[
1
]
&
(
RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
RADEON_GMC_DST_PITCH_OFFSET_CNTL
)
)
{
offset
=
tmp
[
2
]
<<
10
;
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
offset
)
)
{
DRM_ERROR
(
"Invalid first packet offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
tmp
[
2
]
=
(
tmp
[
2
]
&
0xffc00000
)
|
offset
>>
10
;
}
if
(
(
tmp
[
1
]
&
RADEON_GMC_SRC_PITCH_OFFSET_CNTL
)
&&
(
tmp
[
1
]
&
RADEON_GMC_DST_PITCH_OFFSET_CNTL
)
)
{
offset
=
tmp
[
3
]
<<
10
;
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
offset
)
)
{
DRM_ERROR
(
"Invalid second packet offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
tmp
[
3
]
=
(
tmp
[
3
]
&
0xffc00000
)
|
offset
>>
10
;
}
if
(
DRM_COPY_TO_USER_UNCHECKED
(
cmd
,
tmp
,
sizeof
(
tmp
)
)
)
{
DRM_ERROR
(
"Failed to copy data to user space
\n
"
);
return
DRM_ERR
(
EFAULT
);
}
}
return
0
;
}
/* ================================================================
* CP hardware state programming functions
*/
...
...
@@ -57,15 +291,28 @@ static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
/* Emit 1.1 state
*/
static
void
radeon_emit_state
(
drm_radeon_private_t
*
dev_priv
,
drm_radeon_context_regs_t
*
ctx
,
drm_radeon_texture_regs_t
*
tex
,
unsigned
int
dirty
)
static
int
radeon_emit_state
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
drm_radeon_context_regs_t
*
ctx
,
drm_radeon_texture_regs_t
*
tex
,
unsigned
int
dirty
)
{
RING_LOCALS
;
DRM_DEBUG
(
"dirty=0x%08x
\n
"
,
dirty
);
if
(
dirty
&
RADEON_UPLOAD_CONTEXT
)
{
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
ctx
->
rb3d_depthoffset
)
)
{
DRM_ERROR
(
"Invalid depth buffer offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
ctx
->
rb3d_coloroffset
)
)
{
DRM_ERROR
(
"Invalid depth buffer offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
BEGIN_RING
(
14
);
OUT_RING
(
CP_PACKET0
(
RADEON_PP_MISC
,
6
)
);
OUT_RING
(
ctx
->
pp_misc
);
...
...
@@ -149,6 +396,12 @@ static void radeon_emit_state( drm_radeon_private_t *dev_priv,
}
if
(
dirty
&
RADEON_UPLOAD_TEX0
)
{
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
tex
[
0
].
pp_txoffset
)
)
{
DRM_ERROR
(
"Invalid texture offset for unit 0
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
BEGIN_RING
(
9
);
OUT_RING
(
CP_PACKET0
(
RADEON_PP_TXFILTER_0
,
5
)
);
OUT_RING
(
tex
[
0
].
pp_txfilter
);
...
...
@@ -163,6 +416,12 @@ static void radeon_emit_state( drm_radeon_private_t *dev_priv,
}
if
(
dirty
&
RADEON_UPLOAD_TEX1
)
{
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
tex
[
1
].
pp_txoffset
)
)
{
DRM_ERROR
(
"Invalid texture offset for unit 1
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
BEGIN_RING
(
9
);
OUT_RING
(
CP_PACKET0
(
RADEON_PP_TXFILTER_1
,
5
)
);
OUT_RING
(
tex
[
1
].
pp_txfilter
);
...
...
@@ -177,6 +436,12 @@ static void radeon_emit_state( drm_radeon_private_t *dev_priv,
}
if
(
dirty
&
RADEON_UPLOAD_TEX2
)
{
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
tex
[
2
].
pp_txoffset
)
)
{
DRM_ERROR
(
"Invalid texture offset for unit 2
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
BEGIN_RING
(
9
);
OUT_RING
(
CP_PACKET0
(
RADEON_PP_TXFILTER_2
,
5
)
);
OUT_RING
(
tex
[
2
].
pp_txfilter
);
...
...
@@ -189,12 +454,15 @@ static void radeon_emit_state( drm_radeon_private_t *dev_priv,
OUT_RING
(
tex
[
2
].
pp_border_color
);
ADVANCE_RING
();
}
return
0
;
}
/* Emit 1.2 state
*/
static
void
radeon_emit_state2
(
drm_radeon_private_t
*
dev_priv
,
drm_radeon_state_t
*
state
)
static
int
radeon_emit_state2
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
drm_radeon_state_t
*
state
)
{
RING_LOCALS
;
...
...
@@ -206,7 +474,7 @@ static void radeon_emit_state2( drm_radeon_private_t *dev_priv,
ADVANCE_RING
();
}
r
adeon_emit_state
(
dev_priv
,
&
state
->
context
,
r
eturn
radeon_emit_state
(
dev_priv
,
filp_priv
,
&
state
->
context
,
state
->
tex
,
state
->
dirty
);
}
...
...
@@ -1065,6 +1333,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
drm_radeon_tex_image_t
*
image
)
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_file_t
*
filp_priv
;
drm_buf_t
*
buf
;
u32
format
;
u32
*
buffer
;
...
...
@@ -1074,6 +1343,13 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
int
i
;
RING_LOCALS
;
DRM_GET_PRIV_WITH_RETURN
(
filp_priv
,
filp
);
if
(
radeon_check_and_fixup_offset
(
dev_priv
,
filp_priv
,
&
tex
->
offset
)
)
{
DRM_ERROR
(
"Invalid destination offset
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
dev_priv
->
stats
.
boxes
|=
RADEON_BOX_TEXTURE_LOAD
;
/* Flush the pixel cache. This ensures no pixel data gets mixed
...
...
@@ -1377,6 +1653,7 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS )
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_file_t
*
filp_priv
;
drm_radeon_sarea_t
*
sarea_priv
=
dev_priv
->
sarea_priv
;
drm_device_dma_t
*
dma
=
dev
->
dma
;
drm_buf_t
*
buf
;
...
...
@@ -1390,6 +1667,8 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS )
return
DRM_ERR
(
EINVAL
);
}
DRM_GET_PRIV_WITH_RETURN
(
filp_priv
,
filp
);
DRM_COPY_FROM_USER_IOCTL
(
vertex
,
(
drm_radeon_vertex_t
*
)
data
,
sizeof
(
vertex
)
);
...
...
@@ -1429,11 +1708,14 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS )
buf
->
used
=
vertex
.
count
;
/* not used? */
if
(
sarea_priv
->
dirty
&
~
RADEON_UPLOAD_CLIPRECTS
)
{
radeon_emit_state
(
dev_priv
,
&
sarea_priv
->
context_state
,
sarea_priv
->
tex_state
,
sarea_priv
->
dirty
);
if
(
radeon_emit_state
(
dev_priv
,
filp_priv
,
&
sarea_priv
->
context_state
,
sarea_priv
->
tex_state
,
sarea_priv
->
dirty
)
)
{
DRM_ERROR
(
"radeon_emit_state failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
sarea_priv
->
dirty
&=
~
(
RADEON_UPLOAD_TEX0IMAGES
|
RADEON_UPLOAD_TEX1IMAGES
|
RADEON_UPLOAD_TEX2IMAGES
|
...
...
@@ -1461,6 +1743,7 @@ int radeon_cp_indices( DRM_IOCTL_ARGS )
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_file_t
*
filp_priv
;
drm_radeon_sarea_t
*
sarea_priv
=
dev_priv
->
sarea_priv
;
drm_device_dma_t
*
dma
=
dev
->
dma
;
drm_buf_t
*
buf
;
...
...
@@ -1475,6 +1758,8 @@ int radeon_cp_indices( DRM_IOCTL_ARGS )
return
DRM_ERR
(
EINVAL
);
}
DRM_GET_PRIV_WITH_RETURN
(
filp_priv
,
filp
);
DRM_COPY_FROM_USER_IOCTL
(
elts
,
(
drm_radeon_indices_t
*
)
data
,
sizeof
(
elts
)
);
...
...
@@ -1523,10 +1808,13 @@ int radeon_cp_indices( DRM_IOCTL_ARGS )
buf
->
used
=
elts
.
end
;
if
(
sarea_priv
->
dirty
&
~
RADEON_UPLOAD_CLIPRECTS
)
{
radeon_emit_state
(
dev_priv
,
&
sarea_priv
->
context_state
,
sarea_priv
->
tex_state
,
sarea_priv
->
dirty
);
if
(
radeon_emit_state
(
dev_priv
,
filp_priv
,
&
sarea_priv
->
context_state
,
sarea_priv
->
tex_state
,
sarea_priv
->
dirty
)
)
{
DRM_ERROR
(
"radeon_emit_state failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
sarea_priv
->
dirty
&=
~
(
RADEON_UPLOAD_TEX0IMAGES
|
RADEON_UPLOAD_TEX1IMAGES
|
...
...
@@ -1686,6 +1974,7 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_file_t
*
filp_priv
;
drm_radeon_sarea_t
*
sarea_priv
=
dev_priv
->
sarea_priv
;
drm_device_dma_t
*
dma
=
dev
->
dma
;
drm_buf_t
*
buf
;
...
...
@@ -1700,6 +1989,8 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
return
DRM_ERR
(
EINVAL
);
}
DRM_GET_PRIV_WITH_RETURN
(
filp_priv
,
filp
);
DRM_COPY_FROM_USER_IOCTL
(
vertex
,
(
drm_radeon_vertex2_t
*
)
data
,
sizeof
(
vertex
)
);
...
...
@@ -1747,7 +2038,10 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
sizeof
(
state
)
)
)
return
DRM_ERR
(
EFAULT
);
radeon_emit_state2
(
dev_priv
,
&
state
);
if
(
radeon_emit_state2
(
dev_priv
,
filp_priv
,
&
state
)
)
{
DRM_ERROR
(
"radeon_emit_state2 failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
laststate
=
prim
.
stateidx
;
}
...
...
@@ -1784,6 +2078,7 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
static
int
radeon_emit_packets
(
drm_radeon_private_t
*
dev_priv
,
drm_file_t
*
filp_priv
,
drm_radeon_cmd_header_t
header
,
drm_radeon_cmd_buffer_t
*
cmdbuf
)
{
...
...
@@ -1798,8 +2093,15 @@ static int radeon_emit_packets(
sz
=
packet
[
id
].
len
;
reg
=
packet
[
id
].
start
;
if
(
sz
*
sizeof
(
int
)
>
cmdbuf
->
bufsz
)
if
(
sz
*
sizeof
(
int
)
>
cmdbuf
->
bufsz
)
{
DRM_ERROR
(
"Packet size provided larger than data provided
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
if
(
radeon_check_and_fixup_packets
(
dev_priv
,
filp_priv
,
id
,
data
)
)
{
DRM_ERROR
(
"Packet verification failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
BEGIN_RING
(
sz
+
1
);
OUT_RING
(
CP_PACKET0
(
reg
,
(
sz
-
1
)
)
);
...
...
@@ -1882,24 +2184,21 @@ static __inline__ int radeon_emit_vectors(
static
int
radeon_emit_packet3
(
drm_device_t
*
dev
,
drm_file_t
*
filp_priv
,
drm_radeon_cmd_buffer_t
*
cmdbuf
)
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
int
cmdsz
,
tmp
;
int
*
cmd
=
(
int
*
)
cmdbuf
->
buf
;
unsigned
int
cmdsz
;
int
*
cmd
=
(
int
*
)
cmdbuf
->
buf
,
ret
;
RING_LOCALS
;
DRM_DEBUG
(
"
\n
"
);
if
(
DRM_GET_USER_UNCHECKED
(
tmp
,
&
cmd
[
0
]))
return
DRM_ERR
(
EFAULT
);
cmdsz
=
2
+
((
tmp
&
RADEON_CP_PACKET_COUNT_MASK
)
>>
16
);
if
((
tmp
&
0xc0000000
)
!=
RADEON_CP_PACKET3
||
cmdsz
*
4
>
cmdbuf
->
bufsz
)
return
DRM_ERR
(
EINVAL
);
if
(
(
ret
=
radeon_check_and_fixup_packet3
(
dev_priv
,
filp_priv
,
cmdbuf
,
&
cmdsz
)
)
)
{
DRM_ERROR
(
"Packet verification failed
\n
"
);
return
ret
;
}
BEGIN_RING
(
cmdsz
);
OUT_RING_USER_TABLE
(
cmd
,
cmdsz
);
...
...
@@ -1912,27 +2211,25 @@ static int radeon_emit_packet3( drm_device_t *dev,
static
int
radeon_emit_packet3_cliprect
(
drm_device_t
*
dev
,
drm_file_t
*
filp_priv
,
drm_radeon_cmd_buffer_t
*
cmdbuf
,
int
orig_nbox
)
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_clip_rect_t
box
;
int
cmdsz
,
tmp
;
int
*
cmd
=
(
int
*
)
cmdbuf
->
buf
;
unsigned
int
cmdsz
;
int
*
cmd
=
(
int
*
)
cmdbuf
->
buf
,
ret
;
drm_clip_rect_t
*
boxes
=
cmdbuf
->
boxes
;
int
i
=
0
;
RING_LOCALS
;
DRM_DEBUG
(
"
\n
"
);
if
(
DRM_GET_USER_UNCHECKED
(
tmp
,
&
cmd
[
0
]))
return
DRM_ERR
(
EFAULT
);
cmdsz
=
2
+
((
tmp
&
RADEON_CP_PACKET_COUNT_MASK
)
>>
16
);
if
((
tmp
&
0xc0000000
)
!=
RADEON_CP_PACKET3
||
cmdsz
*
4
>
cmdbuf
->
bufsz
)
return
DRM_ERR
(
EINVAL
);
if
(
(
ret
=
radeon_check_and_fixup_packet3
(
dev_priv
,
filp_priv
,
cmdbuf
,
&
cmdsz
)
)
)
{
DRM_ERROR
(
"Packet verification failed
\n
"
);
return
ret
;
}
if
(
!
orig_nbox
)
goto
out
;
...
...
@@ -2009,6 +2306,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_file_t
*
filp_priv
;
drm_device_dma_t
*
dma
=
dev
->
dma
;
drm_buf_t
*
buf
=
0
;
int
idx
;
...
...
@@ -2023,6 +2321,8 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
return
DRM_ERR
(
EINVAL
);
}
DRM_GET_PRIV_WITH_RETURN
(
filp_priv
,
filp
);
DRM_COPY_FROM_USER_IOCTL
(
cmdbuf
,
(
drm_radeon_cmd_buffer_t
*
)
data
,
sizeof
(
cmdbuf
)
);
...
...
@@ -2053,7 +2353,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
switch
(
header
.
header
.
cmd_type
)
{
case
RADEON_CMD_PACKET
:
DRM_DEBUG
(
"RADEON_CMD_PACKET
\n
"
);
if
(
radeon_emit_packets
(
dev_priv
,
header
,
&
cmdbuf
))
{
if
(
radeon_emit_packets
(
dev_priv
,
filp_priv
,
header
,
&
cmdbuf
))
{
DRM_ERROR
(
"radeon_emit_packets failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
...
...
@@ -2096,7 +2396,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case
RADEON_CMD_PACKET3
:
DRM_DEBUG
(
"RADEON_CMD_PACKET3
\n
"
);
if
(
radeon_emit_packet3
(
dev
,
&
cmdbuf
))
{
if
(
radeon_emit_packet3
(
dev
,
filp_priv
,
&
cmdbuf
))
{
DRM_ERROR
(
"radeon_emit_packet3 failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
...
...
@@ -2104,7 +2404,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
case
RADEON_CMD_PACKET3_CLIP
:
DRM_DEBUG
(
"RADEON_CMD_PACKET3_CLIP
\n
"
);
if
(
radeon_emit_packet3_cliprect
(
dev
,
&
cmdbuf
,
orig_nbox
))
{
if
(
radeon_emit_packet3_cliprect
(
dev
,
filp_priv
,
&
cmdbuf
,
orig_nbox
))
{
DRM_ERROR
(
"radeon_emit_packet3_clip failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
...
...
@@ -2214,3 +2514,31 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS )
return
0
;
}
int
radeon_cp_setparam
(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_file_t
*
filp_priv
;
drm_radeon_setparam_t
sp
;
if
(
!
dev_priv
)
{
DRM_ERROR
(
"%s called with no initialization
\n
"
,
__FUNCTION__
);
return
DRM_ERR
(
EINVAL
);
}
DRM_GET_PRIV_WITH_RETURN
(
filp_priv
,
filp
);
DRM_COPY_FROM_USER_IOCTL
(
sp
,
(
drm_radeon_setparam_t
*
)
data
,
sizeof
(
sp
)
);
switch
(
sp
.
param
)
{
case
RADEON_SETPARAM_FB_LOCATION
:
filp_priv
->
radeon_fb_delta
=
dev_priv
->
fb_location
-
sp
.
value
;
break
;
default:
DRM_DEBUG
(
"Invalid parameter %d
\n
"
,
sp
.
param
);
return
DRM_ERR
(
EINVAL
);
}
return
0
;
}
drivers/char/drm/tdfx.h
View file @
4c6b5945
...
...
@@ -39,4 +39,14 @@
#define __HAVE_MTRR 1
#define __HAVE_CTX_BITMAP 1
#define DRIVER_AUTHOR "VA Linux Systems Inc."
#define DRIVER_NAME "tdfx"
#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
#endif
drivers/char/drm/tdfx_drv.c
View file @
4c6b5945
...
...
@@ -34,47 +34,6 @@
#include "tdfx.h"
#include "drmP.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc."
#define DRIVER_NAME "tdfx"
#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
#ifndef PCI_VENDOR_ID_3DFX
#define PCI_VENDOR_ID_3DFX 0x121A
#endif
#ifndef PCI_DEVICE_ID_3DFX_VOODOO5
#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
#endif
#ifndef PCI_DEVICE_ID_3DFX_VOODOO4
#define PCI_DEVICE_ID_3DFX_VOODOO4 0x0007
#endif
#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_3000
/* Voodoo3 3000 */
#define PCI_DEVICE_ID_3DFX_VOODOO3_3000 0x0005
#endif
#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_2000
/* Voodoo3 3000 */
#define PCI_DEVICE_ID_3DFX_VOODOO3_2000 0x0004
#endif
#ifndef PCI_DEVICE_ID_3DFX_BANSHEE
#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
#endif
static
drm_pci_list_t
DRM
(
idlist
)[]
=
{
{
PCI_VENDOR_ID_3DFX
,
PCI_DEVICE_ID_3DFX_BANSHEE
},
{
PCI_VENDOR_ID_3DFX
,
PCI_DEVICE_ID_3DFX_VOODOO3_2000
},
{
PCI_VENDOR_ID_3DFX
,
PCI_DEVICE_ID_3DFX_VOODOO3_3000
},
{
PCI_VENDOR_ID_3DFX
,
PCI_DEVICE_ID_3DFX_VOODOO4
},
{
PCI_VENDOR_ID_3DFX
,
PCI_DEVICE_ID_3DFX_VOODOO5
},
{
0
,
0
}
};
#define DRIVER_CARD_LIST DRM(idlist)
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment