⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 char n block.htm

📁 What is this ``device driver stuff anyway? Here s a very short introduction to the concept.
💻 HTM
📖 第 1 页 / 共 4 页
字号:
The driver initializes
<tt>sc</tt>
to the address of the
<tt>none_softc</tt>
structure associated with this
<tt>NONE</tt>
device.
The minor device number,
<tt><var>unit</var></tt>,
is used as an index into the array of
<tt>none_softc</tt>
structures to determine which
<tt>none_softc</tt>
structure is associated with this
<tt>NONE</tt>
device.
<a href="#co_id_83_rtn_3">[Return to example]</a>
<p></p></li><li>
<a name="co_id_83_4"></a>
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut11.html#RegISIswithhandlerRtns">Section 7.1.6</a>
shows that the
<tt>/dev/none</tt>
device driver stored the I/O handle passed to its
<tt>probe</tt>
interface in
the
<tt><var>reg</var></tt>
variable.
The
<tt>/dev/none</tt>
device driver now initializes
<tt><var>reg</var></tt>
to the system virtual address (SVA) for the
<tt>NONE</tt>
device.
This address is obtained from the
<tt>addr</tt>
member of the
<tt>controller</tt>
structure associated with this
<tt>NONE</tt>
device.
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut24.html#addr">Section 17.2.11</a>
describes the
<tt>addr</tt>
member.
<p>
Because the data types are different, this line performs a type-casting
operation that converts the
<tt>addr</tt>
member (which is of type
<tt>caddr_t</tt>)
to be of type
<tt>io_handle_t</tt>.
<a href="#co_id_83_rtn_4">[Return to example]</a>
</p><p></p></li><li>
<a name="co_id_83_5"></a>
The
<tt>NONE</tt>
device is not a real device and therefore would not initiate interrupts.
However, this line shows how to turn off interrupts by writing the value
zero (0) to the
<tt>NONE</tt>
device's control/status register.
To accomplish the write operation, the
<tt>/dev/none</tt>
device driver calls the
<tt>write_io_port</tt>
interface.
<a name="nx_id_521"></a>
<p>
The
<tt>write_io_port</tt>
interface takes four arguments:
</p><ul>
<p></p><li>
The first argument specifies
an I/O handle that you can use to reference a device register or memory
located in bus address space (either I/O space or memory space).
This I/O handle references a device register in the bus address space
where the write operation occurs.
In this call, the
<tt>/dev/none</tt>
driver specifies the device's I/O address space by adding the system
virtual address (SVA) (stored in the
<tt><var>reg</var></tt>
variable) to the device register offset (represented by the
<tt>NONE_CSR</tt>
bit).
<p></p></li><li>
The second argument specifies
the width (in bytes) of the data to be written.
Valid values are 1, 2, 3, 4, and 8.
Not all CPU platforms or bus adapters support all of these values.
In this call, the
<tt>/dev/none</tt>
driver passes the value 4.
<p></p></li><li>
The third argument specifies
flags to indicate special processing requests.
Because this argument is not currently used, the
<tt>/dev/none</tt>
driver passes the value zero (0).
<p></p></li><li>
The fourth argument specifies
the data to be written to the specified device register in bus address
space.
In this call, the
<tt>/dev/none</tt>
driver passes the value zero (0).
</li></ul><p>
<a href="#co_id_83_rtn_5">[Return to example]</a>
</p><p></p></li><li>
<a name="co_id_83_6"></a>
Calls the
<tt>mb</tt>
interface to perform a memory barrier on Alpha CPUs.
It is generally recommended that drivers operating on Alpha CPUs
call the
<tt>mb</tt>
interface immediately after a call to
<tt>write_io_port</tt>.
See
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut6.html#MemoryBarriers">Section 3.1.6</a>
for a detailed discussion of when to call the
<tt>mb</tt>
interface.
<a name="nx_id_522"></a>
<a href="#co_id_83_rtn_6">[Return to example]</a>
<p></p></li><li>
<a name="co_id_83_7"></a>
Turns off the open flag by setting the
<tt>sc_openf</tt>
member of the
<tt>sc</tt>
pointer to the close bit
<tt>DN_CLOSE</tt>.
This action frees up the unit so that subsequent calls to
<tt>noneopen</tt>
will succeed.
<a href="#co_id_83_rtn_7">[Return to example]</a>
<p></p></li><li>
<a name="co_id_83_8"></a>
Returns
<tt>ESUCCESS</tt>
to indicate a successful close of the
<tt>NONE</tt>
device.
<a href="#co_id_83_rtn_8">[Return to example]</a>
</li></ol><p>
<a name="ImplementTheioctlRoutine"></a>
</p><p></p><hr><p align="center">
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/Digital_UNIX_Bookshelf.html"><img src="char%20n%20block_files/BOOKSHELF.GIF" alt="[Return to Library]" border="0"></a>
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/TOC.html"><img src="char%20n%20block_files/TOC.GIF" alt="[Contents]" border="0"></a>
<a href="#ImplBlkandCharDrvRtns"><img src="char%20n%20block_files/REW.GIF" alt="[Previous Chapter]" border="0"></a>
<a href="#PerformCloseDevTasks"><img src="char%20n%20block_files/PREV.GIF" alt="[Previous Section]" border="0"></a>
<a href="#ImplementTheInterruptRoutine"><img src="char%20n%20block_files/NEXT.GIF" alt="[Next Section]" border="0"></a>
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut15.html"><img src="char%20n%20block_files/FF.GIF" alt="[Next Chapter]" border="0"></a>
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/INDEX.html"><img src="char%20n%20block_files/INDEX.GIF" alt="[Index]" border="0"></a>
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/HELP.html"><img src="char%20n%20block_files/HELP.GIF" alt="[Help]" border="0"></a>
</p><p></p><hr><p>
</p><h2>
10.3&nbsp;&nbsp;&nbsp;&nbsp;Implementing the ioctl Interface
</h2>
<p>
<a name="nx_id_523"></a>
The
<tt>ioctl</tt>
interface
typically performs all device-related operations other than read or
write operations.
A device driver's
<tt>ioctl</tt>
interface is called as a result of an
<tt>ioctl</tt>
system call.
<a name="nx_id_524"></a>
Only those
<tt>ioctl</tt>
commands that are device specific or that require
action on the part of the device driver result in a call to the driver's
<tt>ioctl</tt>
interface.
You specify the entry point for the driver's
<tt>ioctl</tt>
interface
in a
<tt>dsent</tt>
structure.
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut8.html#dev_swit_tbls">Section 5.4</a>
describes the
<tt>dsent</tt>
structure.
<cite>Writing Device Drivers: Reference</cite>
provides a reference page that gives additional information on the
arguments and tasks associated with
an
<tt>ioctl</tt>
interface.
</p><p>
The following example shows a simple implementation of an
<tt>ioctl</tt>
interface, using the
<tt>/dev/none</tt>
driver as an example.
The
<tt>/dev/none</tt>
driver's
<tt>ioctl</tt>
interface (called
<tt>noneioctl</tt>)
obtains and clears the count of bytes that was previously written by
<tt>nonewrite</tt>.
When a user program issues the command to obtain the count, the
<tt>/dev/none</tt>
driver returns the count through the data pointer passed to the
<tt>noneioctl</tt>
interface.
When a user program asks to clear the count, the
<tt>/dev/none</tt>
driver does so.
The code example also shows a call to the
<tt>minor</tt>
interface.
See
<cite>Writing Device Drivers: Advanced Topics</cite>
for an example implementation of an
<tt>ioctl</tt>
interface for disk and tape device drivers.
</p><p>
</p><p>
</p><pre><p>
noneioctl(dev, cmd, data, flag)
dev_t dev;             <a name="co_id_84_rtn_1"></a><a href="#co_id_84_1"><strong>[1]</strong></a>
unsigned int cmd;      <a name="co_id_84_rtn_2"></a><a href="#co_id_84_2"><strong>[2]</strong></a>
caddr_t data;          <a name="co_id_84_rtn_3"></a><a href="#co_id_84_3"><strong>[3]</strong></a>
int flag;              <a name="co_id_84_rtn_4"></a><a href="#co_id_84_4"><strong>[4]</strong></a>
</p><p>
{
</p><p>
</p><p>
	int unit = minor(dev); <a name="co_id_84_rtn_5"></a><a href="#co_id_84_5"><strong>[5]</strong></a>
	int *res; <a name="co_id_84_rtn_6"></a><a href="#co_id_84_6"><strong>[6]</strong></a>
	struct none_softc *sc = &amp;none_softc[unit]; <a name="co_id_84_rtn_7"></a><a href="#co_id_84_7"><strong>[7]</strong></a>
</p><p>
</p><p>
	res = (int *) data; <a name="co_id_84_rtn_8"></a><a href="#co_id_84_8"><strong>[8]</strong></a>
</p><p>
</p><p>
	if(cmd == DN_GETCOUNT)
		*res = sc-&gt;sc_count; <a name="co_id_84_rtn_9"></a><a href="#co_id_84_9"><strong>[9]</strong></a>
</p><p>
</p><p>
	if(cmd == DN_CLRCOUNT)
		sc-&gt;sc_count = 0;  <a name="co_id_84_rtn_10"></a><a href="#co_id_84_10"><strong>[10]</strong></a>
</p><p>
</p><p>
	return (ESUCCESS); <a name="co_id_84_rtn_11"></a><a href="#co_id_84_11"><strong>[11]</strong></a>
}
</p></pre>
<p>
</p><ol>
<p></p><li>
<a name="co_id_84_1"></a>
Declares an
argument that specifies the major and minor device numbers for
a specific
<tt>NONE</tt>
device.
The minor device number is used to determine the logical unit number for
the
<tt>NONE</tt>
device on which the
<tt>ioctl</tt>
operation is to be performed.
<a href="#co_id_84_rtn_1">[Return to example]</a>
<p></p></li><li>
<a name="co_id_84_2"></a>
Declares an argument to contain the
<tt>ioctl</tt>
command as specified
in
<tt>/usr/sys/include/sys/ioctl.h</tt>
or in another include file that you define.
<a href="#co_id_84_rtn_2">[Return to example]</a>
<p></p></li><li>
<a name="co_id_84_3"></a>
Declares a pointer to the
<tt>ioctl</tt>
command-specified data that is to
be passed to the device driver or filled in by the device driver.
This argument is a kernel address.
The size of the data cannot exceed the size of a page
(currently 8 kilobytes (KB) on Alpha systems).
At least 128 bytes are guaranteed.
Any size between 128 bytes and the page size may fail if memory cannot
be allocated.
The particular
<tt>ioctl</tt>
command implicitly determines the action to be
taken.
The
<tt>ioctl</tt>
system call performs all the necessary copy operations to move data to
and from user space.
<a href="#co_id_84_rtn_3">[Return to example]</a>
<p></p></li><li>
<a name="co_id_84_4"></a>
Declares an argument that holds the access mode of the device.
The access modes are represented by flag constants defined in
<tt>/usr/sys/include/sys/file.h</tt>.
<a href="#co_id_84_rtn_4">[Return to example]</a>
<p></p></li><li>
<a name="co_id_84_5"></a>
Declares a
<tt><var>unit</var></tt>
variable and initializes it to the device minor number.
Note the use of the
<tt>minor</tt>
interface to obtain the device minor number.
<p>
The
<tt>minor</tt>
interface takes one argument: the number of the device for which an
associated device minor number will be obtained.
The minor number is encoded in the
<tt><var>dev</var></tt>
argument, which is of type
<tt>dev_t</tt>.
<a name="nx_id_525"></a>
<a href="#co_id_84_rtn_5">[Return to example]</a>
</p><p></p></li><li>
<a name="co_id_84_6"></a>
Declares a pointer to a variable called
<tt><var>res</var></tt>
that will store a pointer to the kernel memory allocated by the
<tt>ioctl</tt>
system call.
This variable also stores the character
count.
The
<tt>nonewrite</tt>
interface stores
this character count in the
<tt>sc_count</tt>
member of the
<tt>softc</tt>
structure associated with this
<tt>NONE</tt>
device.
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut12.html#CopyDataWriteRoutine">Section 8.2.2</a>
discusses the
<tt>nonewrite</tt>
interface.
<a href="#co_id_84_rtn_6">[Return to example]</a>
<p></p></li><li>
<a name="co_id_84_7"></a>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -