taskwatch.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 195 行

C
195
字号
/* * linux/arch/arm/mach-omap/dsp/taskwatch.c * * OMAP DSP task watch device driver * * Copyright (C) 2002-2004 Nokia Corporation * * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: taskwatch.c * $Revision: 3.0.1 * $Date: 2004/10/04 * */#include <linux/module.h>#include <linux/major.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/poll.h>#include <linux/interrupt.h>#include <linux/sched.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/arch/dsp.h>#include "dsp.h"static wait_queue_head_t read_wait_q;static struct semaphore ioctl_sem;static unsigned char n_task_base;static int cfgstat = CFGSTAT_ERR;static unsigned int change_cnt;void omap_dsp_twch_touch(void){	change_cnt++;	wake_up_interruptible(&read_wait_q);}/* * @count: represents the device counts of the user's interst */static ssize_t omap_dsp_twch_read(struct file *file, char *buf,				  size_t count, loff_t *ppos){	char taskstat[TASKDEV_MAX];	int i;	if (cfgstat != CFGSTAT_DONE) {		printk(KERN_ERR "omapdsp: dsp has not been configured.\n");		return -EINVAL;	}	if (change_cnt == 0) {		long current_state;		DECLARE_WAITQUEUE(wait, current);		add_wait_queue(&read_wait_q, &wait);		current_state = current->state;		set_current_state(TASK_INTERRUPTIBLE);		if (change_cnt == 0)	/* last check */			schedule();		set_current_state(current_state);		remove_wait_queue(&read_wait_q, &wait);		/* unconfigured while waiting ;-( */		if (cfgstat != CFGSTAT_DONE)			return -EINVAL;	}	if (count > TASKDEV_MAX)		count = TASKDEV_MAX;	memset(taskstat, OMAP_DSP_OPENSTAT_CLOSE, count);	change_cnt = 0;	for (i = n_task_base; i < count; i++) {		taskstat[i] = omap_dsp_taskdev_openstat(i);	}	if (copy_to_user(buf, taskstat, count))		return -EFAULT;	return count;}static unsigned int omap_dsp_twch_poll(struct file *file, poll_table *wait){	unsigned int mask = 0;	poll_wait(file, &read_wait_q, wait);	if (change_cnt)		mask |= POLLIN | POLLRDNORM;	return mask;}static int omap_dsp_twch_ioctl(struct inode *inode, struct file *file,			       unsigned int cmd, unsigned long arg){	int sem_st, ret;	if ((sem_st = down_interruptible(&ioctl_sem)) < 0)		return sem_st;	switch (cmd) {	case OMAP_DSP_TWCH_IOCTL_MKDEV:		{			char name[OMAP_DSP_TNM_LEN];			if (copy_from_user(name, (void *)arg, OMAP_DSP_TNM_LEN)) {				ret = -EFAULT;				goto finish;			}			ret = omap_dsp_mkdev(name);			break;		}	case OMAP_DSP_TWCH_IOCTL_RMDEV:		{			char name[OMAP_DSP_TNM_LEN];			if (copy_from_user(name, (void *)arg, OMAP_DSP_TNM_LEN)) {				ret = -EFAULT;				goto finish;			}			ret = omap_dsp_rmdev(name);			break;		}	case OMAP_DSP_TWCH_IOCTL_TADD:		{			struct omap_dsp_taddinfo ti;			if (copy_from_user(&ti, (void *)arg, sizeof(ti))) {				ret = -EFAULT;				goto finish;			}			ret = omap_dsp_tadd(ti.minor, ti.taskadr);			break;		}	case OMAP_DSP_TWCH_IOCTL_TDEL:		ret = omap_dsp_tdel(arg);		break;	default:		ret = -ENOIOCTLCMD;	}finish:	up(&ioctl_sem);	return ret;}struct file_operations omap_dsp_twch_fops = {	.owner = THIS_MODULE,	.read  = omap_dsp_twch_read,	.poll  = omap_dsp_twch_poll,	.ioctl = omap_dsp_twch_ioctl,};void omap_dsp_twch_config(unsigned char n){	n_task_base = n;	cfgstat = CFGSTAT_DONE;	change_cnt = 1;		/* first read will not wait */}void omap_dsp_twch_unconfig(void){	wake_up_interruptible(&read_wait_q);	cfgstat = CFGSTAT_ERR;}void __init omap_dsp_twch_init(void){	init_MUTEX(&ioctl_sem);	init_waitqueue_head(&read_wait_q);}void omap_dsp_twch_exit(void){}

⌨️ 快捷键说明

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