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

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

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

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

Jonathan Corbet, Greg Kroah-Hartman, Alessandro Rubini

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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








17.12. Custom ioctl Commands





We have seen that the
ioctl system call is implemented for sockets;
SIOCSIFADDR and SIOCSIFMAP are
examples of "socket
ioctls." Now
let's see how the third argument of the system call
is used by networking code.

When the ioctl system call is invoked on a
socket, the command number is one of the symbols defined in
<linux/sockios.h>, and the
sock_ioctl function directly invokes a
protocol-specific function (where
"protocol" refers to the main
network protocol being used, for example, IP or AppleTalk).


Any ioctl command
that is not recognized by the protocol layer is passed to the device
layer. These device-related ioctl commands
accept a third argument from user space, a struct
ifreq *. This structure is
defined in <linux/if.h>. The
SIOCSIFADDR and SIOCSIFMAP
commands actually work on the ifreq structure. The
extra argument to SIOCSIFMAP, although defined as
ifmap, is just a field of
ifreq.


In
addition to using the standardized calls, each interface can define
its own ioctl commands. The
plip interface, for example, allows the
interface to modify its internal timeout values via
ioctl. The ioctl
implementation for sockets recognizes 16 commands as private to the
interface: SIOCDEVPRIVATE through
SIOCDEVPRIVATE+15.[2]

[2] Note that,
according to <linux/sockios.h>, the
SIOCDEVPRIVATE commands are deprecated. What
should replace them is not clear, however, and numerous in-tree
drivers still use them.



When
one of these commands is recognized,
dev->do_ioctl is called in the relevant
interface driver. The function receives the same
struct ifreq
* pointer that the general-purpose
ioctl function uses:

int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);

The ifr pointer points to a kernel-space address
that holds a copy of the structure passed by the user. After
do_ioctl returns, the structure is copied back
to user space; Therefore, the driver can use the private commands to
both receive and return data.

The device-specific commands can choose to use the fields in
struct ifreq, but they already convey a
standardized meaning, and it's unlikely that the
driver can adapt the structure to its needs. The field
ifr_data is a caddr_t item (a
pointer) that is meant to be used for device-specific needs. The
driver and the program used to invoke its ioctl
commands should agree about the use of ifr_data.
For example, pppstats uses device-specific
commands to retrieve information from the ppp
interface driver.

It's not worth showing an implementation of
do_ioctl here, but with the information in this
chapter and the kernel examples, you should be able to write one when
you need it. Note, however, that the plip
implementation uses ifr_data incorrectly and
should not be used as an example for an ioctl
implementation.


    / 202