📄 char device driver interfaces.htm
字号:
driver.
<a name="nx_id_434"></a>
You specify the entry point for the driver's
<tt>write</tt>
interface
in a
<tt>dsent</tt>
structure.
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut10.html#dsentDataStruct">Section 6.6.5.1</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
a
<tt>write</tt>
interface.
</p><p>
To implement a
<tt>write</tt>
interface you must understand the
<tt>dev_t</tt>
data type and the
<tt>uio</tt>
data structure.
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut12.html#Thedev_tDataType">Section 8.1.1</a>
and
<a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut12.html#theuio_struct">Section 8.1.2</a>
discuss these topics.
The following list describes some typical tasks that you perform when
implementing
a
<tt>write</tt>
interface.
</p><ul>
<p></p><li>
Set up the
<tt>write</tt>
interface
<p></p></li><li>
Copy data to the device
</li></ul><p>
Your
<tt>write</tt>
interface will probably perform most of these tasks and, possibly, some
additional ones.
The following sections describe each of these tasks, using the
<tt>/dev/none</tt>
driver as an example.
<a name="SetUpWriteRoutine"></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%20device%20driver%20interfaces_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%20device%20driver%20interfaces_files/TOC.GIF" alt="[Contents]" border="0"></a>
<a href="#ImplCharDrvRoutines"><img src="char%20device%20driver%20interfaces_files/REW.GIF" alt="[Previous Chapter]" border="0"></a>
<a href="#ImplementTheWriteRoutine"><img src="char%20device%20driver%20interfaces_files/PREV.GIF" alt="[Previous Section]" border="0"></a>
<a href="#CopyDataWriteRoutine"><img src="char%20device%20driver%20interfaces_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/drivertut13.html"><img src="char%20device%20driver%20interfaces_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%20device%20driver%20interfaces_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%20device%20driver%20interfaces_files/HELP.GIF" alt="[Help]" border="0"></a>
</p><p></p><hr><p>
</p><h3>
8.2.1 Setting Up the write Interface
</h3>
<p>
<a name="nx_id_435"></a>
The following code shows you how to set up a
<tt>write</tt>
interface, using the
<tt>/dev/none</tt>
driver as an example:
</p><p>
</p><p>
</p><pre><p>
</p><p>
nonewrite(dev, uio, flag)
dev_t dev; <a name="co_id_66_rtn_1"></a><a href="#co_id_66_1"><strong>[1]</strong></a>
struct uio *uio; <a name="co_id_66_rtn_2"></a><a href="#co_id_66_2"><strong>[2]</strong></a>
int flag; <a name="co_id_66_rtn_3"></a><a href="#co_id_66_3"><strong>[3]</strong></a>
</p><p>
{
</p></pre>
<p>
<br>
<tt>.</tt>
<br>
<tt>.</tt>
<br>
<tt>.</tt>
<br>
</p><p>
</p><ol>
<p></p><li>
<a name="co_id_66_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 device on which the write operation is performed.
<a href="#co_id_66_rtn_1">[Return to example]</a>
<p></p></li><li>
<a name="co_id_66_2"></a>
Declares a pointer to a
<tt>uio</tt>
structure.
This structure contains the information for transferring data to and
from the address space of the user's process.
You typically
pass this pointer unmodified to the
<tt>uiomove</tt>
or
<tt>physio</tt>
kernel interface.
<a href="#co_id_66_rtn_2">[Return to example]</a>
<p></p></li><li>
<a name="co_id_66_3"></a>
Specifies the access mode of the device.
The access modes are represented by a bit mask of flags defined in the
file
<tt>/usr/sys/include/sys/fcntl.h</tt>.
<a href="#co_id_66_rtn_3">[Return to example]</a>
</li></ol><p>
<a name="CopyDataWriteRoutine"></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%20device%20driver%20interfaces_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%20device%20driver%20interfaces_files/TOC.GIF" alt="[Contents]" border="0"></a>
<a href="#ImplCharDrvRoutines"><img src="char%20device%20driver%20interfaces_files/REW.GIF" alt="[Previous Chapter]" border="0"></a>
<a href="#SetUpWriteRoutine"><img src="char%20device%20driver%20interfaces_files/PREV.GIF" alt="[Previous Section]" border="0"></a>
<a href="#ImplementTheResetRoutine"><img src="char%20device%20driver%20interfaces_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/drivertut13.html"><img src="char%20device%20driver%20interfaces_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%20device%20driver%20interfaces_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%20device%20driver%20interfaces_files/HELP.GIF" alt="[Help]" border="0"></a>
</p><p></p><hr><p>
</p><h3>
8.2.2 Copying Data to the Device
</h3>
<p>
<a name="nx_id_436"></a>
The following code shows how a driver's
<tt>write</tt>
interface copies data to a device, using the
<tt>/dev/none</tt>
driver as an example.
The code shows some typical variable and structure
declarations and the use of the
<tt>minor</tt>
and
<tt>panic</tt>
interfaces.
The
<tt>/dev/none</tt>
driver's
<tt>write</tt>
interface (called
<tt>nonewrite</tt>)
copies data from the address space pointed to by the
<tt>uio</tt>
structure to the device.
Upon a successful write,
<tt>nonewrite</tt>
returns the value zero (0) to the write system call.
</p><p>
</p><p>
</p><pre><p>
</p><p>
int unit = minor(dev); <a name="co_id_67_rtn_1"></a><a href="#co_id_67_1"><strong>[1]</strong></a>
struct controller *ctlr = noneinfo[unit]; <a name="co_id_67_rtn_2"></a><a href="#co_id_67_2"><strong>[2]</strong></a>
struct none_softc *sc = &none_softc[unit]; <a name="co_id_67_rtn_3"></a><a href="#co_id_67_3"><strong>[3]</strong></a>
unsigned int count; <a name="co_id_67_rtn_4"></a><a href="#co_id_67_4"><strong>[4]</strong></a>
struct iovec *iov; <a name="co_id_67_rtn_5"></a><a href="#co_id_67_5"><strong>[5]</strong></a>
</p><p>
</p><p>
while(uio->uio_resid > 0) { <a name="co_id_67_rtn_6"></a><a href="#co_id_67_6"><strong>[6]</strong></a>
iov = uio->uio_iov; <a name="co_id_67_rtn_7"></a><a href="#co_id_67_7"><strong>[7]</strong></a>
if(iov->iov_len == 0) { <a name="co_id_67_rtn_8"></a><a href="#co_id_67_8"><strong>[8]</strong></a>
uio->uio_iov++;
uio->uio_iovcnt--;
if(uio->uio_iovcnt < 0) <a name="co_id_67_rtn_9"></a><a href="#co_id_67_9"><strong>[9]</strong></a>
panic("none write");
continue;
}
</p><p>
</p><p>
count = iov->iov_len; <a name="co_id_67_rtn_10"></a><a href="#co_id_67_10"><strong>[10]</strong></a>
</p><p>
</p><p>
iov->iov_base += count; <a name="co_id_67_rtn_11"></a><a href="#co_id_67_11"><strong>[11]</strong></a>
iov->iov_len -= count; <a name="co_id_67_rtn_12"></a><a href="#co_id_67_12"><strong>[12]</strong></a>
uio->uio_offset += count; <a name="co_id_67_rtn_13"></a><a href="#co_id_67_13"><strong>[13]</strong></a>
uio->uio_resid -= count; <a name="co_id_67_rtn_14"></a><a href="#co_id_67_14"><strong>[14]</strong></a>
</p><p>
</p><p>
sc->sc_count +=count; <a name="co_id_67_rtn_15"></a><a href="#co_id_67_15"><strong>[15]</strong></a>
}
return (ESUCCESS);
}
</p></pre>
<p>
</p><p>
</p><ol>
<p></p><li>
<a name="co_id_67_1"></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 href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-PUBVD-TE_html/drivertut12.html#Thedev_tDataType">Section 8.1.1</a>
describes the
<tt>dev_t</tt>
data type.
<a href="#co_id_67_rtn_1">[Return to example]</a>
</p><p></p></li><li>
<a name="co_id_67_2"></a>
Declares a pointer to a
<tt>controller</tt>
structure and calls it
<tt>ctlr</tt>.
The driver initializes
<tt>ctlr</tt>
to the
<tt>controller</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>controller</tt>
structures to determine which
<tt>controller</tt>
structure is associated with this
<tt>NONE</tt>
device.
<a href="#co_id_67_rtn_2">[Return to example]</a>
<p></p></li><li>
<a name="co_id_67_3"></a>
Declares a pointer to a
<tt>none_softc</tt>
structure and calls it
<tt>sc</tt>.
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_67_rtn_3">[Return to example]</a>
<p></p></li><li>
<a name="co_id_67_4"></a>
Declares a variable that stores the size of the write
request.
<a href="#co_id_67_rtn_4">[Return to example]</a>
<p></p></li><li>
<a name="co_id_67_5"></a>
Declares a pointer to an
<tt>iovec</tt>
structure and calls it
<tt>iov</tt>.
<a href="#co_id_67_rtn_5">[Return to example]</a>
<p></p></li><li>
<a name="co_id_67_6"></a>
Checks the
size of the remaining logical buffer (represented by the
<tt>uio_resid</tt>
member)
to determine if
<tt>nonewrite</tt>
must copy data from the address space pointed to by the
<tt>uio</tt>
structure to the device.
The loop continues until all the bytes of data are copied to the
device.
<a href="#co_id_67_rtn_6">[Return to example]</a>
<p></p></li><li>
<a name="co_id_67_7"></a>
Sets the
<tt>iov</tt>
pointer to the
address of the current logical buffer segment (represented by the
<tt>uio_iov</tt>
member).
<a href="#co_id_67_rtn_7">[Return to example]</a>
<p></p></li><li>
<a name="co_id_67_8"></a>
If the remaining size of the current segment (represented by the
<tt>iov_len</tt>
member)
is equal to zero (0), increments the address of the
current logical buffer
segment (represented by the
<tt>uio_iov</tt>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -