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 + -
显示快捷键?