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

 return 0;

#endif

}

/* This function is called whenever a process which

* have 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 data */

 size_t length, /* The length of the buffer */

 loff_t *offset) /* Our offset in 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 (mustn't write beyond that!) */

#endif

{

 /* Number of bytes actually written to the buffer */

 int bytes_read = 0;

 /* If we're 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 wouldn't

  * 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 left\n", 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 - unsupported in this example. */

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

static ssize_t device_write(struct file *file,

 const char *buffer, /* The buffer */

 size_t length, /* The length of the buffer */

 loff_t *offset) /* Our offset in the file */

#else

static int device_write(struct inode *inode, struct file *file, const char *buffer, int length)

#endif

{

 return -EINVAL;

}

/* Module Declarations ***************************** */

/* The major device number for the device. This is

* global (well, static, which in this context is global

* within this file) because it has to be accessible * both for registration and for release. */

static int Major;

/* This structure will hold the functions to be

* called when a process does something to the device

* we created. Since a pointer to this structure is

* kept in the devices table, it can't be local to

* init_module. NULL is for unimplemented functions. */

struct file_operations Fops = {

 NULL, /* seek */

 device_read, device_write,

 NULL, /* readdir */

 NULL, /* select */

 NULL, /* ioctl */

 NULL, /* mmap */

 device_open,

Перейти на страницу:

Все книги серии Проект russian ldp

Похожие книги