diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 26c254af..8b97c7da 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -816,7 +816,7 @@ int drmAgpVersionMajor(int fd) { drm_agp_info_t i; - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; return i.agp_version_major; } diff --git a/linux-core/drmP.h b/linux-core/drmP.h index abf82e92..f8e78eab 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -53,7 +53,7 @@ #include #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -#include +#include #include #endif #include "drm.h" diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index baece7a2..30fda5b8 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -33,7 +33,6 @@ #define __NO_VERSION__ #include "drmP.h" -#include "i810_drm_public.h" #include "i810_drv.h" #include /* For task queue support */ @@ -406,7 +405,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *box = sarea_priv->boxes; + drm_clip_rect_t *box = sarea_priv->boxes; int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; @@ -821,6 +820,11 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; DRM_DEBUG("i810_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_flush_ioctl called without lock held\n"); + return -EINVAL; + } + i810_flush_queue(dev); return 0; } @@ -869,6 +873,11 @@ int i810_dma_general(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma general idx %d used %d\n", general.idx, general.used); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_general called without lock held\n"); + return -EINVAL; + } + retcode = i810DmaGeneral(dev, &general); sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; @@ -890,7 +899,11 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), -EFAULT); - + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_vertex called without lock held\n"); + return -EINVAL; + } + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", vertex.idx, vertex.used, vertex.discard); @@ -933,6 +946,11 @@ int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd, copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return -EINVAL; + } /* Please don't send us buffers. */ diff --git a/linux-core/i810_drm.h b/linux-core/i810_drm.h new file mode 100644 index 00000000..0754874c --- /dev/null +++ b/linux-core/i810_drm.h @@ -0,0 +1,93 @@ +#ifndef _I810_DRM_H_ +#define _I810_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +/* Might one day want to support the client-side ringbuffer code again. + */ +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ + +#define I810_USE_BATCH 1 +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1< #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -#include +#include #include #endif #include "drm.h" diff --git a/linux/i810_dma.c b/linux/i810_dma.c index baece7a2..30fda5b8 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -33,7 +33,6 @@ #define __NO_VERSION__ #include "drmP.h" -#include "i810_drm_public.h" #include "i810_drv.h" #include /* For task queue support */ @@ -406,7 +405,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *box = sarea_priv->boxes; + drm_clip_rect_t *box = sarea_priv->boxes; int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; @@ -821,6 +820,11 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; DRM_DEBUG("i810_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_flush_ioctl called without lock held\n"); + return -EINVAL; + } + i810_flush_queue(dev); return 0; } @@ -869,6 +873,11 @@ int i810_dma_general(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma general idx %d used %d\n", general.idx, general.used); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_general called without lock held\n"); + return -EINVAL; + } + retcode = i810DmaGeneral(dev, &general); sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; @@ -890,7 +899,11 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), -EFAULT); - + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_vertex called without lock held\n"); + return -EINVAL; + } + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", vertex.idx, vertex.used, vertex.discard); @@ -933,6 +946,11 @@ int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd, copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return -EINVAL; + } /* Please don't send us buffers. */ diff --git a/linux/i810_drm.h b/linux/i810_drm.h new file mode 100644 index 00000000..0754874c --- /dev/null +++ b/linux/i810_drm.h @@ -0,0 +1,93 @@ +#ifndef _I810_DRM_H_ +#define _I810_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +/* Might one day want to support the client-side ringbuffer code again. + */ +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ + +#define I810_USE_BATCH 1 +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1< - * Keith Whitwell - * - * $XFree86$ - */ - -#ifndef _I810_DRM_H_ -#define _I810_DRM_H_ - -typedef struct drm_i810_init { - enum { - I810_INIT_DMA = 0x01, - I810_CLEANUP_DMA = 0x02 - } func; - int ring_map_idx; - int buffer_map_idx; - int sarea_priv_offset; - unsigned long ring_start; - unsigned long ring_end; - unsigned long ring_size; - -} drm_i810_init_t; - -typedef struct _xf86drmClipRectRec { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -} xf86drmClipRectRec; - -/* Might one day want to support the client-side ringbuffer code again. - */ - -#define I810_USE_BATCH 1 - -#define I810_DMA_BUF_ORDER 12 -#define I810_DMA_BUF_SZ (1<mAccess); memcpy(&dev_priv->WarpIndex, &init->WarpIndex, - sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); + sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES); for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n", @@ -1116,7 +1116,12 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp, int i; copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); - + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_flush_ioctl called without lock held\n"); + return -EINVAL; + } + if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) { mga_flush_queue(dev); diff --git a/linux/mga_drm_public.h b/linux/mga_drm.h similarity index 86% rename from linux/mga_drm_public.h rename to linux/mga_drm.h index 29b06a11..12a858e7 100644 --- a/linux/mga_drm_public.h +++ b/linux/mga_drm.h @@ -1,4 +1,4 @@ -/* mga_drm_public.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- +/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -29,9 +29,14 @@ * $XFree86$ */ -#ifndef _MGA_DRM_PUBLIC_H_ -#define _MGA_DRM_PUBLIC_H_ +#ifndef _MGA_DRM_H_ +#define _MGA_DRM_H_ +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmMga.h) + */ +#ifndef _MGA_DEFINES_ +#define _MGA_DEFINES_ #define MGA_F 0x1 /* fog */ #define MGA_A 0x2 /* alpha */ #define MGA_S 0x4 /* specular */ @@ -61,52 +66,10 @@ #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 - - -typedef struct _drm_mga_warp_index { - int installed; - unsigned long phys_addr; - int size; -} mgaWarpIndex; - -typedef struct drm_mga_init { - enum { - MGA_INIT_DMA = 0x01, - MGA_CLEANUP_DMA = 0x02 - } func; - int reserved_map_agpstart; - int reserved_map_idx; - int buffer_map_idx; - int sarea_priv_offset; - int primary_size; - int warp_ucode_size; - int frontOffset; - int backOffset; - int depthOffset; - int textureOffset; - int textureSize; - int agpTextureOffset; - int agpTextureSize; - int cpp; - int stride; - int sgram; - int chipset; - mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; - int mAccess; -} drm_mga_init_t; - -typedef struct _xf86drmClipRectRec { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -} xf86drmClipRectRec; - #define MGA_FRONT 0x1 #define MGA_BACK 0x2 #define MGA_DEPTH 0x4 - /* 3d state excluding texture units: */ #define MGA_CTXREG_DSTORG 0 /* validated */ @@ -155,42 +118,72 @@ typedef struct _xf86drmClipRectRec { #define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock quiescent */ - /* 64 buffers of 16k each, total 1 meg. */ #define MGA_DMA_BUF_ORDER 14 #define MGA_DMA_BUF_SZ (1<sarea_priv; unsigned int *regs = sarea_priv->ContextState; @@ -546,7 +546,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags, drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; int nbox = sarea_priv->nbox; - xf86drmClipRectRec *pbox = sarea_priv->boxes; + drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int cmd; int i; int primary_needed; @@ -629,7 +629,7 @@ static void mga_dma_dispatch_swap( drm_device_t *dev ) drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; int nbox = sarea_priv->nbox; - xf86drmClipRectRec *pbox = sarea_priv->boxes; + drm_clip_rect_t *pbox = sarea_priv->boxes; int i; int primary_needed; PRIMLOCALS; @@ -687,11 +687,15 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; __volatile__ unsigned int *status = (__volatile__ unsigned int *)dev_priv->status_page; - drm_mga_clear_t clear; copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear), -EFAULT); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_clear_bufs called without lock held\n"); + return -EINVAL; + } if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; @@ -718,6 +722,11 @@ int mga_swap_bufs(struct inode *inode, struct file *filp, __volatile__ unsigned int *status = (__volatile__ unsigned int *)dev_priv->status_page; + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_swap_bufs called without lock held\n"); + return -EINVAL; + } + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; @@ -752,6 +761,11 @@ int mga_iload(struct inode *inode, struct file *filp, copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload), -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_iload called without lock held\n"); + return -EINVAL; + } + buf = dma->buflist[ iload.idx ]; buf_priv = buf->dev_private; bus_address = buf->bus_address; @@ -795,6 +809,10 @@ int mga_vertex(struct inode *inode, struct file *filp, copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex), -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_vertex called without lock held\n"); + return -EINVAL; + } DRM_DEBUG("mga_vertex\n"); @@ -859,6 +877,11 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_dma called without lock held\n"); + return -EINVAL; + } + /* Please don't send us buffers. */ if (d.send_count != 0) { diff --git a/shared-core/drm.h b/shared-core/drm.h index ebc6f7e7..ae4c65ca 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -61,6 +61,19 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -321,5 +334,19 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) -/* 0x40 is reserved for mga dma init */ +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + #endif diff --git a/shared/drm.h b/shared/drm.h index ebc6f7e7..ae4c65ca 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -61,6 +61,19 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -321,5 +334,19 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) -/* 0x40 is reserved for mga dma init */ +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + #endif