Энциклопедия разработчика модулей ядра Linux | страница 8
>/* 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
>/* Conditional compilation. LINUX_VERSION_CODE is the code (as per KERNEL_VERSION) of this version. */
>#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
>#include
>#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 from 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) {
> static int counter = 0;
>#ifdef DEBUG
> printk("device_open(%p,%p)\n", inode, file);
>#endif
>/* This is how you get the minor device number in case you have more than one physical device using the driver. */
> printk("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
> /* 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.
> *
> * In the case of processes, the danger would be
> * that one process might have check Device_Open
> * and then be replaced by the schedualer by another
> * process which runs this function. Then, when the
> * first process was back on the CPU, it would assume
> * the device is still not open.
> *
> * However, Linux guarantees that a process won't be
> * replaced while it is running in kernel context.
> *
> * In the case of SMP, one CPU might increment
> * Device_Open while another CPU is here, right after
> * the check. However, in version 2.0 of the
> * kernel this is not a problem because there's a lock
> * to guarantee only one CPU will be kernel module at
> * the same time. This is bad in terms of
> * performance, so version 2.2 changed it.
> * Unfortunately, I don't have access to an SMP box
> * to check how it works with SMP. */