⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drm_bufs.h

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 H
📖 第 1 页 / 共 2 页
字号:
	temp_pagelist = DRM(realloc)( dma->pagelist,				      dma->page_count * sizeof(*dma->pagelist),				      (dma->page_count + (count << page_order))				      * sizeof(*dma->pagelist),				      DRM_MEM_PAGES );	if(!temp_pagelist) {		DRM(free)( entry->buflist,			   count * sizeof(*entry->buflist),			   DRM_MEM_BUFS );		DRM(free)( entry->seglist,			   count * sizeof(*entry->seglist),			   DRM_MEM_SEGS );		up( &dev->struct_sem );		atomic_dec( &dev->buf_alloc );		return -ENOMEM;	}	dma->pagelist = temp_pagelist;	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 ) {		page = DRM(alloc_pages)( page_order, DRM_MEM_DMA );		if ( !page ) 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 __HAVE_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;	}	temp_buflist = DRM(realloc)( dma->buflist,				     dma->buf_count * sizeof(*dma->buflist),				     (dma->buf_count + entry->buf_count)				     * sizeof(*dma->buflist),				     DRM_MEM_BUFS );	if(!temp_buflist) {		/* Free the entry because it isn't valid */		DRM(cleanup_buf_error)(entry);		up( &dev->struct_sem );		atomic_dec( &dev->buf_alloc );		return -ENOMEM;	}	dma->buflist = temp_buflist;	for ( i = 0 ; i < entry->buf_count ; i++ ) {		dma->buflist[i + dma->buf_count] = &entry->buflist[i];	}	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);#if __HAVE_DMA_FREELIST	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] );	}#endif	up( &dev->struct_sem );	request.count = entry->buf_count;	request.size = size;	if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )		return -EFAULT;	atomic_dec( &dev->buf_alloc );	return 0;}#endif /* __HAVE_PCI_DMA */#ifdef __HAVE_SGint DRM(addbufs_sg)( 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;	drm_buf_entry_t *entry;	drm_buf_t *buf;	unsigned long offset;	unsigned long agp_offset;	int count;	int order;	int size;	int alignment;	int page_order;	int total;	int byte_count;	int i;	drm_buf_t **temp_buflist;	if ( !dma ) return -EINVAL;	if ( copy_from_user( &request, (drm_buf_desc_t *)arg,                             sizeof(request) ) )		return -EFAULT;	count = request.count;	order = DRM(order)( request.size );	size = 1 << order;	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;	byte_count = 0;	agp_offset = request.agp_start;	DRM_DEBUG( "count:      %d\n",  count );	DRM_DEBUG( "order:      %d\n",  order );	DRM_DEBUG( "size:       %d\n",  size );	DRM_DEBUG( "agp_offset: %ld\n", agp_offset );	DRM_DEBUG( "alignment:  %d\n",  alignment );	DRM_DEBUG( "page_order: %d\n",  page_order );	DRM_DEBUG( "total:      %d\n",  total );	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;	if ( dev->queue_count ) return -EBUSY; /* Not while in use */	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 */	}	if (count < 0 || count > 4096) {		up( &dev->struct_sem );		atomic_dec( &dev->buf_alloc );		return -EINVAL;	}	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->buf_size = size;	entry->page_order = page_order;	offset = 0;	while ( entry->buf_count < 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 + offset);		buf->bus_address = agp_offset + offset;		buf->address = (void *)(agp_offset + offset + dev->sg->handle);		buf->next    = NULL;		buf->waiting = 0;		buf->pending = 0;		init_waitqueue_head( &buf->dma_wait );		buf->pid     = 0;		buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);		buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),					       DRM_MEM_BUFS );		if(!buf->dev_private) {			/* Set count correctly so we free the proper amount. */			entry->buf_count = count;			DRM(cleanup_buf_error)(entry);			up( &dev->struct_sem );			atomic_dec( &dev->buf_alloc );			return -ENOMEM;		}		memset( buf->dev_private, 0, buf->dev_priv_size );# if __HAVE_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 );		offset += alignment;		entry->buf_count++;		byte_count += PAGE_SIZE << page_order;	}	DRM_DEBUG( "byte_count: %d\n", byte_count );	temp_buflist = DRM(realloc)( dma->buflist,				     dma->buf_count * sizeof(*dma->buflist),				     (dma->buf_count + entry->buf_count)				     * sizeof(*dma->buflist),				     DRM_MEM_BUFS );	if(!temp_buflist) {		/* Free the entry because it isn't valid */		DRM(cleanup_buf_error)(entry);		up( &dev->struct_sem );		atomic_dec( &dev->buf_alloc );		return -ENOMEM;	}	dma->buflist = temp_buflist;	for ( i = 0 ; i < entry->buf_count ; i++ ) {		dma->buflist[i + dma->buf_count] = &entry->buflist[i];	}	dma->buf_count += entry->buf_count;	dma->byte_count += byte_count;	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );#if __HAVE_DMA_FREELIST	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] );	}#endif	up( &dev->struct_sem );	request.count = entry->buf_count;	request.size = size;	if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )		return -EFAULT;	dma->flags = _DRM_DMA_USE_SG;	atomic_dec( &dev->buf_alloc );	return 0;}#endif /* __HAVE_SG */int DRM(addbufs)( struct inode *inode, struct file *filp,		  unsigned int cmd, unsigned long arg ){	drm_buf_desc_t request;	if ( copy_from_user( &request, (drm_buf_desc_t *)arg,			     sizeof(request) ) )		return -EFAULT;#if __REALLY_HAVE_AGP	if ( request.flags & _DRM_AGP_BUFFER )		return DRM(addbufs_agp)( inode, filp, cmd, arg );	else#endif#if __HAVE_SG	if ( request.flags & _DRM_SG_BUFFER )		return DRM(addbufs_sg)( inode, filp, cmd, arg );	else#endif#if __HAVE_PCI_DMA		return DRM(addbufs_pci)( inode, filp, cmd, arg );#else		return -EINVAL;#endif}int DRM(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 );	if ( copy_from_user( &request,			     (drm_buf_info_t *)arg,			     sizeof(request) ) )		return -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 ) {				drm_buf_desc_t *to = &request.list[count];				drm_buf_entry_t *from = &dma->bufs[i];				drm_freelist_t *list = &dma->bufs[i].freelist;				if ( copy_to_user( &to->count,						   &from->buf_count,						   sizeof(from->buf_count) ) ||				     copy_to_user( &to->size,						   &from->buf_size,						   sizeof(from->buf_size) ) ||				     copy_to_user( &to->low_mark,						   &list->low_mark,						   sizeof(list->low_mark) ) ||				     copy_to_user( &to->high_mark,						   &list->high_mark,						   sizeof(list->high_mark) ) )					return -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;	if ( copy_to_user( (drm_buf_info_t *)arg,			   &request,			   sizeof(request) ) )		return -EFAULT;	return 0;}int DRM(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;	if ( copy_from_user( &request,			     (drm_buf_desc_t *)arg,			     sizeof(request) ) )		return -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 DRM(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;	if ( copy_from_user( &request,			     (drm_buf_free_t *)arg,			     sizeof(request) ) )		return -EFAULT;	DRM_DEBUG( "%d\n", request.count );	for ( i = 0 ; i < request.count ; i++ ) {		if ( copy_from_user( &idx,				     &request.list[i],				     sizeof(idx) ) )			return -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 DRM(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;	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 );	if ( copy_from_user( &request, (drm_buf_map_t *)arg,			     sizeof(request) ) )		return -EFAULT;	if ( request.count >= dma->buf_count ) {		if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||		     (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {			drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );			if ( !map ) {				retcode = -EINVAL;				goto done;			}#if LINUX_VERSION_CODE <= 0x020402			down( &current->mm->mmap_sem );#else			down_write( &current->mm->mmap_sem );#endif			virtual = do_mmap( filp, 0, map->size,					   PROT_READ | PROT_WRITE,					   MAP_SHARED,					   (unsigned long)map->offset );#if LINUX_VERSION_CODE <= 0x020402			up( &current->mm->mmap_sem );#else			up_write( &current->mm->mmap_sem );#endif		} else {#if LINUX_VERSION_CODE <= 0x020402			down( &current->mm->mmap_sem );#else			down_write( &current->mm->mmap_sem );#endif			virtual = do_mmap( filp, 0, dma->byte_count,					   PROT_READ | PROT_WRITE,					   MAP_SHARED, 0 );#if LINUX_VERSION_CODE <= 0x020402			up( &current->mm->mmap_sem );#else			up_write( &current->mm->mmap_sem );#endif		}		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 );	if ( copy_to_user( (drm_buf_map_t *)arg, &request, sizeof(request) ) )		return -EFAULT;	return retcode;}#endif /* __HAVE_DMA */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -