LinuxÒÁµéÔ°ÂÛ̳'s Archiver

alldying ·¢±íÓÚ 2006-9-18 16:18

¡¾ÇóÖú¡¿Çë½ÌÒ»¸öÇý¶¯º¯ÊýÈë¿ÚµÄÎÊÌâ

[color=#555555]¸÷λÐֵܰïæ£¡

ÒÔÏÂÊÇÎÒ×Ô¼ºÐ´µÄÒ»¸öÇý¶¯³ÌÐòµÄ.cÎļþ£¬open¡¢close¡¢read3¸öº¯ÊýÔËÐÐÕý³££¬¶Á³öÊý¾ÝÕýÈ·£¬Ö»ÓÐwrite²»¶Ô£¬ºÃÏóÊǸù±¾¾ÍûÓе÷Óã¬Ã»Óнøµ½º¯ÊýÀïÃæÈ¥£¬²»ÖªµÀΪʲô£¬ÇëÓо­ÑéµÄÐֵܰï°ï棡
/////////////´úÂ뿪ʼ////////////////////
/*********************************************************************
*              ÔÚAT91RM9200ÉÏ×ÔÐÐÀ©Õ¹µÄ´úÌæpc104µÄ×ÜÏßµÄÇý¶¯³ÌÐò
*********************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <asm/io.h>

#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
#endif

static int AT91_PC104;

#define PC104_SIZE 1024
#define PC104_MAJOR 125
#define NR_PC104_DEVICES 1

#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_handle = NULL;
static devfs_handle_t devfs_pc104[NR_PC104_DEVICES];
#endif
/*********************************************************************
*              º¯ÊýÉùÃ÷
*********************************************************************/
static int at91_pc104_init(void);
static void at91_pc104_cleanup(void);
static void pc104_init(void);
static int pc104_open(struct inode *inode, struct file *filp);
static int pc104_close(struct inode *inode, struct file *filp);
static ssize_t pc104_read(struct file *filp, char *buf, size_t count, loff_t *offset);
static ssize_t pc104_write(struct file *filp, const char *buf, size_t count, loff_t *offset);
/*********************************************************************+
*              È«¾Ö±äÁ¿¶¨Òå
**********************************************************************/
int pc104_param = 9;
static int pc104_initialized = 0;
static int pc104_reading=0;
static int pc104_writing=0;
static volatile int pc104_flag = 0;
static struct file_operations pc104_fops = {
owner: THIS_MODULE,
read: pc104_read,
write: pc104_write,
open: pc104_open,
release: pc104_close,
};
[b]static int at91_pc104_init(void)[/b]
{
int i = 0;
       char name[2];
/*È·¶¨Ä£¿éÒÔǰδ³õʼ»¯*/
if(pc104_initialized == 1)
return 0;
/*·ÖÅä²¢³õʼ»¯ËùÓÐÊý¾Ý½á¹¹ÎªÈ±Ê¡×´Ì¬*/
#ifdef CONFIG_DEVFS_FS
     if(devfs_register_chrdev(PC104_MAJOR, "pc104", &pc104_fops)){
#else
     if(register_chrdev(PC104_MAJOR, "pc104", &pc104_fops)){
#endif
  printk(KERN_CRIT"pc104:i = %d\n",i);
  return -EIO;
}
printk(KERN_CRIT"pc104 registerred successfully!\n");
/*ÇëÇóÖжÏ*/
pc104_initialized = 1;
#ifdef CONFIG_DEVFS_FS
       devfs_handle = devfs_mk_dir(NULL, "pc104", NULL);
       for(i = 0; i < NR_PC104_DEVICES; i++)
         {
           sprintf(name, "%d", i);
           devfs_pc104[i] = devfs_register(devfs_handle, name,
           DEVFS_FL_DEFAULT, PC104_MAJOR, i, S_IFCHR|S_IRUSR|S_IWUSR,&pc104_fops, NULL);
         }
#endif
return 0;
}
void pc104_init()
{
       AT91_PC104 = (unsigned long) ioremap(0x80000000,SZ_1K);
AT91_SYS->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);
AT91_SYS->EBI_SMC2_CSR[7] = (AT91C_SMC2_NWS & 0x4)  | AT91C_SMC2_WSEN |
                              (AT91C_SMC2_TDF & 0x200)| AT91C_SMC2_DBW_8;
}
[b]static int pc104_open(struct inode *inode, struct file *filp)[/b]
{
if(pc104_flag == 1)/*¼ì²éÇý¶¯ÊÇ·ñæ*/
{
return -1;
}
/*¿ÉÒÔ³õʼ»¯Ò»Ð©ÄÚ²¿Êý¾Ý½á¹¹*/
pc104_init();
MOD_INC_USE_COUNT;
pc104_flag = 1;
return 0;
}
[b]static int pc104_close(struct inode *inode, struct file *filp)[/b]
{
if(pc104_flag == 0)
{
return 0;
}
/*¿ÉÒÔɾ³ýһЩÄÚ²¿Êý¾Ý½á¹¹*/
MOD_DEC_USE_COUNT;
     pc104_reading = 0;
      pc104_writing = 0;
pc104_flag = 0;
return 0;
}
[b]static ssize_t pc104_read(struct file *filp, char *buf, size_t count, loff_t *offset)[/b]
{
size_t i;
ssize_t ret=0;
/*¼ì²éÊÇ·ñÓÐÏß³ÌÔÚ¶ÁÊý¾Ý£¬·µ»Ø error*/
if(pc104_reading)
return -1;
pc104_reading=1;//DEMO_RD_LOCK;
if(!count)
return ret;
if(*offset>=PC104_SIZE)
return -EINVAL;
if((*offset+count)>PC104_SIZE)
count=PC104_SIZE-*offset;
for(i = 0; i < count; i++)
{
            buf[i] = readb(AT91_PC104+*offset+i);
}
       buf[i] = '\0';
*offset +=count;
ret=count;
pc104_reading=0;//DEMO_RD_UNLOCK;
/*ͨ³£·µ»Ø³É¹¦¶Áµ½µÄÊý¾Ý*/
return ret;
}
[b]static ssize_t pc104_write(struct file *filp, const char *buf, size_t count, loff_t *offset)[/b]
{
  ssize_t ret = 0;
  printk("pc104 devices writing!\n");
  return ret;
}
[b]static void at91_pc104_cleanup(void)[/b]
{
/*È·±£ÒªÇåµôµÄÄ£¿éÊÇ·ñÒѳõʼ»¯*/
if(pc104_initialized == 1)
{
unregister_chrdev(PC104_MAJOR,"pc104");
pc104_initialized = 0;
printk(KERN_CRIT"pc104 device is cleanup\n");
}
}
[b]module_init(at91_pc104_init);[/b]
[b]module_exit(at91_pc104_cleanup);[/b]
//////////´úÂë½áÊø///////////////////////////////[/color]

Ò³: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.