Linux操作系统内核和设备文件对话( 二 )


#endif;
/* We dont 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, were in the;
* kernel, so were protected against context switches.;
*;
* This is NOT the right attitude to take, because we;
* might be running on an SMP box, but well deal with;
* SMP in a later chapter.;
*/;
Device_Open
/* Initialize the message */;
Message_Ptr = Message
MOD_INC_USE_COUNT
return SUCCESS
};

/* This function is called when a process closes the;
* device file. It doesnt have a return value because;
* it cannot fail. Regardless of what else happens, you;
* should always be able to close a device (in 2.0, a 2.2;
* device file could be impossible to close). */;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
static int device_release(struct inode *inode,;
struct file *file);
#else;
static void device_release(struct inode *inode,;
struct file *file);
#endif;
{;
#ifdef DEBUG;
printk ("device_release(%p,%p)n", inode, file)
#endif;
/* Were now ready for our next caller */;
Device_Open --
MOD_DEC_USE_COUNT
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
return 0
#endif;
}
/* This function is called whenever a process which;
* has already opened the device file attempts to;
* read from it. */;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
static ssize_t device_read(;
struct file *file,;
char *buffer, /* The buffer to fill with the data */;
size_t length, /* The length of the buffer */;
loff_t *offset) /* offset to the file */;
#else;
static int device_read(;
struct inode *inode,;
struct file *file,;
char *buffer, /* The buffer to fill with the data */;
int length) /* The length of the buffer;
* (mustnt write beyond that!) */;
#endif;
{;
/* Number of bytes actually written to the buffer */;
int bytes_read = 0
#ifdef DEBUG;
printk("device_read(%p,%p,%d)n",;
file, buffer, length)
#endif;
/* If were at the end of the message, return 0;
* (which signifies end of file) */;
if (*Message_Ptr == 0);
return 0
/* Actually put the data into the buffer */;
while (length && *Message_Ptr) {;
/* Because the buffer is in the user data segment,;
* not the kernel data segment, assignment wouldnt;
* work. Instead, we have to use put_user which;
* copies data from the kernel data segment to the;
* user data segment. */;
put_user(*(Message_Ptr), buffer)
length --
bytes_read
};
#ifdef DEBUG;
printk ("Read %d bytes, %d leftn",;
bytes_read, length)
#endif;
/* Read functions are supposed to return the number;
* of bytes actually inserted into the buffer */;
return bytes_read
}
/* This function is called when somebody tries to;
* write into our device file. */;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
static ssize_t device_write(struct file *file,;
const char *buffer,;
size_t length,;
loff_t *offset);
#else;
static int device_write(struct inode *inode,;
struct file *file,;
const char *buffer,;
int length);
#endif;
{;
int i
#ifdef DEBUG;
printk ("device_write(%p,%s,%d)",;
file, buffer, length)
#endif;
for(i=0; i;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
get_user(Message, buffer i)
#else;
Message = get_user(buffer i)
#endif;
Message_Ptr = Message
/* Again, return the number of input characters used */;
return i
}
/* This function is called whenever a process tries to;
* do an ioctl on our device file. We get two extra;
* parameters (additional to the inode and file;
* structures, which all device functions get): the number;

推荐阅读