Энциклопедия разработчика модулей ядра Linux | страница 20



chardev.c 

>/* chardev.c

>*

>* Create an input/output character device

>*/

>/* Copyright (C) 1998-99 by Ori Pomerantz */


>/* The necessary header files */

>/* Standard in kernel modules */

>#include /* We're doing kernel work */

>#include /* Specifically, a module */


>/* Deal with CONFIG_MODVERSIONS */

>#if CONFIG_MODVERSIONS==1

>#define MODVERSIONS

>#include

>#endif


>/* For character devices */

>/* The character device definitions are here */

>#include


>/* A wrapper which does next to nothing at

>* at present, but may help for compatibility

>* with future versions of Linux */

>#include


>/* Our own ioctl numbers */

>#include "chardev.h"


>/* In 2.2.3 /usr/include/linux/version.h includes a

>* macro for this, but 2.0.35 doesn't - so I add it

>* here if necessary. */

>#ifndef KERNEL_VERSION

>#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))

>#endif


>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>#include /* for get_user and put_user */

>#endif


>#define SUCCESS 0


>/* Device Declarations ******************************** */

>/* The name for our device, as it will appear in /proc/devices */

>#define DEVICE_NAME "char_dev"


>/* The maximum length of the message for the device */

>#define BUF_LEN 80


>/* Is the device open right now? Used to prevent concurent access into the same device */

>static int Device_Open = 0;


>/* The message the device will give when asked */

>static char Message[BUF_LEN];


>/* How far did the process reading the message get?

>* Useful if the message is larger than the size of the

>* buffer we get to fill in device_read. */

>static char *Message_Ptr;


>/* This function is called whenever a process attempts to open the device file */

>static int device_open(struct inode *inode, struct file *file) {

>#ifdef DEBUG

> printk("device_open(%p)\n", file);

>#endif

> /* We don't want to talk to two processes at the  same time */

> if (Device_Open) return -EBUSY;

> /* If this was a process, we would have had to be

> * more careful here, because one process might have

> * checked Device_Open right before the other one

> * tried to increment it. However, we're in the

> * kernel, so we're protected against context switches.

> *

> * This is NOT the right attitude to take, because we

> * might be running on an SMP box, but we'll deal with

> * SMP in a later chapter. */

> Device_Open++;

> /* Initialize the message */

> Message_Ptr = Message;