09年智手各组组长,组员重新招募中 发贴得礼品有实物,有金币和道具 重新招募09年各版版主 每月获奖名单
新人报到加分贴 对我们的意见告诉这里 新增奖品及奖励办法 广告招商
 
发新话题
打印

字符驱动,希望对大家有帮助

字符驱动,希望对大家有帮助

#include <linux/module.h>

#if defined(CONFIG_SMP)
#define __SMP__
#endif

#if defined(CONFIG_MODVERSIONS)
#define MODVERSIONS
#include <linux/modversions.h>
#endif

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/timer.h>/* for timers */
#include <linux/fs.h>/* file modes and device registration */
#include <linux/poll.h>/* for poll */
#include <linux/wrapper.h>/* mem_map_reserve,mem_map_unreserve */
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/init.h>

#include <asm/io.h>

#include "schar.h"

/* forward declarations for _fops */
static ssize_t schar_read(struct file *file, char *buf, size_t count, loff_t *offset);
static ssize_t schar_write(struct file *file, const char *buf, size_t count, loff_t *offset);
static int schar_open(struct inode *inode, struct file *file);
static int schar_release(struct inode *inode, struct file *file);

static struct file_operations schar_fops = {

schar_read,
schar_write,
schar_open,
schar_release,
};

/* data */
static long schar_pool, schar_data_read, schar_data_written;
static char *schar_buffer;

static struct wait_queue *schar_wq = NULL;
static struct wait_queue *schar_poll_read = NULL;
static char *schar_name;

/* module parameters and descriptions */
MODULE_PARM(schar_name, "s");
MODULE_PARM_DESC(schar_name, "Name of device");

MODULE_DESCRIPTION("schar, Sample character driver");
MODULE_AUTHOR("zz");

static ssize_t schar_read(struct file *file, char *buf, size_t count,
loff_t *offset)
{

/* if less data than requested is here, put reading process to sleep */
while (count > schar_pool) {
/* if the device is opened non blocking satisfy what we
  can of the request and don't put the process to sleep. */
if (file->f_flags & O_NONBLOCK) {
if (schar_pool > 0) {
file->f_pos += schar_pool;
schar_data_read += file->f_pos;
if(copy_to_user(buf, schar_buffer, schar_pool))
return -EFAULT;
count = schar_pool;
schar_pool = 0;
return count;
} else {
return -EAGAIN;
}
}

MSG("putting process with pid %u to sleep\n", current->pid);
/* go to sleep, but wake up on signals */
interruptible_sleep_on(&schar_wq);
if (signal_pending(current)) {
MSG("pid %u got signal\n", (unsigned)current->pid);
/* tell vfs about the signal */
return -EINTR;
}
}

/* copy the data the our buffer */
if (copy_to_user(buf, schar_buffer, count))
return -EFAULT;

schar_pool -= count;
schar_data_read += count;

MSG("want to read %u bytes, %ld bytes in queue\n", (unsigned)count,
   schar_pool);

/* return data written */
file->f_pos += count;
return count;
}

static ssize_t schar_write(struct file *file, const char *buf, size_t count,
  loff_t *offset)
{
schar_pool += count;
schar_data_written += count;

/* if we were really writing - modify the file position to
   reflect the amount of data written */
file->f_pos += count;
if (copy_from_user(schar_buffer, buf, count))
return -EFAULT;

/* wake up reading processes, if any */
if (schar_pool > 0) {
wake_up_interruptible(&schar_wq);
wake_up_interruptible(&schar_poll_read);
}

MSG("trying to write %u bytes, %ld bytes in queue now\n",
(unsigned)count, schar_pool);

/* return data written */
return count;
}

static int schar_open(struct inode *inode, struct file *file)
{
/* increment usage count */
MOD_INC_USE_COUNT;

if (file->f_mode & FMODE_READ) {
MSG("opened for reading\n");
} else if (file->f_mode & FMODE_WRITE) {
MSG("opened for writing \n");
}

MSG("major: %d minor: %d\n", MAJOR(inode->i_rdev), MINOR(inode->i_rdev));

return 0;
}
static int schar_release(struct inode *inode, struct file *file)
{
MOD_DEC_USE_COUNT;
MSG("schar_release\n");
return 0;
}

int init_module(void)
{
int res;

if (schar_name == NULL)
schar_name = "schar";

/* register device with kernel */
res = register_chrdev(SCHAR_MAJOR, schar_name, &schar_fops);
if (res) {
MSG("can't register device with kernel\n");
return res;
}

MSG("module loaded\n");
return 0;
}

void cleanup_module(void)
{
/* unregister device and proc entry */
unregister_chrdev(SCHAR_MAJOR, "schar");
if (schar_root_header)
unregister_sysctl_table(schar_root_header);

MSG("unloaded\n");
return;
}

本站以服务广大智能设备爱好者和开发者为立站之本.是你在此交流提高的乐园,本站不做任何形式的广告,不发布任何无意义帖子,论坛靠大家,希望大家踊跃交流,给大家一片洁净的天地!只有大家的支持才是本站生存的根本

TOP

多米诺骨牌小游戏

提示: 作者被禁止或删除 内容自动屏蔽

TOP

发新话题
版块跳转 
   京ICP备06029169号

本社区言论纯属发表者个人意见  与 智手移动中文网论坛 立场无关