来自 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_ */