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

📄 i810_dma.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
}int i810_irq_uninstall(drm_device_t *dev){	int irq;   	u16 temp;/*  	return 0; */	down(&dev->struct_sem);	irq	 = dev->irq;	dev->irq = 0;	up(&dev->struct_sem);		if (!irq) return -EINVAL;   	DRM_DEBUG(  "Interrupt UnInstall: %d\n", irq);		DRM_DEBUG("%d\n", irq);      	temp = I810_READ16(I810REG_INT_IDENTITY_R);   	temp = temp & ~(0x6000);   	if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, 				   temp); /* Clear all interrupts */      	temp = I810_READ16(I810REG_INT_ENABLE_R);   	temp = temp & 0x6000;   	I810_WRITE16(I810REG_INT_ENABLE_R, 		     temp);                     /* Disable all interrupts */   	free_irq(irq, dev);	return 0;}int i810_control(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_control_t	ctl;	int		retcode;      	DRM_DEBUG(  "i810_control\n");	if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))		return -EFAULT;		switch (ctl.func) {	case DRM_INST_HANDLER:		if ((retcode = i810_irq_install(dev, ctl.irq)))			return retcode;		break;	case DRM_UNINST_HANDLER:		if ((retcode = i810_irq_uninstall(dev)))			return retcode;		break;	default:		return -EINVAL;	}	return 0;}static inline void i810_dma_emit_flush(drm_device_t *dev){   	drm_i810_private_t *dev_priv = dev->dev_private;   	RING_LOCALS;   	i810_kernel_lost_context(dev);   	BEGIN_LP_RING(2);      	OUT_RING( CMD_REPORT_HEAD );      	OUT_RING( GFX_OP_USER_INTERRUPT );      	ADVANCE_LP_RING();/*  	i810_wait_ring( dev, dev_priv->ring.Size - 8 ); *//*     	atomic_set(&dev_priv->flush_done, 1); *//*     	wake_up_interruptible(&dev_priv->flush_queue); */}static inline void i810_dma_quiescent_emit(drm_device_t *dev){      	drm_i810_private_t *dev_priv = dev->dev_private;   	RING_LOCALS;  	i810_kernel_lost_context(dev);   	BEGIN_LP_RING(4);   	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );   	OUT_RING( CMD_REPORT_HEAD );      	OUT_RING( 0 );      	OUT_RING( GFX_OP_USER_INTERRUPT );   	ADVANCE_LP_RING();/*  	i810_wait_ring( dev, dev_priv->ring.Size - 8 ); *//*     	atomic_set(&dev_priv->flush_done, 1); *//*     	wake_up_interruptible(&dev_priv->flush_queue); */}static void i810_dma_quiescent(drm_device_t *dev){      	DECLARE_WAITQUEUE(entry, current);  	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;	unsigned long end;         	if(dev_priv == NULL) {	   	return;	}      	atomic_set(&dev_priv->flush_done, 0);   	add_wait_queue(&dev_priv->flush_queue, &entry);   	end = jiffies + (HZ*3);      	for (;;) {		current->state = TASK_INTERRUPTIBLE;	      	i810_dma_quiescent_emit(dev);	   	if (atomic_read(&dev_priv->flush_done) == 1) break;		if((signed)(end - jiffies) <= 0) {		   	DRM_ERROR("lockup\n");		   	break;		}	   	      	schedule_timeout(HZ*3);	      	if (signal_pending(current)) {		   	break;		}	}      	current->state = TASK_RUNNING;   	remove_wait_queue(&dev_priv->flush_queue, &entry);      	return;}static int i810_flush_queue(drm_device_t *dev){   	DECLARE_WAITQUEUE(entry, current);  	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;	drm_device_dma_t *dma = dev->dma;	unsigned long end;   	int i, ret = 0;         	if(dev_priv == NULL) {	   	return 0;	}      	atomic_set(&dev_priv->flush_done, 0);   	add_wait_queue(&dev_priv->flush_queue, &entry);   	end = jiffies + (HZ*3);   	for (;;) {		current->state = TASK_INTERRUPTIBLE;	      	i810_dma_emit_flush(dev);	   	if (atomic_read(&dev_priv->flush_done) == 1) break;		if((signed)(end - jiffies) <= 0) {		   	DRM_ERROR("lockup\n");		   	break;		}	   	      	schedule_timeout(HZ*3);	      	if (signal_pending(current)) {		   	ret = -EINTR; /* Can't restart */		   	break;		}	}      	current->state = TASK_RUNNING;   	remove_wait_queue(&dev_priv->flush_queue, &entry);   	for (i = 0; i < dma->buf_count; i++) {	   	drm_buf_t *buf = dma->buflist[ i ];	   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;	   		int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, 				   I810_BUF_FREE);		if (used == I810_BUF_HARDWARE)			DRM_DEBUG("reclaimed from HARDWARE\n");		if (used == I810_BUF_CLIENT)			DRM_DEBUG("still on client HARDWARE\n");	}   	return ret;}/* Must be called with the lock held */void i810_reclaim_buffers(drm_device_t *dev, pid_t pid){	drm_device_dma_t *dma = dev->dma;	int		 i;	if (!dma) return;      	if (!dev->dev_private) return;	if (!dma->buflist) return;        i810_flush_queue(dev);	for (i = 0; i < dma->buf_count; i++) {	   	drm_buf_t *buf = dma->buflist[ i ];	   	drm_i810_buf_priv_t *buf_priv = buf->dev_private;	   		if (buf->pid == pid && buf_priv) {			int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, 					   I810_BUF_FREE);			if (used == I810_BUF_CLIENT)				DRM_DEBUG("reclaimed from client\n");		   	if(buf_priv->currently_mapped == I810_BUF_MAPPED)		     		buf_priv->currently_mapped = I810_BUF_UNMAPPED;		}	}}int i810_lock(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;	DECLARE_WAITQUEUE(entry, current);	int		  ret	= 0;	drm_lock_t	  lock;	if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))		return -EFAULT;	if (lock.context == DRM_KERNEL_CONTEXT) {		DRM_ERROR("Process %d using kernel context %d\n",			  current->pid, lock.context);		return -EINVAL;	}      	DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",		  lock.context, current->pid, dev->lock.hw_lock->lock,		  lock.flags);	if (lock.context < 0) {		return -EINVAL;	}	/* Only one queue:	 */	if (!ret) {		add_wait_queue(&dev->lock.lock_queue, &entry);		for (;;) {			current->state = TASK_INTERRUPTIBLE;			if (!dev->lock.hw_lock) {				/* Device has been unregistered */				ret = -EINTR;				break;			}			if (drm_lock_take(&dev->lock.hw_lock->lock,					  lock.context)) {				dev->lock.pid	    = current->pid;				dev->lock.lock_time = jiffies;				atomic_inc(&dev->total_locks);				break;	/* Got lock */			}							/* Contention */			atomic_inc(&dev->total_sleeps);		   	DRM_DEBUG("Calling lock schedule\n");			schedule();			if (signal_pending(current)) {				ret = -ERESTARTSYS;				break;			}		}		current->state = TASK_RUNNING;		remove_wait_queue(&dev->lock.lock_queue, &entry);	}		if (!ret) {		sigemptyset(&dev->sigmask);		sigaddset(&dev->sigmask, SIGSTOP);		sigaddset(&dev->sigmask, SIGTSTP);		sigaddset(&dev->sigmask, SIGTTIN);		sigaddset(&dev->sigmask, SIGTTOU);		dev->sigdata.context = lock.context;		dev->sigdata.lock    = dev->lock.hw_lock;		block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);		if (lock.flags & _DRM_LOCK_QUIESCENT) {		   DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");		   DRM_DEBUG("fred\n");		   i810_dma_quiescent(dev);		}	}	DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");	return ret;}int i810_flush_ioctl(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_DEBUG("i810_flush_ioctl\n");   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("i810_flush_ioctl called without lock held\n");		return -EINVAL;	}   	i810_flush_queue(dev);   	return 0;}int i810_dma_vertex(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_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;      	u32 *hw_status = (u32 *)dev_priv->hw_status_page;   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)      					dev_priv->sarea_priv; 	drm_i810_vertex_t vertex;	if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))		return -EFAULT;   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("i810_dma_vertex called without lock held\n");		return -EINVAL;	}	DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",		  vertex.idx, vertex.used, vertex.discard);	if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;	i810_dma_dispatch_vertex( dev, 				  dma->buflist[ vertex.idx ], 				  vertex.discard, vertex.used );   	atomic_add(vertex.used, &dma->total_bytes);	atomic_inc(&dma->total_dmas);	sarea_priv->last_enqueue = dev_priv->counter-1;   	sarea_priv->last_dispatch = (int) hw_status[5];   	return 0;}int i810_clear_bufs(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_i810_clear_t clear;   	if (copy_from_user(&clear, (drm_i810_clear_t *)arg, sizeof(clear)))		return -EFAULT;      	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("i810_clear_bufs called without lock held\n");		return -EINVAL;	}	i810_dma_dispatch_clear( dev, clear.flags, 				 clear.clear_color, 				 clear.clear_depth );   	return 0;}int i810_swap_bufs(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_DEBUG("i810_swap_bufs\n");   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("i810_swap_buf called without lock held\n");		return -EINVAL;	}	i810_dma_dispatch_swap( dev );   	return 0;}int i810_getage(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_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;      	u32 *hw_status = (u32 *)dev_priv->hw_status_page;   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)      					dev_priv->sarea_priv;       	sarea_priv->last_dispatch = (int) hw_status[5];	return 0;}int i810_getbuf(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;	int		  retcode   = 0;	drm_i810_dma_t	  d;   	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;   	u32 *hw_status = (u32 *)dev_priv->hw_status_page;   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)      					dev_priv->sarea_priv; 	DRM_DEBUG("getbuf\n");   	if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d)))		return -EFAULT;   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("i810_dma called without lock held\n");		return -EINVAL;	}		d.granted = 0;	retcode = i810_dma_get_buffer(dev, &d, filp);	DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",		  current->pid, retcode, d.granted);	if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))		return -EFAULT;   	sarea_priv->last_dispatch = (int) hw_status[5];	return retcode;}int i810_copybuf(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_i810_copy_t	  d;   	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;   	u32 *hw_status = (u32 *)dev_priv->hw_status_page;   	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)      					dev_priv->sarea_priv; 	drm_buf_t *buf;	drm_i810_buf_priv_t *buf_priv;	drm_device_dma_t *dma = dev->dma;	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {		DRM_ERROR("i810_dma called without lock held\n");		return -EINVAL;	}      	if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))		return -EFAULT;	if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;	buf = dma->buflist[ d.idx ];   	buf_priv = buf->dev_private;	if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;	/* Stopping end users copying their data to the entire kernel	   is good.. */	if (d.used < 0 || d.used > buf->total)		return -EINVAL;		   	if (copy_from_user(buf_priv->virtual, d.address, d.used))		return -EFAULT;   	sarea_priv->last_dispatch = (int) hw_status[5];	return 0;}int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,		unsigned long arg){	if(VM_DONTCOPY == 0) return 1;	return 0;}

⌨️ 快捷键说明

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