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

📄 mga_dma.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	DRM_DEBUG( "returning NULL!\n" );	return NULL;}int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ){	drm_mga_private_t *dev_priv = dev->dev_private;	drm_mga_buf_priv_t *buf_priv = buf->dev_private;	drm_mga_freelist_t *head, *entry, *prev;	DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n",		   __FUNCTION__,		   buf_priv->list_entry->age.head -		   dev_priv->primary->offset,		   buf_priv->list_entry->age.wrap );	entry = buf_priv->list_entry;	head = dev_priv->head;	if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {		SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );		prev = dev_priv->tail;		prev->next = entry;		entry->prev = prev;		entry->next = NULL;	} else {		prev = head->next;		head->next = entry;		prev->prev = entry;		entry->prev = head;		entry->next = prev;	}	return 0;}/* ================================================================ * DMA initialization, cleanup */static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ){	drm_mga_private_t *dev_priv;	struct list_head *list;	int ret;	DRM_DEBUG( "%s\n", __FUNCTION__ );	dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );	if ( !dev_priv )		return -ENOMEM;	memset( dev_priv, 0, sizeof(drm_mga_private_t) );	dev_priv->chipset = init->chipset;	dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;	if ( init->sgram ) {		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;	} else {		dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;	}	dev_priv->maccess	= init->maccess;	dev_priv->fb_cpp	= init->fb_cpp;	dev_priv->front_offset	= init->front_offset;	dev_priv->front_pitch	= init->front_pitch;	dev_priv->back_offset	= init->back_offset;	dev_priv->back_pitch	= init->back_pitch;	dev_priv->depth_cpp	= init->depth_cpp;	dev_priv->depth_offset	= init->depth_offset;	dev_priv->depth_pitch	= init->depth_pitch;	/* FIXME: Need to support AGP textures...	 */	dev_priv->texture_offset = init->texture_offset[0];	dev_priv->texture_size = init->texture_size[0];	list_for_each( list, &dev->maplist->head ) {		drm_map_list_t *entry = (drm_map_list_t *)list;		if ( entry->map &&		     entry->map->type == _DRM_SHM &&		     (entry->map->flags & _DRM_CONTAINS_LOCK) ) {			dev_priv->sarea = entry->map; 			break; 		} 	}	if(!dev_priv->sarea) {		DRM_ERROR( "failed to find sarea!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	DRM_FIND_MAP( dev_priv->fb, init->fb_offset );	if(!dev_priv->fb) {		DRM_ERROR( "failed to find framebuffer!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );	if(!dev_priv->mmio) {		DRM_ERROR( "failed to find mmio region!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	DRM_FIND_MAP( dev_priv->status, init->status_offset );	if(!dev_priv->status) {		DRM_ERROR( "failed to find status page!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	DRM_FIND_MAP( dev_priv->warp, init->warp_offset );	if(!dev_priv->warp) {		DRM_ERROR( "failed to find warp microcode region!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	DRM_FIND_MAP( dev_priv->primary, init->primary_offset );	if(!dev_priv->primary) {		DRM_ERROR( "failed to find primary dma region!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );	if(!dev_priv->buffers) {		DRM_ERROR( "failed to find dma buffer region!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -EINVAL;	}	dev_priv->sarea_priv =		(drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +				    init->sarea_priv_offset);	DRM_IOREMAP( dev_priv->warp );	DRM_IOREMAP( dev_priv->primary );	DRM_IOREMAP( dev_priv->buffers );	if(!dev_priv->warp->handle ||	   !dev_priv->primary->handle ||	   !dev_priv->buffers->handle ) {		DRM_ERROR( "failed to ioremap agp regions!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -ENOMEM;	}	ret = mga_warp_install_microcode( dev_priv );	if ( ret < 0 ) {		DRM_ERROR( "failed to install WARP ucode!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return ret;	}	ret = mga_warp_init( dev_priv );	if ( ret < 0 ) {		DRM_ERROR( "failed to init WARP engine!\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return ret;	}	dev_priv->prim.status = (u32 *)dev_priv->status->handle;	mga_do_wait_for_idle( dev_priv );	/* Init the primary DMA registers.	 */	MGA_WRITE( MGA_PRIMADDRESS,		   dev_priv->primary->offset | MGA_DMA_GENERAL );#if 0	MGA_WRITE( MGA_PRIMPTR,		   virt_to_bus((void *)dev_priv->prim.status) |		   MGA_PRIMPTREN0 |	/* Soft trap, SECEND, SETUPEND */		   MGA_PRIMPTREN1 );	/* DWGSYNC */#endif	dev_priv->prim.start = (u8 *)dev_priv->primary->handle;	dev_priv->prim.end = ((u8 *)dev_priv->primary->handle			      + dev_priv->primary->size);	dev_priv->prim.size = dev_priv->primary->size;	dev_priv->prim.tail = 0;	dev_priv->prim.space = dev_priv->prim.size;	dev_priv->prim.wrapped = 0;	dev_priv->prim.last_flush = 0;	dev_priv->prim.last_wrap = 0;	dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;	spin_lock_init( &dev_priv->prim.list_lock );	dev_priv->prim.status[0] = dev_priv->primary->offset;	dev_priv->prim.status[1] = 0;	dev_priv->sarea_priv->last_wrap = 0;	dev_priv->sarea_priv->last_frame.head = 0;	dev_priv->sarea_priv->last_frame.wrap = 0;	if ( mga_freelist_init( dev, dev_priv ) < 0 ) {		DRM_ERROR( "could not initialize freelist\n" );		/* Assign dev_private so we can do cleanup. */		dev->dev_private = (void *)dev_priv;		mga_do_cleanup_dma( dev );		return -ENOMEM;	}	/* Make dev_private visable to others. */	dev->dev_private = (void *)dev_priv;	return 0;}int mga_do_cleanup_dma( drm_device_t *dev ){	DRM_DEBUG( "%s\n", __FUNCTION__ );	if ( dev->dev_private ) {		drm_mga_private_t *dev_priv = dev->dev_private;		DRM_IOREMAPFREE( dev_priv->warp );		DRM_IOREMAPFREE( dev_priv->primary );		DRM_IOREMAPFREE( dev_priv->buffers );		if ( dev_priv->head != NULL ) {			mga_freelist_cleanup( dev );		}		DRM(free)( dev->dev_private, sizeof(drm_mga_private_t),			   DRM_MEM_DRIVER );		dev->dev_private = NULL;	}	return 0;}int mga_dma_init( 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_mga_init_t init;	if ( copy_from_user( &init, (drm_mga_init_t *)arg, sizeof(init) ) )		return -EFAULT;	switch ( init.func ) {	case MGA_INIT_DMA:		return mga_do_init_dma( dev, &init );	case MGA_CLEANUP_DMA:		return mga_do_cleanup_dma( dev );	}	return -EINVAL;}/* ================================================================ * Primary DMA stream management */int mga_dma_flush( 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_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;	drm_lock_t lock;	LOCK_TEST_WITH_RETURN( dev );	if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )		return -EFAULT;	DRM_DEBUG( "%s: %s%s%s\n",		   __FUNCTION__,		   (lock.flags & _DRM_LOCK_FLUSH) ?	"flush, " : "",		   (lock.flags & _DRM_LOCK_FLUSH_ALL) ?	"flush all, " : "",		   (lock.flags & _DRM_LOCK_QUIESCENT) ?	"idle, " : "" );	WRAP_WAIT_WITH_RETURN( dev_priv );	if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) {		mga_do_dma_flush( dev_priv );	}	if ( lock.flags & _DRM_LOCK_QUIESCENT ) {#if MGA_DMA_DEBUG		int ret = mga_do_wait_for_idle( dev_priv );		if ( ret < 0 )			DRM_INFO( __FUNCTION__": -EBUSY\n" );		return ret;#else		return mga_do_wait_for_idle( dev_priv );#endif	} else {		return 0;	}}int mga_dma_reset( 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_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;	LOCK_TEST_WITH_RETURN( dev );	return mga_do_dma_reset( dev_priv );}/* ================================================================ * DMA buffer management */static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ){	drm_buf_t *buf;	int i;	for ( i = d->granted_count ; i < d->request_count ; i++ ) {		buf = mga_freelist_get( dev );		if ( !buf ) return -EAGAIN;		buf->pid = current->pid;		if ( copy_to_user( &d->request_indices[i],				   &buf->idx, sizeof(buf->idx) ) )			return -EFAULT;		if ( copy_to_user( &d->request_sizes[i],				   &buf->total, sizeof(buf->total) ) )			return -EFAULT;		d->granted_count++;	}	return 0;}int mga_dma_buffers( 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_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;	drm_dma_t d;	int ret = 0;	LOCK_TEST_WITH_RETURN( dev );	if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )		return -EFAULT;	/* Please don't send us buffers.	 */	if ( d.send_count != 0 ) {		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",			   current->pid, d.send_count );		return -EINVAL;	}	/* We'll send you buffers.	 */	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",			   current->pid, d.request_count, dma->buf_count );		return -EINVAL;	}	WRAP_TEST_WITH_RETURN( dev_priv );	d.granted_count = 0;	if ( d.request_count ) {		ret = mga_dma_get_buffers( dev, &d );	}	if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )		return -EFAULT;	return ret;}

⌨️ 快捷键说明

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