Linux Device Drivers (3rd Edition) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Linux Device Drivers (3rd Edition) [Electronic resources] - نسخه متنی

Jonathan Corbet, Greg Kroah-Hartman, Alessandro Rubini

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








6.5. Seeking a Device


One of the last things we need to




cover in
this chapter is the llseek method, which is
useful (for some devices) and easy to implement.


6.5.1. The llseek Implementation


The llseek method implements the
lseek and llseek system
calls. We have already stated that if the llseek
method is missing from the device's operations, the
default implementation in the kernel performs seeks by modifying
filp->f_pos, the current reading/writing
position within the file. Please note that for the
lseek system call to work correctly, the
read and write methods must
cooperate by using and updating the offset item they receive as an
argument.

You may need to provide your own
llseek method if the seek operation corresponds
to a physical operation on the device. A simple example can be seen
in the scull driver:

loff_t scull_llseek(struct file *filp, loff_t off, int whence)
{
struct scull_dev *dev = filp->private_data;
loff_t newpos;
switch(whence) {
case 0: /* SEEK_SET */
newpos = off;
break;
case 1: /* SEEK_CUR */
newpos = filp->f_pos + off;
break;
case 2: /* SEEK_END */
newpos = dev->size + off;
break;
default: /* can't happen */
return -EINVAL;
}
if (newpos < 0) return -EINVAL;
filp->f_pos = newpos;
return newpos;
}

The only device-specific operation here is retrieving the file length
from the device. In scull the
read and write methods
cooperate as needed, as shown in Chapter 3.

Although the implementation just shown makes sense for
scull, which handles a well-defined data area,
most devices offer a data flow rather than a data area (just think
about the serial ports or the keyboard), and seeking those devices
does not make sense. If this is the case for your device, you
can't just refrain from declaring the
llseek operation, because the default method
allows seeking. Instead, you should inform the kernel that your
device does not support llseek by calling
nonseekable_open in your
open method:

int nonseekable_open(struct inode *inode; struct file *filp);

This call marks the given filp as being
nonseekable; the kernel never allows an lseek
call on such a file to succeed. By marking the file in this way, you
can also be assured that no attempts will be made to seek the file by
way of the pread and pwrite
system calls.

For completeness, you should also set the llseek
method in your file_operations structure to the
special helper function no_llseek, which is
defined in <linux/fs.h>.


    / 202