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

Commit 9c8da5eb authored by Dave Airlie's avatar Dave Airlie Committed by Dave Airlie
Browse files

drm: update support for drm pci buffers



The DRM needs to change the drm_pci interface for FreeBSD compatiblity,
this patch introduces the drm_dma_handle_t and uses it in the Linux code.

From: Tonnerre Lombard, Eric Anholt, and Sergey Vlasov
Signed-off-by: default avatarDavid Airlie <airlied@linux.ie>
parent d59431bf
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -527,6 +527,12 @@ typedef struct drm_sigdata {
	drm_hw_lock_t *lock;
} drm_sigdata_t;

typedef struct drm_dma_handle {
	dma_addr_t busaddr;
	void *vaddr;
	size_t size;
} drm_dma_handle_t;

/**
 * Mappings list
 */
@@ -978,12 +984,10 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev,
					       unsigned long addr,
					       dma_addr_t bus_addr);

extern void *drm_pci_alloc(drm_device_t * dev, size_t size,
			   size_t align, dma_addr_t maxaddr,
			   dma_addr_t * busaddr);

extern void drm_pci_free(drm_device_t * dev, size_t size,
			 void *vaddr, dma_addr_t busaddr);
extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
				       size_t align, dma_addr_t maxaddr);
extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);

			       /* sysfs support (drm_sysfs.c) */
struct drm_sysfs_class;
+13 −9
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ int drm_addmap( struct inode *inode, struct file *filp,
	drm_map_t *map;
	drm_map_t __user *argp = (void __user *)arg;
	drm_map_list_t *list;
	drm_dma_handle_t *dmah;

	if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */

@@ -181,21 +182,19 @@ int drm_addmap( struct inode *inode, struct file *filp,
		map->offset += dev->sg->handle;
		break;
	case _DRM_CONSISTENT: 
	{
		/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
		 * As we're limit the address to 2^32-1 (or lses),
		 * As we're limiting the address to 2^32-1 (or less),
		 * casting it down to 32 bits is no problem, but we
		 * need to point to a 64bit variable first. */
		dma_addr_t bus_addr;
		map->handle = drm_pci_alloc(dev, map->size, map->size,
					    0xffffffffUL, &bus_addr);
		map->offset = (unsigned long)bus_addr;
		if (!map->handle) {
		dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
		if (!dmah) {
			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
			return -ENOMEM;
		}
		map->handle = dmah->vaddr;
		map->offset = (unsigned long)dmah->busaddr;
		kfree(dmah);
		break;
	}
	default:
		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
		return -EINVAL;
@@ -286,6 +285,8 @@ int drm_rmmap(struct inode *inode, struct file *filp,
	}

	if(!found_maps) {
		drm_dma_handle_t dmah;

		switch (map->type) {
		case _DRM_REGISTERS:
		case _DRM_FRAME_BUFFER:
@@ -307,7 +308,10 @@ int drm_rmmap(struct inode *inode, struct file *filp,
		case _DRM_SCATTER_GATHER:
			break;
		case _DRM_CONSISTENT:
			drm_pci_free(dev, map->size, map->handle, map->offset);
			dmah.vaddr = map->handle;
			dmah.busaddr = map->offset;
			dmah.size = map->size;
			__drm_pci_free(dev, &dmah);
			break;
		}
		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+6 −2
Original line number Diff line number Diff line
@@ -198,6 +198,8 @@ int drm_takedown( drm_device_t *dev )
			r_list = (drm_map_list_t *)list;

			if ( ( map = r_list->map ) ) {
				drm_dma_handle_t dmah;

				switch ( map->type ) {
				case _DRM_REGISTERS:
				case _DRM_FRAME_BUFFER:
@@ -229,8 +231,10 @@ int drm_takedown( drm_device_t *dev )
					}
					break;
				case _DRM_CONSISTENT:
					drm_pci_free(dev, map->size,
						     map->handle, map->offset);
					dmah.vaddr = map->handle;
					dmah.busaddr = map->offset;
					dmah.size = map->size;
					__drm_pci_free(dev, &dmah);
					break;
				}
				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+33 −12
Original line number Diff line number Diff line
@@ -46,10 +46,10 @@
/**
 * \brief Allocate a PCI consistent memory block, for DMA.
 */
void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
		    dma_addr_t maxaddr, dma_addr_t * busaddr)
drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
				dma_addr_t maxaddr)
{
	void *address;
	drm_dma_handle_t *dmah;
#if DRM_DEBUG_MEMORY
	int area = DRM_MEM_DMA;

@@ -74,13 +74,19 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
		return NULL;
	}

	address = pci_alloc_consistent(dev->pdev, size, busaddr);
	dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
	if (!dmah)
		return NULL;
	
	dmah->size = size;
	dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);

#if DRM_DEBUG_MEMORY
	if (address == NULL) {
	if (dmah->vaddr == NULL) {
		spin_lock(&drm_mem_lock);
		++drm_mem_stats[area].fail_count;
		spin_unlock(&drm_mem_lock);
		kfree(dmah);
		return NULL;
	}

@@ -90,21 +96,25 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
	drm_ram_used += size;
	spin_unlock(&drm_mem_lock);
#else
	if (address == NULL)
	if (dmah->vaddr == NULL) {
		kfree(dmah);
		return NULL;
	}
#endif

	memset(address, 0, size);
	memset(dmah->vaddr, 0, size);

	return address;
	return dmah;
}
EXPORT_SYMBOL(drm_pci_alloc);

/**
 * \brief Free a PCI consistent memory block.
 * \brief Free a PCI consistent memory block with freeing its descriptor.
 *
 * This function is for internal use in the Linux-specific DRM core code.
 */
void
drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
{
#if DRM_DEBUG_MEMORY
	int area = DRM_MEM_DMA;
@@ -112,12 +122,13 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
	int free_count;
#endif

	if (!vaddr) {
	if (!dmah->vaddr) {
#if DRM_DEBUG_MEMORY
		DRM_MEM_ERROR(area, "Attempt to free address 0\n");
#endif
	} else {
		pci_free_consistent(dev->pdev, size, vaddr, busaddr);
		pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr,
				    dmah->busaddr);
	}

#if DRM_DEBUG_MEMORY
@@ -135,6 +146,16 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
#endif

}

/**
 * \brief Free a PCI consistent memory block
 */
void
drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
{
	__drm_pci_free(dev, dmah);
	kfree(dmah);
}
EXPORT_SYMBOL(drm_pci_free);

/*@}*/
+6 −2
Original line number Diff line number Diff line
@@ -210,6 +210,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
		}

		if(!found_maps) {
			drm_dma_handle_t dmah;

			switch (map->type) {
			case _DRM_REGISTERS:
			case _DRM_FRAME_BUFFER:
@@ -229,8 +231,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
			case _DRM_SCATTER_GATHER:
				break;
			case _DRM_CONSISTENT:
				drm_pci_free(dev, map->size, map->handle,
					     map->offset);
				dmah.vaddr = map->handle;
				dmah.busaddr = map->offset;
				dmah.size = map->size;
				__drm_pci_free(dev, &dmah);
				break;
			}
			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
Loading