linux device drive 第六章代码示例-scullpipe的实验(poll和fasync方法的实现)之一
一 scullpipe的代码
1 scull.h
#ifndef _SCULL_H_ #define _SCULL_H_ #include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */ /* * Macros to help debugging */ #undef PDEBUG /* undef it, just in case */ #ifdef SCULL_DEBUG # ifdef __KERNEL__ /* This one if debugging is on, and kernel space */ # define PDEBUG(fmt, args...) printk( KERN_DEBUG "scull: " fmt, ## args) # else /* This one for user space */ # define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) # endif #else # define PDEBUG(fmt, args...) /* not debugging: nothing */ #endif #undef PDEBUGG #define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */ #ifndef SCULL_MAJOR #define SCULL_MAJOR 0 /* dynamic major by default */ #endif #ifndef SCULL_P_NR_DEVS #define SCULL_P_NR_DEVS 4 /* scullpipe0 through scullpipe3 */ #endif /* * The pipe device is a simple circular buffer. Here its default size */ #ifndef SCULL_P_BUFFER #define SCULL_P_BUFFER 4000 #endif /* * Representation of scull quantum sets. */ /* * 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_p_nr_devs; extern int scull_p_buffer; /* pipe.c */ /* * Prototypes for shared functions */ int scull_p_init(void); void scull_p_cleanup(void); /* * Ioctl definitions */ /* Use 'k' as magic number */ #define SCULL_IOC_MAGIC 'k' /* Please use a different 8-bit number in your code */ #define SCULL_P_IOCTSIZE _IO(SCULL_IOC_MAGIC, 0) #define SCULL_P_IOCQSIZE _IO(SCULL_IOC_MAGIC, 1) /* ... more to come */ #define SCULL_IOC_MAXNR 1 #endif /* _SCULL_H_ */
2 pipe.c的源码
/*
* pipe.c -- fifo driver for scull
*
* 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.
*
*/#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>#include <linux/kernel.h> /* printk(), min() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/proc_fs.h>
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>#include "scull.h" /* local definitions */
int scull_major = SCULL_MAJOR;
int scull_minor = 0;
int scull_p_nr_devs = SCULL_P_NR_DEVS; /* number of pipe devices */
int scull_p_buffer = SCULL_P_BUFFER; /* buffer size */module_param(scull_major, int, S_IRUGO);
module_param(scull_minor, int, S_IRUGO);
module_param(scull_p_nr_devs, int, 0); /* FIXME check perms */
module_param(scull_p_buffer, int, 0);struct scull_pipe {
wait_queue_head_t inq, outq; /* read and write queues */
char *buffer, *end; /* begin of buf, end of buf */
int buffersize; /* used in pointer arithmetic */
char *rp, *wp; /* where to read, where to write */
int nreaders, nwriters; /* number of openings for r/w */
struct fasync_struct *async_queue; /* asynchronous readers */