Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f757f91 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/i915: Add 965GM pci id update
  drm: just use io_remap_pfn_range on all archs..
  drm: fix DRM_CONSISTENT mapping
  drm: fix up mmap locking in preparation for ttm changes
  drm: fix driver deadlock with AIGLX and reclaim_buffers_locked
  drm: fix warning in drm_fops.c
  drm: allow for more generic drm ioctls
  drm: fix alpha domain handling
  via: fix CX700 pci id
  drm: make drm_io_prot static.
  drm: remove via_mm.h
  drm: add missing NULL assignment
  drm/radeon: Fix u32 overflows when determining AGP base address in card space.
  drm: port over use_vmalloc code from git hashtab
  drm: fix crash with fops lock and fixup sarea/page size locking
  drm: bring bufs code from git tree.
  drm: move protection stuff into separate function
  drm: Use ARRAY_SIZE macro when appropriate
  drm: update README.drm (bugzilla #7933)
  drm: remove unused exports
parents 9fa0853a ce7dd063
Loading
Loading
Loading
Loading
+7 −9
Original line number Diff line number Diff line
************************************************************
* For the very latest on DRI development, please see:      *
*     http://dri.sourceforge.net/                          *
*     http://dri.freedesktop.org/                          *
************************************************************

The Direct Rendering Manager (drm) is a device-independent kernel-level
@@ -26,21 +26,19 @@ ways:


Documentation on the DRI is available from:
    http://precisioninsight.com/piinsights.html
    http://dri.freedesktop.org/wiki/Documentation
    http://sourceforge.net/project/showfiles.php?group_id=387
    http://dri.sourceforge.net/doc/

For specific information about kernel-level support, see:

    The Direct Rendering Manager, Kernel Support for the Direct Rendering
    Infrastructure
    http://precisioninsight.com/dr/drm.html
    http://dri.sourceforge.net/doc/drm_low_level.html

    Hardware Locking for the Direct Rendering Infrastructure
    http://precisioninsight.com/dr/locking.html
    http://dri.sourceforge.net/doc/hardware_locking_low_level.html

    A Security Analysis of the Direct Rendering Infrastructure
    http://precisioninsight.com/dr/security.html
    http://dri.sourceforge.net/doc/security_low_level.html
************************************************************
* For the very latest on DRI development, please see:      *
*     http://dri.sourceforge.net/                          *
************************************************************
+3 −1
Original line number Diff line number Diff line
@@ -654,11 +654,13 @@ typedef struct drm_set_version {

/**
 * Device specific ioctls should only be in their respective headers
 * The device specific ioctl range is from 0x40 to 0x79.
 * The device specific ioctl range is from 0x40 to 0x99.
 * Generic IOCTLS restart at 0xA0.
 *
 * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
 * drmCommandReadWrite().
 */
#define DRM_COMMAND_BASE                0x40
#define DRM_COMMAND_END			0xA0

#endif
+19 −4
Original line number Diff line number Diff line
@@ -414,6 +414,10 @@ typedef struct drm_lock_data {
	struct file *filp;		/**< File descr of lock holder (0=kernel) */
	wait_queue_head_t lock_queue;	/**< Queue of blocked processes */
	unsigned long lock_time;	/**< Time of last lock in jiffies */
	spinlock_t spinlock;
	uint32_t kernel_waiters;
	uint32_t user_waiters;
	int idle_has_lock;
} drm_lock_data_t;

/**
@@ -590,6 +594,8 @@ struct drm_driver {
	void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
	void (*reclaim_buffers_locked) (struct drm_device *dev,
					struct file *filp);
	void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
					struct file * filp);
	unsigned long (*get_map_ofs) (drm_map_t * map);
	unsigned long (*get_reg_ofs) (struct drm_device * dev);
	void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
@@ -764,7 +770,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
}

#ifdef __alpha__
#define drm_get_pci_domain(dev) dev->hose->bus->number
#define drm_get_pci_domain(dev) dev->hose->index
#else
#define drm_get_pci_domain(dev) 0
#endif
@@ -915,9 +921,18 @@ extern int drm_lock(struct inode *inode, struct file *filp,
		    unsigned int cmd, unsigned long arg);
extern int drm_unlock(struct inode *inode, struct file *filp,
		      unsigned int cmd, unsigned long arg);
extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context);
extern int drm_lock_free(drm_device_t * dev,
			 __volatile__ unsigned int *lock, unsigned int context);
extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context);
extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context);
extern void drm_idlelock_take(drm_lock_data_t *lock_data);
extern void drm_idlelock_release(drm_lock_data_t *lock_data);

/*
 * These are exported to drivers so that they can implement fencing using
 * DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
 */

extern int drm_i_have_hw_lock(struct file *filp);
extern int drm_kernel_take_hw_lock(struct file *filp);

				/* Buffer management support (drm_bufs.h) */
extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
+66 −9
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
	list_for_each(list, &dev->maplist->head) {
		drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
		if (entry->map && map->type == entry->map->type &&
		    entry->map->offset == map->offset) {
		    ((entry->map->offset == map->offset) ||
		     (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) {
			return entry;
		}
	}
@@ -180,8 +181,20 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
		if (map->type == _DRM_REGISTERS)
			map->handle = ioremap(map->offset, map->size);
		break;

	case _DRM_SHM:
		list = drm_find_matching_map(dev, map);
		if (list != NULL) {
			if(list->map->size != map->size) {
				DRM_DEBUG("Matching maps of type %d with "
					  "mismatched sizes, (%ld vs %ld)\n",
					  map->type, map->size, list->map->size);
				list->map->size = map->size;
			}

			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
			*maplist = list;
			return 0;
		}
		map->handle = vmalloc_user(map->size);
		DRM_DEBUG("%lu %d %p\n",
			  map->size, drm_order(map->size), map->handle);
@@ -200,15 +213,45 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
			dev->sigdata.lock = dev->lock.hw_lock = map->handle;	/* Pointer to lock */
		}
		break;
	case _DRM_AGP:
		if (drm_core_has_AGP(dev)) {
	case _DRM_AGP: {
		drm_agp_mem_t *entry;
		int valid = 0;

		if (!drm_core_has_AGP(dev)) {
			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
			return -EINVAL;
		}
#ifdef __alpha__
		map->offset += dev->hose->mem_space->start;
#endif
		/* Note: dev->agp->base may actually be 0 when the DRM
		 * is not in control of AGP space. But if user space is
		 * it should already have added the AGP base itself.
		 */
		map->offset += dev->agp->base;
		map->mtrr = dev->agp->agp_mtrr;	/* for getmap */

		/* This assumes the DRM is in total control of AGP space.
		 * It's not always the case as AGP can be in the control
		 * of user space (i.e. i810 driver). So this loop will get
		 * skipped and we double check that dev->agp->memory is
		 * actually set as well as being invalid before EPERM'ing
		 */
		for (entry = dev->agp->memory; entry; entry = entry->next) {
			if ((map->offset >= entry->bound) &&
			    (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
				valid = 1;
				break;
			}
		}
		if (dev->agp->memory && !valid) {
			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
			return -EPERM;
		}
		DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);

		break;
	}
	case _DRM_SCATTER_GATHER:
		if (!dev->sg) {
			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
@@ -519,6 +562,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
{
	drm_device_dma_t *dma = dev->dma;
	drm_buf_entry_t *entry;
	drm_agp_mem_t *agp_entry;
	drm_buf_t *buf;
	unsigned long offset;
	unsigned long agp_offset;
@@ -529,7 +573,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
	int page_order;
	int total;
	int byte_count;
	int i;
	int i, valid;
	drm_buf_t **temp_buflist;

	if (!dma)
@@ -560,6 +604,19 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
	if (dev->queue_count)
		return -EBUSY;	/* Not while in use */

	/* Make sure buffers are located in AGP memory that we own */
	valid = 0;
	for (agp_entry = dev->agp->memory; agp_entry; agp_entry = agp_entry->next) {
		if ((agp_offset >= agp_entry->bound) &&
		    (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
			valid = 1;
			break;
		}
	}
	if (dev->agp->memory && !valid) {
		DRM_DEBUG("zone invalid\n");
		return -EINVAL;
	}
	spin_lock(&dev->count_lock);
	if (dev->buf_use) {
		spin_unlock(&dev->count_lock);
+6 −3
Original line number Diff line number Diff line
@@ -496,11 +496,14 @@ int drm_ioctl(struct inode *inode, struct file *filp,
		  (long)old_encode_dev(priv->head->device),
		  priv->authenticated);

	if (nr < DRIVER_IOCTL_COUNT)
		ioctl = &drm_ioctls[nr];
	else if ((nr >= DRM_COMMAND_BASE)
	if ((nr >= DRIVER_IOCTL_COUNT) &&
	    ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
		goto err_i1;
	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
		 && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
	else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
		ioctl = &drm_ioctls[nr];
	else
		goto err_i1;

Loading