来自 http://dev.firnow.com/course/6_system/linux/Linuxjs/2008108/149162.html
/*
* scull.h -- definitions for the char module
*
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
* Copyright (C) 2001 O'Reilly & Associates
*
* The source code in this file can be freely used, adapted,
* and redistributed in source or binary form, so long as an
* acknowledgment appears in derived source files. The citation
* should list that the code comes from the book "Linux Device
* Drivers" by Alessandro Rubini and Jonathan Corbet, published
* by O'Reilly & Associates. No warranty is attached;
* we cannot take responsibility for errors or fitness for use.
*
* $Id: scull.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
*/
# ifndef _SCULL_H_
# define _SCULL_H_
# include < linux/ ioctl. h> /* 为了使用_IOW/
/*
* 定义一些宏来帮助调试
*/
# undef PDEBUG /* 取消对PDEBUG的定义,防止重复定义*/
# ifdef SCULL_DEBUG /*开启调试*/
# ifdef __KERNEL__ /*在内核空间下,将调试信息用printk打印*/
# define PDEBUG( fmt, args. . . ) printk( KERN_DEBUG "scull: " fmt, # # args)
# else /*在用户空间下,将信息打印到stderr*/
# define PDEBUG( fmt, args. . . ) fprintf ( stderr , fmt, # # args)
# endif
# else
# define PDEBUG( fmt, args. . . ) /* 调试没开启,PDEBUG定义为什么都不做 */
# endif
# undef PDEBUGG
# define PDEBUGG( fmt, args. . . ) /* PDEBUGG不做任何事,充当占位符 */
# ifndef SCULL_MAJOR
# define SCULL_MAJOR 0 /* 默认使用动态分配主设备号 */
# endif
/*这里将SCULL_MAJOR(主设备号)初始化为0,是为了在 scull_init_module()中动态分配设备号,
在scull.c中,有一全局变量 int scull_major = SCULL_MAJOR; 用来代表设备号。在scull_init_module中有以下:
if (scull_major)
regidter_chrdev_region -----静态
else
alloc_chrdev_region --------动态
*/
# ifndef SCULL_NR_DEVS
# define SCULL_NR_DEVS 4 /* 设备数目或设备序号,从scull0到scull3 */
# endif
/*
* The bare device is a variable-length region of memory.
* Use a linked list of indirect blocks.
* "scull_dev->data" points to an array of pointers, each
* pointer refers to a memory area of SCULL_QUANTUM bytes.
* The array (quantum-set) is SCULL_QSET long.
scull_dev->data指向一组指针,其中每一个指针指向一个SCULL_QUANTUM字节
的内存空间.
*/
# ifndef SCULL_QUANTUM
# define SCULL_QUANTUM 4000 /*量子的大小,4000字节.指的是数据区域中的指针所引用的内存大小*/
# endif
# ifndef SCULL_QSET
# define SCULL_QSET 1000 /*量
子集大小,1000 个,指的是共有 1000 个指针,或者指针数组的长度。每一个指针用来应用 4000 字节的小的空间 */
# endif
/*
* Representation of scull quantum sets.
scull设备的 quantum 的实现如下
*/
struct scull_qset { /*设备的实现为一个简单的链表结点。 data 作为一个指向 4000 字节的区域 */
void ** data ;
struct scull_qset * next ;
};
struct scull_dev { /*设备的结构 */
struct scull_qset * data ; /* 指向第一个量子集 */
int quantum ; /* 当前量子的大小 */
int qset ; /* 当前数组的大小 */
unsigned long size ; /* 保存在其中的数据总量 */
unsigned int access_key ; /* 由 sculluid 和 scullpriv 使用 */
struct semaphore sem ; /* 互斥信号量 */
struct cdev cdev ; /* 字符设备结构 */
};
/* 对于字符设备的实现,一般要定义自己的设备类型的结构。 scull_dev 就是该设备类型。
一般要把信号量,锁之类的保护措施和struct cdev 放在其中
*/
/*
* Split minors in two parts
*/
# define TYPE ( minor ) ((( minor ) >> 4 ) & 0xf ) /* high nibble */
# define NUM ( minor ) (( minor ) & 0xf ) /* low nibble */
/*这两个东西不知道有什么作用 */
/*
* The different configurable parameters
一些外部声明
*/
extern int scull_major ; /* main.c */
extern int scull_nr_devs ;
extern int scull_quantum ;
extern int scull_qset ;
/*函数声明 */
int scull_trim ( struct scull_dev * dev );
ssize_t scull_read ( struct file * filp , char __user * buf , size_t count , loff_t * f_pos );
ssize_t scull_write ( struct file * filp , const char __user * buf , size_t count , loff_t * f_pos );
loff_t scull_llseek ( struct file
子集大小,1000 个,指的是共有 1000 个指针,或者指针数组的长度。每一个指针用来应用 4000 字节的小的空间 */
# endif
/*
* Representation of scull quantum sets.
scull设备的 quantum 的实现如下
*/
struct scull_qset { /*设备的实现为一个简单的链表结点。 data 作为一个指向 4000 字节的区域 */
void ** data ;
struct scull_qset * next ;
};
struct scull_dev { /*设备的结构 */
struct scull_qset * data ; /* 指向第一个量子集 */
int quantum ; /* 当前量子的大小 */
int qset ; /* 当前数组的大小 */
unsigned long size ; /* 保存在其中的数据总量 */
unsigned int access_key ; /* 由 sculluid 和 scullpriv 使用 */
struct semaphore sem ; /* 互斥信号量 */
struct cdev cdev ; /* 字符设备结构 */
};
/* 对于字符设备的实现,一般要定义自己的设备类型的结构。 scull_dev 就是该设备类型。
一般要把信号量,锁之类的保护措施和struct cdev 放在其中
*/
/*
* Split minors in two parts
*/
# define TYPE ( minor ) ((( minor ) >> 4 ) & 0xf ) /* high nibble */
# define NUM ( minor ) (( minor ) & 0xf ) /* low nibble */
/*这两个东西不知道有什么作用 */
/*
* The different configurable parameters
一些外部声明
*/
extern int scull_major ; /* main.c */
extern int scull_nr_devs ;
extern int scull_quantum ;
extern int scull_qset ;
/*函数声明 */
int scull_trim ( struct scull_dev * dev );
ssize_t scull_read ( struct file * filp , char __user * buf , size_t count , loff_t * f_pos );
ssize_t scull_write ( struct file * filp , const char __user * buf , size_t count , loff_t * f_pos );
loff_t scull_llseek ( struct file yle="color: rgb(0, 0, 204);">*filp , loff_t off , int whence );
int scull_ioctl ( struct inode * inode , struct file * filp , unsigned int cmd , unsigned long arg );
/*
* Ioctl definitions
IO控制的定义
*/
/* Use 'k' as magic number
使用k 作为幻数 */
# define SCULL_IOC_MAGIC 'k'
/* Please use a different 8-bit number in your code */
# define SCULL_IOCRESET _IO ( SCULL_IOC_MAGIC , 0 )
/*
* S means 通过指针 “ 设置 ”
* T means 直接用参数值通知
* G means 表示 “ 获取 ” ,通过设置指针来应答
* Q means 表示 “ 查询 ” ,通过返回值应答
* X means 表示 “ 交换 ” ,原子地交换 G S
* H means 表示 “ 切换 ” ,原子地交换 T Q
*/
# define SCULL_IOCSQUANTUM _IOW ( SCULL_IOC_MAGIC , 1 , int )
# define SCULL_IOCSQSET _IOW ( SCULL_IOC_MAGIC , 2 , int )
# define SCULL_IOCTQUANTUM _IO ( SCULL_IOC_MAGIC , 3 )
# define SCULL_IOCTQSET _IO ( SCULL_IOC_MAGIC , 4 )
# define SCULL_IOCGQUANTUM _IOR ( SCULL_IOC_MAGIC , 5 , int )
# define SCULL_IOCGQSET _IOR ( SCULL_IOC_MAGIC , 6 , int )
# define SCULL_IOCQQUANTUM _IO ( SCULL_IOC_MAGIC , 7 )
# define SCULL_IOCQQSET _IO ( SCULL_IOC_MAGIC , 8 )
# define SCULL_IOCXQUANTUM _IOWR ( SCULL_IOC_MAGIC , 9 , int )
# define SCULL_IOCXQSET _IOWR ( SCULL_IOC_MAGIC , 10 , int )
# define SCULL_IOCHQUANTUM _IO ( SCULL_IOC_MAGIC , 11 )
# define SCULL_IOCHQSET _IO ( SCULL_IOC_MAGIC , 12 )
/*
* The other entities only have "Tell" and "Query", because they're
* not printed in the book, and there's no need to have all six.
* (The previous stuff was only there to show different ways to do it.
*/
# define SCULL_IOC_MAXNR 12
# endif /* _SCULL_H_ */