Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1264321
  • 博文数量: 404
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 5382
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-03 16:29
文章存档

2010年(40)

2009年(140)

2008年(224)

我的朋友

分类: LINUX

2008-09-26 11:05:07

int chardev_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
        
struct my_dev *dev = file->private_data;
        
int retval = 0, tmp = 0;
        
if( _IOC_TYPE(cmd) != KF701_IOC_MAGIC )
                
return -ENOTTY;
        
if( _IOC_NR(cmd) > KF701_IOC_MAXNR )
                
return -ENOTTY;

        
switch(cmd)
        
{
                
case KF701_IO_RESET:
                        printk
(KERN_DEBUG "%s:IO_RESET CMD\n",DEVICE);
                        
break;
                
case KF701_IO_R:
                        printk
(KERN_DEBUG "%s:IO READ CMD\n",DEVICE);
                        retval
= put_user(dev->index, (int __user *)arg);
                        
break;
                
case KF701_IO_W:
                        printk
(KERN_DEBUG "%s:IO WRITE CMD\n",DEVICE);
                        retval
= get_user(tmp, (int __user *)arg);
                        printk
(KERN_DEBUG "CMD ARG = %d\n", tmp);
                        
break;
                
case KF701_IO_RW:
                        printk
(KERN_DEBUG "%s:IO W-R CMD\n",DEVICE);
                        
break;
                
default:
                        
return -ENOTTY;
        
}
        
return retval;
}

unsigned int chardev_poll(struct file * file, poll_table * wait)
{
        
struct my_dev *dev = file->private_data;
        
unsigned int mask = 0;
        down
(&dev->sem);
        poll_wait
(file,&dev->rq,wait);
        
if( 0 != dev->index )
                mask
|= POLLIN | POLLRDNORM;
        up
(&dev->sem);
        
return mask;
}

// 此函数在进程上下文之外运行,类似中断上下文,因此:
// 1. 不能访问用户空间
// 2. current指针没有意义
// 3. 不能调用可能引起体眠和调度的代码,信号量也不行。
// 4. 最好使用 spinlock

void timer_function(unsigned long arg)
{
        
struct my_dev *dev = (struct my_dev*)arg;
        
if( dev->index >= (dev->size - 1) )
                
return;
        
if( dev->timer_char > 'Z' )
                dev
->timer_char = 'A';
        
if( '\n' == dev->buf[dev->index-1] )
                dev
->index--;
        dev
->buf[dev->index++] = (dev->timer_char)++;
        dev
->buf[dev->index++] = '\n';

        
// 唤醒阻塞在 read select 上的进程
        wake_up_interruptible
(&dev->rq);
        dev
->timer.expires += dev->timer_interval;
        add_timer
( &dev->timer );
}

module_init
(chardev_init);
module_exit
(chardev_exit);

MODULE_AUTHOR
("kf701.ye at gmail.com");
MODULE_DESCRIPTION
("Study for kf701");
MODULE_SUPPORTED_DEVICE
(DEVICE);
MODULE_LICENSE
("GPL");
阅读(762) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~