mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 16:00:13 +01:00
Work in progress checkin
This commit is contained in:
parent
0c9c9a805d
commit
8e20fb13f3
13 changed files with 1209 additions and 82 deletions
|
|
@ -13,7 +13,7 @@
|
|||
L_TARGET := libdrm.a
|
||||
|
||||
L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
|
||||
M_OBJS :=
|
||||
|
||||
|
|
@ -25,6 +25,10 @@ ifdef CONFIG_DRM_TDFX
|
|||
M_OBJS += tdfx.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRM_MGA
|
||||
M_OBJS += mga.o
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/Rules.make
|
||||
|
||||
gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
|
||||
|
|
@ -32,3 +36,7 @@ gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
|
|||
|
||||
tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET)
|
||||
$(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm
|
||||
|
||||
mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET)
|
||||
$(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_context.o mga_bufs.o mga_dma.o -L. -ldrm
|
||||
|
||||
|
|
|
|||
|
|
@ -70,24 +70,27 @@
|
|||
#define DRM_FLAG_DEBUG 0x01
|
||||
#define DRM_FLAG_NOCTX 0x02
|
||||
|
||||
#define DRM_MEM_DMA 0
|
||||
#define DRM_MEM_SAREA 1
|
||||
#define DRM_MEM_DRIVER 2
|
||||
#define DRM_MEM_MAGIC 3
|
||||
#define DRM_MEM_IOCTLS 4
|
||||
#define DRM_MEM_MAPS 5
|
||||
#define DRM_MEM_VMAS 6
|
||||
#define DRM_MEM_BUFS 7
|
||||
#define DRM_MEM_SEGS 8
|
||||
#define DRM_MEM_PAGES 9
|
||||
#define DRM_MEM_FILES 10
|
||||
#define DRM_MEM_QUEUES 11
|
||||
#define DRM_MEM_CMDS 12
|
||||
#define DRM_MEM_MAPPINGS 13
|
||||
#define DRM_MEM_BUFLISTS 14
|
||||
#define DRM_MEM_AGPLISTS 15
|
||||
#define DRM_MEM_TOTALAGP 16
|
||||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_DMA 0
|
||||
#define DRM_MEM_SAREA 1
|
||||
#define DRM_MEM_DRIVER 2
|
||||
#define DRM_MEM_MAGIC 3
|
||||
#define DRM_MEM_IOCTLS 4
|
||||
#define DRM_MEM_MAPS 5
|
||||
#define DRM_MEM_VMAS 6
|
||||
#define DRM_MEM_BUFS 7
|
||||
#define DRM_MEM_SEGS 8
|
||||
#define DRM_MEM_PAGES 9
|
||||
#define DRM_MEM_FILES 10
|
||||
#define DRM_MEM_QUEUES 11
|
||||
#define DRM_MEM_CMDS 12
|
||||
#define DRM_MEM_MAPPINGS 13
|
||||
#define DRM_MEM_BUFLISTS 14
|
||||
#define DRM_MEM_AGPLISTS 15
|
||||
#define DRM_MEM_TOTALAGP 16
|
||||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_CTXBITMAP 18
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 4 * 8)
|
||||
|
||||
/* Backward compatibility section */
|
||||
/* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
|
||||
|
|
@ -504,6 +507,7 @@ typedef struct drm_device {
|
|||
#ifdef DRM_AGP
|
||||
drm_agp_head_t *agp;
|
||||
#endif
|
||||
unsigned long *ctx_bitmap;
|
||||
} drm_device_t;
|
||||
|
||||
|
||||
|
|
@ -692,6 +696,12 @@ extern int drm_flush_unblock(drm_device_t *dev, int context,
|
|||
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
|
||||
drm_lock_flags_t flags);
|
||||
|
||||
/* Context Bitmap support (ctxbitmap.c) */
|
||||
extern int drm_ctxbitmap_init(drm_device_t *dev);
|
||||
extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
|
||||
extern int drm_ctxbitmap_next(drm_device_t *dev);
|
||||
extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
|
||||
|
||||
#ifdef DRM_AGP
|
||||
/* AGP/GART support (agpsupport.c) */
|
||||
extern drm_agp_head_t *drm_agp_init(void);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*-
|
||||
* Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
|
||||
* Revised: Mon Dec 13 02:26:34 1999 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
|
|
@ -23,7 +22,11 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
|
||||
* Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -70,26 +73,36 @@ static drm_ioctl_desc_t mga_ioctls[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
|
||||
[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 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_unbind, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_bind, 1, 1},
|
||||
};
|
||||
|
||||
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
|
||||
|
||||
#ifdef MODULE
|
||||
|
|
@ -269,6 +282,8 @@ static int mga_takedown(drm_device_t *dev)
|
|||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
break;
|
||||
}
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
|
|
@ -319,6 +334,10 @@ int mga_init(void)
|
|||
DRM_DEBUG("\n");
|
||||
|
||||
memset((void *)dev, 0, sizeof(*dev));
|
||||
if((retcode = drm_ctxbitmap_init(dev))) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
return retcode;
|
||||
}
|
||||
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
||||
sema_init(&dev->struct_sem, 1);
|
||||
|
||||
|
|
@ -328,6 +347,7 @@ int mga_init(void)
|
|||
|
||||
if ((retcode = misc_register(&mga_misc))) {
|
||||
DRM_ERROR("Cannot register \"%s\"\n", MGA_NAME);
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
return retcode;
|
||||
}
|
||||
dev->device = MKDEV(MISC_MAJOR, mga_misc.minor);
|
||||
|
|
@ -343,7 +363,9 @@ int mga_init(void)
|
|||
MGA_PATCHLEVEL,
|
||||
MGA_DATE,
|
||||
mga_misc.minor);
|
||||
|
||||
|
||||
dev->agp = drm_agp_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -362,6 +384,7 @@ void mga_cleanup(void)
|
|||
DRM_INFO("Module unloaded\n");
|
||||
}
|
||||
mga_takedown(dev);
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
}
|
||||
|
||||
int mga_version(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
|
|
@ -484,6 +507,151 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int mga_lock(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;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
int ret = 0;
|
||||
drm_lock_t lock;
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
cycles_t start;
|
||||
|
||||
dev->lck_start = start = get_cycles();
|
||||
#endif
|
||||
|
||||
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid, dev->lock.hw_lock->lock,
|
||||
lock.flags);
|
||||
|
||||
#if 0
|
||||
/* dev->queue_count == 0 right now for
|
||||
mga. FIXME? */
|
||||
if (lock.context < 0 || lock.context >= dev->queue_count)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if 0
|
||||
if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
|
||||
!= lock.context) {
|
||||
long j = jiffies - dev->lock.lock_time;
|
||||
|
||||
if (lock.context == mga_res_ctx.handle &&
|
||||
j >= 0 && j < DRM_LOCK_SLICE) {
|
||||
/* Can't take lock if we just had it and
|
||||
there is contention. */
|
||||
DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
|
||||
lock.context, current->pid, j,
|
||||
dev->lock.lock_time, jiffies);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule_timeout(DRM_LOCK_SLICE-j);
|
||||
DRM_DEBUG("jiffies=%d\n", jiffies);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
lock.context)) {
|
||||
dev->lock.pid = current->pid;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->total_locks);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
#if 1
|
||||
current->policy |= SCHED_YIELD;
|
||||
#endif
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!ret && dev->last_context != lock.context &&
|
||||
lock.context != mga_res_ctx.handle &&
|
||||
dev->last_context != mga_res_ctx.handle) {
|
||||
add_wait_queue(&dev->context_wait, &entry);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
/* PRE: dev->last_context != lock.context */
|
||||
mga_context_switch(dev, dev->last_context, lock.context);
|
||||
/* POST: we will wait for the context
|
||||
switch and will dispatch on a later call
|
||||
when dev->last_context == lock.context
|
||||
NOTE WE HOLD THE LOCK THROUGHOUT THIS
|
||||
TIME! */
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule();
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->context_wait, &entry);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
} else if (dev->last_context != lock.context) {
|
||||
DRM_ERROR("Context mismatch: %d %d\n",
|
||||
dev->last_context, lock.context);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
/* Make hardware quiescent */
|
||||
#if 0
|
||||
mga_quiescent(dev);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
DRM_ERROR("pid = %5d, old counter = %5ld\n",
|
||||
current->pid, current->counter);
|
||||
#endif
|
||||
if (lock.context != mga_res_ctx.handle) {
|
||||
current->counter = 5;
|
||||
current->priority = DEF_PRIORITY/4;
|
||||
}
|
||||
#if 0
|
||||
while (current->counter > 25)
|
||||
current->counter >>= 1; /* decrease time slice */
|
||||
DRM_ERROR("pid = %5d, new counter = %5ld\n",
|
||||
current->pid, current->counter);
|
||||
#endif
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
L_TARGET := libdrm.a
|
||||
|
||||
L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
|
||||
M_OBJS :=
|
||||
|
||||
|
|
@ -25,6 +25,10 @@ ifdef CONFIG_DRM_TDFX
|
|||
M_OBJS += tdfx.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRM_MGA
|
||||
M_OBJS += mga.o
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/Rules.make
|
||||
|
||||
gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
|
||||
|
|
@ -32,3 +36,7 @@ gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
|
|||
|
||||
tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET)
|
||||
$(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm
|
||||
|
||||
mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET)
|
||||
$(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_context.o mga_bufs.o mga_dma.o -L. -ldrm
|
||||
|
||||
|
|
|
|||
|
|
@ -56,12 +56,12 @@ MODVERSIONS := $(shell \
|
|||
|
||||
# **** End of SMP/MODVERSIONS detection
|
||||
|
||||
MODS= gamma.o tdfx.o r128.o
|
||||
MODS= gamma.o tdfx.o mga.o
|
||||
LIBS= libdrm.a
|
||||
PROGS= drmstat
|
||||
|
||||
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.c
|
||||
DRMHEADERS= drm.h drmP.h
|
||||
|
||||
GAMMAOBJS= gamma_drv.o gamma_dma.o
|
||||
|
|
@ -70,8 +70,8 @@ GAMMAHEADERS= gamma_drv.h $(DRMHEADERS)
|
|||
TDFXOBJS= tdfx_drv.o tdfx_context.o
|
||||
TDFXHEADERS= tdfx_drv.h $(DRMHEADERS)
|
||||
|
||||
R128OBJS= r128_drv.o r128_context.o
|
||||
R128HEADERS= r128_drv.h $(DRMHEADERS)
|
||||
MGAOBJS= mga_drv.o mga_context.o mga_dma.o mga_bufs.o
|
||||
MGAHEADERS= mga_drv.h $(DRMHEADERS)
|
||||
|
||||
PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po
|
||||
PROGHEADERS= xf86drm.h $(DRMHEADERS)
|
||||
|
|
@ -111,7 +111,7 @@ gamma.o: $(GAMMAOBJS) $(LIBS)
|
|||
tdfx.o: $(TDFXOBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
r128.o: $(R128OBJS) $(LIBS)
|
||||
mga.o: $(MGAOBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
drmstat: $(PROGOBJS)
|
||||
|
|
@ -135,7 +135,7 @@ ChangeLog:
|
|||
$(DRMOBJS): $(DRMHEADERS)
|
||||
$(GAMMAOBJS): $(GAMMAHEADERS)
|
||||
$(TDFXOBJS): $(TDFXHEADERS)
|
||||
$(R128OBJS): $(R128HEADERS)
|
||||
$(MGAOBJS): $(MGAHEADERS)
|
||||
$(PROGOBJS): $(PROGHEADERS)
|
||||
|
||||
clean:
|
||||
|
|
|
|||
80
linux/ctxbitmap.c
Normal file
80
linux/ctxbitmap.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* ctxbitmap.c -- Context bitmap management -*- linux-c -*-
|
||||
* Created: Thu Jan 6 03:56:42 2000 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* 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
|
||||
* PRECISION INSIGHT 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.
|
||||
*
|
||||
* Author: Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle)
|
||||
{
|
||||
if (ctx_handle < 0) goto failed;
|
||||
|
||||
if (ctx_handle < DRM_MAX_CTXBITMAP) {
|
||||
clear_bit(ctx_handle, dev->ctx_bitmap);
|
||||
return;
|
||||
}
|
||||
failed:
|
||||
DRM_DEBUG("Attempt to free invalid context handle: %d\n",
|
||||
ctx_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
int drm_ctxbitmap_next(drm_device_t *dev)
|
||||
{
|
||||
int bit;
|
||||
|
||||
bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
|
||||
if (bit < DRM_MAX_CTXBITMAP) {
|
||||
set_bit(bit, dev->ctx_bitmap);
|
||||
return bit;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int drm_ctxbitmap_init(drm_device_t *dev)
|
||||
{
|
||||
dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE * 4,
|
||||
DRM_MEM_CTXBITMAP);
|
||||
if(dev->ctx_bitmap == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE * 4);
|
||||
for(i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
drm_ctxbitmap_next(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drm_ctxbitmap_cleanup(drm_device_t *dev)
|
||||
{
|
||||
drm_free((void *)dev->ctx_bitmap, PAGE_SIZE * 4,
|
||||
DRM_MEM_CTXBITMAP);
|
||||
}
|
||||
|
||||
46
linux/drmP.h
46
linux/drmP.h
|
|
@ -70,24 +70,27 @@
|
|||
#define DRM_FLAG_DEBUG 0x01
|
||||
#define DRM_FLAG_NOCTX 0x02
|
||||
|
||||
#define DRM_MEM_DMA 0
|
||||
#define DRM_MEM_SAREA 1
|
||||
#define DRM_MEM_DRIVER 2
|
||||
#define DRM_MEM_MAGIC 3
|
||||
#define DRM_MEM_IOCTLS 4
|
||||
#define DRM_MEM_MAPS 5
|
||||
#define DRM_MEM_VMAS 6
|
||||
#define DRM_MEM_BUFS 7
|
||||
#define DRM_MEM_SEGS 8
|
||||
#define DRM_MEM_PAGES 9
|
||||
#define DRM_MEM_FILES 10
|
||||
#define DRM_MEM_QUEUES 11
|
||||
#define DRM_MEM_CMDS 12
|
||||
#define DRM_MEM_MAPPINGS 13
|
||||
#define DRM_MEM_BUFLISTS 14
|
||||
#define DRM_MEM_AGPLISTS 15
|
||||
#define DRM_MEM_TOTALAGP 16
|
||||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_DMA 0
|
||||
#define DRM_MEM_SAREA 1
|
||||
#define DRM_MEM_DRIVER 2
|
||||
#define DRM_MEM_MAGIC 3
|
||||
#define DRM_MEM_IOCTLS 4
|
||||
#define DRM_MEM_MAPS 5
|
||||
#define DRM_MEM_VMAS 6
|
||||
#define DRM_MEM_BUFS 7
|
||||
#define DRM_MEM_SEGS 8
|
||||
#define DRM_MEM_PAGES 9
|
||||
#define DRM_MEM_FILES 10
|
||||
#define DRM_MEM_QUEUES 11
|
||||
#define DRM_MEM_CMDS 12
|
||||
#define DRM_MEM_MAPPINGS 13
|
||||
#define DRM_MEM_BUFLISTS 14
|
||||
#define DRM_MEM_AGPLISTS 15
|
||||
#define DRM_MEM_TOTALAGP 16
|
||||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_CTXBITMAP 18
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 4 * 8)
|
||||
|
||||
/* Backward compatibility section */
|
||||
/* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
|
||||
|
|
@ -504,6 +507,7 @@ typedef struct drm_device {
|
|||
#ifdef DRM_AGP
|
||||
drm_agp_head_t *agp;
|
||||
#endif
|
||||
unsigned long *ctx_bitmap;
|
||||
} drm_device_t;
|
||||
|
||||
|
||||
|
|
@ -692,6 +696,12 @@ extern int drm_flush_unblock(drm_device_t *dev, int context,
|
|||
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
|
||||
drm_lock_flags_t flags);
|
||||
|
||||
/* Context Bitmap support (ctxbitmap.c) */
|
||||
extern int drm_ctxbitmap_init(drm_device_t *dev);
|
||||
extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
|
||||
extern int drm_ctxbitmap_next(drm_device_t *dev);
|
||||
extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
|
||||
|
||||
#ifdef DRM_AGP
|
||||
/* AGP/GART support (agpsupport.c) */
|
||||
extern drm_agp_head_t *drm_agp_init(void);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ static drm_mem_stats_t drm_mem_stats[] = {
|
|||
[DRM_MEM_AGPLISTS] = { "agplist" },
|
||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
{ NULL, 0, } /* Last entry must be null */
|
||||
};
|
||||
|
||||
|
|
|
|||
427
linux/mga_bufs.c
Normal file
427
linux/mga_bufs.c
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
/* mga_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
|
||||
* Created: Thu Jan 6 01:47:26 2000 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* 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
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
|
||||
* Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*
|
||||
*/
|
||||
|
||||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
#include "linux/un.h"
|
||||
|
||||
int mga_addbufs(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_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
int count;
|
||||
int order;
|
||||
int size;
|
||||
int total;
|
||||
int page_order;
|
||||
drm_buf_entry_t *entry;
|
||||
unsigned long page;
|
||||
drm_buf_t *buf;
|
||||
int alignment;
|
||||
unsigned long offset;
|
||||
int i;
|
||||
int byte_count;
|
||||
int page_count;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
copy_from_user_ret(&request,
|
||||
(drm_buf_desc_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
count = request.count;
|
||||
order = drm_order(request.size);
|
||||
size = 1 << order;
|
||||
|
||||
DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
|
||||
request.count, request.size, size, order, dev->queue_count);
|
||||
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
|
||||
if (dev->queue_count) return -EBUSY; /* Not while in use */
|
||||
|
||||
alignment = (request.flags & DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
|
||||
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
|
||||
total = PAGE_SIZE << page_order;
|
||||
|
||||
spin_lock(&dev->count_lock);
|
||||
if (dev->buf_use) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
atomic_inc(&dev->buf_alloc);
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
down(&dev->struct_sem);
|
||||
entry = &dma->bufs[order];
|
||||
if (entry->buf_count) {
|
||||
up(&dev->struct_sem);
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM; /* May only call once for each order */
|
||||
}
|
||||
|
||||
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
if (!entry->buflist) {
|
||||
up(&dev->struct_sem);
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->buflist, 0, count * sizeof(*entry->buflist));
|
||||
|
||||
entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
|
||||
DRM_MEM_SEGS);
|
||||
if (!entry->seglist) {
|
||||
drm_free(entry->buflist,
|
||||
count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
up(&dev->struct_sem);
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->seglist, 0, count * sizeof(*entry->seglist));
|
||||
|
||||
dma->pagelist = drm_realloc(dma->pagelist,
|
||||
dma->page_count * sizeof(*dma->pagelist),
|
||||
(dma->page_count + (count << page_order))
|
||||
* sizeof(*dma->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
DRM_DEBUG("pagelist: %d entries\n",
|
||||
dma->page_count + (count << page_order));
|
||||
|
||||
|
||||
entry->buf_size = size;
|
||||
entry->page_order = page_order;
|
||||
byte_count = 0;
|
||||
page_count = 0;
|
||||
while (entry->buf_count < count) {
|
||||
if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break;
|
||||
entry->seglist[entry->seg_count++] = page;
|
||||
for (i = 0; i < (1 << page_order); i++) {
|
||||
DRM_DEBUG("page %d @ 0x%08lx\n",
|
||||
dma->page_count + page_count,
|
||||
page + PAGE_SIZE * i);
|
||||
dma->pagelist[dma->page_count + page_count++]
|
||||
= page + PAGE_SIZE * i;
|
||||
}
|
||||
for (offset = 0;
|
||||
offset + size <= total && entry->buf_count < count;
|
||||
offset += alignment, ++entry->buf_count) {
|
||||
buf = &entry->buflist[entry->buf_count];
|
||||
buf->idx = dma->buf_count + entry->buf_count;
|
||||
buf->total = alignment;
|
||||
buf->order = order;
|
||||
buf->used = 0;
|
||||
buf->offset = (dma->byte_count + byte_count + offset);
|
||||
buf->address = (void *)(page + offset);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head(&buf->dma_wait);
|
||||
buf->pid = 0;
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
buf->time_queued = 0;
|
||||
buf->time_dispatched = 0;
|
||||
buf->time_completed = 0;
|
||||
buf->time_freed = 0;
|
||||
#endif
|
||||
DRM_DEBUG("buffer %d @ %p\n",
|
||||
entry->buf_count, buf->address);
|
||||
}
|
||||
byte_count += PAGE_SIZE << page_order;
|
||||
}
|
||||
|
||||
dma->buflist = drm_realloc(dma->buflist,
|
||||
dma->buf_count * sizeof(*dma->buflist),
|
||||
(dma->buf_count + entry->buf_count)
|
||||
* sizeof(*dma->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
|
||||
dma->buflist[i] = &entry->buflist[i - dma->buf_count];
|
||||
|
||||
dma->buf_count += entry->buf_count;
|
||||
dma->seg_count += entry->seg_count;
|
||||
dma->page_count += entry->seg_count << page_order;
|
||||
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
|
||||
|
||||
drm_freelist_create(&entry->freelist, entry->buf_count);
|
||||
for (i = 0; i < entry->buf_count; i++) {
|
||||
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
|
||||
}
|
||||
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.count = entry->buf_count;
|
||||
request.size = size;
|
||||
|
||||
copy_to_user_ret((drm_buf_desc_t *)arg,
|
||||
&request,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_infobufs(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_device_dma_t *dma = dev->dma;
|
||||
drm_buf_info_t request;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
spin_lock(&dev->count_lock);
|
||||
if (atomic_read(&dev->buf_alloc)) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
++dev->buf_use; /* Can't allocate more after this call */
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
copy_from_user_ret(&request,
|
||||
(drm_buf_info_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
|
||||
if (dma->bufs[i].buf_count) ++count;
|
||||
}
|
||||
|
||||
DRM_DEBUG("count = %d\n", count);
|
||||
|
||||
if (request.count >= count) {
|
||||
for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
|
||||
if (dma->bufs[i].buf_count) {
|
||||
copy_to_user_ret(&request.list[count].count,
|
||||
&dma->bufs[i].buf_count,
|
||||
sizeof(dma->bufs[0]
|
||||
.buf_count),
|
||||
-EFAULT);
|
||||
copy_to_user_ret(&request.list[count].size,
|
||||
&dma->bufs[i].buf_size,
|
||||
sizeof(dma->bufs[0].buf_size),
|
||||
-EFAULT);
|
||||
copy_to_user_ret(&request.list[count].low_mark,
|
||||
&dma->bufs[i]
|
||||
.freelist.low_mark,
|
||||
sizeof(dma->bufs[0]
|
||||
.freelist.low_mark),
|
||||
-EFAULT);
|
||||
copy_to_user_ret(&request.list[count]
|
||||
.high_mark,
|
||||
&dma->bufs[i]
|
||||
.freelist.high_mark,
|
||||
sizeof(dma->bufs[0]
|
||||
.freelist.high_mark),
|
||||
-EFAULT);
|
||||
DRM_DEBUG("%d %d %d %d %d\n",
|
||||
i,
|
||||
dma->bufs[i].buf_count,
|
||||
dma->bufs[i].buf_size,
|
||||
dma->bufs[i].freelist.low_mark,
|
||||
dma->bufs[i].freelist.high_mark);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
request.count = count;
|
||||
|
||||
copy_to_user_ret((drm_buf_info_t *)arg,
|
||||
&request,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_markbufs(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_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
int order;
|
||||
drm_buf_entry_t *entry;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
copy_from_user_ret(&request,
|
||||
(drm_buf_desc_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
DRM_DEBUG("%d, %d, %d\n",
|
||||
request.size, request.low_mark, request.high_mark);
|
||||
order = drm_order(request.size);
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
|
||||
entry = &dma->bufs[order];
|
||||
|
||||
if (request.low_mark < 0 || request.low_mark > entry->buf_count)
|
||||
return -EINVAL;
|
||||
if (request.high_mark < 0 || request.high_mark > entry->buf_count)
|
||||
return -EINVAL;
|
||||
|
||||
entry->freelist.low_mark = request.low_mark;
|
||||
entry->freelist.high_mark = request.high_mark;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_freebufs(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_device_dma_t *dma = dev->dma;
|
||||
drm_buf_free_t request;
|
||||
int i;
|
||||
int idx;
|
||||
drm_buf_t *buf;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
copy_from_user_ret(&request,
|
||||
(drm_buf_free_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
DRM_DEBUG("%d\n", request.count);
|
||||
for (i = 0; i < request.count; i++) {
|
||||
copy_from_user_ret(&idx,
|
||||
&request.list[i],
|
||||
sizeof(idx),
|
||||
-EFAULT);
|
||||
if (idx < 0 || idx >= dma->buf_count) {
|
||||
DRM_ERROR("Index %d (of %d max)\n",
|
||||
idx, dma->buf_count - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
buf = dma->buflist[idx];
|
||||
if (buf->pid != current->pid) {
|
||||
DRM_ERROR("Process %d freeing buffer owned by %d\n",
|
||||
current->pid, buf->pid);
|
||||
return -EINVAL;
|
||||
}
|
||||
drm_free_buffer(dev, buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_mapbufs(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_device_dma_t *dma = dev->dma;
|
||||
int retcode = 0;
|
||||
const int zero = 0;
|
||||
unsigned long virtual;
|
||||
unsigned long address;
|
||||
drm_buf_map_t request;
|
||||
int i;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
spin_lock(&dev->count_lock);
|
||||
if (atomic_read(&dev->buf_alloc)) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
++dev->buf_use; /* Can't allocate more after this call */
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
copy_from_user_ret(&request,
|
||||
(drm_buf_map_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
if (request.count >= dma->buf_count) {
|
||||
virtual = do_mmap(filp, 0, dma->byte_count,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED, 0);
|
||||
if (virtual > -1024UL) {
|
||||
/* Real error */
|
||||
retcode = (signed long)virtual;
|
||||
goto done;
|
||||
}
|
||||
request.virtual = (void *)virtual;
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (copy_to_user(&request.list[i].idx,
|
||||
&dma->buflist[i]->idx,
|
||||
sizeof(request.list[0].idx))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].total,
|
||||
&dma->buflist[i]->total,
|
||||
sizeof(request.list[0].total))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].used,
|
||||
&zero,
|
||||
sizeof(zero))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
address = virtual + dma->buflist[i]->offset;
|
||||
if (copy_to_user(&request.list[i].address,
|
||||
&address,
|
||||
sizeof(address))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
request.count = dma->buf_count;
|
||||
DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
|
||||
|
||||
copy_to_user_ret((drm_buf_map_t *)arg,
|
||||
&request,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
210
linux/mga_context.c
Normal file
210
linux/mga_context.c
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/* mga_context.c -- IOCTLs for mga contexts -*- linux-c -*-
|
||||
* Created: Thu Jan 6 01:42:46 2000 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* 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
|
||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
|
||||
* Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
#include "mga_drv.h"
|
||||
|
||||
extern drm_ctx_t mga_res_ctx;
|
||||
|
||||
static int mga_alloc_queue(drm_device_t *dev)
|
||||
{
|
||||
return drm_ctxbitmap_next(dev);
|
||||
}
|
||||
|
||||
int mga_context_switch(drm_device_t *dev, int old, int new)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
atomic_inc(&dev->total_ctx);
|
||||
|
||||
if (test_and_set_bit(0, &dev->context_flag)) {
|
||||
DRM_ERROR("Reentering -- FIXME\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
dev->ctx_start = get_cycles();
|
||||
#endif
|
||||
|
||||
DRM_DEBUG("Context switch from %d to %d\n", old, new);
|
||||
|
||||
if (new == dev->last_context) {
|
||||
clear_bit(0, &dev->context_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (drm_flags & DRM_FLAG_NOCTX) {
|
||||
mga_context_switch_complete(dev, new);
|
||||
} else {
|
||||
sprintf(buf, "C %d %d\n", old, new);
|
||||
drm_write_string(dev, buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_context_switch_complete(drm_device_t *dev, int new)
|
||||
{
|
||||
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
|
||||
dev->last_switch = jiffies;
|
||||
|
||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("Lock isn't held after context switch\n");
|
||||
}
|
||||
|
||||
/* If a context switch is ever initiated
|
||||
when the kernel holds the lock, release
|
||||
that lock here. */
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
|
||||
- dev->ctx_start)]);
|
||||
|
||||
#endif
|
||||
clear_bit(0, &dev->context_flag);
|
||||
wake_up(&dev->context_wait);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_ctx_res_t res;
|
||||
drm_ctx_t ctx;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
|
||||
copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
|
||||
if (res.count >= DRM_RESERVED_CONTEXTS) {
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
ctx.handle = i;
|
||||
copy_to_user_ret(&res.contexts[i],
|
||||
&i,
|
||||
sizeof(i),
|
||||
-EFAULT);
|
||||
}
|
||||
}
|
||||
res.count = DRM_RESERVED_CONTEXTS;
|
||||
copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
if ((ctx.handle = mga_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
|
||||
/* Skip kernel's context and get a new one. */
|
||||
ctx.handle = mga_alloc_queue(dev);
|
||||
}
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if (ctx.handle == -1) {
|
||||
DRM_DEBUG("Not enough free contexts.\n");
|
||||
/* Should this return -EBUSY instead? */
|
||||
return -ENOMEM;
|
||||
}
|
||||
copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
|
||||
if (ctx.flags==_DRM_CONTEXT_PRESERVED)
|
||||
mga_res_ctx.handle=ctx.handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
|
||||
/* This is 0, because we don't hanlde any context flags */
|
||||
ctx.flags = 0;
|
||||
copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
return mga_context_switch(dev, dev->last_context, ctx.handle);
|
||||
}
|
||||
|
||||
int mga_newctx(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_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
mga_context_switch_complete(dev, ctx.handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_rmctx(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_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
/* mga_dma.c -- DMA support for GMX 2000 -*- linux-c -*-
|
||||
/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*-
|
||||
* Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
|
||||
* Revised: Mon Dec 13 02:19:32 1999 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
|
|
@ -23,7 +22,11 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
|
||||
* Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
200
linux/mga_drv.c
200
linux/mga_drv.c
|
|
@ -1,6 +1,5 @@
|
|||
/* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*-
|
||||
* Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
|
||||
* Revised: Mon Dec 13 02:26:34 1999 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
|
|
@ -23,7 +22,11 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
|
||||
* Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -70,26 +73,36 @@ static drm_ioctl_desc_t mga_ioctls[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
|
||||
[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 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_unbind, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_bind, 1, 1},
|
||||
};
|
||||
|
||||
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
|
||||
|
||||
#ifdef MODULE
|
||||
|
|
@ -269,6 +282,8 @@ static int mga_takedown(drm_device_t *dev)
|
|||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
break;
|
||||
}
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
|
|
@ -319,6 +334,10 @@ int mga_init(void)
|
|||
DRM_DEBUG("\n");
|
||||
|
||||
memset((void *)dev, 0, sizeof(*dev));
|
||||
if((retcode = drm_ctxbitmap_init(dev))) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
return retcode;
|
||||
}
|
||||
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
||||
sema_init(&dev->struct_sem, 1);
|
||||
|
||||
|
|
@ -328,6 +347,7 @@ int mga_init(void)
|
|||
|
||||
if ((retcode = misc_register(&mga_misc))) {
|
||||
DRM_ERROR("Cannot register \"%s\"\n", MGA_NAME);
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
return retcode;
|
||||
}
|
||||
dev->device = MKDEV(MISC_MAJOR, mga_misc.minor);
|
||||
|
|
@ -343,7 +363,9 @@ int mga_init(void)
|
|||
MGA_PATCHLEVEL,
|
||||
MGA_DATE,
|
||||
mga_misc.minor);
|
||||
|
||||
|
||||
dev->agp = drm_agp_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -362,6 +384,7 @@ void mga_cleanup(void)
|
|||
DRM_INFO("Module unloaded\n");
|
||||
}
|
||||
mga_takedown(dev);
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
}
|
||||
|
||||
int mga_version(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
|
|
@ -484,6 +507,151 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int mga_lock(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;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
int ret = 0;
|
||||
drm_lock_t lock;
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
cycles_t start;
|
||||
|
||||
dev->lck_start = start = get_cycles();
|
||||
#endif
|
||||
|
||||
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid, dev->lock.hw_lock->lock,
|
||||
lock.flags);
|
||||
|
||||
#if 0
|
||||
/* dev->queue_count == 0 right now for
|
||||
mga. FIXME? */
|
||||
if (lock.context < 0 || lock.context >= dev->queue_count)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if 0
|
||||
if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
|
||||
!= lock.context) {
|
||||
long j = jiffies - dev->lock.lock_time;
|
||||
|
||||
if (lock.context == mga_res_ctx.handle &&
|
||||
j >= 0 && j < DRM_LOCK_SLICE) {
|
||||
/* Can't take lock if we just had it and
|
||||
there is contention. */
|
||||
DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
|
||||
lock.context, current->pid, j,
|
||||
dev->lock.lock_time, jiffies);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule_timeout(DRM_LOCK_SLICE-j);
|
||||
DRM_DEBUG("jiffies=%d\n", jiffies);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
lock.context)) {
|
||||
dev->lock.pid = current->pid;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->total_locks);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
#if 1
|
||||
current->policy |= SCHED_YIELD;
|
||||
#endif
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!ret && dev->last_context != lock.context &&
|
||||
lock.context != mga_res_ctx.handle &&
|
||||
dev->last_context != mga_res_ctx.handle) {
|
||||
add_wait_queue(&dev->context_wait, &entry);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
/* PRE: dev->last_context != lock.context */
|
||||
mga_context_switch(dev, dev->last_context, lock.context);
|
||||
/* POST: we will wait for the context
|
||||
switch and will dispatch on a later call
|
||||
when dev->last_context == lock.context
|
||||
NOTE WE HOLD THE LOCK THROUGHOUT THIS
|
||||
TIME! */
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule();
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->context_wait, &entry);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
} else if (dev->last_context != lock.context) {
|
||||
DRM_ERROR("Context mismatch: %d %d\n",
|
||||
dev->last_context, lock.context);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
/* Make hardware quiescent */
|
||||
#if 0
|
||||
mga_quiescent(dev);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
DRM_ERROR("pid = %5d, old counter = %5ld\n",
|
||||
current->pid, current->counter);
|
||||
#endif
|
||||
if (lock.context != mga_res_ctx.handle) {
|
||||
current->counter = 5;
|
||||
current->priority = DEF_PRIORITY/4;
|
||||
}
|
||||
#if 0
|
||||
while (current->counter > 25)
|
||||
current->counter >>= 1; /* decrease time slice */
|
||||
DRM_ERROR("pid = %5d, new counter = %5ld\n",
|
||||
current->pid, current->counter);
|
||||
#endif
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/* mga_drv.h -- Private header for the Matrox g200/g400 driver -*- linux-c -*-
|
||||
* Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
|
||||
* Revised: Mon Dec 13 02:27:49 1999 by jhartmann@precisioninsight.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* All rights reserved.
|
||||
|
|
@ -23,8 +22,11 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
|
||||
* Jeff Hartmann <jhartmann@precisioninsight.com>
|
||||
*
|
||||
* $XFree86$
|
||||
*/
|
||||
|
||||
#ifndef _MGA_DRV_H_
|
||||
|
|
@ -53,6 +55,38 @@ extern int mga_irq_uninstall(drm_device_t *dev);
|
|||
extern int mga_control(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* mga_bufs.c */
|
||||
extern int mga_addbufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_infobufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_markbufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_freebufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_mapbufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* mga_context.c */
|
||||
extern int mga_resctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_addctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_modctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_getctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_switchctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_newctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int mga_rmctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern int mga_context_switch(drm_device_t *dev, int old, int new);
|
||||
extern int mga_context_switch_complete(drm_device_t *dev, int new);
|
||||
|
||||
|
||||
#define MGAREG_MGA_EXEC 0x0100
|
||||
#define MGAREG_AGP_PLL 0x1e4c
|
||||
#define MGAREG_ALPHACTRL 0x2c7c
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue