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

📄 mga_bufs.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		     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;	if (copy_to_user((drm_buf_desc_t *)arg,			 &request,			 sizeof(request)))		return -EFAULT;		atomic_dec(&dev->buf_alloc);	return 0;}int mga_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(request.flags & _DRM_AGP_BUFFER)		return mga_addbufs_agp(inode, filp, cmd, arg);	else		return mga_addbufs_pci(inode, filp, cmd, arg);}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);	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;	}		if (request.count >= count) {		for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {			if (dma->bufs[i].buf_count) {				if (copy_to_user(&request.list[count].count,						 &dma->bufs[i].buf_count,						 sizeof(dma->bufs[0]							.buf_count)) ||				    copy_to_user(&request.list[count].size,						 &dma->bufs[i].buf_size,						 sizeof(dma->bufs[0].buf_size)) ||				    copy_to_user(&request.list[count].low_mark,						 &dma->bufs[i]						 .freelist.low_mark,						 sizeof(dma->bufs[0]							.freelist.low_mark)) ||				    copy_to_user(&request.list[count]						 .high_mark,						 &dma->bufs[i]						 .freelist.high_mark,						 sizeof(dma->bufs[0]							.freelist.high_mark)))					return -EFAULT;				++count;			}		}	}	request.count = count;	if (copy_to_user((drm_buf_info_t *)arg,			 &request,			 sizeof(request)))		return -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;	if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))		return -EFAULT;	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;	if (copy_from_user(&request,			   (drm_buf_free_t *)arg,			   sizeof(request)))		return -EFAULT;	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 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;		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(dma->flags & _DRM_DMA_USE_AGP) {			drm_mga_private_t *dev_priv = dev->dev_private;			drm_map_t *map = NULL;	 			map = dev->maplist[dev_priv->buffer_map_idx];			if (!map) {				retcode = -EINVAL;				goto done;			}			DRM_DEBUG("map->offset : %lx\n", map->offset);			DRM_DEBUG("map->size : %lx\n", map->size);			DRM_DEBUG("map->type : %d\n", map->type);			DRM_DEBUG("map->flags : %x\n", map->flags);			DRM_DEBUG("map->handle : %p\n", map->handle);			DRM_DEBUG("map->mtrr : %d\n", map->mtrr);			down_write(&current->mm->mmap_sem);			virtual = do_mmap(filp, 0, map->size, 					  PROT_READ|PROT_WRITE,					  MAP_SHARED, 					  (unsigned long)map->offset);			up_write(&current->mm->mmap_sem);		} else {			down_write(&current->mm->mmap_sem);			virtual = do_mmap(filp, 0, dma->byte_count,					  PROT_READ|PROT_WRITE, MAP_SHARED, 0);			up_write(&current->mm->mmap_sem);		}		if (virtual > -1024UL) {			/* Real error */			DRM_DEBUG("mmap error\n");			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;	DRM_DEBUG("retcode : %d\n", retcode);	return retcode;}

⌨️ 快捷键说明

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